diff -Nru linux-6.0.6/arch/arc/include/asm/io.h linux-6.0.12/arch/arc/include/asm/io.h --- linux-6.0.6/arch/arc/include/asm/io.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arc/include/asm/io.h 2023-01-18 18:27:39.000000000 +0000 @@ -32,7 +32,7 @@ { } -extern void iounmap(const void __iomem *addr); +extern void iounmap(const volatile void __iomem *addr); /* * io{read,write}{16,32}be() macros diff -Nru linux-6.0.6/arch/arc/include/asm/pgtable-levels.h linux-6.0.12/arch/arc/include/asm/pgtable-levels.h --- linux-6.0.6/arch/arc/include/asm/pgtable-levels.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arc/include/asm/pgtable-levels.h 2023-01-18 18:27:39.000000000 +0000 @@ -161,7 +161,7 @@ #define pmd_pfn(pmd) ((pmd_val(pmd) & PAGE_MASK) >> PAGE_SHIFT) #define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd)) #define set_pmd(pmdp, pmd) (*(pmdp) = pmd) -#define pmd_pgtable(pmd) ((pgtable_t) pmd_page_vaddr(pmd)) +#define pmd_pgtable(pmd) ((pgtable_t) pmd_page(pmd)) /* * 4th level paging: pte diff -Nru linux-6.0.6/arch/arc/mm/ioremap.c linux-6.0.12/arch/arc/mm/ioremap.c --- linux-6.0.6/arch/arc/mm/ioremap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arc/mm/ioremap.c 2023-01-18 18:27:39.000000000 +0000 @@ -94,7 +94,7 @@ EXPORT_SYMBOL(ioremap_prot); -void iounmap(const void __iomem *addr) +void iounmap(const volatile void __iomem *addr) { /* weird double cast to handle phys_addr_t > 32 bits */ if (arc_uncached_addr_space((phys_addr_t)(u32)addr)) diff -Nru linux-6.0.6/arch/arm/boot/dts/am335x-pcm-953.dtsi linux-6.0.12/arch/arm/boot/dts/am335x-pcm-953.dtsi --- linux-6.0.6/arch/arm/boot/dts/am335x-pcm-953.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/am335x-pcm-953.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -12,22 +12,20 @@ compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx"; /* Power */ - regulators { - vcc3v3: fixedregulator@1 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - }; + vcc3v3: fixedregulator1 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; - vcc1v8: fixedregulator@2 { - compatible = "regulator-fixed"; - regulator-name = "vcc1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - }; + vcc1v8: fixedregulator2 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; }; /* User IO */ diff -Nru linux-6.0.6/arch/arm/boot/dts/at91rm9200.dtsi linux-6.0.12/arch/arm/boot/dts/at91rm9200.dtsi --- linux-6.0.6/arch/arm/boot/dts/at91rm9200.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/at91rm9200.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -660,7 +660,7 @@ compatible = "atmel,at91rm9200-udc"; reg = <0xfffb0000 0x4000>; interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 2>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 1>; clock-names = "pclk", "hclk"; status = "disabled"; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/at91sam9g20ek_common.dtsi linux-6.0.12/arch/arm/boot/dts/at91sam9g20ek_common.dtsi --- linux-6.0.6/arch/arm/boot/dts/at91sam9g20ek_common.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/at91sam9g20ek_common.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -39,6 +39,13 @@ }; + usb1 { + pinctrl_usb1_vbus_gpio: usb1_vbus_gpio { + atmel,pins = + ; /* PC5 GPIO */ + }; + }; + mmc0_slot1 { pinctrl_board_mmc0_slot1: mmc0_slot1-board { atmel,pins = @@ -84,6 +91,8 @@ }; usb1: gadget@fffa4000 { + pinctrl-0 = <&pinctrl_usb1_vbus_gpio>; + pinctrl-names = "default"; atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/imx6qdl-gw5910.dtsi linux-6.0.12/arch/arm/boot/dts/imx6qdl-gw5910.dtsi --- linux-6.0.6/arch/arm/boot/dts/imx6qdl-gw5910.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/imx6qdl-gw5910.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -29,7 +29,7 @@ user-pb { label = "user_pb"; - gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>; + gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>; linux,code = ; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/imx6qdl-gw5913.dtsi linux-6.0.12/arch/arm/boot/dts/imx6qdl-gw5913.dtsi --- linux-6.0.6/arch/arm/boot/dts/imx6qdl-gw5913.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/imx6qdl-gw5913.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -26,7 +26,7 @@ user-pb { label = "user_pb"; - gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>; + gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>; linux,code = ; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/imx6q-prti6q.dts linux-6.0.12/arch/arm/boot/dts/imx6q-prti6q.dts --- linux-6.0.6/arch/arm/boot/dts/imx6q-prti6q.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/imx6q-prti6q.dts 2023-01-18 18:27:39.000000000 +0000 @@ -364,8 +364,8 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_wifi>; interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>; - ref-clock-frequency = "38400000"; - tcxo-clock-frequency = "19200000"; + ref-clock-frequency = <38400000>; + tcxo-clock-frequency = <19200000>; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts linux-6.0.12/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts --- linux-6.0.6/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts 2023-01-18 18:27:39.000000000 +0000 @@ -33,6 +33,10 @@ status = "okay"; }; +®_pu { + regulator-always-on; +}; + ®_usb_h1_vbus { status = "okay"; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/imx6q-yapp4-crux.dts linux-6.0.12/arch/arm/boot/dts/imx6q-yapp4-crux.dts --- linux-6.0.6/arch/arm/boot/dts/imx6q-yapp4-crux.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/imx6q-yapp4-crux.dts 2023-01-18 18:27:39.000000000 +0000 @@ -33,6 +33,10 @@ status = "okay"; }; +®_pu { + regulator-always-on; +}; + ®_usb_h1_vbus { status = "okay"; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/imx7s.dtsi linux-6.0.12/arch/arm/boot/dts/imx7s.dtsi --- linux-6.0.6/arch/arm/boot/dts/imx7s.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/imx7s.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -1270,10 +1270,10 @@ clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; }; - gpmi: nand-controller@33002000{ + gpmi: nand-controller@33002000 { compatible = "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; diff -Nru linux-6.0.6/arch/arm/boot/dts/sama7g5-pinfunc.h linux-6.0.12/arch/arm/boot/dts/sama7g5-pinfunc.h --- linux-6.0.6/arch/arm/boot/dts/sama7g5-pinfunc.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/sama7g5-pinfunc.h 2023-01-18 18:27:39.000000000 +0000 @@ -261,7 +261,7 @@ #define PIN_PB2__FLEXCOM6_IO0 PINMUX_PIN(PIN_PB2, 2, 1) #define PIN_PB2__ADTRG PINMUX_PIN(PIN_PB2, 3, 1) #define PIN_PB2__A20 PINMUX_PIN(PIN_PB2, 4, 1) -#define PIN_PB2__FLEXCOM11_IO0 PINMUX_PIN(PIN_PB2, 6, 3) +#define PIN_PB2__FLEXCOM11_IO1 PINMUX_PIN(PIN_PB2, 6, 3) #define PIN_PB3 35 #define PIN_PB3__GPIO PINMUX_PIN(PIN_PB3, 0, 0) #define PIN_PB3__RF1 PINMUX_PIN(PIN_PB3, 1, 1) diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-href.dtsi linux-6.0.12/arch/arm/boot/dts/ste-href.dtsi --- linux-6.0.6/arch/arm/boot/dts/ste-href.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-href.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -24,6 +24,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-snowball.dts linux-6.0.12/arch/arm/boot/dts/ste-snowball.dts --- linux-6.0.6/arch/arm/boot/dts/ste-snowball.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-snowball.dts 2023-01-18 18:27:39.000000000 +0000 @@ -28,6 +28,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-codina.dts linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-codina.dts --- linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-codina.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-codina.dts 2023-01-18 18:27:39.000000000 +0000 @@ -57,6 +57,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts --- linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts 2023-01-18 18:27:39.000000000 +0000 @@ -44,6 +44,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts --- linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts 2023-01-18 18:27:39.000000000 +0000 @@ -30,6 +30,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-golden.dts linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-golden.dts --- linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-golden.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-golden.dts 2023-01-18 18:27:39.000000000 +0000 @@ -35,6 +35,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-janice.dts linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-janice.dts --- linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-janice.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-janice.dts 2023-01-18 18:27:39.000000000 +0000 @@ -30,6 +30,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts --- linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts 2023-01-18 18:27:39.000000000 +0000 @@ -34,6 +34,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts --- linux-6.0.6/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts 2023-01-18 18:27:39.000000000 +0000 @@ -30,6 +30,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/arch/arm/mach-at91/pm_suspend.S linux-6.0.12/arch/arm/mach-at91/pm_suspend.S --- linux-6.0.6/arch/arm/mach-at91/pm_suspend.S 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/mach-at91/pm_suspend.S 2023-01-18 18:27:39.000000000 +0000 @@ -169,10 +169,15 @@ cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW bne sr_ena_2 - /* Put DDR PHY's DLL in bypass mode for non-backup modes. */ + /* Disable DX DLLs for non-backup modes. */ cmp r7, #AT91_PM_BACKUP beq sr_ena_3 + /* Do not soft reset the AC DLL. */ + ldr tmp1, [r3, DDR3PHY_ACDLLCR] + bic tmp1, tmp1, DDR3PHY_ACDLLCR_DLLSRST + str tmp1, [r3, DDR3PHY_ACDLLCR] + /* Disable DX DLLs. */ ldr tmp1, [r3, #DDR3PHY_DX0DLLCR] orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS diff -Nru linux-6.0.6/arch/arm/mach-mxs/mach-mxs.c linux-6.0.12/arch/arm/mach-mxs/mach-mxs.c --- linux-6.0.6/arch/arm/mach-mxs/mach-mxs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm/mach-mxs/mach-mxs.c 2023-01-18 18:27:39.000000000 +0000 @@ -393,8 +393,10 @@ root = of_find_node_by_path("/"); ret = of_property_read_string(root, "model", &soc_dev_attr->machine); - if (ret) + if (ret) { + kfree(soc_dev_attr); return; + } soc_dev_attr->family = "Freescale MXS Family"; soc_dev_attr->soc_id = mxs_get_soc_id(); diff -Nru linux-6.0.6/arch/arm64/boot/dts/arm/juno-base.dtsi linux-6.0.12/arch/arm64/boot/dts/arm/juno-base.dtsi --- linux-6.0.6/arch/arm64/boot/dts/arm/juno-base.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/arm/juno-base.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -751,12 +751,26 @@ polling-delay = <1000>; polling-delay-passive = <100>; thermal-sensors = <&scpi_sensors0 0>; + trips { + pmic_crit0: trip0 { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; soc { polling-delay = <1000>; polling-delay-passive = <100>; thermal-sensors = <&scpi_sensors0 3>; + trips { + soc_crit0: trip0 { + temperature = <80000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; big_cluster_thermal_zone: big-cluster { diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi linux-6.0.12/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi --- linux-6.0.6/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -779,6 +779,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(1)>; status = "disabled"; }; @@ -788,6 +791,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(1)>; status = "disabled"; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi linux-6.0.12/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi --- linux-6.0.6/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -533,6 +533,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(2)>; status = "disabled"; }; @@ -542,6 +545,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(2)>; status = "disabled"; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi linux-6.0.12/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi --- linux-6.0.6/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -1385,6 +1385,9 @@ #address-cells = <1>; #size-cells = <0>; little-endian; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(2)>; status = "disabled"; }; @@ -1395,6 +1398,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(2)>; status = "disabled"; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mm.dtsi linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mm.dtsi --- linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mm.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mm.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -276,6 +276,7 @@ assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; clock-names = "main_clk"; + power-domains = <&pgc_otg1>; }; usbphynop2: usbphynop2 { @@ -285,6 +286,7 @@ assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; clock-names = "main_clk"; + power-domains = <&pgc_otg2>; }; soc: soc@0 { @@ -674,13 +676,11 @@ pgc_otg1: power-domain@2 { #power-domain-cells = <0>; reg = ; - power-domains = <&pgc_hsiomix>; }; pgc_otg2: power-domain@3 { #power-domain-cells = <0>; reg = ; - power-domains = <&pgc_hsiomix>; }; pgc_gpumix: power-domain@4 { @@ -1186,7 +1186,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; phys = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>; - power-domains = <&pgc_otg1>; + power-domains = <&pgc_hsiomix>; status = "disabled"; }; @@ -1206,7 +1206,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; phys = <&usbphynop2>; fsl,usbmisc = <&usbmisc2 0>; - power-domains = <&pgc_otg2>; + power-domains = <&pgc_hsiomix>; status = "disabled"; }; @@ -1244,10 +1244,10 @@ clocks = <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>; }; - gpmi: nand-controller@33002000{ + gpmi: nand-controller@33002000 { compatible = "fsl,imx8mm-gpmi-nand", "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts --- linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts 2023-01-18 18:27:39.000000000 +0000 @@ -250,21 +250,21 @@ /* SODIMM 96 */ MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x1c4 /* CPLD_D[7] */ - MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x1c4 + MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x184 /* CPLD_D[6] */ - MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x1c4 + MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x184 /* CPLD_D[5] */ - MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x1c4 + MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x184 /* CPLD_D[4] */ - MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x1c4 + MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x184 /* CPLD_D[3] */ - MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x1c4 + MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x184 /* CPLD_D[2] */ - MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x1c4 + MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x184 /* CPLD_D[1] */ - MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x1c4 + MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x184 /* CPLD_D[0] */ - MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x1c4 + MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x184 /* KBD_intK */ MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x1c4 /* DISP_reset */ diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts --- linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts 2023-01-18 18:27:39.000000000 +0000 @@ -34,11 +34,25 @@ off-on-delay-us = <12000>; }; - extcon_usbotg1: extcon-usbotg1 { - compatible = "linux,extcon-usb-gpio"; + connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + type = "micro"; + label = "X19"; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usb1_extcon>; - id-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pinctrl_usb1_connector>; + id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usb_dr_connector: endpoint { + remote-endpoint = <&usb1_drd_sw>; + }; + }; + }; }; }; @@ -105,13 +119,19 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotg1>; dr_mode = "otg"; - extcon = <&extcon_usbotg1>; srp-disable; hnp-disable; adp-disable; power-active-high; over-current-active-low; + usb-role-switch; status = "okay"; + + port { + usb1_drd_sw: endpoint { + remote-endpoint = <&usb_dr_connector>; + }; + }; }; &usbotg2 { @@ -231,7 +251,7 @@ ; }; - pinctrl_usb1_extcon: usb1-extcongrp { + pinctrl_usb1_connector: usb1-connectorgrp { fsl,pins = ; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mn.dtsi linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mn.dtsi --- linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mn.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mn.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -662,7 +662,6 @@ pgc_otg1: power-domain@1 { #power-domain-cells = <0>; reg = ; - power-domains = <&pgc_hsiomix>; }; pgc_gpumix: power-domain@2 { @@ -1076,7 +1075,7 @@ assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>; phys = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>; - power-domains = <&pgc_otg1>; + power-domains = <&pgc_hsiomix>; status = "disabled"; }; @@ -1103,7 +1102,7 @@ gpmi: nand-controller@33002000 { compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; @@ -1175,5 +1174,6 @@ assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>; assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>; clock-names = "main_clk"; + power-domains = <&pgc_otg1>; }; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi --- linux-6.0.6/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -339,16 +339,6 @@ "SODIMM_82", "SODIMM_70", "SODIMM_72"; - - ctrl-sleep-moci-hog { - gpio-hog; - /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */ - gpios = <29 GPIO_ACTIVE_HIGH>; - line-name = "CTRL_SLEEP_MOCI#"; - output-high; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_ctrl_sleep_moci>; - }; }; &gpio3 { @@ -417,6 +407,16 @@ "SODIMM_256", "SODIMM_48", "SODIMM_44"; + + ctrl-sleep-moci-hog { + gpio-hog; + /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */ + gpios = <29 GPIO_ACTIVE_HIGH>; + line-name = "CTRL_SLEEP_MOCI#"; + output-high; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ctrl_sleep_moci>; + }; }; /* On-module I2C */ diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi linux-6.0.12/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi --- linux-6.0.6/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -38,9 +38,9 @@ interrupts = ; reg = <0x5b010000 0x10000>; clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>, - <&sdhc0_lpcg IMX_LPCG_CLK_5>, - <&sdhc0_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "per", "ahb"; + <&sdhc0_lpcg IMX_LPCG_CLK_0>, + <&sdhc0_lpcg IMX_LPCG_CLK_5>; + clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_0>; status = "disabled"; }; @@ -49,9 +49,9 @@ interrupts = ; reg = <0x5b020000 0x10000>; clocks = <&sdhc1_lpcg IMX_LPCG_CLK_4>, - <&sdhc1_lpcg IMX_LPCG_CLK_5>, - <&sdhc1_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "per", "ahb"; + <&sdhc1_lpcg IMX_LPCG_CLK_0>, + <&sdhc1_lpcg IMX_LPCG_CLK_5>; + clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_1>; fsl,tuning-start-tap = <20>; fsl,tuning-step = <2>; @@ -62,9 +62,9 @@ interrupts = ; reg = <0x5b030000 0x10000>; clocks = <&sdhc2_lpcg IMX_LPCG_CLK_4>, - <&sdhc2_lpcg IMX_LPCG_CLK_5>, - <&sdhc2_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "per", "ahb"; + <&sdhc2_lpcg IMX_LPCG_CLK_0>, + <&sdhc2_lpcg IMX_LPCG_CLK_5>; + clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_2>; status = "disabled"; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/freescale/imx93.dtsi linux-6.0.12/arch/arm64/boot/dts/freescale/imx93.dtsi --- linux-6.0.6/arch/arm64/boot/dts/freescale/imx93.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/freescale/imx93.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -295,7 +295,10 @@ interrupts = ; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 32 32>; + clocks = <&clk IMX93_CLK_GPIO2_GATE>, + <&clk IMX93_CLK_GPIO2_GATE>; + clock-names = "gpio", "port"; + gpio-ranges = <&iomuxc 0 4 30>; }; gpio3: gpio@43820080 { @@ -306,7 +309,11 @@ interrupts = ; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 64 32>; + clocks = <&clk IMX93_CLK_GPIO3_GATE>, + <&clk IMX93_CLK_GPIO3_GATE>; + clock-names = "gpio", "port"; + gpio-ranges = <&iomuxc 0 84 8>, <&iomuxc 8 66 18>, + <&iomuxc 26 34 2>, <&iomuxc 28 0 4>; }; gpio4: gpio@43830080 { @@ -317,7 +324,10 @@ interrupts = ; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 96 32>; + clocks = <&clk IMX93_CLK_GPIO4_GATE>, + <&clk IMX93_CLK_GPIO4_GATE>; + clock-names = "gpio", "port"; + gpio-ranges = <&iomuxc 0 38 28>, <&iomuxc 28 36 2>; }; gpio1: gpio@47400080 { @@ -328,7 +338,10 @@ interrupts = ; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 0 32>; + clocks = <&clk IMX93_CLK_GPIO1_GATE>, + <&clk IMX93_CLK_GPIO1_GATE>; + clock-names = "gpio", "port"; + gpio-ranges = <&iomuxc 0 92 16>; }; }; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/ipq8074.dtsi linux-6.0.12/arch/arm64/boot/dts/qcom/ipq8074.dtsi --- linux-6.0.6/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/ipq8074.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -668,7 +668,7 @@ apcs_glb: mailbox@b111000 { compatible = "qcom,ipq8074-apcs-apps-global"; - reg = <0x0b111000 0x6000>; + reg = <0x0b111000 0x1000>; #clock-cells = <1>; #mbox-cells = <1>; diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sa8155p-adp.dts linux-6.0.12/arch/arm64/boot/dts/qcom/sa8155p-adp.dts --- linux-6.0.6/arch/arm64/boot/dts/qcom/sa8155p-adp.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sa8155p-adp.dts 2023-01-18 18:27:39.000000000 +0000 @@ -43,7 +43,6 @@ regulator-always-on; regulator-boot-on; - regulator-allow-set-load; vin-supply = <&vreg_3p3>; }; @@ -137,6 +136,9 @@ regulator-max-microvolt = <880000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7a_1p8: ldo7 { @@ -152,6 +154,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l11a_0p8: ldo11 { @@ -258,6 +263,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7c_1p8: ldo7 { @@ -273,6 +281,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l10c_3p3: ldo10 { diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sa8295p-adp.dts linux-6.0.12/arch/arm64/boot/dts/qcom/sa8295p-adp.dts --- linux-6.0.6/arch/arm64/boot/dts/qcom/sa8295p-adp.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sa8295p-adp.dts 2023-01-18 18:27:39.000000000 +0000 @@ -83,6 +83,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l4c: ldo4 { @@ -98,6 +101,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7c: ldo7 { @@ -113,6 +119,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l17c: ldo17 { @@ -121,6 +130,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sc7280.dtsi linux-6.0.12/arch/arm64/boot/dts/qcom/sc7280.dtsi --- linux-6.0.6/arch/arm64/boot/dts/qcom/sc7280.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sc7280.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -2177,7 +2177,8 @@ lpass_audiocc: clock-controller@3300000 { compatible = "qcom,sc7280-lpassaudiocc"; - reg = <0 0x03300000 0 0x30000>; + reg = <0 0x03300000 0 0x30000>, + <0 0x032a9000 0 0x1000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>; clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src"; diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts linux-6.0.12/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts --- linux-6.0.6/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts 2023-01-18 18:27:39.000000000 +0000 @@ -124,6 +124,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l13c: ldo13 { @@ -146,6 +149,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l4d: ldo4 { diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sc8280xp.dtsi linux-6.0.12/arch/arm64/boot/dts/qcom/sc8280xp.dtsi --- linux-6.0.6/arch/arm64/boot/dts/qcom/sc8280xp.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sc8280xp.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -885,13 +885,13 @@ ufs_mem_phy: phy@1d87000 { compatible = "qcom,sc8280xp-qmp-ufs-phy"; - reg = <0 0x01d87000 0 0xe10>; + reg = <0 0x01d87000 0 0x1c8>; #address-cells = <2>; #size-cells = <2>; ranges; clock-names = "ref", "ref_aux"; - clocks = <&rpmhcc RPMH_CXO_CLK>, + clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; resets = <&ufs_mem_hc 0>; @@ -953,13 +953,13 @@ ufs_card_phy: phy@1da7000 { compatible = "qcom,sc8280xp-qmp-ufs-phy"; - reg = <0 0x01da7000 0 0xe10>; + reg = <0 0x01da7000 0 0x1c8>; #address-cells = <2>; #size-cells = <2>; ranges; clock-names = "ref", "ref_aux"; - clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>, + clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_CARD_PHY_AUX_CLK>; resets = <&ufs_card_hc 0>; @@ -1181,26 +1181,16 @@ usb_0_ssphy: usb3-phy@88eb400 { reg = <0 0x088eb400 0 0x100>, <0 0x088eb600 0 0x3ec>, - <0 0x088ec400 0 0x1f0>, + <0 0x088ec400 0 0x364>, <0 0x088eba00 0 0x100>, <0 0x088ebc00 0 0x3ec>, - <0 0x088ec700 0 0x64>; + <0 0x088ec200 0 0x18>; #phy-cells = <0>; #clock-cells = <0>; clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; clock-names = "pipe0"; clock-output-names = "usb0_phy_pipe_clk_src"; }; - - usb_0_dpphy: dp-phy@88ed200 { - reg = <0 0x088ed200 0 0x200>, - <0 0x088ed400 0 0x200>, - <0 0x088eda00 0 0x200>, - <0 0x088ea600 0 0x200>, - <0 0x088ea800 0 0x200>; - #clock-cells = <1>; - #phy-cells = <0>; - }; }; usb_1_hsphy: phy@8902000 { @@ -1242,8 +1232,8 @@ usb_1_ssphy: usb3-phy@8903400 { reg = <0 0x08903400 0 0x100>, - <0 0x08903c00 0 0x3ec>, - <0 0x08904400 0 0x1f0>, + <0 0x08903600 0 0x3ec>, + <0 0x08904400 0 0x364>, <0 0x08903a00 0 0x100>, <0 0x08903c00 0 0x3ec>, <0 0x08904200 0 0x18>; @@ -1253,16 +1243,6 @@ clock-names = "pipe0"; clock-output-names = "usb1_phy_pipe_clk_src"; }; - - usb_1_dpphy: dp-phy@8904200 { - reg = <0 0x08904200 0 0x200>, - <0 0x08904400 0 0x200>, - <0 0x08904a00 0 0x200>, - <0 0x08904600 0 0x200>, - <0 0x08904800 0 0x200>; - #clock-cells = <1>; - #phy-cells = <0>; - }; }; system-cache-controller@9200000 { diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi linux-6.0.12/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi --- linux-6.0.6/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -348,6 +348,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7c_3p0: ldo7 { @@ -367,6 +370,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l10c_3p3: ldo10 { diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sm8250.dtsi linux-6.0.12/arch/arm64/boot/dts/qcom/sm8250.dtsi --- linux-6.0.6/arch/arm64/boot/dts/qcom/sm8250.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sm8250.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -334,6 +334,7 @@ exit-latency-us = <6562>; min-residency-us = <9987>; local-timer-stop; + status = "disabled"; }; }; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi linux-6.0.12/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi --- linux-6.0.6/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -317,6 +317,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7c_2p85: ldo7 { @@ -339,6 +342,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l10c_3p3: ldo10 { diff -Nru linux-6.0.6/arch/arm64/boot/dts/qcom/sm8350-hdk.dts linux-6.0.12/arch/arm64/boot/dts/qcom/sm8350-hdk.dts --- linux-6.0.6/arch/arm64/boot/dts/qcom/sm8350-hdk.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/qcom/sm8350-hdk.dts 2023-01-18 18:27:39.000000000 +0000 @@ -107,6 +107,9 @@ regulator-max-microvolt = <888000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l6b_1p2: ldo6 { @@ -115,6 +118,9 @@ regulator-max-microvolt = <1208000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7b_2p96: ldo7 { @@ -123,6 +129,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l9b_1p2: ldo9 { @@ -131,6 +140,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts linux-6.0.12/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts --- linux-6.0.6/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts 2023-01-18 18:27:39.000000000 +0000 @@ -207,7 +207,7 @@ cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; disable-wp; - max-frequency = <150000000>; + max-frequency = <40000000>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc3v3_baseboard>; diff -Nru linux-6.0.6/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts linux-6.0.12/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts --- linux-6.0.6/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts 2023-01-18 18:27:39.000000000 +0000 @@ -740,7 +740,7 @@ &uart1 { pinctrl-names = "default"; - pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn>; + pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>; status = "okay"; uart-has-rtscts; @@ -748,13 +748,14 @@ compatible = "brcm,bcm43438-bt"; clocks = <&rk817 1>; clock-names = "lpo"; - device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; - host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; vbat-supply = <&vcc_sys>; vddio-supply = <&vcca1v8_pmu>; + max-speed = <3000000>; }; }; diff -Nru linux-6.0.6/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts linux-6.0.12/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts --- linux-6.0.6/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts 2023-01-18 18:27:39.000000000 +0000 @@ -176,7 +176,7 @@ compatible = "rockchip,rk809"; reg = <0x20>; interrupt-parent = <&gpio0>; - interrupts = ; + interrupts = ; clock-output-names = "rk808-clkout1", "rk808-clkout2"; pinctrl-names = "default"; diff -Nru linux-6.0.6/arch/arm64/include/asm/cputype.h linux-6.0.12/arch/arm64/include/asm/cputype.h --- linux-6.0.6/arch/arm64/include/asm/cputype.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/include/asm/cputype.h 2023-01-18 18:27:39.000000000 +0000 @@ -41,7 +41,7 @@ (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) #define MIDR_CPU_MODEL(imp, partnum) \ - (((imp) << MIDR_IMPLEMENTOR_SHIFT) | \ + ((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \ (0xf << MIDR_ARCHITECTURE_SHIFT) | \ ((partnum) << MIDR_PARTNUM_SHIFT)) @@ -60,6 +60,7 @@ #define ARM_CPU_IMP_FUJITSU 0x46 #define ARM_CPU_IMP_HISI 0x48 #define ARM_CPU_IMP_APPLE 0x61 +#define ARM_CPU_IMP_AMPERE 0xC0 #define ARM_CPU_PART_AEM_V8 0xD0F #define ARM_CPU_PART_FOUNDATION 0xD00 @@ -123,6 +124,8 @@ #define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028 #define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029 +#define AMPERE_CPU_PART_AMPERE1 0xAC3 + #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) @@ -172,6 +175,7 @@ #define MIDR_APPLE_M1_FIRESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) #define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX) #define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX) +#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */ #define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX diff -Nru linux-6.0.6/arch/arm64/include/asm/pgtable.h linux-6.0.12/arch/arm64/include/asm/pgtable.h --- linux-6.0.6/arch/arm64/include/asm/pgtable.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/include/asm/pgtable.h 2023-01-18 18:27:39.000000000 +0000 @@ -863,12 +863,12 @@ static inline bool pmd_user_accessible_page(pmd_t pmd) { - return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)); + return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)); } static inline bool pud_user_accessible_page(pud_t pud) { - return pud_present(pud) && pud_user(pud); + return pud_leaf(pud) && pud_user(pud); } #endif diff -Nru linux-6.0.6/arch/arm64/include/asm/syscall_wrapper.h linux-6.0.12/arch/arm64/include/asm/syscall_wrapper.h --- linux-6.0.6/arch/arm64/include/asm/syscall_wrapper.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/include/asm/syscall_wrapper.h 2023-01-18 18:27:39.000000000 +0000 @@ -8,7 +8,7 @@ #ifndef __ASM_SYSCALL_WRAPPER_H #define __ASM_SYSCALL_WRAPPER_H -struct pt_regs; +#include #define SC_ARM64_REGS_TO_ARGS(x, ...) \ __MAP(x,__SC_ARGS \ diff -Nru linux-6.0.6/arch/arm64/kernel/efi.c linux-6.0.12/arch/arm64/kernel/efi.c --- linux-6.0.6/arch/arm64/kernel/efi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/kernel/efi.c 2023-01-18 18:27:39.000000000 +0000 @@ -12,6 +12,14 @@ #include +static bool region_is_misaligned(const efi_memory_desc_t *md) +{ + if (PAGE_SIZE == EFI_PAGE_SIZE) + return false; + return !PAGE_ALIGNED(md->phys_addr) || + !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT); +} + /* * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be * executable, everything else can be mapped with the XN bits @@ -25,14 +33,22 @@ if (type == EFI_MEMORY_MAPPED_IO) return PROT_DEVICE_nGnRE; - if (WARN_ONCE(!PAGE_ALIGNED(md->phys_addr), - "UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?")) + if (region_is_misaligned(md)) { + static bool __initdata code_is_misaligned; + /* - * If the region is not aligned to the page size of the OS, we - * can not use strict permissions, since that would also affect - * the mapping attributes of the adjacent regions. + * Regions that are not aligned to the OS page size cannot be + * mapped with strict permissions, as those might interfere + * with the permissions that are needed by the adjacent + * region's mapping. However, if we haven't encountered any + * misaligned runtime code regions so far, we can safely use + * non-executable permissions for non-code regions. */ - return pgprot_val(PAGE_KERNEL_EXEC); + code_is_misaligned |= (type == EFI_RUNTIME_SERVICES_CODE); + + return code_is_misaligned ? pgprot_val(PAGE_KERNEL_EXEC) + : pgprot_val(PAGE_KERNEL); + } /* R-- */ if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) == @@ -63,19 +79,16 @@ bool page_mappings_only = (md->type == EFI_RUNTIME_SERVICES_CODE || md->type == EFI_RUNTIME_SERVICES_DATA); - if (!PAGE_ALIGNED(md->phys_addr) || - !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT)) { - /* - * If the end address of this region is not aligned to page - * size, the mapping is rounded up, and may end up sharing a - * page frame with the next UEFI memory region. If we create - * a block entry now, we may need to split it again when mapping - * the next region, and support for that is going to be removed - * from the MMU routines. So avoid block mappings altogether in - * that case. - */ + /* + * If this region is not aligned to the page size used by the OS, the + * mapping will be rounded outwards, and may end up sharing a page + * frame with an adjacent runtime memory region. Given that the page + * table descriptor covering the shared page will be rewritten when the + * adjacent region gets mapped, we must avoid block mappings here so we + * don't have to worry about splitting them when that happens. + */ + if (region_is_misaligned(md)) page_mappings_only = true; - } create_pgd_mapping(mm, md->phys_addr, md->virt_addr, md->num_pages << EFI_PAGE_SHIFT, @@ -102,6 +115,9 @@ BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && md->type != EFI_RUNTIME_SERVICES_DATA); + if (region_is_misaligned(md)) + return 0; + /* * Calling apply_to_page_range() is only safe on regions that are * guaranteed to be mapped down to pages. Since we are only called diff -Nru linux-6.0.6/arch/arm64/kernel/entry-common.c linux-6.0.12/arch/arm64/kernel/entry-common.c --- linux-6.0.6/arch/arm64/kernel/entry-common.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/kernel/entry-common.c 2023-01-18 18:27:39.000000000 +0000 @@ -329,7 +329,8 @@ __this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 0); } -static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) +static __always_inline bool +cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) { if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa)) return false; diff -Nru linux-6.0.6/arch/arm64/kernel/proton-pack.c linux-6.0.12/arch/arm64/kernel/proton-pack.c --- linux-6.0.6/arch/arm64/kernel/proton-pack.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/kernel/proton-pack.c 2023-01-18 18:27:39.000000000 +0000 @@ -868,6 +868,10 @@ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), {}, }; + static const struct midr_range spectre_bhb_k11_list[] = { + MIDR_ALL_VERSIONS(MIDR_AMPERE1), + {}, + }; static const struct midr_range spectre_bhb_k8_list[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), MIDR_ALL_VERSIONS(MIDR_CORTEX_A57), @@ -878,6 +882,8 @@ k = 32; else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list)) k = 24; + else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list)) + k = 11; else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list)) k = 8; diff -Nru linux-6.0.6/arch/arm64/kvm/hyp/exception.c linux-6.0.12/arch/arm64/kvm/hyp/exception.c --- linux-6.0.6/arch/arm64/kvm/hyp/exception.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/kvm/hyp/exception.c 2023-01-18 18:27:39.000000000 +0000 @@ -13,6 +13,7 @@ #include #include #include +#include #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__) #error Hypervisor code only! @@ -115,7 +116,7 @@ new |= (old & PSR_C_BIT); new |= (old & PSR_V_BIT); - if (kvm_has_mte(vcpu->kvm)) + if (kvm_has_mte(kern_hyp_va(vcpu->kvm))) new |= PSR_TCO_BIT; new |= (old & PSR_DIT_BIT); diff -Nru linux-6.0.6/arch/arm64/kvm/hyp/include/hyp/switch.h linux-6.0.12/arch/arm64/kvm/hyp/include/hyp/switch.h --- linux-6.0.6/arch/arm64/kvm/hyp/include/hyp/switch.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/kvm/hyp/include/hyp/switch.h 2023-01-18 18:27:39.000000000 +0000 @@ -87,6 +87,17 @@ vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); + + if (cpus_have_final_cap(ARM64_SME)) { + sysreg_clear_set_s(SYS_HFGRTR_EL2, + HFGxTR_EL2_nSMPRI_EL1_MASK | + HFGxTR_EL2_nTPIDR2_EL0_MASK, + 0); + sysreg_clear_set_s(SYS_HFGWTR_EL2, + HFGxTR_EL2_nSMPRI_EL1_MASK | + HFGxTR_EL2_nTPIDR2_EL0_MASK, + 0); + } } static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) @@ -96,6 +107,15 @@ write_sysreg(0, hstr_el2); if (kvm_arm_support_pmu_v3()) write_sysreg(0, pmuserenr_el0); + + if (cpus_have_final_cap(ARM64_SME)) { + sysreg_clear_set_s(SYS_HFGRTR_EL2, 0, + HFGxTR_EL2_nSMPRI_EL1_MASK | + HFGxTR_EL2_nTPIDR2_EL0_MASK); + sysreg_clear_set_s(SYS_HFGWTR_EL2, 0, + HFGxTR_EL2_nSMPRI_EL1_MASK | + HFGxTR_EL2_nTPIDR2_EL0_MASK); + } } static inline void ___activate_traps(struct kvm_vcpu *vcpu) diff -Nru linux-6.0.6/arch/arm64/kvm/hyp/nvhe/switch.c linux-6.0.12/arch/arm64/kvm/hyp/nvhe/switch.c --- linux-6.0.6/arch/arm64/kvm/hyp/nvhe/switch.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/kvm/hyp/nvhe/switch.c 2023-01-18 18:27:39.000000000 +0000 @@ -55,18 +55,6 @@ write_sysreg(val, cptr_el2); write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2); - if (cpus_have_final_cap(ARM64_SME)) { - val = read_sysreg_s(SYS_HFGRTR_EL2); - val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK | - HFGxTR_EL2_nSMPRI_EL1_MASK); - write_sysreg_s(val, SYS_HFGRTR_EL2); - - val = read_sysreg_s(SYS_HFGWTR_EL2); - val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK | - HFGxTR_EL2_nSMPRI_EL1_MASK); - write_sysreg_s(val, SYS_HFGWTR_EL2); - } - if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt; @@ -110,20 +98,6 @@ write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2); - if (cpus_have_final_cap(ARM64_SME)) { - u64 val; - - val = read_sysreg_s(SYS_HFGRTR_EL2); - val |= HFGxTR_EL2_nTPIDR2_EL0_MASK | - HFGxTR_EL2_nSMPRI_EL1_MASK; - write_sysreg_s(val, SYS_HFGRTR_EL2); - - val = read_sysreg_s(SYS_HFGWTR_EL2); - val |= HFGxTR_EL2_nTPIDR2_EL0_MASK | - HFGxTR_EL2_nSMPRI_EL1_MASK; - write_sysreg_s(val, SYS_HFGWTR_EL2); - } - cptr = CPTR_EL2_DEFAULT; if (vcpu_has_sve(vcpu) && (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)) cptr |= CPTR_EL2_TZ; diff -Nru linux-6.0.6/arch/arm64/kvm/hyp/vhe/switch.c linux-6.0.12/arch/arm64/kvm/hyp/vhe/switch.c --- linux-6.0.6/arch/arm64/kvm/hyp/vhe/switch.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/kvm/hyp/vhe/switch.c 2023-01-18 18:27:39.000000000 +0000 @@ -63,10 +63,6 @@ __activate_traps_fpsimd32(vcpu); } - if (cpus_have_final_cap(ARM64_SME)) - write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2, - sctlr_el2); - write_sysreg(val, cpacr_el1); write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1); @@ -88,10 +84,6 @@ */ asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT)); - if (cpus_have_final_cap(ARM64_SME)) - write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2, - sctlr_el2); - write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); if (!arm64_kernel_unmapped_at_el0()) diff -Nru linux-6.0.6/arch/arm64/mm/mmu.c linux-6.0.12/arch/arm64/mm/mmu.c --- linux-6.0.6/arch/arm64/mm/mmu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/mm/mmu.c 2023-01-18 18:27:39.000000000 +0000 @@ -539,7 +539,7 @@ */ BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end)); - if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE)) + if (can_set_direct_map()) flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; /* @@ -1551,11 +1551,7 @@ VM_BUG_ON(!mhp_range_allowed(start, size, true)); - /* - * KFENCE requires linear map to be mapped at page granularity, so that - * it is possible to protect/unprotect single pages in the KFENCE pool. - */ - if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE)) + if (can_set_direct_map()) flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start), diff -Nru linux-6.0.6/arch/arm64/mm/pageattr.c linux-6.0.12/arch/arm64/mm/pageattr.c --- linux-6.0.6/arch/arm64/mm/pageattr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/arm64/mm/pageattr.c 2023-01-18 18:27:39.000000000 +0000 @@ -21,7 +21,13 @@ bool can_set_direct_map(void) { - return rodata_full || debug_pagealloc_enabled(); + /* + * rodata_full, DEBUG_PAGEALLOC and KFENCE require linear map to be + * mapped at page granularity, so that it is possible to + * protect/unprotect single pages. + */ + return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() || + IS_ENABLED(CONFIG_KFENCE); } static int change_page_range(pte_t *ptep, unsigned long addr, void *data) @@ -96,7 +102,8 @@ * If we are manipulating read-only permissions, apply the same * change to the linear mapping of the pages that back this VM area. */ - if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || + if (rodata_enabled && + rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || pgprot_val(clear_mask) == PTE_RDONLY)) { for (i = 0; i < area->nr_pages; i++) { __change_memory_common((u64)page_address(area->pages[i]), diff -Nru linux-6.0.6/arch/loongarch/include/asm/pgtable.h linux-6.0.12/arch/loongarch/include/asm/pgtable.h --- linux-6.0.6/arch/loongarch/include/asm/pgtable.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/loongarch/include/asm/pgtable.h 2023-01-18 18:27:39.000000000 +0000 @@ -349,7 +349,9 @@ static inline pte_t pte_mkdirty(pte_t pte) { - pte_val(pte) |= (_PAGE_DIRTY | _PAGE_MODIFIED); + pte_val(pte) |= _PAGE_MODIFIED; + if (pte_val(pte) & _PAGE_WRITE) + pte_val(pte) |= _PAGE_DIRTY; return pte; } @@ -475,7 +477,9 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd) { - pmd_val(pmd) |= (_PAGE_DIRTY | _PAGE_MODIFIED); + pmd_val(pmd) |= _PAGE_MODIFIED; + if (pmd_val(pmd) & _PAGE_WRITE) + pmd_val(pmd) |= _PAGE_DIRTY; return pmd; } diff -Nru linux-6.0.6/arch/loongarch/kernel/process.c linux-6.0.12/arch/loongarch/kernel/process.c --- linux-6.0.6/arch/loongarch/kernel/process.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/loongarch/kernel/process.c 2023-01-18 18:27:39.000000000 +0000 @@ -152,7 +152,7 @@ childregs->csr_crmd = p->thread.csr_crmd; childregs->csr_prmd = p->thread.csr_prmd; childregs->csr_ecfg = p->thread.csr_ecfg; - return 0; + goto out; } /* user thread */ @@ -171,14 +171,15 @@ */ childregs->csr_euen = 0; + if (clone_flags & CLONE_SETTLS) + childregs->regs[2] = tls; + +out: clear_tsk_thread_flag(p, TIF_USEDFPU); clear_tsk_thread_flag(p, TIF_USEDSIMD); clear_tsk_thread_flag(p, TIF_LSX_CTX_LIVE); clear_tsk_thread_flag(p, TIF_LASX_CTX_LIVE); - if (clone_flags & CLONE_SETTLS) - childregs->regs[2] = tls; - return 0; } diff -Nru linux-6.0.6/arch/m68k/include/uapi/asm/bootinfo.h linux-6.0.12/arch/m68k/include/uapi/asm/bootinfo.h --- linux-6.0.6/arch/m68k/include/uapi/asm/bootinfo.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/m68k/include/uapi/asm/bootinfo.h 2023-01-18 18:27:39.000000000 +0000 @@ -64,6 +64,13 @@ /* (struct mem_info) */ #define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */ /* (string) */ +/* + * A random seed used to initialize the RNG. Record format: + * + * - length [ 2 bytes, 16-bit big endian ] + * - seed data [ `length` bytes, padded to preserve 4-byte struct alignment ] + */ +#define BI_RNG_SEED 0x0008 /* diff -Nru linux-6.0.6/arch/m68k/include/uapi/asm/bootinfo-virt.h linux-6.0.12/arch/m68k/include/uapi/asm/bootinfo-virt.h --- linux-6.0.6/arch/m68k/include/uapi/asm/bootinfo-virt.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/m68k/include/uapi/asm/bootinfo-virt.h 2023-01-18 18:27:39.000000000 +0000 @@ -13,13 +13,8 @@ #define BI_VIRT_VIRTIO_BASE 0x8004 #define BI_VIRT_CTRL_BASE 0x8005 -/* - * A random seed used to initialize the RNG. Record format: - * - * - length [ 2 bytes, 16-bit big endian ] - * - seed data [ `length` bytes, padded to preserve 2-byte alignment ] - */ -#define BI_VIRT_RNG_SEED 0x8006 +/* No longer used -- replaced with BI_RNG_SEED -- but don't reuse this index: + * #define BI_VIRT_RNG_SEED 0x8006 */ #define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0) diff -Nru linux-6.0.6/arch/m68k/kernel/setup_mm.c linux-6.0.12/arch/m68k/kernel/setup_mm.c --- linux-6.0.6/arch/m68k/kernel/setup_mm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/m68k/kernel/setup_mm.c 2023-01-18 18:27:39.000000000 +0000 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -151,6 +152,17 @@ sizeof(m68k_command_line)); break; + case BI_RNG_SEED: { + u16 len = be16_to_cpup(data); + add_bootloader_randomness(data + 2, len); + /* + * Zero the data to preserve forward secrecy, and zero the + * length to prevent kexec from using it. + */ + memzero_explicit((void *)data, len + 2); + break; + } + default: if (MACH_IS_AMIGA) unknown = amiga_parse_bootinfo(record); diff -Nru linux-6.0.6/arch/m68k/virt/config.c linux-6.0.12/arch/m68k/virt/config.c --- linux-6.0.6/arch/m68k/virt/config.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/m68k/virt/config.c 2023-01-18 18:27:39.000000000 +0000 @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -93,16 +92,6 @@ data += 4; virt_bi_data.virtio.irq = be32_to_cpup(data); break; - case BI_VIRT_RNG_SEED: { - u16 len = be16_to_cpup(data); - add_bootloader_randomness(data + 2, len); - /* - * Zero the data to preserve forward secrecy, and zero the - * length to prevent kexec from using it. - */ - memzero_explicit((void *)data, len + 2); - break; - } default: unknown = 1; break; diff -Nru linux-6.0.6/arch/mips/include/asm/fw/fw.h linux-6.0.12/arch/mips/include/asm/fw/fw.h --- linux-6.0.6/arch/mips/include/asm/fw/fw.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/mips/include/asm/fw/fw.h 2023-01-18 18:27:39.000000000 +0000 @@ -26,6 +26,6 @@ extern void fw_meminit(void); extern char *fw_getenv(char *name); extern unsigned long fw_getenvl(char *name); -extern void fw_init_early_console(char port); +extern void fw_init_early_console(void); #endif /* __ASM_FW_H_ */ diff -Nru linux-6.0.6/arch/mips/kernel/jump_label.c linux-6.0.12/arch/mips/kernel/jump_label.c --- linux-6.0.6/arch/mips/kernel/jump_label.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/mips/kernel/jump_label.c 2023-01-18 18:27:39.000000000 +0000 @@ -56,7 +56,7 @@ * The branch offset must fit in the instruction's 26 * bit field. */ - WARN_ON((offset >= BIT(25)) || + WARN_ON((offset >= (long)BIT(25)) || (offset < -(long)BIT(25))); insn.j_format.opcode = bc6_op; diff -Nru linux-6.0.6/arch/mips/kernel/relocate_kernel.S linux-6.0.12/arch/mips/kernel/relocate_kernel.S --- linux-6.0.6/arch/mips/kernel/relocate_kernel.S 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/mips/kernel/relocate_kernel.S 2023-01-18 18:27:39.000000000 +0000 @@ -145,8 +145,7 @@ * kexec_args[0..3] are used to prepare register values. */ -kexec_args: - EXPORT(kexec_args) +EXPORT(kexec_args) arg0: PTR_WD 0x0 arg1: PTR_WD 0x0 arg2: PTR_WD 0x0 @@ -159,8 +158,7 @@ * their registers a0-a3. secondary_kexec_args[0..3] are used * to prepare register values. */ -secondary_kexec_args: - EXPORT(secondary_kexec_args) +EXPORT(secondary_kexec_args) s_arg0: PTR_WD 0x0 s_arg1: PTR_WD 0x0 s_arg2: PTR_WD 0x0 @@ -171,19 +169,16 @@ #endif -kexec_start_address: - EXPORT(kexec_start_address) +EXPORT(kexec_start_address) PTR_WD 0x0 .size kexec_start_address, PTRSIZE -kexec_indirection_page: - EXPORT(kexec_indirection_page) +EXPORT(kexec_indirection_page) PTR_WD 0 .size kexec_indirection_page, PTRSIZE relocate_new_kernel_end: -relocate_new_kernel_size: - EXPORT(relocate_new_kernel_size) +EXPORT(relocate_new_kernel_size) PTR_WD relocate_new_kernel_end - relocate_new_kernel .size relocate_new_kernel_size, PTRSIZE diff -Nru linux-6.0.6/arch/mips/loongson64/reset.c linux-6.0.12/arch/mips/loongson64/reset.c --- linux-6.0.6/arch/mips/loongson64/reset.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/mips/loongson64/reset.c 2023-01-18 18:27:39.000000000 +0000 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -159,8 +160,17 @@ #ifdef CONFIG_KEXEC kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL); + if (WARN_ON(!kexec_argv)) + return -ENOMEM; + kdump_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL); + if (WARN_ON(!kdump_argv)) + return -ENOMEM; + kexec_envp = kmalloc(KEXEC_ENVP_SIZE, GFP_KERNEL); + if (WARN_ON(!kexec_envp)) + return -ENOMEM; + fw_arg1 = KEXEC_ARGV_ADDR; memcpy(kexec_envp, (void *)fw_arg2, KEXEC_ENVP_SIZE); diff -Nru linux-6.0.6/arch/mips/pic32/pic32mzda/early_console.c linux-6.0.12/arch/mips/pic32/pic32mzda/early_console.c --- linux-6.0.6/arch/mips/pic32/pic32mzda/early_console.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/mips/pic32/pic32mzda/early_console.c 2023-01-18 18:27:39.000000000 +0000 @@ -27,7 +27,7 @@ #define U_BRG(x) (UART_BASE(x) + 0x40) static void __iomem *uart_base; -static char console_port = -1; +static int console_port = -1; static int __init configure_uart_pins(int port) { @@ -47,7 +47,7 @@ return 0; } -static void __init configure_uart(char port, int baud) +static void __init configure_uart(int port, int baud) { u32 pbclk; @@ -60,7 +60,7 @@ uart_base + PIC32_SET(U_STA(port))); } -static void __init setup_early_console(char port, int baud) +static void __init setup_early_console(int port, int baud) { if (configure_uart_pins(port)) return; @@ -130,16 +130,15 @@ return baud; } -void __init fw_init_early_console(char port) +void __init fw_init_early_console(void) { char *arch_cmdline = pic32_getcmdline(); - int baud = -1; + int baud, port; uart_base = ioremap(PIC32_BASE_UART, 0xc00); baud = get_baud_from_cmdline(arch_cmdline); - if (port == -1) - port = get_port_from_cmdline(arch_cmdline); + port = get_port_from_cmdline(arch_cmdline); if (port == -1) port = EARLY_CONSOLE_PORT; diff -Nru linux-6.0.6/arch/mips/pic32/pic32mzda/init.c linux-6.0.12/arch/mips/pic32/pic32mzda/init.c --- linux-6.0.6/arch/mips/pic32/pic32mzda/init.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/mips/pic32/pic32mzda/init.c 2023-01-18 18:27:39.000000000 +0000 @@ -47,7 +47,7 @@ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); #ifdef CONFIG_EARLY_PRINTK - fw_init_early_console(-1); + fw_init_early_console(); #endif pic32_config_init(); } diff -Nru linux-6.0.6/arch/nios2/boot/Makefile linux-6.0.12/arch/nios2/boot/Makefile --- linux-6.0.6/arch/nios2/boot/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/nios2/boot/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -20,7 +20,7 @@ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) -$(obj)/vmImage: $(obj)/vmlinux.gz +$(obj)/vmImage: $(obj)/vmlinux.gz FORCE $(call if_changed,uimage) @$(kecho) 'Kernel: $@ is ready' diff -Nru linux-6.0.6/arch/parisc/include/asm/hardware.h linux-6.0.12/arch/parisc/include/asm/hardware.h --- linux-6.0.6/arch/parisc/include/asm/hardware.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/parisc/include/asm/hardware.h 2023-01-18 18:27:39.000000000 +0000 @@ -10,12 +10,12 @@ #define SVERSION_ANY_ID PA_SVERSION_ANY_ID struct hp_hardware { - unsigned short hw_type:5; /* HPHW_xxx */ - unsigned short hversion; - unsigned long sversion:28; - unsigned short opt; - const char name[80]; /* The hardware description */ -}; + unsigned int hw_type:8; /* HPHW_xxx */ + unsigned int hversion:12; + unsigned int sversion:12; + unsigned char opt; + unsigned char name[59]; /* The hardware description */ +} __packed; struct parisc_device; diff -Nru linux-6.0.6/arch/parisc/kernel/drivers.c linux-6.0.12/arch/parisc/kernel/drivers.c --- linux-6.0.6/arch/parisc/kernel/drivers.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/parisc/kernel/drivers.c 2023-01-18 18:27:39.000000000 +0000 @@ -882,15 +882,13 @@ &root); } -static void print_parisc_device(struct parisc_device *dev) +static __init void print_parisc_device(struct parisc_device *dev) { - char hw_path[64]; - static int count; + static int count __initdata; - print_pa_hwpath(dev, hw_path); - pr_info("%d. %s at %pap [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }", - ++count, dev->name, &(dev->hpa.start), hw_path, dev->id.hw_type, - dev->id.hversion_rev, dev->id.hversion, dev->id.sversion); + pr_info("%d. %s at %pap { type:%d, hv:%#x, sv:%#x, rev:%#x }", + ++count, dev->name, &(dev->hpa.start), dev->id.hw_type, + dev->id.hversion, dev->id.sversion, dev->id.hversion_rev); if (dev->num_addrs) { int k; @@ -1079,7 +1077,7 @@ -static int print_one_device(struct device * dev, void * data) +static __init int print_one_device(struct device * dev, void * data) { struct parisc_device * pdev = to_parisc_device(dev); diff -Nru linux-6.0.6/arch/powerpc/Kconfig linux-6.0.12/arch/powerpc/Kconfig --- linux-6.0.6/arch/powerpc/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/powerpc/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -284,7 +284,7 @@ # config PPC_LONG_DOUBLE_128 - depends on PPC64 + depends on PPC64 && ALTIVEC def_bool $(success,test "$(shell,echo __LONG_DOUBLE_128__ | $(CC) -E -P -)" = 1) config PPC_BARRIER_NOSPEC diff -Nru linux-6.0.6/arch/powerpc/kernel/interrupt_64.S linux-6.0.12/arch/powerpc/kernel/interrupt_64.S --- linux-6.0.6/arch/powerpc/kernel/interrupt_64.S 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/powerpc/kernel/interrupt_64.S 2023-01-18 18:27:39.000000000 +0000 @@ -565,15 +565,24 @@ * Returning to soft-disabled context. * Check if a MUST_HARD_MASK interrupt has become pending, in which * case we need to disable MSR[EE] in the return context. + * + * The MSR[EE] check catches among other things the short incoherency + * in hard_irq_disable() between clearing MSR[EE] and setting + * PACA_IRQ_HARD_DIS. */ ld r12,_MSR(r1) andi. r10,r12,MSR_EE beq .Lfast_kernel_interrupt_return_\srr\() // EE already disabled lbz r11,PACAIRQHAPPENED(r13) andi. r10,r11,PACA_IRQ_MUST_HARD_MASK - beq .Lfast_kernel_interrupt_return_\srr\() // No HARD_MASK pending + bne 1f // HARD_MASK is pending + // No HARD_MASK pending, clear possible HARD_DIS set by interrupt + andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l + stb r11,PACAIRQHAPPENED(r13) + b .Lfast_kernel_interrupt_return_\srr\() - /* Must clear MSR_EE from _MSR */ + +1: /* Must clear MSR_EE from _MSR */ #ifdef CONFIG_PPC_BOOK3S li r10,0 /* Clear valid before changing _MSR */ diff -Nru linux-6.0.6/arch/powerpc/Makefile linux-6.0.12/arch/powerpc/Makefile --- linux-6.0.6/arch/powerpc/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/powerpc/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -242,7 +242,7 @@ all: zImage # With make 3.82 we cannot mix normal and wildcard targets -BOOT_TARGETS1 := zImage zImage.initrd uImage vmlinux.strip +BOOT_TARGETS1 := zImage zImage.initrd uImage BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% uImage.% PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) diff -Nru linux-6.0.6/arch/powerpc/net/bpf_jit_comp32.c linux-6.0.12/arch/powerpc/net/bpf_jit_comp32.c --- linux-6.0.6/arch/powerpc/net/bpf_jit_comp32.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/powerpc/net/bpf_jit_comp32.c 2023-01-18 18:27:39.000000000 +0000 @@ -113,23 +113,19 @@ { int i; - /* First arg comes in as a 32 bits pointer. */ - EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3)); - EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0)); + /* Initialize tail_call_cnt, to be skipped if we do tail calls. */ + EMIT(PPC_RAW_LI(_R4, 0)); + +#define BPF_TAILCALL_PROLOGUE_SIZE 4 + EMIT(PPC_RAW_STWU(_R1, _R1, -BPF_PPC_STACKFRAME(ctx))); - /* - * Initialize tail_call_cnt in stack frame if we do tail calls. - * Otherwise, put in NOPs so that it can be skipped when we are - * invoked through a tail call. - */ if (ctx->seen & SEEN_TAILCALL) - EMIT(PPC_RAW_STW(bpf_to_ppc(BPF_REG_1) - 1, _R1, - bpf_jit_stack_offsetof(ctx, BPF_PPC_TC))); - else - EMIT(PPC_RAW_NOP()); + EMIT(PPC_RAW_STW(_R4, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC))); -#define BPF_TAILCALL_PROLOGUE_SIZE 16 + /* First arg comes in as a 32 bits pointer. */ + EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3)); + EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0)); /* * We need a stack frame, but we don't necessarily need to @@ -170,24 +166,24 @@ for (i = BPF_PPC_NVR_MIN; i <= 31; i++) if (bpf_is_seen_register(ctx, i)) EMIT(PPC_RAW_LWZ(i, _R1, bpf_jit_stack_offsetof(ctx, i))); -} - -void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) -{ - EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0))); - - bpf_jit_emit_common_epilogue(image, ctx); - - /* Tear down our stack frame */ if (ctx->seen & SEEN_FUNC) EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF)); + /* Tear down our stack frame */ EMIT(PPC_RAW_ADDI(_R1, _R1, BPF_PPC_STACKFRAME(ctx))); if (ctx->seen & SEEN_FUNC) EMIT(PPC_RAW_MTLR(_R0)); +} + +void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) +{ + EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0))); + + bpf_jit_emit_common_epilogue(image, ctx); + EMIT(PPC_RAW_BLR()); } @@ -244,7 +240,6 @@ EMIT(PPC_RAW_RLWINM(_R3, b2p_index, 2, 0, 29)); EMIT(PPC_RAW_ADD(_R3, _R3, b2p_bpf_array)); EMIT(PPC_RAW_LWZ(_R3, _R3, offsetof(struct bpf_array, ptrs))); - EMIT(PPC_RAW_STW(_R0, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC))); /* * if (prog == NULL) @@ -255,19 +250,14 @@ /* goto *(prog->bpf_func + prologue_size); */ EMIT(PPC_RAW_LWZ(_R3, _R3, offsetof(struct bpf_prog, bpf_func))); - - if (ctx->seen & SEEN_FUNC) - EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF)); - EMIT(PPC_RAW_ADDIC(_R3, _R3, BPF_TAILCALL_PROLOGUE_SIZE)); - - if (ctx->seen & SEEN_FUNC) - EMIT(PPC_RAW_MTLR(_R0)); - EMIT(PPC_RAW_MTCTR(_R3)); EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_1))); + /* Put tail_call_cnt in r4 */ + EMIT(PPC_RAW_MR(_R4, _R0)); + /* tear restore NVRs, ... */ bpf_jit_emit_common_epilogue(image, ctx); diff -Nru linux-6.0.6/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts linux-6.0.12/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts --- linux-6.0.6/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts 2023-01-18 18:27:39.000000000 +0000 @@ -3,6 +3,8 @@ #include "fu540-c000.dtsi" #include +#include +#include /* Clock frequency (in Hz) of the PCB crystal for rtcclk */ #define RTCCLK_FREQ 1000000 @@ -42,6 +44,42 @@ compatible = "gpio-restart"; gpios = <&gpio 10 GPIO_ACTIVE_LOW>; }; + + led-controller { + compatible = "pwm-leds"; + + led-d1 { + pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>; + active-low; + color = ; + max-brightness = <255>; + label = "d1"; + }; + + led-d2 { + pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>; + active-low; + color = ; + max-brightness = <255>; + label = "d2"; + }; + + led-d3 { + pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>; + active-low; + color = ; + max-brightness = <255>; + label = "d3"; + }; + + led-d4 { + pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>; + active-low; + color = ; + max-brightness = <255>; + label = "d4"; + }; + }; }; &uart0 { diff -Nru linux-6.0.6/arch/riscv/include/asm/asm.h linux-6.0.12/arch/riscv/include/asm/asm.h --- linux-6.0.6/arch/riscv/include/asm/asm.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/include/asm/asm.h 2023-01-18 18:27:39.000000000 +0000 @@ -23,6 +23,7 @@ #define REG_L __REG_SEL(ld, lw) #define REG_S __REG_SEL(sd, sw) #define REG_SC __REG_SEL(sc.d, sc.w) +#define REG_AMOSWAP_AQ __REG_SEL(amoswap.d.aq, amoswap.w.aq) #define REG_ASM __REG_SEL(.dword, .word) #define SZREG __REG_SEL(8, 4) #define LGREG __REG_SEL(3, 2) diff -Nru linux-6.0.6/arch/riscv/include/asm/cacheflush.h linux-6.0.12/arch/riscv/include/asm/cacheflush.h --- linux-6.0.6/arch/riscv/include/asm/cacheflush.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/include/asm/cacheflush.h 2023-01-18 18:27:39.000000000 +0000 @@ -42,16 +42,8 @@ #endif /* CONFIG_SMP */ -/* - * The T-Head CMO errata internally probe the CBOM block size, but otherwise - * don't depend on Zicbom. - */ extern unsigned int riscv_cbom_block_size; -#ifdef CONFIG_RISCV_ISA_ZICBOM void riscv_init_cbom_blocksize(void); -#else -static inline void riscv_init_cbom_blocksize(void) { } -#endif #ifdef CONFIG_RISCV_DMA_NONCOHERENT void riscv_noncoherent_supported(void); diff -Nru linux-6.0.6/arch/riscv/include/asm/efi.h linux-6.0.12/arch/riscv/include/asm/efi.h --- linux-6.0.6/arch/riscv/include/asm/efi.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/include/asm/efi.h 2023-01-18 18:27:39.000000000 +0000 @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_EFI extern void efi_init(void); @@ -20,7 +21,10 @@ int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); -#define arch_efi_call_virt_setup() efi_virtmap_load() +#define arch_efi_call_virt_setup() ({ \ + sync_kernel_mappings(efi_mm.pgd); \ + efi_virtmap_load(); \ + }) #define arch_efi_call_virt_teardown() efi_virtmap_unload() #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE) diff -Nru linux-6.0.6/arch/riscv/include/asm/jump_label.h linux-6.0.12/arch/riscv/include/asm/jump_label.h --- linux-6.0.6/arch/riscv/include/asm/jump_label.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/include/asm/jump_label.h 2023-01-18 18:27:39.000000000 +0000 @@ -14,8 +14,8 @@ #define JUMP_LABEL_NOP_SIZE 4 -static __always_inline bool arch_static_branch(struct static_key *key, - bool branch) +static __always_inline bool arch_static_branch(struct static_key * const key, + const bool branch) { asm_volatile_goto( " .option push \n\t" @@ -35,8 +35,8 @@ return true; } -static __always_inline bool arch_static_branch_jump(struct static_key *key, - bool branch) +static __always_inline bool arch_static_branch_jump(struct static_key * const key, + const bool branch) { asm_volatile_goto( " .option push \n\t" diff -Nru linux-6.0.6/arch/riscv/include/asm/kvm_vcpu_timer.h linux-6.0.12/arch/riscv/include/asm/kvm_vcpu_timer.h --- linux-6.0.6/arch/riscv/include/asm/kvm_vcpu_timer.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/include/asm/kvm_vcpu_timer.h 2023-01-18 18:27:39.000000000 +0000 @@ -45,6 +45,7 @@ int kvm_riscv_vcpu_timer_reset(struct kvm_vcpu *vcpu); void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu); void kvm_riscv_guest_timer_init(struct kvm *kvm); +void kvm_riscv_vcpu_timer_sync(struct kvm_vcpu *vcpu); void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu); bool kvm_riscv_vcpu_timer_pending(struct kvm_vcpu *vcpu); diff -Nru linux-6.0.6/arch/riscv/include/asm/pgalloc.h linux-6.0.12/arch/riscv/include/asm/pgalloc.h --- linux-6.0.6/arch/riscv/include/asm/pgalloc.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/include/asm/pgalloc.h 2023-01-18 18:27:39.000000000 +0000 @@ -127,6 +127,13 @@ #define __p4d_free_tlb(tlb, p4d, addr) p4d_free((tlb)->mm, p4d) #endif /* __PAGETABLE_PMD_FOLDED */ +static inline void sync_kernel_mappings(pgd_t *pgd) +{ + memcpy(pgd + USER_PTRS_PER_PGD, + init_mm.pgd + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); +} + static inline pgd_t *pgd_alloc(struct mm_struct *mm) { pgd_t *pgd; @@ -135,9 +142,7 @@ if (likely(pgd != NULL)) { memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); /* Copy kernel mappings */ - memcpy(pgd + USER_PTRS_PER_PGD, - init_mm.pgd + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + sync_kernel_mappings(pgd); } return pgd; } diff -Nru linux-6.0.6/arch/riscv/include/asm/vdso/processor.h linux-6.0.12/arch/riscv/include/asm/vdso/processor.h --- linux-6.0.6/arch/riscv/include/asm/vdso/processor.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/include/asm/vdso/processor.h 2023-01-18 18:27:39.000000000 +0000 @@ -21,7 +21,7 @@ * Reduce instruction retirement. * This assumes the PC changes. */ -#ifdef __riscv_zihintpause +#ifdef CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE __asm__ __volatile__ ("pause"); #else /* Encoding of the pause instruction */ diff -Nru linux-6.0.6/arch/riscv/include/uapi/asm/kvm.h linux-6.0.12/arch/riscv/include/uapi/asm/kvm.h --- linux-6.0.6/arch/riscv/include/uapi/asm/kvm.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/include/uapi/asm/kvm.h 2023-01-18 18:27:39.000000000 +0000 @@ -48,6 +48,7 @@ /* CONFIG registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ struct kvm_riscv_config { unsigned long isa; + unsigned long zicbom_block_size; }; /* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ diff -Nru linux-6.0.6/arch/riscv/Kconfig linux-6.0.12/arch/riscv/Kconfig --- linux-6.0.6/arch/riscv/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -402,14 +402,16 @@ If you don't know what to do here, say Y. -config CC_HAS_ZICBOM +config TOOLCHAIN_HAS_ZICBOM bool - default y if 64BIT && $(cc-option,-mabi=lp64 -march=rv64ima_zicbom) - default y if 32BIT && $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom) + default y + depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zicbom) + depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom) + depends on LLD_VERSION >= 150000 || LD_VERSION >= 23800 config RISCV_ISA_ZICBOM bool "Zicbom extension support for non-coherent DMA operation" - depends on CC_HAS_ZICBOM + depends on TOOLCHAIN_HAS_ZICBOM depends on !XIP_KERNEL && MMU select RISCV_DMA_NONCOHERENT select RISCV_ALTERNATIVE @@ -424,6 +426,13 @@ If you don't know what to do here, say Y. +config TOOLCHAIN_HAS_ZIHINTPAUSE + bool + default y + depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zihintpause) + depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zihintpause) + depends on LLD_VERSION >= 150000 || LD_VERSION >= 23600 + config FPU bool "FPU support" default y diff -Nru linux-6.0.6/arch/riscv/kernel/entry.S linux-6.0.12/arch/riscv/kernel/entry.S --- linux-6.0.6/arch/riscv/kernel/entry.S 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kernel/entry.S 2023-01-18 18:27:39.000000000 +0000 @@ -404,6 +404,19 @@ #ifdef CONFIG_VMAP_STACK handle_kernel_stack_overflow: + /* + * Takes the psuedo-spinlock for the shadow stack, in case multiple + * harts are concurrently overflowing their kernel stacks. We could + * store any value here, but since we're overflowing the kernel stack + * already we only have SP to use as a scratch register. So we just + * swap in the address of the spinlock, as that's definately non-zero. + * + * Pairs with a store_release in handle_bad_stack(). + */ +1: la sp, spin_shadow_stack + REG_AMOSWAP_AQ sp, sp, (sp) + bnez sp, 1b + la sp, shadow_stack addi sp, sp, SHADOW_OVERFLOW_STACK_SIZE diff -Nru linux-6.0.6/arch/riscv/kernel/machine_kexec.c linux-6.0.12/arch/riscv/kernel/machine_kexec.c --- linux-6.0.6/arch/riscv/kernel/machine_kexec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kernel/machine_kexec.c 2023-01-18 18:27:39.000000000 +0000 @@ -15,6 +15,8 @@ #include /* For unreachable() */ #include /* For cpu_down() */ #include +#include +#include /* * kexec_image_info - Print received image details @@ -154,6 +156,37 @@ cpus_stopped = 1; } +static void machine_kexec_mask_interrupts(void) +{ + unsigned int i; + struct irq_desc *desc; + + for_each_irq_desc(i, desc) { + struct irq_chip *chip; + int ret; + + chip = irq_desc_get_chip(desc); + if (!chip) + continue; + + /* + * First try to remove the active state. If this + * fails, try to EOI the interrupt. + */ + ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false); + + if (ret && irqd_irq_inprogress(&desc->irq_data) && + chip->irq_eoi) + chip->irq_eoi(&desc->irq_data); + + if (chip->irq_mask) + chip->irq_mask(&desc->irq_data); + + if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) + chip->irq_disable(&desc->irq_data); + } +} + /* * machine_crash_shutdown - Prepare to kexec after a kernel crash * @@ -169,6 +202,8 @@ crash_smp_send_stop(); crash_save_cpu(regs, smp_processor_id()); + machine_kexec_mask_interrupts(); + pr_info("Starting crashdump kernel...\n"); } diff -Nru linux-6.0.6/arch/riscv/kernel/process.c linux-6.0.12/arch/riscv/kernel/process.c --- linux-6.0.6/arch/riscv/kernel/process.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kernel/process.c 2023-01-18 18:27:39.000000000 +0000 @@ -164,6 +164,8 @@ unsigned long tls = args->tls; struct pt_regs *childregs = task_pt_regs(p); + memset(&p->thread.s, 0, sizeof(p->thread.s)); + /* p->thread holds context to be restored by __switch_to() */ if (unlikely(args->fn)) { /* Kernel thread */ diff -Nru linux-6.0.6/arch/riscv/kernel/setup.c linux-6.0.12/arch/riscv/kernel/setup.c --- linux-6.0.6/arch/riscv/kernel/setup.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kernel/setup.c 2023-01-18 18:27:39.000000000 +0000 @@ -283,6 +283,7 @@ else pr_err("No DTB found in kernel mappings\n"); #endif + early_init_fdt_scan_reserved_mem(); misc_mem_init(); init_resources(); @@ -321,10 +322,11 @@ void free_initmem(void) { - if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) - set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end), - IS_ENABLED(CONFIG_64BIT) ? - set_memory_rw : set_memory_rw_nx); + if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) { + set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end), set_memory_rw_nx); + if (IS_ENABLED(CONFIG_64BIT)) + set_kernel_memory(__init_begin, __init_end, set_memory_nx); + } free_initmem_default(POISON_FREE_INITMEM); } diff -Nru linux-6.0.6/arch/riscv/kernel/traps.c linux-6.0.12/arch/riscv/kernel/traps.c --- linux-6.0.6/arch/riscv/kernel/traps.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kernel/traps.c 2023-01-18 18:27:39.000000000 +0000 @@ -218,11 +218,29 @@ OVERFLOW_STACK_SIZE; } +/* + * A pseudo spinlock to protect the shadow stack from being used by multiple + * harts concurrently. This isn't a real spinlock because the lock side must + * be taken without a valid stack and only a single register, it's only taken + * while in the process of panicing anyway so the performance and error + * checking a proper spinlock gives us doesn't matter. + */ +unsigned long spin_shadow_stack; + asmlinkage void handle_bad_stack(struct pt_regs *regs) { unsigned long tsk_stk = (unsigned long)current->stack; unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack); + /* + * We're done with the shadow stack by this point, as we're on the + * overflow stack. Tell any other concurrent overflowing harts that + * they can proceed with panicing by releasing the pseudo-spinlock. + * + * This pairs with an amoswap.aq in handle_kernel_stack_overflow. + */ + smp_store_release(&spin_shadow_stack, 0); + console_verbose(); pr_emerg("Insufficient stack space to handle exception!\n"); diff -Nru linux-6.0.6/arch/riscv/kernel/vdso/Makefile linux-6.0.12/arch/riscv/kernel/vdso/Makefile --- linux-6.0.6/arch/riscv/kernel/vdso/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kernel/vdso/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -17,6 +17,7 @@ obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o ccflags-y := -fno-stack-protector +ccflags-y += -DDISABLE_BRANCH_PROFILING ifneq ($(c-gettimeofday-y),) CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y) @@ -28,9 +29,12 @@ obj-y += vdso.o CPPFLAGS_vdso.lds += -P -C -U$(ARCH) +ifneq ($(filter vgettimeofday, $(vdso-syms)),) +CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY +endif # Disable -pg to prevent insert call site -CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) # Disable profiling and instrumentation for VDSO code GCOV_PROFILE := n diff -Nru linux-6.0.6/arch/riscv/kernel/vdso/vdso.lds.S linux-6.0.12/arch/riscv/kernel/vdso/vdso.lds.S --- linux-6.0.6/arch/riscv/kernel/vdso/vdso.lds.S 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kernel/vdso/vdso.lds.S 2023-01-18 18:27:39.000000000 +0000 @@ -68,9 +68,11 @@ LINUX_4.15 { global: __vdso_rt_sigreturn; +#ifdef HAS_VGETTIMEOFDAY __vdso_gettimeofday; __vdso_clock_gettime; __vdso_clock_getres; +#endif __vdso_getcpu; __vdso_flush_icache; local: *; diff -Nru linux-6.0.6/arch/riscv/kvm/vcpu.c linux-6.0.12/arch/riscv/kvm/vcpu.c --- linux-6.0.6/arch/riscv/kvm/vcpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kvm/vcpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -18,6 +18,7 @@ #include #include #include +#include #include const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { @@ -254,6 +255,11 @@ case KVM_REG_RISCV_CONFIG_REG(isa): reg_val = vcpu->arch.isa[0] & KVM_RISCV_BASE_ISA_MASK; break; + case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size): + if (!riscv_isa_extension_available(vcpu->arch.isa, ZICBOM)) + return -EINVAL; + reg_val = riscv_cbom_block_size; + break; default: return -EINVAL; } @@ -311,6 +317,8 @@ return -EOPNOTSUPP; } break; + case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size): + return -EOPNOTSUPP; default: return -EINVAL; } @@ -690,6 +698,9 @@ clear_bit(IRQ_VS_SOFT, &v->irqs_pending); } } + + /* Sync-up timer CSRs */ + kvm_riscv_vcpu_timer_sync(vcpu); } int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq) diff -Nru linux-6.0.6/arch/riscv/kvm/vcpu_timer.c linux-6.0.12/arch/riscv/kvm/vcpu_timer.c --- linux-6.0.6/arch/riscv/kvm/vcpu_timer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/kvm/vcpu_timer.c 2023-01-18 18:27:39.000000000 +0000 @@ -320,20 +320,33 @@ kvm_riscv_vcpu_timer_unblocking(vcpu); } -void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu) +void kvm_riscv_vcpu_timer_sync(struct kvm_vcpu *vcpu) { struct kvm_vcpu_timer *t = &vcpu->arch.timer; if (!t->sstc_enabled) return; - t = &vcpu->arch.timer; #if defined(CONFIG_32BIT) t->next_cycles = csr_read(CSR_VSTIMECMP); t->next_cycles |= (u64)csr_read(CSR_VSTIMECMPH) << 32; #else t->next_cycles = csr_read(CSR_VSTIMECMP); #endif +} + +void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu_timer *t = &vcpu->arch.timer; + + if (!t->sstc_enabled) + return; + + /* + * The vstimecmp CSRs are saved by kvm_riscv_vcpu_timer_sync() + * upon every VM exit so no need to save here. + */ + /* timer should be enabled for the remaining operations */ if (unlikely(!t->init_done)) return; diff -Nru linux-6.0.6/arch/riscv/Makefile linux-6.0.12/arch/riscv/Makefile --- linux-6.0.6/arch/riscv/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -59,12 +59,10 @@ riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei # Check if the toolchain supports Zicbom extension -toolchain-supports-zicbom := $(call cc-option-yn, -march=$(riscv-march-y)_zicbom) -riscv-march-$(toolchain-supports-zicbom) := $(riscv-march-y)_zicbom +riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZICBOM) := $(riscv-march-y)_zicbom # Check if the toolchain supports Zihintpause extension -toolchain-supports-zihintpause := $(call cc-option-yn, -march=$(riscv-march-y)_zihintpause) -riscv-march-$(toolchain-supports-zihintpause) := $(riscv-march-y)_zihintpause +riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y)) KBUILD_AFLAGS += -march=$(riscv-march-y) diff -Nru linux-6.0.6/arch/riscv/mm/cacheflush.c linux-6.0.12/arch/riscv/mm/cacheflush.c --- linux-6.0.6/arch/riscv/mm/cacheflush.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/mm/cacheflush.c 2023-01-18 18:27:39.000000000 +0000 @@ -3,6 +3,7 @@ * Copyright (C) 2017 SiFive */ +#include #include #ifdef CONFIG_SMP @@ -86,3 +87,40 @@ flush_icache_all(); } #endif /* CONFIG_MMU */ + +unsigned int riscv_cbom_block_size; +EXPORT_SYMBOL_GPL(riscv_cbom_block_size); + +void riscv_init_cbom_blocksize(void) +{ + struct device_node *node; + unsigned long cbom_hartid; + u32 val, probed_block_size; + int ret; + + probed_block_size = 0; + for_each_of_cpu_node(node) { + unsigned long hartid; + + ret = riscv_of_processor_hartid(node, &hartid); + if (ret) + continue; + + /* set block-size for cbom extension if available */ + ret = of_property_read_u32(node, "riscv,cbom-block-size", &val); + if (ret) + continue; + + if (!probed_block_size) { + probed_block_size = val; + cbom_hartid = hartid; + } else { + if (probed_block_size != val) + pr_warn("cbom-block-size mismatched between harts %lu and %lu\n", + cbom_hartid, hartid); + } + } + + if (probed_block_size) + riscv_cbom_block_size = probed_block_size; +} diff -Nru linux-6.0.6/arch/riscv/mm/dma-noncoherent.c linux-6.0.12/arch/riscv/mm/dma-noncoherent.c --- linux-6.0.6/arch/riscv/mm/dma-noncoherent.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/mm/dma-noncoherent.c 2023-01-18 18:27:39.000000000 +0000 @@ -8,11 +8,8 @@ #include #include #include -#include -#include #include -unsigned int riscv_cbom_block_size; static bool noncoherent_supported; void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, @@ -75,42 +72,6 @@ dev->dma_coherent = coherent; } -#ifdef CONFIG_RISCV_ISA_ZICBOM -void riscv_init_cbom_blocksize(void) -{ - struct device_node *node; - unsigned long cbom_hartid; - u32 val, probed_block_size; - int ret; - - probed_block_size = 0; - for_each_of_cpu_node(node) { - unsigned long hartid; - - ret = riscv_of_processor_hartid(node, &hartid); - if (ret) - continue; - - /* set block-size for cbom extension if available */ - ret = of_property_read_u32(node, "riscv,cbom-block-size", &val); - if (ret) - continue; - - if (!probed_block_size) { - probed_block_size = val; - cbom_hartid = hartid; - } else { - if (probed_block_size != val) - pr_warn("cbom-block-size mismatched between harts %lu and %lu\n", - cbom_hartid, hartid); - } - } - - if (probed_block_size) - riscv_cbom_block_size = probed_block_size; -} -#endif - void riscv_noncoherent_supported(void) { WARN(!riscv_cbom_block_size, diff -Nru linux-6.0.6/arch/riscv/mm/init.c linux-6.0.12/arch/riscv/mm/init.c --- linux-6.0.6/arch/riscv/mm/init.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/mm/init.c 2023-01-18 18:27:39.000000000 +0000 @@ -262,7 +262,6 @@ memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va)); } - early_init_fdt_scan_reserved_mem(); dma_contiguous_reserve(dma32_phys_limit); if (IS_ENABLED(CONFIG_64BIT)) hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); diff -Nru linux-6.0.6/arch/riscv/mm/kasan_init.c linux-6.0.12/arch/riscv/mm/kasan_init.c --- linux-6.0.6/arch/riscv/mm/kasan_init.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/riscv/mm/kasan_init.c 2023-01-18 18:27:39.000000000 +0000 @@ -113,6 +113,8 @@ base_pud = pt_ops.get_pud_virt(pfn_to_phys(_pgd_pfn(*pgd))); } else if (pgd_none(*pgd)) { base_pud = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE); + memcpy(base_pud, (void *)kasan_early_shadow_pud, + sizeof(pud_t) * PTRS_PER_PUD); } else { base_pud = (pud_t *)pgd_page_vaddr(*pgd); if (base_pud == lm_alias(kasan_early_shadow_pud)) { @@ -173,8 +175,11 @@ base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(*pgd))); } else { base_p4d = (p4d_t *)pgd_page_vaddr(*pgd); - if (base_p4d == lm_alias(kasan_early_shadow_p4d)) + if (base_p4d == lm_alias(kasan_early_shadow_p4d)) { base_p4d = memblock_alloc(PTRS_PER_PUD * sizeof(p4d_t), PAGE_SIZE); + memcpy(base_p4d, (void *)kasan_early_shadow_p4d, + sizeof(p4d_t) * PTRS_PER_P4D); + } } p4dp = base_p4d + p4d_index(vaddr); diff -Nru linux-6.0.6/arch/s390/boot/Makefile linux-6.0.12/arch/s390/boot/Makefile --- linux-6.0.6/arch/s390/boot/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/boot/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -37,9 +37,8 @@ obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o -obj-y += version.o pgm_check_info.o ctype.o ipl_data.o +obj-y += version.o pgm_check_info.o ctype.o ipl_data.o machine_kexec_reloc.o obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o -obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o diff -Nru linux-6.0.6/arch/s390/boot/startup.c linux-6.0.12/arch/s390/boot/startup.c --- linux-6.0.6/arch/s390/boot/startup.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/boot/startup.c 2023-01-18 18:27:39.000000000 +0000 @@ -285,8 +285,7 @@ clear_bss_section(); copy_bootdata(); - if (IS_ENABLED(CONFIG_RELOCATABLE)) - handle_relocs(__kaslr_offset); + handle_relocs(__kaslr_offset); if (__kaslr_offset) { /* diff -Nru linux-6.0.6/arch/s390/boot/vmlinux.lds.S linux-6.0.12/arch/s390/boot/vmlinux.lds.S --- linux-6.0.6/arch/s390/boot/vmlinux.lds.S 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/boot/vmlinux.lds.S 2023-01-18 18:27:39.000000000 +0000 @@ -102,8 +102,17 @@ _compressed_start = .; *(.vmlinux.bin.compressed) _compressed_end = .; - FILL(0xff); - . = ALIGN(4096); + } + +#define SB_TRAILER_SIZE 32 + /* Trailer needed for Secure Boot */ + . += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */ + . = ALIGN(4096) - SB_TRAILER_SIZE; + .sb.trailer : { + QUAD(0) + QUAD(0) + QUAD(0) + QUAD(0x000000207a49504c) } _end = .; diff -Nru linux-6.0.6/arch/s390/include/asm/futex.h linux-6.0.12/arch/s390/include/asm/futex.h --- linux-6.0.6/arch/s390/include/asm/futex.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/include/asm/futex.h 2023-01-18 18:27:39.000000000 +0000 @@ -17,7 +17,8 @@ "3: jl 1b\n" \ " lhi %0,0\n" \ "4: sacf 768\n" \ - EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \ + EX_TABLE(0b,4b) EX_TABLE(1b,4b) \ + EX_TABLE(2b,4b) EX_TABLE(3b,4b) \ : "=d" (ret), "=&d" (oldval), "=&d" (newval), \ "=m" (*uaddr) \ : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ diff -Nru linux-6.0.6/arch/s390/include/asm/processor.h linux-6.0.12/arch/s390/include/asm/processor.h --- linux-6.0.6/arch/s390/include/asm/processor.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/include/asm/processor.h 2023-01-18 18:27:39.000000000 +0000 @@ -202,7 +202,16 @@ /* Has task runtime instrumentation enabled ? */ #define is_ri_task(tsk) (!!(tsk)->thread.ri_cb) -register unsigned long current_stack_pointer asm("r15"); +/* avoid using global register due to gcc bug in versions < 8.4 */ +#define current_stack_pointer (__current_stack_pointer()) + +static __always_inline unsigned long __current_stack_pointer(void) +{ + unsigned long sp; + + asm volatile("lgr %0,15" : "=d" (sp)); + return sp; +} static __always_inline unsigned short stap(void) { diff -Nru linux-6.0.6/arch/s390/Kconfig linux-6.0.12/arch/s390/Kconfig --- linux-6.0.6/arch/s390/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -568,8 +568,7 @@ endchoice config RELOCATABLE - bool "Build a relocatable kernel" - default y + def_bool y help This builds a kernel image that retains relocation information so it can be loaded at an arbitrary address. @@ -578,10 +577,11 @@ bootup process. The relocations make the kernel image about 15% larger (compressed 10%), but are discarded at runtime. + Note: this option exists only for documentation purposes, please do + not remove it. config RANDOMIZE_BASE bool "Randomize the address of the kernel image (KASLR)" - depends on RELOCATABLE default y help In support of Kernel Address Space Layout Randomization (KASLR), diff -Nru linux-6.0.6/arch/s390/kernel/crash_dump.c linux-6.0.12/arch/s390/kernel/crash_dump.c --- linux-6.0.6/arch/s390/kernel/crash_dump.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/kernel/crash_dump.c 2023-01-18 18:27:39.000000000 +0000 @@ -45,7 +45,7 @@ u64 fprs[16]; u32 fpc; u32 prefix; - u64 todpreg; + u32 todpreg; u64 timer; u64 todcmp; u64 vxrs_low[16]; diff -Nru linux-6.0.6/arch/s390/kvm/kvm-s390.c linux-6.0.12/arch/s390/kvm/kvm-s390.c --- linux-6.0.6/arch/s390/kvm/kvm-s390.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/kvm/kvm-s390.c 2023-01-18 18:27:39.000000000 +0000 @@ -1207,6 +1207,8 @@ return 0; } +static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod); + static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr) { struct kvm_s390_vm_tod_clock gtod; @@ -1216,7 +1218,7 @@ if (!test_kvm_facility(kvm, 139) && gtod.epoch_idx) return -EINVAL; - kvm_s390_set_tod_clock(kvm, >od); + __kvm_s390_set_tod_clock(kvm, >od); VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x, TOD base: 0x%llx", gtod.epoch_idx, gtod.tod); @@ -1247,7 +1249,7 @@ sizeof(gtod.tod))) return -EFAULT; - kvm_s390_set_tod_clock(kvm, >od); + __kvm_s390_set_tod_clock(kvm, >od); VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod.tod); return 0; } @@ -1259,6 +1261,16 @@ if (attr->flags) return -EINVAL; + mutex_lock(&kvm->lock); + /* + * For protected guests, the TOD is managed by the ultravisor, so trying + * to change it will never bring the expected results. + */ + if (kvm_s390_pv_is_protected(kvm)) { + ret = -EOPNOTSUPP; + goto out_unlock; + } + switch (attr->attr) { case KVM_S390_VM_TOD_EXT: ret = kvm_s390_set_tod_ext(kvm, attr); @@ -1273,6 +1285,9 @@ ret = -ENXIO; break; } + +out_unlock: + mutex_unlock(&kvm->lock); return ret; } @@ -4379,13 +4394,6 @@ preempt_enable(); } -void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod) -{ - mutex_lock(&kvm->lock); - __kvm_s390_set_tod_clock(kvm, gtod); - mutex_unlock(&kvm->lock); -} - int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod) { if (!mutex_trylock(&kvm->lock)) diff -Nru linux-6.0.6/arch/s390/kvm/kvm-s390.h linux-6.0.12/arch/s390/kvm/kvm-s390.h --- linux-6.0.6/arch/s390/kvm/kvm-s390.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/kvm/kvm-s390.h 2023-01-18 18:27:39.000000000 +0000 @@ -363,7 +363,6 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu); /* implemented in kvm-s390.c */ -void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod); int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod); long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); diff -Nru linux-6.0.6/arch/s390/kvm/pci.c linux-6.0.12/arch/s390/kvm/pci.c --- linux-6.0.6/arch/s390/kvm/pci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/kvm/pci.c 2023-01-18 18:27:39.000000000 +0000 @@ -126,7 +126,7 @@ return -EPERM; mutex_lock(&aift->aift_lock); - aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev), + aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev *), GFP_KERNEL); if (!aift->kzdev) { rc = -ENOMEM; diff -Nru linux-6.0.6/arch/s390/lib/uaccess.c linux-6.0.12/arch/s390/lib/uaccess.c --- linux-6.0.6/arch/s390/lib/uaccess.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/lib/uaccess.c 2023-01-18 18:27:39.000000000 +0000 @@ -156,7 +156,7 @@ asm volatile( " lr 0,%[spec]\n" "0: mvcos 0(%1),0(%4),%0\n" - " jz 4f\n" + "6: jz 4f\n" "1: algr %0,%2\n" " slgr %1,%2\n" " j 0b\n" @@ -166,11 +166,11 @@ " clgr %0,%3\n" /* copy crosses next page boundary? */ " jnh 5f\n" "3: mvcos 0(%1),0(%4),%3\n" - " slgr %0,%3\n" + "7: slgr %0,%3\n" " j 5f\n" "4: slgr %0,%0\n" "5:\n" - EX_TABLE(0b,2b) EX_TABLE(3b,5b) + EX_TABLE(0b,2b) EX_TABLE(6b,2b) EX_TABLE(3b,5b) EX_TABLE(7b,5b) : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2) : "a" (empty_zero_page), [spec] "d" (spec.val) : "cc", "memory", "0"); diff -Nru linux-6.0.6/arch/s390/Makefile linux-6.0.12/arch/s390/Makefile --- linux-6.0.6/arch/s390/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -14,10 +14,8 @@ KBUILD_CFLAGS_MODULE += -fPIC KBUILD_AFLAGS += -m64 KBUILD_CFLAGS += -m64 -ifeq ($(CONFIG_RELOCATABLE),y) KBUILD_CFLAGS += -fPIE LDFLAGS_vmlinux := -pie -endif aflags_dwarf := -Wa,-gdwarf-2 KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__ ifndef CONFIG_AS_IS_LLVM diff -Nru linux-6.0.6/arch/s390/pci/pci_mmio.c linux-6.0.12/arch/s390/pci/pci_mmio.c --- linux-6.0.6/arch/s390/pci/pci_mmio.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/s390/pci/pci_mmio.c 2023-01-18 18:27:39.000000000 +0000 @@ -64,7 +64,7 @@ asm volatile ( " sacf 256\n" "0: llgc %[tmp],0(%[src])\n" - " sllg %[val],%[val],8\n" + "4: sllg %[val],%[val],8\n" " aghi %[src],1\n" " ogr %[val],%[tmp]\n" " brctg %[cnt],0b\n" @@ -72,7 +72,7 @@ "2: ipm %[cc]\n" " srl %[cc],28\n" "3: sacf 768\n" - EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b) + EX_TABLE(0b, 3b) EX_TABLE(4b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b) : [src] "+a" (src), [cnt] "+d" (cnt), [val] "+d" (val), [tmp] "=d" (tmp), @@ -215,10 +215,10 @@ "2: ahi %[shift],-8\n" " srlg %[tmp],%[val],0(%[shift])\n" "3: stc %[tmp],0(%[dst])\n" - " aghi %[dst],1\n" + "5: aghi %[dst],1\n" " brctg %[cnt],2b\n" "4: sacf 768\n" - EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b) + EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b) EX_TABLE(5b, 4b) : [ioaddr_len] "+&d" (ioaddr_len.pair), [cc] "+d" (cc), [val] "=d" (val), diff -Nru linux-6.0.6/arch/x86/coco/tdx/tdx.c linux-6.0.12/arch/x86/coco/tdx/tdx.c --- linux-6.0.6/arch/x86/coco/tdx/tdx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/coco/tdx/tdx.c 2023-01-18 18:27:39.000000000 +0000 @@ -34,6 +34,8 @@ #define VE_GET_PORT_NUM(e) ((e) >> 16) #define VE_IS_IO_STRING(e) ((e) & BIT(4)) +#define ATTR_SEPT_VE_DISABLE BIT(28) + /* * Wrapper for standard use of __tdx_hypercall with no output aside from * return code. @@ -98,10 +100,11 @@ panic("TDCALL %lld failed (Buggy TDX module!)\n", fn); } -static u64 get_cc_mask(void) +static void tdx_parse_tdinfo(u64 *cc_mask) { struct tdx_module_output out; unsigned int gpa_width; + u64 td_attr; /* * TDINFO TDX module call is used to get the TD execution environment @@ -109,19 +112,27 @@ * information, etc. More details about the ABI can be found in TDX * Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL * [TDG.VP.INFO]. + */ + tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out); + + /* + * The highest bit of a guest physical address is the "sharing" bit. + * Set it for shared pages and clear it for private pages. * * The GPA width that comes out of this call is critical. TDX guests * can not meaningfully run without it. */ - tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out); - gpa_width = out.rcx & GENMASK(5, 0); + *cc_mask = BIT_ULL(gpa_width - 1); /* - * The highest bit of a guest physical address is the "sharing" bit. - * Set it for shared pages and clear it for private pages. + * The kernel can not handle #VE's when accessing normal kernel + * memory. Ensure that no #VE will be delivered for accesses to + * TD-private memory. Only VMM-shared memory (MMIO) will #VE. */ - return BIT_ULL(gpa_width - 1); + td_attr = out.rdx; + if (!(td_attr & ATTR_SEPT_VE_DISABLE)) + panic("TD misconfiguration: SEPT_VE_DISABLE attibute must be set.\n"); } /* @@ -758,7 +769,7 @@ setup_force_cpu_cap(X86_FEATURE_TDX_GUEST); cc_set_vendor(CC_VENDOR_INTEL); - cc_mask = get_cc_mask(); + tdx_parse_tdinfo(&cc_mask); cc_set_mask(cc_mask); /* diff -Nru linux-6.0.6/arch/x86/crypto/polyval-clmulni_glue.c linux-6.0.12/arch/x86/crypto/polyval-clmulni_glue.c --- linux-6.0.6/arch/x86/crypto/polyval-clmulni_glue.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/crypto/polyval-clmulni_glue.c 2023-01-18 18:27:39.000000000 +0000 @@ -27,13 +27,17 @@ #include #include +#define POLYVAL_ALIGN 16 +#define POLYVAL_ALIGN_ATTR __aligned(POLYVAL_ALIGN) +#define POLYVAL_ALIGN_EXTRA ((POLYVAL_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1)) +#define POLYVAL_CTX_SIZE (sizeof(struct polyval_tfm_ctx) + POLYVAL_ALIGN_EXTRA) #define NUM_KEY_POWERS 8 struct polyval_tfm_ctx { /* * These powers must be in the order h^8, ..., h^1. */ - u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE]; + u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE] POLYVAL_ALIGN_ATTR; }; struct polyval_desc_ctx { @@ -45,6 +49,11 @@ const u8 *in, size_t nblocks, u8 *accumulator); asmlinkage void clmul_polyval_mul(u8 *op1, const u8 *op2); +static inline struct polyval_tfm_ctx *polyval_tfm_ctx(struct crypto_shash *tfm) +{ + return PTR_ALIGN(crypto_shash_ctx(tfm), POLYVAL_ALIGN); +} + static void internal_polyval_update(const struct polyval_tfm_ctx *keys, const u8 *in, size_t nblocks, u8 *accumulator) { @@ -72,7 +81,7 @@ static int polyval_x86_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen) { - struct polyval_tfm_ctx *tctx = crypto_shash_ctx(tfm); + struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(tfm); int i; if (keylen != POLYVAL_BLOCK_SIZE) @@ -102,7 +111,7 @@ const u8 *src, unsigned int srclen) { struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); - const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm); u8 *pos; unsigned int nblocks; unsigned int n; @@ -143,7 +152,7 @@ static int polyval_x86_final(struct shash_desc *desc, u8 *dst) { struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); - const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm); if (dctx->bytes) { internal_polyval_mul(dctx->buffer, @@ -167,7 +176,7 @@ .cra_driver_name = "polyval-clmulni", .cra_priority = 200, .cra_blocksize = POLYVAL_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct polyval_tfm_ctx), + .cra_ctxsize = POLYVAL_CTX_SIZE, .cra_module = THIS_MODULE, }, }; diff -Nru linux-6.0.6/arch/x86/events/amd/core.c linux-6.0.12/arch/x86/events/amd/core.c --- linux-6.0.6/arch/x86/events/amd/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/events/amd/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -896,8 +896,7 @@ pmu_enabled = cpuc->enabled; cpuc->enabled = 0; - /* stop everything (includes BRS) */ - amd_pmu_disable_all(); + amd_brs_disable_all(); /* Drain BRS is in use (could be inactive) */ if (cpuc->lbr_users) @@ -908,7 +907,7 @@ cpuc->enabled = pmu_enabled; if (pmu_enabled) - amd_pmu_enable_all(0); + amd_brs_enable_all(); return amd_pmu_adjust_nmi_window(handled); } diff -Nru linux-6.0.6/arch/x86/events/amd/uncore.c linux-6.0.12/arch/x86/events/amd/uncore.c --- linux-6.0.6/arch/x86/events/amd/uncore.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/events/amd/uncore.c 2023-01-18 18:27:39.000000000 +0000 @@ -553,6 +553,7 @@ hlist_for_each_entry_safe(uncore, n, &uncore_unused_list, node) { hlist_del(&uncore->node); + kfree(uncore->events); kfree(uncore); } } diff -Nru linux-6.0.6/arch/x86/events/intel/core.c linux-6.0.12/arch/x86/events/intel/core.c --- linux-6.0.6/arch/x86/events/intel/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/events/intel/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -4891,6 +4891,7 @@ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 5, 0x00000000), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 6, 0x00000000), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 7, 0x00000000), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 11, 0x00000000), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L, 3, 0x0000007c), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x0000007c), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x0000004e), diff -Nru linux-6.0.6/arch/x86/events/intel/ds.c linux-6.0.12/arch/x86/events/intel/ds.c --- linux-6.0.6/arch/x86/events/intel/ds.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/events/intel/ds.c 2023-01-18 18:27:39.000000000 +0000 @@ -982,8 +982,13 @@ INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL), /* SLOTS */ INTEL_PLD_CONSTRAINT(0x1cd, 0xff), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ - INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf), /* MEM_INST_RETIRED.LOAD */ - INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf), /* MEM_INST_RETIRED.STORE */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), /* MEM_LOAD_*_RETIRED.* */ @@ -1004,8 +1009,13 @@ INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xfe), INTEL_PLD_CONSTRAINT(0x1cd, 0xfe), INTEL_PSD_CONSTRAINT(0x2cd, 0x1), - INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf), - INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf), + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), diff -Nru linux-6.0.6/arch/x86/events/intel/lbr.c linux-6.0.12/arch/x86/events/intel/lbr.c --- linux-6.0.6/arch/x86/events/intel/lbr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/events/intel/lbr.c 2023-01-18 18:27:39.000000000 +0000 @@ -1869,7 +1869,7 @@ return; clear_arch_lbr: - clear_cpu_cap(&boot_cpu_data, X86_FEATURE_ARCH_LBR); + setup_clear_cpu_cap(X86_FEATURE_ARCH_LBR); } /** diff -Nru linux-6.0.6/arch/x86/events/intel/pt.c linux-6.0.12/arch/x86/events/intel/pt.c --- linux-6.0.6/arch/x86/events/intel/pt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/events/intel/pt.c 2023-01-18 18:27:39.000000000 +0000 @@ -1263,6 +1263,15 @@ if (1 << order != nr_pages) goto out; + /* + * Some processors cannot always support single range for more than + * 4KB - refer errata TGL052, ADL037 and RPL017. Future processors might + * also be affected, so for now rather than trying to keep track of + * which ones, just disable it for all. + */ + if (nr_pages > 1) + goto out; + buf->single = true; buf->nr_pages = nr_pages; ret = 0; diff -Nru linux-6.0.6/arch/x86/hyperv/hv_init.c linux-6.0.12/arch/x86/hyperv/hv_init.c --- linux-6.0.6/arch/x86/hyperv/hv_init.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/hyperv/hv_init.c 2023-01-18 18:27:39.000000000 +0000 @@ -77,7 +77,7 @@ static int hv_cpu_init(unsigned int cpu) { union hv_vp_assist_msr_contents msr = { 0 }; - struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()]; + struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu]; int ret; ret = hv_common_cpu_init(cpu); @@ -87,34 +87,32 @@ if (!hv_vp_assist_page) return 0; - if (!*hvp) { - if (hv_root_partition) { - /* - * For root partition we get the hypervisor provided VP assist - * page, instead of allocating a new page. - */ - rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); - *hvp = memremap(msr.pfn << - HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT, - PAGE_SIZE, MEMREMAP_WB); - } else { - /* - * The VP assist page is an "overlay" page (see Hyper-V TLFS's - * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed - * out to make sure we always write the EOI MSR in - * hv_apic_eoi_write() *after* the EOI optimization is disabled - * in hv_cpu_die(), otherwise a CPU may not be stopped in the - * case of CPU offlining and the VM will hang. - */ + if (hv_root_partition) { + /* + * For root partition we get the hypervisor provided VP assist + * page, instead of allocating a new page. + */ + rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); + *hvp = memremap(msr.pfn << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT, + PAGE_SIZE, MEMREMAP_WB); + } else { + /* + * The VP assist page is an "overlay" page (see Hyper-V TLFS's + * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed + * out to make sure we always write the EOI MSR in + * hv_apic_eoi_write() *after* the EOI optimization is disabled + * in hv_cpu_die(), otherwise a CPU may not be stopped in the + * case of CPU offlining and the VM will hang. + */ + if (!*hvp) *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO); - if (*hvp) - msr.pfn = vmalloc_to_pfn(*hvp); - } - WARN_ON(!(*hvp)); - if (*hvp) { - msr.enable = 1; - wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); - } + if (*hvp) + msr.pfn = vmalloc_to_pfn(*hvp); + + } + if (!WARN_ON(!(*hvp))) { + msr.enable = 1; + wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); } return hyperv_init_ghcb(); diff -Nru linux-6.0.6/arch/x86/include/asm/cpufeatures.h linux-6.0.12/arch/x86/include/asm/cpufeatures.h --- linux-6.0.6/arch/x86/include/asm/cpufeatures.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/include/asm/cpufeatures.h 2023-01-18 18:27:39.000000000 +0000 @@ -305,6 +305,9 @@ #define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */ #define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */ + +#define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */ + /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ diff -Nru linux-6.0.6/arch/x86/include/asm/intel-family.h linux-6.0.12/arch/x86/include/asm/intel-family.h --- linux-6.0.6/arch/x86/include/asm/intel-family.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/include/asm/intel-family.h 2023-01-18 18:27:39.000000000 +0000 @@ -107,6 +107,11 @@ #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F /* Golden Cove */ +#define INTEL_FAM6_EMERALDRAPIDS_X 0xCF + +#define INTEL_FAM6_GRANITERAPIDS_X 0xAD +#define INTEL_FAM6_GRANITERAPIDS_D 0xAE + #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ #define INTEL_FAM6_ALDERLAKE_N 0xBE @@ -118,7 +123,7 @@ #define INTEL_FAM6_METEORLAKE 0xAC #define INTEL_FAM6_METEORLAKE_L 0xAA -/* "Small Core" Processors (Atom) */ +/* "Small Core" Processors (Atom/E-Core) */ #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */ #define INTEL_FAM6_ATOM_BONNELL_MID 0x26 /* Silverthorne, Lincroft */ @@ -145,6 +150,10 @@ #define INTEL_FAM6_ATOM_TREMONT 0x96 /* Elkhart Lake */ #define INTEL_FAM6_ATOM_TREMONT_L 0x9C /* Jasper Lake */ +#define INTEL_FAM6_SIERRAFOREST_X 0xAF + +#define INTEL_FAM6_GRANDRIDGE 0xB6 + /* Xeon Phi */ #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */ diff -Nru linux-6.0.6/arch/x86/include/asm/msr-index.h linux-6.0.12/arch/x86/include/asm/msr-index.h --- linux-6.0.6/arch/x86/include/asm/msr-index.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/include/asm/msr-index.h 2023-01-18 18:27:39.000000000 +0000 @@ -535,6 +535,11 @@ #define MSR_AMD64_CPUID_FN_1 0xc0011004 #define MSR_AMD64_LS_CFG 0xc0011020 #define MSR_AMD64_DC_CFG 0xc0011022 + +#define MSR_AMD64_DE_CFG 0xc0011029 +#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1 +#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT) + #define MSR_AMD64_BU_CFG2 0xc001102a #define MSR_AMD64_IBSFETCHCTL 0xc0011030 #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 @@ -637,9 +642,6 @@ #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL #define FAM10H_MMIO_CONF_BASE_SHIFT 20 #define MSR_FAM10H_NODE_ID 0xc001100c -#define MSR_F10H_DECFG 0xc0011029 -#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT 1 -#define MSR_F10H_DECFG_LFENCE_SERIALIZE BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT) /* K8 MSRs */ #define MSR_K8_TOP_MEM1 0xc001001a diff -Nru linux-6.0.6/arch/x86/include/asm/nospec-branch.h linux-6.0.12/arch/x86/include/asm/nospec-branch.h --- linux-6.0.6/arch/x86/include/asm/nospec-branch.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/include/asm/nospec-branch.h 2023-01-18 18:27:39.000000000 +0000 @@ -321,7 +321,7 @@ /* The Intel SPEC CTRL MSR base value cache */ extern u64 x86_spec_ctrl_base; DECLARE_PER_CPU(u64, x86_spec_ctrl_current); -extern void write_spec_ctrl_current(u64 val, bool force); +extern void update_spec_ctrl_cond(u64 val); extern u64 spec_ctrl_current(void); /* diff -Nru linux-6.0.6/arch/x86/include/asm/syscall_wrapper.h linux-6.0.12/arch/x86/include/asm/syscall_wrapper.h --- linux-6.0.6/arch/x86/include/asm/syscall_wrapper.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/include/asm/syscall_wrapper.h 2023-01-18 18:27:39.000000000 +0000 @@ -6,7 +6,7 @@ #ifndef _ASM_X86_SYSCALL_WRAPPER_H #define _ASM_X86_SYSCALL_WRAPPER_H -struct pt_regs; +#include extern long __x64_sys_ni_syscall(const struct pt_regs *regs); extern long __ia32_sys_ni_syscall(const struct pt_regs *regs); diff -Nru linux-6.0.6/arch/x86/kernel/asm-offsets.c linux-6.0.12/arch/x86/kernel/asm-offsets.c --- linux-6.0.6/arch/x86/kernel/asm-offsets.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/asm-offsets.c 2023-01-18 18:27:39.000000000 +0000 @@ -19,7 +19,6 @@ #include #include #include -#include "../kvm/vmx/vmx.h" #ifdef CONFIG_XEN #include @@ -108,9 +107,4 @@ OFFSET(TSS_sp0, tss_struct, x86_tss.sp0); OFFSET(TSS_sp1, tss_struct, x86_tss.sp1); OFFSET(TSS_sp2, tss_struct, x86_tss.sp2); - - if (IS_ENABLED(CONFIG_KVM_INTEL)) { - BLANK(); - OFFSET(VMX_spec_ctrl, vcpu_vmx, spec_ctrl); - } } diff -Nru linux-6.0.6/arch/x86/kernel/cpu/amd.c linux-6.0.12/arch/x86/kernel/cpu/amd.c --- linux-6.0.6/arch/x86/kernel/cpu/amd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/cpu/amd.c 2023-01-18 18:27:39.000000000 +0000 @@ -770,8 +770,6 @@ set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); } -#define MSR_AMD64_DE_CFG 0xC0011029 - static void init_amd_ln(struct cpuinfo_x86 *c) { /* @@ -965,8 +963,8 @@ * msr_set_bit() uses the safe accessors, too, even if the MSR * is not present. */ - msr_set_bit(MSR_F10H_DECFG, - MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); + msr_set_bit(MSR_AMD64_DE_CFG, + MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT); /* A serializing LFENCE stops RDTSC speculation */ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); diff -Nru linux-6.0.6/arch/x86/kernel/cpu/bugs.c linux-6.0.12/arch/x86/kernel/cpu/bugs.c --- linux-6.0.6/arch/x86/kernel/cpu/bugs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/cpu/bugs.c 2023-01-18 18:27:39.000000000 +0000 @@ -60,11 +60,18 @@ static DEFINE_MUTEX(spec_ctrl_mutex); +/* Update SPEC_CTRL MSR and its cached copy unconditionally */ +static void update_spec_ctrl(u64 val) +{ + this_cpu_write(x86_spec_ctrl_current, val); + wrmsrl(MSR_IA32_SPEC_CTRL, val); +} + /* * Keep track of the SPEC_CTRL MSR value for the current task, which may differ * from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update(). */ -void write_spec_ctrl_current(u64 val, bool force) +void update_spec_ctrl_cond(u64 val) { if (this_cpu_read(x86_spec_ctrl_current) == val) return; @@ -75,7 +82,7 @@ * When KERNEL_IBRS this MSR is written on return-to-user, unless * forced the update can be delayed until that time. */ - if (force || !cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS)) + if (!cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS)) wrmsrl(MSR_IA32_SPEC_CTRL, val); } @@ -196,22 +203,15 @@ } /* - * NOTE: This function is *only* called for SVM. VMX spec_ctrl handling is - * done in vmenter.S. + * NOTE: This function is *only* called for SVM, since Intel uses + * MSR_IA32_SPEC_CTRL for SSBD. */ void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) { - u64 msrval, guestval = guest_spec_ctrl, hostval = spec_ctrl_current(); + u64 guestval, hostval; struct thread_info *ti = current_thread_info(); - if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { - if (hostval != guestval) { - msrval = setguest ? guestval : hostval; - wrmsrl(MSR_IA32_SPEC_CTRL, msrval); - } - } - /* * If SSBD is not handled in MSR_SPEC_CTRL on AMD, update * MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported. @@ -1335,7 +1335,7 @@ if (ia32_cap & ARCH_CAP_RRSBA) { x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S; - write_spec_ctrl_current(x86_spec_ctrl_base, true); + update_spec_ctrl(x86_spec_ctrl_base); } } @@ -1457,7 +1457,7 @@ if (spectre_v2_in_ibrs_mode(mode)) { x86_spec_ctrl_base |= SPEC_CTRL_IBRS; - write_spec_ctrl_current(x86_spec_ctrl_base, true); + update_spec_ctrl(x86_spec_ctrl_base); } switch (mode) { @@ -1571,7 +1571,7 @@ static void update_stibp_msr(void * __unused) { u64 val = spec_ctrl_current() | (x86_spec_ctrl_base & SPEC_CTRL_STIBP); - write_spec_ctrl_current(val, true); + update_spec_ctrl(val); } /* Update x86_spec_ctrl_base in case SMT state changed. */ @@ -1804,7 +1804,7 @@ x86_amd_ssb_disable(); } else { x86_spec_ctrl_base |= SPEC_CTRL_SSBD; - write_spec_ctrl_current(x86_spec_ctrl_base, true); + update_spec_ctrl(x86_spec_ctrl_base); } } @@ -2055,7 +2055,7 @@ void x86_spec_ctrl_setup_ap(void) { if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) - write_spec_ctrl_current(x86_spec_ctrl_base, true); + update_spec_ctrl(x86_spec_ctrl_base); if (ssb_mode == SPEC_STORE_BYPASS_DISABLE) x86_amd_ssb_disable(); diff -Nru linux-6.0.6/arch/x86/kernel/cpu/hygon.c linux-6.0.12/arch/x86/kernel/cpu/hygon.c --- linux-6.0.6/arch/x86/kernel/cpu/hygon.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/cpu/hygon.c 2023-01-18 18:27:39.000000000 +0000 @@ -326,8 +326,8 @@ * msr_set_bit() uses the safe accessors, too, even if the MSR * is not present. */ - msr_set_bit(MSR_F10H_DECFG, - MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); + msr_set_bit(MSR_AMD64_DE_CFG, + MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT); /* A serializing LFENCE stops RDTSC speculation */ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); diff -Nru linux-6.0.6/arch/x86/kernel/cpu/sgx/ioctl.c linux-6.0.12/arch/x86/kernel/cpu/sgx/ioctl.c --- linux-6.0.6/arch/x86/kernel/cpu/sgx/ioctl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/cpu/sgx/ioctl.c 2023-01-18 18:27:39.000000000 +0000 @@ -356,6 +356,9 @@ if (!length || !IS_ALIGNED(length, PAGE_SIZE)) return -EINVAL; + if (offset + length < offset) + return -EINVAL; + if (offset + length - PAGE_SIZE >= encl->size) return -EINVAL; diff -Nru linux-6.0.6/arch/x86/kernel/cpu/tsx.c linux-6.0.12/arch/x86/kernel/cpu/tsx.c --- linux-6.0.6/arch/x86/kernel/cpu/tsx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/cpu/tsx.c 2023-01-18 18:27:39.000000000 +0000 @@ -58,24 +58,6 @@ wrmsrl(MSR_IA32_TSX_CTRL, tsx); } -static bool tsx_ctrl_is_supported(void) -{ - u64 ia32_cap = x86_read_arch_cap_msr(); - - /* - * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this - * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES. - * - * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a - * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES - * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get - * MSR_IA32_TSX_CTRL support even after a microcode update. Thus, - * tsx= cmdline requests will do nothing on CPUs without - * MSR_IA32_TSX_CTRL support. - */ - return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR); -} - static enum tsx_ctrl_states x86_get_tsx_auto_mode(void) { if (boot_cpu_has_bug(X86_BUG_TAA)) @@ -135,7 +117,7 @@ rdmsrl(MSR_TSX_FORCE_ABORT, msr); msr |= MSR_TFA_TSX_CPUID_CLEAR; wrmsrl(MSR_TSX_FORCE_ABORT, msr); - } else if (tsx_ctrl_is_supported()) { + } else if (cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL)) { rdmsrl(MSR_IA32_TSX_CTRL, msr); msr |= TSX_CTRL_CPUID_CLEAR; wrmsrl(MSR_IA32_TSX_CTRL, msr); @@ -158,7 +140,8 @@ u64 mcu_opt_ctrl; /* Check if RTM_ALLOW exists */ - if (!boot_cpu_has_bug(X86_BUG_TAA) || !tsx_ctrl_is_supported() || + if (!boot_cpu_has_bug(X86_BUG_TAA) || + !cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL) || !cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL)) return; @@ -191,7 +174,20 @@ return; } - if (!tsx_ctrl_is_supported()) { + /* + * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this + * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES. + * + * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a + * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES + * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get + * MSR_IA32_TSX_CTRL support even after a microcode update. Thus, + * tsx= cmdline requests will do nothing on CPUs without + * MSR_IA32_TSX_CTRL support. + */ + if (x86_read_arch_cap_msr() & ARCH_CAP_TSX_CTRL_MSR) { + setup_force_cpu_cap(X86_FEATURE_MSR_TSX_CTRL); + } else { tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED; return; } diff -Nru linux-6.0.6/arch/x86/kernel/fpu/core.c linux-6.0.12/arch/x86/kernel/fpu/core.c --- linux-6.0.6/arch/x86/kernel/fpu/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/fpu/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -605,9 +605,9 @@ if (test_thread_flag(TIF_NEED_FPU_LOAD)) fpregs_restore_userregs(); save_fpregs_to_fpstate(dst_fpu); + fpregs_unlock(); if (!(clone_flags & CLONE_THREAD)) fpu_inherit_perms(dst_fpu); - fpregs_unlock(); /* * Children never inherit PASID state. diff -Nru linux-6.0.6/arch/x86/kernel/fpu/init.c linux-6.0.12/arch/x86/kernel/fpu/init.c --- linux-6.0.6/arch/x86/kernel/fpu/init.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/fpu/init.c 2023-01-18 18:27:39.000000000 +0000 @@ -210,13 +210,6 @@ fpstate_reset(¤t->thread.fpu); } -static void __init fpu__init_init_fpstate(void) -{ - /* Bring init_fpstate size and features up to date */ - init_fpstate.size = fpu_kernel_cfg.max_size; - init_fpstate.xfeatures = fpu_kernel_cfg.max_features; -} - /* * Called on the boot CPU once per system bootup, to set up the initial * FPU state that is later cloned into all processes: @@ -236,5 +229,4 @@ fpu__init_system_xstate_size_legacy(); fpu__init_system_xstate(fpu_kernel_cfg.max_size); fpu__init_task_struct_size(); - fpu__init_init_fpstate(); } diff -Nru linux-6.0.6/arch/x86/kernel/fpu/xstate.c linux-6.0.12/arch/x86/kernel/fpu/xstate.c --- linux-6.0.6/arch/x86/kernel/fpu/xstate.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/fpu/xstate.c 2023-01-18 18:27:39.000000000 +0000 @@ -360,7 +360,7 @@ print_xstate_features(); - xstate_init_xcomp_bv(&init_fpstate.regs.xsave, fpu_kernel_cfg.max_features); + xstate_init_xcomp_bv(&init_fpstate.regs.xsave, init_fpstate.xfeatures); /* * Init all the features state with header.xfeatures being 0x0 @@ -678,20 +678,6 @@ return ebx; } -/* - * Will the runtime-enumerated 'xstate_size' fit in the init - * task's statically-allocated buffer? - */ -static bool __init is_supported_xstate_size(unsigned int test_xstate_size) -{ - if (test_xstate_size <= sizeof(init_fpstate.regs)) - return true; - - pr_warn("x86/fpu: xstate buffer too small (%zu < %d), disabling xsave\n", - sizeof(init_fpstate.regs), test_xstate_size); - return false; -} - static int __init init_xstate_size(void) { /* Recompute the context size for enabled features: */ @@ -717,10 +703,6 @@ kernel_default_size = xstate_calculate_size(fpu_kernel_cfg.default_features, compacted); - /* Ensure we have the space to store all default enabled features. */ - if (!is_supported_xstate_size(kernel_default_size)) - return -EINVAL; - if (!paranoid_xstate_size_valid(kernel_size)) return -EINVAL; @@ -875,6 +857,19 @@ update_regset_xstate_info(fpu_user_cfg.max_size, fpu_user_cfg.max_features); + /* + * init_fpstate excludes dynamic states as they are large but init + * state is zero. + */ + init_fpstate.size = fpu_kernel_cfg.default_size; + init_fpstate.xfeatures = fpu_kernel_cfg.default_features; + + if (init_fpstate.size > sizeof(init_fpstate.regs)) { + pr_warn("x86/fpu: init_fpstate buffer too small (%zu < %d), disabling XSAVE\n", + sizeof(init_fpstate.regs), init_fpstate.size); + goto out_disable; + } + setup_init_fpu_buf(); /* @@ -1130,6 +1125,15 @@ */ mask = fpstate->user_xfeatures; + /* + * Dynamic features are not present in init_fpstate. When they are + * in an all zeros init state, remove those from 'mask' to zero + * those features in the user buffer instead of retrieving them + * from init_fpstate. + */ + if (fpu_state_size_dynamic()) + mask &= (header.xfeatures | xinit->header.xcomp_bv); + for_each_extended_xfeature(i, mask) { /* * If there was a feature or alignment gap, zero the space diff -Nru linux-6.0.6/arch/x86/kernel/process.c linux-6.0.12/arch/x86/kernel/process.c --- linux-6.0.6/arch/x86/kernel/process.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/process.c 2023-01-18 18:27:39.000000000 +0000 @@ -600,7 +600,7 @@ } if (updmsr) - write_spec_ctrl_current(msr, false); + update_spec_ctrl_cond(msr); } static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk) diff -Nru linux-6.0.6/arch/x86/kernel/unwind_orc.c linux-6.0.12/arch/x86/kernel/unwind_orc.c --- linux-6.0.6/arch/x86/kernel/unwind_orc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kernel/unwind_orc.c 2023-01-18 18:27:39.000000000 +0000 @@ -713,7 +713,7 @@ /* Otherwise, skip ahead to the user-specified starting frame: */ while (!unwind_done(state) && (!on_stack(&state->stack_info, first_frame, sizeof(long)) || - state->sp < (unsigned long)first_frame)) + state->sp <= (unsigned long)first_frame)) unwind_next_frame(state); return; diff -Nru linux-6.0.6/arch/x86/kvm/cpuid.c linux-6.0.12/arch/x86/kvm/cpuid.c --- linux-6.0.6/arch/x86/kvm/cpuid.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/cpuid.c 2023-01-18 18:27:39.000000000 +0000 @@ -1117,11 +1117,13 @@ entry->eax = max(entry->eax, 0x80000021); break; case 0x80000001: + entry->ebx &= ~GENMASK(27, 16); cpuid_entry_override(entry, CPUID_8000_0001_EDX); cpuid_entry_override(entry, CPUID_8000_0001_ECX); break; case 0x80000006: - /* L2 cache and TLB: pass through host info. */ + /* Drop reserved bits, pass host L2 cache and TLB info. */ + entry->edx &= ~GENMASK(17, 16); break; case 0x80000007: /* Advanced power management */ /* invariant TSC is CPUID.80000007H:EDX[8] */ @@ -1151,6 +1153,7 @@ g_phys_as = phys_as; entry->eax = g_phys_as | (virt_as << 8); + entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8)); entry->edx = 0; cpuid_entry_override(entry, CPUID_8000_0008_EBX); break; @@ -1170,6 +1173,9 @@ entry->ecx = entry->edx = 0; break; case 0x8000001a: + entry->eax &= GENMASK(2, 0); + entry->ebx = entry->ecx = entry->edx = 0; + break; case 0x8000001e: break; case 0x8000001F: @@ -1177,7 +1183,8 @@ entry->eax = entry->ebx = entry->ecx = entry->edx = 0; } else { cpuid_entry_override(entry, CPUID_8000_001F_EAX); - + /* Clear NumVMPL since KVM does not support VMPL. */ + entry->ebx &= ~GENMASK(31, 12); /* * Enumerate '0' for "PA bits reduction", the adjusted * MAXPHYADDR is enumerated directly (see 0x80000008). diff -Nru linux-6.0.6/arch/x86/kvm/emulate.c linux-6.0.12/arch/x86/kvm/emulate.c --- linux-6.0.6/arch/x86/kvm/emulate.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/emulate.c 2023-01-18 18:27:39.000000000 +0000 @@ -791,8 +791,7 @@ ctxt->mode, linear); } -static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst, - enum x86emul_mode mode) +static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst) { ulong linear; int rc; @@ -802,41 +801,71 @@ if (ctxt->op_bytes != sizeof(unsigned long)) addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1); - rc = __linearize(ctxt, addr, &max_size, 1, false, true, mode, &linear); + rc = __linearize(ctxt, addr, &max_size, 1, false, true, ctxt->mode, &linear); if (rc == X86EMUL_CONTINUE) ctxt->_eip = addr.ea; return rc; } +static inline int emulator_recalc_and_set_mode(struct x86_emulate_ctxt *ctxt) +{ + u64 efer; + struct desc_struct cs; + u16 selector; + u32 base3; + + ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); + + if (!(ctxt->ops->get_cr(ctxt, 0) & X86_CR0_PE)) { + /* Real mode. cpu must not have long mode active */ + if (efer & EFER_LMA) + return X86EMUL_UNHANDLEABLE; + ctxt->mode = X86EMUL_MODE_REAL; + return X86EMUL_CONTINUE; + } + + if (ctxt->eflags & X86_EFLAGS_VM) { + /* Protected/VM86 mode. cpu must not have long mode active */ + if (efer & EFER_LMA) + return X86EMUL_UNHANDLEABLE; + ctxt->mode = X86EMUL_MODE_VM86; + return X86EMUL_CONTINUE; + } + + if (!ctxt->ops->get_segment(ctxt, &selector, &cs, &base3, VCPU_SREG_CS)) + return X86EMUL_UNHANDLEABLE; + + if (efer & EFER_LMA) { + if (cs.l) { + /* Proper long mode */ + ctxt->mode = X86EMUL_MODE_PROT64; + } else if (cs.d) { + /* 32 bit compatibility mode*/ + ctxt->mode = X86EMUL_MODE_PROT32; + } else { + ctxt->mode = X86EMUL_MODE_PROT16; + } + } else { + /* Legacy 32 bit / 16 bit mode */ + ctxt->mode = cs.d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; + } + + return X86EMUL_CONTINUE; +} + static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst) { - return assign_eip(ctxt, dst, ctxt->mode); + return assign_eip(ctxt, dst); } -static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, - const struct desc_struct *cs_desc) +static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst) { - enum x86emul_mode mode = ctxt->mode; - int rc; + int rc = emulator_recalc_and_set_mode(ctxt); -#ifdef CONFIG_X86_64 - if (ctxt->mode >= X86EMUL_MODE_PROT16) { - if (cs_desc->l) { - u64 efer = 0; + if (rc != X86EMUL_CONTINUE) + return rc; - ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); - if (efer & EFER_LMA) - mode = X86EMUL_MODE_PROT64; - } else - mode = X86EMUL_MODE_PROT32; /* temporary value */ - } -#endif - if (mode == X86EMUL_MODE_PROT16 || mode == X86EMUL_MODE_PROT32) - mode = cs_desc->d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; - rc = assign_eip(ctxt, dst, mode); - if (rc == X86EMUL_CONTINUE) - ctxt->mode = mode; - return rc; + return assign_eip(ctxt, dst); } static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) @@ -2170,7 +2199,7 @@ if (rc != X86EMUL_CONTINUE) return rc; - rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); + rc = assign_eip_far(ctxt, ctxt->src.val); /* Error handling is not implemented. */ if (rc != X86EMUL_CONTINUE) return X86EMUL_UNHANDLEABLE; @@ -2248,7 +2277,7 @@ &new_desc); if (rc != X86EMUL_CONTINUE) return rc; - rc = assign_eip_far(ctxt, eip, &new_desc); + rc = assign_eip_far(ctxt, eip); /* Error handling is not implemented. */ if (rc != X86EMUL_CONTINUE) return X86EMUL_UNHANDLEABLE; @@ -2430,7 +2459,7 @@ ctxt->eflags = GET_SMSTATE(u32, smstate, 0x7ff4) | X86_EFLAGS_FIXED; ctxt->_eip = GET_SMSTATE(u32, smstate, 0x7ff0); - for (i = 0; i < NR_EMULATOR_GPRS; i++) + for (i = 0; i < 8; i++) *reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4); val = GET_SMSTATE(u32, smstate, 0x7fcc); @@ -2487,7 +2516,7 @@ u16 selector; int i, r; - for (i = 0; i < NR_EMULATOR_GPRS; i++) + for (i = 0; i < 16; i++) *reg_write(ctxt, i) = GET_SMSTATE(u64, smstate, 0x7ff8 - i * 8); ctxt->_eip = GET_SMSTATE(u64, smstate, 0x7f78); @@ -2631,7 +2660,7 @@ * those side effects need to be explicitly handled for both success * and shutdown. */ - return X86EMUL_CONTINUE; + return emulator_recalc_and_set_mode(ctxt); emulate_shutdown: ctxt->ops->triple_fault(ctxt); @@ -2874,6 +2903,7 @@ ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS); ctxt->_eip = rdx; + ctxt->mode = usermode; *reg_write(ctxt, VCPU_REGS_RSP) = rcx; return X86EMUL_CONTINUE; @@ -3467,7 +3497,7 @@ if (rc != X86EMUL_CONTINUE) return rc; - rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); + rc = assign_eip_far(ctxt, ctxt->src.val); if (rc != X86EMUL_CONTINUE) goto fail; @@ -3609,11 +3639,25 @@ static int em_cr_write(struct x86_emulate_ctxt *ctxt) { - if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) + int cr_num = ctxt->modrm_reg; + int r; + + if (ctxt->ops->set_cr(ctxt, cr_num, ctxt->src.val)) return emulate_gp(ctxt, 0); /* Disable writeback. */ ctxt->dst.type = OP_NONE; + + if (cr_num == 0) { + /* + * CR0 write might have updated CR0.PE and/or CR0.PG + * which can affect the cpu's execution mode. + */ + r = emulator_recalc_and_set_mode(ctxt); + if (r != X86EMUL_CONTINUE) + return r; + } + return X86EMUL_CONTINUE; } diff -Nru linux-6.0.6/arch/x86/kvm/kvm-asm-offsets.c linux-6.0.12/arch/x86/kvm/kvm-asm-offsets.c --- linux-6.0.6/arch/x86/kvm/kvm-asm-offsets.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/kvm-asm-offsets.c 2023-01-18 18:27:39.000000000 +0000 @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Generate definitions needed by assembly language modules. + * This code generates raw asm output which is post-processed to extract + * and format the required data. + */ +#define COMPILE_OFFSETS + +#include +#include "vmx/vmx.h" +#include "svm/svm.h" + +static void __used common(void) +{ + if (IS_ENABLED(CONFIG_KVM_AMD)) { + BLANK(); + OFFSET(SVM_vcpu_arch_regs, vcpu_svm, vcpu.arch.regs); + OFFSET(SVM_current_vmcb, vcpu_svm, current_vmcb); + OFFSET(SVM_spec_ctrl, vcpu_svm, spec_ctrl); + OFFSET(SVM_vmcb01, vcpu_svm, vmcb01); + OFFSET(KVM_VMCB_pa, kvm_vmcb_info, pa); + OFFSET(SD_save_area_pa, svm_cpu_data, save_area_pa); + } + + if (IS_ENABLED(CONFIG_KVM_INTEL)) { + BLANK(); + OFFSET(VMX_spec_ctrl, vcpu_vmx, spec_ctrl); + } +} diff -Nru linux-6.0.6/arch/x86/kvm/Makefile linux-6.0.12/arch/x86/kvm/Makefile --- linux-6.0.6/arch/x86/kvm/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -34,3 +34,15 @@ obj-$(CONFIG_KVM) += kvm.o obj-$(CONFIG_KVM_INTEL) += kvm-intel.o obj-$(CONFIG_KVM_AMD) += kvm-amd.o + +AFLAGS_svm/vmenter.o := -iquote $(obj) +$(obj)/svm/vmenter.o: $(obj)/kvm-asm-offsets.h + +AFLAGS_vmx/vmenter.o := -iquote $(obj) +$(obj)/vmx/vmenter.o: $(obj)/kvm-asm-offsets.h + +$(obj)/kvm-asm-offsets.h: $(obj)/kvm-asm-offsets.s FORCE + $(call filechk,offsets,__KVM_ASM_OFFSETS_H__) + +targets += kvm-asm-offsets.s +clean-files += kvm-asm-offsets.h diff -Nru linux-6.0.6/arch/x86/kvm/mmu/mmu.c linux-6.0.12/arch/x86/kvm/mmu/mmu.c --- linux-6.0.6/arch/x86/kvm/mmu/mmu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/mmu/mmu.c 2023-01-18 18:27:39.000000000 +0000 @@ -2431,6 +2431,7 @@ { bool list_unstable, zapped_root = false; + lockdep_assert_held_write(&kvm->mmu_lock); trace_kvm_mmu_prepare_zap_page(sp); ++kvm->stat.mmu_shadow_zapped; *nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list); @@ -4250,14 +4251,14 @@ if (is_page_fault_stale(vcpu, fault, mmu_seq)) goto out_unlock; - r = make_mmu_pages_available(vcpu); - if (r) - goto out_unlock; - - if (is_tdp_mmu_fault) + if (is_tdp_mmu_fault) { r = kvm_tdp_mmu_map(vcpu, fault); - else + } else { + r = make_mmu_pages_available(vcpu); + if (r) + goto out_unlock; r = __direct_map(vcpu, fault); + } out_unlock: if (is_tdp_mmu_fault) @@ -6044,7 +6045,7 @@ write_lock(&kvm->mmu_lock); - kvm_mmu_invalidate_begin(kvm, gfn_start, gfn_end); + kvm_mmu_invalidate_begin(kvm, 0, -1ul); flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end); @@ -6058,7 +6059,7 @@ kvm_flush_remote_tlbs_with_address(kvm, gfn_start, gfn_end - gfn_start); - kvm_mmu_invalidate_end(kvm, gfn_start, gfn_end); + kvm_mmu_invalidate_end(kvm, 0, -1ul); write_unlock(&kvm->mmu_lock); } diff -Nru linux-6.0.6/arch/x86/kvm/svm/nested.c linux-6.0.12/arch/x86/kvm/svm/nested.c --- linux-6.0.6/arch/x86/kvm/svm/nested.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/svm/nested.c 2023-01-18 18:27:39.000000000 +0000 @@ -1143,6 +1143,9 @@ if (!svm->nested.initialized) return; + if (WARN_ON_ONCE(svm->vmcb != svm->vmcb01.ptr)) + svm_switch_vmcb(svm, &svm->vmcb01); + svm_vcpu_free_msrpm(svm->nested.msrpm); svm->nested.msrpm = NULL; @@ -1161,9 +1164,6 @@ svm->nested.initialized = false; } -/* - * Forcibly leave nested mode in order to be able to reset the VCPU later on. - */ void svm_leave_nested(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); diff -Nru linux-6.0.6/arch/x86/kvm/svm/sev.c linux-6.0.12/arch/x86/kvm/svm/sev.c --- linux-6.0.6/arch/x86/kvm/svm/sev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/svm/sev.c 2023-01-18 18:27:39.000000000 +0000 @@ -196,7 +196,7 @@ __set_bit(sev->asid, sev_reclaim_asid_bitmap); for_each_possible_cpu(cpu) { - sd = per_cpu(svm_data, cpu); + sd = per_cpu_ptr(&svm_data, cpu); sd->sev_vmcbs[sev->asid] = NULL; } @@ -605,7 +605,7 @@ save->dr6 = svm->vcpu.arch.dr6; pr_debug("Virtual Machine Save Area (VMSA):\n"); - print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false); + print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false); return 0; } @@ -2600,7 +2600,7 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu) { - struct svm_cpu_data *sd = per_cpu(svm_data, cpu); + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); int asid = sev_get_asid(svm->vcpu.kvm); /* Assign the asid allocated with this SEV guest */ diff -Nru linux-6.0.6/arch/x86/kvm/svm/svm.c linux-6.0.12/arch/x86/kvm/svm/svm.c --- linux-6.0.6/arch/x86/kvm/svm/svm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/svm/svm.c 2023-01-18 18:27:39.000000000 +0000 @@ -245,7 +245,7 @@ u32 zero1; } __attribute__((packed)); -DEFINE_PER_CPU(struct svm_cpu_data *, svm_data); +DEFINE_PER_CPU(struct svm_cpu_data, svm_data); /* * Only MSR_TSC_AUX is switched via the user return hook. EFER is switched via @@ -346,12 +346,6 @@ return 0; } -static int is_external_interrupt(u32 info) -{ - info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; - return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR); -} - static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); @@ -583,12 +577,7 @@ pr_err("%s: err EOPNOTSUPP on %d\n", __func__, me); return -EINVAL; } - sd = per_cpu(svm_data, me); - if (!sd) { - pr_err("%s: svm_data is NULL on %d\n", __func__, me); - return -EINVAL; - } - + sd = per_cpu_ptr(&svm_data, me); sd->asid_generation = 1; sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; sd->next_asid = sd->max_asid + 1; @@ -599,7 +588,7 @@ wrmsrl(MSR_EFER, efer | EFER_SVME); - wrmsrl(MSR_VM_HSAVE_PA, __sme_page_pa(sd->save_area)); + wrmsrl(MSR_VM_HSAVE_PA, sd->save_area_pa); if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) { /* @@ -648,42 +637,37 @@ static void svm_cpu_uninit(int cpu) { - struct svm_cpu_data *sd = per_cpu(svm_data, cpu); + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); - if (!sd) + if (!sd->save_area) return; - per_cpu(svm_data, cpu) = NULL; kfree(sd->sev_vmcbs); __free_page(sd->save_area); - kfree(sd); + sd->save_area_pa = 0; + sd->save_area = NULL; } static int svm_cpu_init(int cpu) { - struct svm_cpu_data *sd; + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); int ret = -ENOMEM; - sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL); - if (!sd) - return ret; - sd->cpu = cpu; + memset(sd, 0, sizeof(struct svm_cpu_data)); sd->save_area = alloc_page(GFP_KERNEL | __GFP_ZERO); if (!sd->save_area) - goto free_cpu_data; + return ret; ret = sev_cpu_init(sd); if (ret) goto free_save_area; - per_cpu(svm_data, cpu) = sd; - + sd->save_area_pa = __sme_page_pa(sd->save_area); return 0; free_save_area: __free_page(sd->save_area); -free_cpu_data: - kfree(sd); + sd->save_area = NULL; return ret; } @@ -732,6 +716,15 @@ u32 offset; u32 *msrpm; + /* + * For non-nested case: + * If the L01 MSR bitmap does not intercept the MSR, then we need to + * save it. + * + * For nested case: + * If the L02 MSR bitmap does not intercept the MSR, then we need to + * save it. + */ msrpm = is_guest_mode(vcpu) ? to_svm(vcpu)->nested.msrpm: to_svm(vcpu)->msrpm; @@ -1427,7 +1420,7 @@ int i; for_each_online_cpu(i) - cmpxchg(&per_cpu(svm_data, i)->current_vmcb, vmcb, NULL); + cmpxchg(per_cpu_ptr(&svm_data.current_vmcb, i), vmcb, NULL); } static void svm_vcpu_free(struct kvm_vcpu *vcpu) @@ -1441,6 +1434,7 @@ */ svm_clear_current_vmcb(svm->vmcb); + svm_leave_nested(vcpu); svm_free_nested(svm); sev_free_vcpu(vcpu); @@ -1452,7 +1446,7 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); - struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu); + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu); if (sev_es_guest(vcpu->kvm)) sev_es_unmap_ghcb(svm); @@ -1464,7 +1458,7 @@ * Save additional host state that will be restored on VMEXIT (sev-es) * or subsequent vmload of host save area. */ - vmsave(__sme_page_pa(sd->save_area)); + vmsave(sd->save_area_pa); if (sev_es_guest(vcpu->kvm)) { struct sev_es_save_area *hostsa; hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400); @@ -1489,7 +1483,7 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct vcpu_svm *svm = to_svm(vcpu); - struct svm_cpu_data *sd = per_cpu(svm_data, cpu); + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); if (sd->current_vmcb != svm->vmcb) { sd->current_vmcb = svm->vmcb; @@ -2711,9 +2705,9 @@ msr->data = 0; switch (msr->index) { - case MSR_F10H_DECFG: - if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) - msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE; + case MSR_AMD64_DE_CFG: + if (cpu_feature_enabled(X86_FEATURE_LFENCE_RDTSC)) + msr->data |= MSR_AMD64_DE_CFG_LFENCE_SERIALIZE; break; case MSR_IA32_PERF_CAPABILITIES: return 0; @@ -2814,7 +2808,7 @@ msr_info->data = 0x1E; } break; - case MSR_F10H_DECFG: + case MSR_AMD64_DE_CFG: msr_info->data = svm->msr_decfg; break; default: @@ -3043,7 +3037,7 @@ case MSR_VM_IGNNE: vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); break; - case MSR_F10H_DECFG: { + case MSR_AMD64_DE_CFG: { struct kvm_msr_entry msr_entry; msr_entry.index = msr->index; @@ -3427,15 +3421,6 @@ return 0; } - if (is_external_interrupt(svm->vmcb->control.exit_int_info) && - exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR && - exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH && - exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI) - printk(KERN_ERR "%s: unexpected exit_int_info 0x%x " - "exit_code 0x%x\n", - __func__, svm->vmcb->control.exit_int_info, - exit_code); - if (exit_fastpath != EXIT_FASTPATH_NONE) return 1; @@ -3444,7 +3429,7 @@ static void reload_tss(struct kvm_vcpu *vcpu) { - struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu); + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu); sd->tss_desc->type = 9; /* available 32/64-bit TSS */ load_TR_desc(); @@ -3452,7 +3437,7 @@ static void pre_svm_run(struct kvm_vcpu *vcpu) { - struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu); + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu); struct vcpu_svm *svm = to_svm(vcpu); /* @@ -3912,30 +3897,16 @@ return EXIT_FASTPATH_NONE; } -static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu) +static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, bool spec_ctrl_intercepted) { struct vcpu_svm *svm = to_svm(vcpu); - unsigned long vmcb_pa = svm->current_vmcb->pa; guest_state_enter_irqoff(); - if (sev_es_guest(vcpu->kvm)) { - __svm_sev_es_vcpu_run(vmcb_pa); - } else { - struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu); - - /* - * Use a single vmcb (vmcb01 because it's always valid) for - * context switching guest state via VMLOAD/VMSAVE, that way - * the state doesn't need to be copied between vmcb01 and - * vmcb02 when switching vmcbs for nested virtualization. - */ - vmload(svm->vmcb01.pa); - __svm_vcpu_run(vmcb_pa, (unsigned long *)&vcpu->arch.regs); - vmsave(svm->vmcb01.pa); - - vmload(__sme_page_pa(sd->save_area)); - } + if (sev_es_guest(vcpu->kvm)) + __svm_sev_es_vcpu_run(svm, spec_ctrl_intercepted); + else + __svm_vcpu_run(svm, spec_ctrl_intercepted); guest_state_exit_irqoff(); } @@ -3943,6 +3914,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + bool spec_ctrl_intercepted = msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL); trace_kvm_entry(vcpu); @@ -4001,26 +3973,7 @@ if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL)) x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl); - svm_vcpu_enter_exit(vcpu); - - /* - * We do not use IBRS in the kernel. If this vCPU has used the - * SPEC_CTRL MSR it may have left it on; save the value and - * turn it off. This is much more efficient than blindly adding - * it to the atomic save/restore list. Especially as the former - * (Saving guest MSRs on vmexit) doesn't even exist in KVM. - * - * For non-nested case: - * If the L01 MSR bitmap does not intercept the MSR, then we need to - * save it. - * - * For nested case: - * If the L02 MSR bitmap does not intercept the MSR, then we need to - * save it. - */ - if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL) && - unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) - svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); + svm_vcpu_enter_exit(vcpu, spec_ctrl_intercepted); if (!sev_es_guest(vcpu->kvm)) reload_tss(vcpu); diff -Nru linux-6.0.6/arch/x86/kvm/svm/svm.h linux-6.0.12/arch/x86/kvm/svm/svm.h --- linux-6.0.6/arch/x86/kvm/svm/svm.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/svm/svm.h 2023-01-18 18:27:39.000000000 +0000 @@ -281,8 +281,6 @@ }; struct svm_cpu_data { - int cpu; - u64 asid_generation; u32 max_asid; u32 next_asid; @@ -290,13 +288,15 @@ struct kvm_ldttss_desc *tss_desc; struct page *save_area; + unsigned long save_area_pa; + struct vmcb *current_vmcb; /* index = sev_asid, value = vmcb pointer */ struct vmcb **sev_vmcbs; }; -DECLARE_PER_CPU(struct svm_cpu_data *, svm_data); +DECLARE_PER_CPU(struct svm_cpu_data, svm_data); void recalc_intercepts(struct vcpu_svm *svm); @@ -683,7 +683,7 @@ /* vmenter.S */ -void __svm_sev_es_vcpu_run(unsigned long vmcb_pa); -void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); +void __svm_sev_es_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted); +void __svm_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted); #endif diff -Nru linux-6.0.6/arch/x86/kvm/svm/svm_ops.h linux-6.0.12/arch/x86/kvm/svm/svm_ops.h --- linux-6.0.6/arch/x86/kvm/svm/svm_ops.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/svm/svm_ops.h 2023-01-18 18:27:39.000000000 +0000 @@ -61,9 +61,4 @@ svm_asm1(vmsave, "a" (pa), "memory"); } -static __always_inline void vmload(unsigned long pa) -{ - svm_asm1(vmload, "a" (pa), "memory"); -} - #endif /* __KVM_X86_SVM_OPS_H */ diff -Nru linux-6.0.6/arch/x86/kvm/svm/vmenter.S linux-6.0.12/arch/x86/kvm/svm/vmenter.S --- linux-6.0.6/arch/x86/kvm/svm/vmenter.S 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/svm/vmenter.S 2023-01-18 18:27:39.000000000 +0000 @@ -4,35 +4,97 @@ #include #include #include +#include "kvm-asm-offsets.h" #define WORD_SIZE (BITS_PER_LONG / 8) /* Intentionally omit RAX as it's context switched by hardware */ -#define VCPU_RCX __VCPU_REGS_RCX * WORD_SIZE -#define VCPU_RDX __VCPU_REGS_RDX * WORD_SIZE -#define VCPU_RBX __VCPU_REGS_RBX * WORD_SIZE +#define VCPU_RCX (SVM_vcpu_arch_regs + __VCPU_REGS_RCX * WORD_SIZE) +#define VCPU_RDX (SVM_vcpu_arch_regs + __VCPU_REGS_RDX * WORD_SIZE) +#define VCPU_RBX (SVM_vcpu_arch_regs + __VCPU_REGS_RBX * WORD_SIZE) /* Intentionally omit RSP as it's context switched by hardware */ -#define VCPU_RBP __VCPU_REGS_RBP * WORD_SIZE -#define VCPU_RSI __VCPU_REGS_RSI * WORD_SIZE -#define VCPU_RDI __VCPU_REGS_RDI * WORD_SIZE +#define VCPU_RBP (SVM_vcpu_arch_regs + __VCPU_REGS_RBP * WORD_SIZE) +#define VCPU_RSI (SVM_vcpu_arch_regs + __VCPU_REGS_RSI * WORD_SIZE) +#define VCPU_RDI (SVM_vcpu_arch_regs + __VCPU_REGS_RDI * WORD_SIZE) #ifdef CONFIG_X86_64 -#define VCPU_R8 __VCPU_REGS_R8 * WORD_SIZE -#define VCPU_R9 __VCPU_REGS_R9 * WORD_SIZE -#define VCPU_R10 __VCPU_REGS_R10 * WORD_SIZE -#define VCPU_R11 __VCPU_REGS_R11 * WORD_SIZE -#define VCPU_R12 __VCPU_REGS_R12 * WORD_SIZE -#define VCPU_R13 __VCPU_REGS_R13 * WORD_SIZE -#define VCPU_R14 __VCPU_REGS_R14 * WORD_SIZE -#define VCPU_R15 __VCPU_REGS_R15 * WORD_SIZE +#define VCPU_R8 (SVM_vcpu_arch_regs + __VCPU_REGS_R8 * WORD_SIZE) +#define VCPU_R9 (SVM_vcpu_arch_regs + __VCPU_REGS_R9 * WORD_SIZE) +#define VCPU_R10 (SVM_vcpu_arch_regs + __VCPU_REGS_R10 * WORD_SIZE) +#define VCPU_R11 (SVM_vcpu_arch_regs + __VCPU_REGS_R11 * WORD_SIZE) +#define VCPU_R12 (SVM_vcpu_arch_regs + __VCPU_REGS_R12 * WORD_SIZE) +#define VCPU_R13 (SVM_vcpu_arch_regs + __VCPU_REGS_R13 * WORD_SIZE) +#define VCPU_R14 (SVM_vcpu_arch_regs + __VCPU_REGS_R14 * WORD_SIZE) +#define VCPU_R15 (SVM_vcpu_arch_regs + __VCPU_REGS_R15 * WORD_SIZE) #endif +#define SVM_vmcb01_pa (SVM_vmcb01 + KVM_VMCB_pa) + .section .noinstr.text, "ax" +.macro RESTORE_GUEST_SPEC_CTRL + /* No need to do anything if SPEC_CTRL is unset or V_SPEC_CTRL is set */ + ALTERNATIVE_2 "", \ + "jmp 800f", X86_FEATURE_MSR_SPEC_CTRL, \ + "", X86_FEATURE_V_SPEC_CTRL +801: +.endm +.macro RESTORE_GUEST_SPEC_CTRL_BODY +800: + /* + * SPEC_CTRL handling: if the guest's SPEC_CTRL value differs from the + * host's, write the MSR. This is kept out-of-line so that the common + * case does not have to jump. + * + * IMPORTANT: To avoid RSB underflow attacks and any other nastiness, + * there must not be any returns or indirect branches between this code + * and vmentry. + */ + movl SVM_spec_ctrl(%_ASM_DI), %eax + cmp PER_CPU_VAR(x86_spec_ctrl_current), %eax + je 801b + mov $MSR_IA32_SPEC_CTRL, %ecx + xor %edx, %edx + wrmsr + jmp 801b +.endm + +.macro RESTORE_HOST_SPEC_CTRL + /* No need to do anything if SPEC_CTRL is unset or V_SPEC_CTRL is set */ + ALTERNATIVE_2 "", \ + "jmp 900f", X86_FEATURE_MSR_SPEC_CTRL, \ + "", X86_FEATURE_V_SPEC_CTRL +901: +.endm +.macro RESTORE_HOST_SPEC_CTRL_BODY +900: + /* Same for after vmexit. */ + mov $MSR_IA32_SPEC_CTRL, %ecx + + /* + * Load the value that the guest had written into MSR_IA32_SPEC_CTRL, + * if it was not intercepted during guest execution. + */ + cmpb $0, (%_ASM_SP) + jnz 998f + rdmsr + movl %eax, SVM_spec_ctrl(%_ASM_DI) +998: + + /* Now restore the host value of the MSR if different from the guest's. */ + movl PER_CPU_VAR(x86_spec_ctrl_current), %eax + cmp SVM_spec_ctrl(%_ASM_DI), %eax + je 901b + xor %edx, %edx + wrmsr + jmp 901b +.endm + + /** * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode - * @vmcb_pa: unsigned long - * @regs: unsigned long * (to guest registers) + * @svm: struct vcpu_svm * + * @spec_ctrl_intercepted: bool */ SYM_FUNC_START(__svm_vcpu_run) push %_ASM_BP @@ -47,49 +109,71 @@ #endif push %_ASM_BX - /* Save @regs. */ + /* + * Save variables needed after vmexit on the stack, in inverse + * order compared to when they are needed. + */ + + /* Accessed directly from the stack in RESTORE_HOST_SPEC_CTRL. */ push %_ASM_ARG2 - /* Save @vmcb. */ + /* Needed to restore access to percpu variables. */ + __ASM_SIZE(push) PER_CPU_VAR(svm_data + SD_save_area_pa) + + /* Finally save @svm. */ push %_ASM_ARG1 - /* Move @regs to RAX. */ - mov %_ASM_ARG2, %_ASM_AX +.ifnc _ASM_ARG1, _ASM_DI + /* + * Stash @svm in RDI early. On 32-bit, arguments are in RAX, RCX + * and RDX which are clobbered by RESTORE_GUEST_SPEC_CTRL. + */ + mov %_ASM_ARG1, %_ASM_DI +.endif + + /* Clobbers RAX, RCX, RDX. */ + RESTORE_GUEST_SPEC_CTRL + + /* + * Use a single vmcb (vmcb01 because it's always valid) for + * context switching guest state via VMLOAD/VMSAVE, that way + * the state doesn't need to be copied between vmcb01 and + * vmcb02 when switching vmcbs for nested virtualization. + */ + mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX +1: vmload %_ASM_AX +2: + + /* Get svm->current_vmcb->pa into RAX. */ + mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX + mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX /* Load guest registers. */ - mov VCPU_RCX(%_ASM_AX), %_ASM_CX - mov VCPU_RDX(%_ASM_AX), %_ASM_DX - mov VCPU_RBX(%_ASM_AX), %_ASM_BX - mov VCPU_RBP(%_ASM_AX), %_ASM_BP - mov VCPU_RSI(%_ASM_AX), %_ASM_SI - mov VCPU_RDI(%_ASM_AX), %_ASM_DI -#ifdef CONFIG_X86_64 - mov VCPU_R8 (%_ASM_AX), %r8 - mov VCPU_R9 (%_ASM_AX), %r9 - mov VCPU_R10(%_ASM_AX), %r10 - mov VCPU_R11(%_ASM_AX), %r11 - mov VCPU_R12(%_ASM_AX), %r12 - mov VCPU_R13(%_ASM_AX), %r13 - mov VCPU_R14(%_ASM_AX), %r14 - mov VCPU_R15(%_ASM_AX), %r15 + mov VCPU_RCX(%_ASM_DI), %_ASM_CX + mov VCPU_RDX(%_ASM_DI), %_ASM_DX + mov VCPU_RBX(%_ASM_DI), %_ASM_BX + mov VCPU_RBP(%_ASM_DI), %_ASM_BP + mov VCPU_RSI(%_ASM_DI), %_ASM_SI +#ifdef CONFIG_X86_64 + mov VCPU_R8 (%_ASM_DI), %r8 + mov VCPU_R9 (%_ASM_DI), %r9 + mov VCPU_R10(%_ASM_DI), %r10 + mov VCPU_R11(%_ASM_DI), %r11 + mov VCPU_R12(%_ASM_DI), %r12 + mov VCPU_R13(%_ASM_DI), %r13 + mov VCPU_R14(%_ASM_DI), %r14 + mov VCPU_R15(%_ASM_DI), %r15 #endif - - /* "POP" @vmcb to RAX. */ - pop %_ASM_AX + mov VCPU_RDI(%_ASM_DI), %_ASM_DI /* Enter guest mode */ sti -1: vmrun %_ASM_AX - -2: cli - -#ifdef CONFIG_RETPOLINE - /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ - FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE -#endif +3: vmrun %_ASM_AX +4: + cli - /* "POP" @regs to RAX. */ + /* Pop @svm to RAX while it's the only available register. */ pop %_ASM_AX /* Save all guest registers. */ @@ -110,6 +194,26 @@ mov %r15, VCPU_R15(%_ASM_AX) #endif + /* @svm can stay in RDI from now on. */ + mov %_ASM_AX, %_ASM_DI + + mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX +5: vmsave %_ASM_AX +6: + + /* Restores GSBASE among other things, allowing access to percpu data. */ + pop %_ASM_AX +7: vmload %_ASM_AX +8: + +#ifdef CONFIG_RETPOLINE + /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ + FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE +#endif + + /* Clobbers RAX, RCX, RDX. */ + RESTORE_HOST_SPEC_CTRL + /* * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be * untrained as soon as we exit the VM and are back to the @@ -145,6 +249,9 @@ xor %r15d, %r15d #endif + /* "Pop" @spec_ctrl_intercepted. */ + pop %_ASM_BX + pop %_ASM_BX #ifdef CONFIG_X86_64 @@ -159,17 +266,33 @@ pop %_ASM_BP RET -3: cmpb $0, kvm_rebooting + RESTORE_GUEST_SPEC_CTRL_BODY + RESTORE_HOST_SPEC_CTRL_BODY + +10: cmpb $0, kvm_rebooting jne 2b ud2 +30: cmpb $0, kvm_rebooting + jne 4b + ud2 +50: cmpb $0, kvm_rebooting + jne 6b + ud2 +70: cmpb $0, kvm_rebooting + jne 8b + ud2 - _ASM_EXTABLE(1b, 3b) + _ASM_EXTABLE(1b, 10b) + _ASM_EXTABLE(3b, 30b) + _ASM_EXTABLE(5b, 50b) + _ASM_EXTABLE(7b, 70b) SYM_FUNC_END(__svm_vcpu_run) /** * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode - * @vmcb_pa: unsigned long + * @svm: struct vcpu_svm * + * @spec_ctrl_intercepted: bool */ SYM_FUNC_START(__svm_sev_es_vcpu_run) push %_ASM_BP @@ -184,8 +307,31 @@ #endif push %_ASM_BX - /* Move @vmcb to RAX. */ - mov %_ASM_ARG1, %_ASM_AX + /* + * Save variables needed after vmexit on the stack, in inverse + * order compared to when they are needed. + */ + + /* Accessed directly from the stack in RESTORE_HOST_SPEC_CTRL. */ + push %_ASM_ARG2 + + /* Save @svm. */ + push %_ASM_ARG1 + +.ifnc _ASM_ARG1, _ASM_DI + /* + * Stash @svm in RDI early. On 32-bit, arguments are in RAX, RCX + * and RDX which are clobbered by RESTORE_GUEST_SPEC_CTRL. + */ + mov %_ASM_ARG1, %_ASM_DI +.endif + + /* Clobbers RAX, RCX, RDX. */ + RESTORE_GUEST_SPEC_CTRL + + /* Get svm->current_vmcb->pa into RAX. */ + mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX + mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX /* Enter guest mode */ sti @@ -194,11 +340,17 @@ 2: cli + /* Pop @svm to RDI, guest registers have been saved already. */ + pop %_ASM_DI + #ifdef CONFIG_RETPOLINE /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE #endif + /* Clobbers RAX, RCX, RDX. */ + RESTORE_HOST_SPEC_CTRL + /* * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be * untrained as soon as we exit the VM and are back to the @@ -208,6 +360,9 @@ */ UNTRAIN_RET + /* "Pop" @spec_ctrl_intercepted. */ + pop %_ASM_BX + pop %_ASM_BX #ifdef CONFIG_X86_64 @@ -222,6 +377,9 @@ pop %_ASM_BP RET + RESTORE_GUEST_SPEC_CTRL_BODY + RESTORE_HOST_SPEC_CTRL_BODY + 3: cmpb $0, kvm_rebooting jne 2b ud2 diff -Nru linux-6.0.6/arch/x86/kvm/vmx/capabilities.h linux-6.0.12/arch/x86/kvm/vmx/capabilities.h --- linux-6.0.6/arch/x86/kvm/vmx/capabilities.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/vmx/capabilities.h 2023-01-18 18:27:39.000000000 +0000 @@ -24,8 +24,6 @@ #define PMU_CAP_FW_WRITES (1ULL << 13) #define PMU_CAP_LBR_FMT 0x3f -#define DEBUGCTLMSR_LBR_MASK (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) - struct nested_vmx_msrs { /* * We only store the "true" versions of the VMX capability MSRs. We @@ -404,6 +402,7 @@ static inline u64 vmx_get_perf_capabilities(void) { u64 perf_cap = PMU_CAP_FW_WRITES; + struct x86_pmu_lbr lbr; u64 host_perf_cap = 0; if (!enable_pmu) @@ -412,7 +411,8 @@ if (boot_cpu_has(X86_FEATURE_PDCM)) rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap); - perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT; + if (x86_perf_get_lbr(&lbr) >= 0 && lbr.nr) + perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT; if (vmx_pebs_supported()) { perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK; @@ -423,19 +423,6 @@ return perf_cap; } -static inline u64 vmx_supported_debugctl(void) -{ - u64 debugctl = 0; - - if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT)) - debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT; - - if (vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT) - debugctl |= DEBUGCTLMSR_LBR_MASK; - - return debugctl; -} - static inline bool cpu_has_notify_vmexit(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & diff -Nru linux-6.0.6/arch/x86/kvm/vmx/nested.c linux-6.0.12/arch/x86/kvm/vmx/nested.c --- linux-6.0.6/arch/x86/kvm/vmx/nested.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/vmx/nested.c 2023-01-18 18:27:39.000000000 +0000 @@ -6294,9 +6294,6 @@ return kvm_state.size; } -/* - * Forcibly leave nested mode in order to be able to reset the VCPU later on. - */ void vmx_leave_nested(struct kvm_vcpu *vcpu) { if (is_guest_mode(vcpu)) { diff -Nru linux-6.0.6/arch/x86/kvm/vmx/vmenter.S linux-6.0.12/arch/x86/kvm/vmx/vmenter.S --- linux-6.0.6/arch/x86/kvm/vmx/vmenter.S 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/vmx/vmenter.S 2023-01-18 18:27:39.000000000 +0000 @@ -1,12 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include #include -#include #include #include #include #include #include +#include "kvm-asm-offsets.h" #include "run_flags.h" #define WORD_SIZE (BITS_PER_LONG / 8) diff -Nru linux-6.0.6/arch/x86/kvm/vmx/vmx.c linux-6.0.12/arch/x86/kvm/vmx/vmx.c --- linux-6.0.6/arch/x86/kvm/vmx/vmx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/vmx/vmx.c 2023-01-18 18:27:39.000000000 +0000 @@ -2016,15 +2016,17 @@ return (unsigned long)data; } -static u64 vcpu_supported_debugctl(struct kvm_vcpu *vcpu) +static u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated) { - u64 debugctl = vmx_supported_debugctl(); + u64 debugctl = 0; - if (!intel_pmu_lbr_is_enabled(vcpu)) - debugctl &= ~DEBUGCTLMSR_LBR_MASK; + if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT) && + (host_initiated || guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))) + debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT; - if (!guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT)) - debugctl &= ~DEBUGCTLMSR_BUS_LOCK_DETECT; + if ((vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT) && + (host_initiated || intel_pmu_lbr_is_enabled(vcpu))) + debugctl |= DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI; return debugctl; } @@ -2098,7 +2100,9 @@ vmcs_writel(GUEST_SYSENTER_ESP, data); break; case MSR_IA32_DEBUGCTLMSR: { - u64 invalid = data & ~vcpu_supported_debugctl(vcpu); + u64 invalid; + + invalid = data & ~vmx_get_supported_debugctl(vcpu, msr_info->host_initiated); if (invalid & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) { if (report_ignored_msrs) vcpu_unimpl(vcpu, "%s: BTF|LBR in IA32_DEBUGCTLMSR 0x%llx, nop\n", @@ -8277,6 +8281,11 @@ if (!cpu_has_virtual_nmis()) enable_vnmi = 0; +#ifdef CONFIG_X86_SGX_KVM + if (!cpu_has_vmx_encls_vmexit()) + enable_sgx = false; +#endif + /* * set_apic_access_page_addr() is used to reload apic access * page upon invalidation. No need to do anything if not diff -Nru linux-6.0.6/arch/x86/kvm/x86.c linux-6.0.12/arch/x86/kvm/x86.c --- linux-6.0.6/arch/x86/kvm/x86.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/x86.c 2023-01-18 18:27:39.000000000 +0000 @@ -611,6 +611,12 @@ } EXPORT_SYMBOL_GPL(kvm_deliver_exception_payload); +/* Forcibly leave the nested mode in cases like a vCPU reset */ +static void kvm_leave_nested(struct kvm_vcpu *vcpu) +{ + kvm_x86_ops.nested_ops->leave_nested(vcpu); +} + static void kvm_multiple_exception(struct kvm_vcpu *vcpu, unsigned nr, bool has_error, u32 error_code, bool has_payload, unsigned long payload, bool reinject) @@ -1431,20 +1437,10 @@ MSR_ARCH_PERFMON_PERFCTR0 + 2, MSR_ARCH_PERFMON_PERFCTR0 + 3, MSR_ARCH_PERFMON_PERFCTR0 + 4, MSR_ARCH_PERFMON_PERFCTR0 + 5, MSR_ARCH_PERFMON_PERFCTR0 + 6, MSR_ARCH_PERFMON_PERFCTR0 + 7, - MSR_ARCH_PERFMON_PERFCTR0 + 8, MSR_ARCH_PERFMON_PERFCTR0 + 9, - MSR_ARCH_PERFMON_PERFCTR0 + 10, MSR_ARCH_PERFMON_PERFCTR0 + 11, - MSR_ARCH_PERFMON_PERFCTR0 + 12, MSR_ARCH_PERFMON_PERFCTR0 + 13, - MSR_ARCH_PERFMON_PERFCTR0 + 14, MSR_ARCH_PERFMON_PERFCTR0 + 15, - MSR_ARCH_PERFMON_PERFCTR0 + 16, MSR_ARCH_PERFMON_PERFCTR0 + 17, MSR_ARCH_PERFMON_EVENTSEL0, MSR_ARCH_PERFMON_EVENTSEL1, MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3, MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5, MSR_ARCH_PERFMON_EVENTSEL0 + 6, MSR_ARCH_PERFMON_EVENTSEL0 + 7, - MSR_ARCH_PERFMON_EVENTSEL0 + 8, MSR_ARCH_PERFMON_EVENTSEL0 + 9, - MSR_ARCH_PERFMON_EVENTSEL0 + 10, MSR_ARCH_PERFMON_EVENTSEL0 + 11, - MSR_ARCH_PERFMON_EVENTSEL0 + 12, MSR_ARCH_PERFMON_EVENTSEL0 + 13, - MSR_ARCH_PERFMON_EVENTSEL0 + 14, MSR_ARCH_PERFMON_EVENTSEL0 + 15, - MSR_ARCH_PERFMON_EVENTSEL0 + 16, MSR_ARCH_PERFMON_EVENTSEL0 + 17, MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG, MSR_K7_EVNTSEL0, MSR_K7_EVNTSEL1, MSR_K7_EVNTSEL2, MSR_K7_EVNTSEL3, @@ -1551,7 +1547,7 @@ MSR_IA32_VMX_EPT_VPID_CAP, MSR_IA32_VMX_VMFUNC, - MSR_F10H_DECFG, + MSR_AMD64_DE_CFG, MSR_IA32_UCODE_REV, MSR_IA32_ARCH_CAPABILITIES, MSR_IA32_PERF_CAPABILITIES, @@ -2304,11 +2300,11 @@ /* we verify if the enable bit is set... */ if (system_time & 1) { - kvm_gfn_to_pfn_cache_init(vcpu->kvm, &vcpu->arch.pv_time, vcpu, - KVM_HOST_USES_PFN, system_time & ~1ULL, - sizeof(struct pvclock_vcpu_time_info)); + kvm_gpc_activate(vcpu->kvm, &vcpu->arch.pv_time, vcpu, + KVM_HOST_USES_PFN, system_time & ~1ULL, + sizeof(struct pvclock_vcpu_time_info)); } else { - kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.pv_time); + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.pv_time); } return; @@ -3377,7 +3373,7 @@ static void kvmclock_reset(struct kvm_vcpu *vcpu) { - kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.pv_time); + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.pv_time); vcpu->arch.time = 0; } @@ -5164,7 +5160,7 @@ if (events->flags & KVM_VCPUEVENT_VALID_SMM) { if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) { - kvm_x86_ops.nested_ops->leave_nested(vcpu); + kvm_leave_nested(vcpu); kvm_smm_changed(vcpu, events->smi.smm); } @@ -7005,12 +7001,12 @@ intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2) continue; break; - case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 17: + case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 7: if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_PERFCTR0 >= min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp)) continue; break; - case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 17: + case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 7: if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_EVENTSEL0 >= min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp)) continue; @@ -11629,6 +11625,8 @@ vcpu->arch.regs_avail = ~0; vcpu->arch.regs_dirty = ~0; + kvm_gpc_init(&vcpu->arch.pv_time); + if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu)) vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; else @@ -11797,8 +11795,18 @@ WARN_ON_ONCE(!init_event && (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu))); + /* + * SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's + * possible to INIT the vCPU while L2 is active. Force the vCPU back + * into L1 as EFER.SVME is cleared on INIT (along with all other EFER + * bits), i.e. virtualization is disabled. + */ + if (is_guest_mode(vcpu)) + kvm_leave_nested(vcpu); + kvm_lapic_reset(vcpu, init_event); + WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu)); vcpu->arch.hflags = 0; vcpu->arch.smi_pending = 0; diff -Nru linux-6.0.6/arch/x86/kvm/xen.c linux-6.0.12/arch/x86/kvm/xen.c --- linux-6.0.6/arch/x86/kvm/xen.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/kvm/xen.c 2023-01-18 18:27:39.000000000 +0000 @@ -42,13 +42,13 @@ int idx = srcu_read_lock(&kvm->srcu); if (gfn == GPA_INVALID) { - kvm_gfn_to_pfn_cache_destroy(kvm, gpc); + kvm_gpc_deactivate(kvm, gpc); goto out; } do { - ret = kvm_gfn_to_pfn_cache_init(kvm, gpc, NULL, KVM_HOST_USES_PFN, - gpa, PAGE_SIZE); + ret = kvm_gpc_activate(kvm, gpc, NULL, KVM_HOST_USES_PFN, gpa, + PAGE_SIZE); if (ret) goto out; @@ -554,15 +554,15 @@ offsetof(struct compat_vcpu_info, time)); if (data->u.gpa == GPA_INVALID) { - kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache); + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache); r = 0; break; } - r = kvm_gfn_to_pfn_cache_init(vcpu->kvm, - &vcpu->arch.xen.vcpu_info_cache, - NULL, KVM_HOST_USES_PFN, data->u.gpa, - sizeof(struct vcpu_info)); + r = kvm_gpc_activate(vcpu->kvm, + &vcpu->arch.xen.vcpu_info_cache, NULL, + KVM_HOST_USES_PFN, data->u.gpa, + sizeof(struct vcpu_info)); if (!r) kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); @@ -570,16 +570,16 @@ case KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO: if (data->u.gpa == GPA_INVALID) { - kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, - &vcpu->arch.xen.vcpu_time_info_cache); + kvm_gpc_deactivate(vcpu->kvm, + &vcpu->arch.xen.vcpu_time_info_cache); r = 0; break; } - r = kvm_gfn_to_pfn_cache_init(vcpu->kvm, - &vcpu->arch.xen.vcpu_time_info_cache, - NULL, KVM_HOST_USES_PFN, data->u.gpa, - sizeof(struct pvclock_vcpu_time_info)); + r = kvm_gpc_activate(vcpu->kvm, + &vcpu->arch.xen.vcpu_time_info_cache, + NULL, KVM_HOST_USES_PFN, data->u.gpa, + sizeof(struct pvclock_vcpu_time_info)); if (!r) kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); break; @@ -590,16 +590,15 @@ break; } if (data->u.gpa == GPA_INVALID) { - kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, - &vcpu->arch.xen.runstate_cache); + kvm_gpc_deactivate(vcpu->kvm, + &vcpu->arch.xen.runstate_cache); r = 0; break; } - r = kvm_gfn_to_pfn_cache_init(vcpu->kvm, - &vcpu->arch.xen.runstate_cache, - NULL, KVM_HOST_USES_PFN, data->u.gpa, - sizeof(struct vcpu_runstate_info)); + r = kvm_gpc_activate(vcpu->kvm, &vcpu->arch.xen.runstate_cache, + NULL, KVM_HOST_USES_PFN, data->u.gpa, + sizeof(struct vcpu_runstate_info)); break; case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT: @@ -955,6 +954,14 @@ return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result); } +static inline int max_evtchn_port(struct kvm *kvm) +{ + if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) + return EVTCHN_2L_NR_CHANNELS; + else + return COMPAT_EVTCHN_2L_NR_CHANNELS; +} + static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports, evtchn_port_t *ports) { @@ -1043,6 +1050,10 @@ *r = -EFAULT; goto out; } + if (ports[i] >= max_evtchn_port(vcpu->kvm)) { + *r = -EINVAL; + goto out; + } } if (sched_poll.nr_ports == 1) @@ -1217,6 +1228,7 @@ bool longmode; u64 input, params[6], r = -ENOSYS; bool handled = false; + u8 cpl; input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX); @@ -1244,9 +1256,17 @@ params[5] = (u64)kvm_r9_read(vcpu); } #endif + cpl = static_call(kvm_x86_get_cpl)(vcpu); trace_kvm_xen_hypercall(input, params[0], params[1], params[2], params[3], params[4], params[5]); + /* + * Only allow hypercall acceleration for CPL0. The rare hypercalls that + * are permitted in guest userspace can be handled by the VMM. + */ + if (unlikely(cpl > 0)) + goto handle_in_userspace; + switch (input) { case __HYPERVISOR_xen_version: if (params[0] == XENVER_version && vcpu->kvm->arch.xen.xen_version) { @@ -1281,10 +1301,11 @@ if (handled) return kvm_xen_hypercall_set_result(vcpu, r); +handle_in_userspace: vcpu->run->exit_reason = KVM_EXIT_XEN; vcpu->run->xen.type = KVM_EXIT_XEN_HCALL; vcpu->run->xen.u.hcall.longmode = longmode; - vcpu->run->xen.u.hcall.cpl = static_call(kvm_x86_get_cpl)(vcpu); + vcpu->run->xen.u.hcall.cpl = cpl; vcpu->run->xen.u.hcall.input = input; vcpu->run->xen.u.hcall.params[0] = params[0]; vcpu->run->xen.u.hcall.params[1] = params[1]; @@ -1299,14 +1320,6 @@ return 0; } -static inline int max_evtchn_port(struct kvm *kvm) -{ - if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) - return EVTCHN_2L_NR_CHANNELS; - else - return COMPAT_EVTCHN_2L_NR_CHANNELS; -} - static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port) { int poll_evtchn = vcpu->arch.xen.poll_evtchn; @@ -1668,18 +1681,18 @@ case EVTCHNSTAT_ipi: /* IPI must map back to the same port# */ if (data->u.evtchn.deliver.port.port != data->u.evtchn.send_port) - goto out; /* -EINVAL */ + goto out_noeventfd; /* -EINVAL */ break; case EVTCHNSTAT_interdomain: if (data->u.evtchn.deliver.port.port) { if (data->u.evtchn.deliver.port.port >= max_evtchn_port(kvm)) - goto out; /* -EINVAL */ + goto out_noeventfd; /* -EINVAL */ } else { eventfd = eventfd_ctx_fdget(data->u.evtchn.deliver.eventfd.fd); if (IS_ERR(eventfd)) { ret = PTR_ERR(eventfd); - goto out; + goto out_noeventfd; } } break; @@ -1719,6 +1732,7 @@ out: if (eventfd) eventfd_ctx_put(eventfd); +out_noeventfd: kfree(evtchnfd); return ret; } @@ -1817,7 +1831,12 @@ { vcpu->arch.xen.vcpu_id = vcpu->vcpu_idx; vcpu->arch.xen.poll_evtchn = 0; + timer_setup(&vcpu->arch.xen.poll_timer, cancel_evtchn_poll, 0); + + kvm_gpc_init(&vcpu->arch.xen.runstate_cache); + kvm_gpc_init(&vcpu->arch.xen.vcpu_info_cache); + kvm_gpc_init(&vcpu->arch.xen.vcpu_time_info_cache); } void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu) @@ -1825,18 +1844,17 @@ if (kvm_xen_timer_enabled(vcpu)) kvm_xen_stop_timer(vcpu); - kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, - &vcpu->arch.xen.runstate_cache); - kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, - &vcpu->arch.xen.vcpu_info_cache); - kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, - &vcpu->arch.xen.vcpu_time_info_cache); + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.runstate_cache); + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache); + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_time_info_cache); + del_timer_sync(&vcpu->arch.xen.poll_timer); } void kvm_xen_init_vm(struct kvm *kvm) { idr_init(&kvm->arch.xen.evtchn_ports); + kvm_gpc_init(&kvm->arch.xen.shinfo_cache); } void kvm_xen_destroy_vm(struct kvm *kvm) @@ -1844,7 +1862,7 @@ struct evtchnfd *evtchnfd; int i; - kvm_gfn_to_pfn_cache_destroy(kvm, &kvm->arch.xen.shinfo_cache); + kvm_gpc_deactivate(kvm, &kvm->arch.xen.shinfo_cache); idr_for_each_entry(&kvm->arch.xen.evtchn_ports, evtchnfd, i) { if (!evtchnfd->deliver.port.port) diff -Nru linux-6.0.6/arch/x86/mm/hugetlbpage.c linux-6.0.12/arch/x86/mm/hugetlbpage.c --- linux-6.0.6/arch/x86/mm/hugetlbpage.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/mm/hugetlbpage.c 2023-01-18 18:27:39.000000000 +0000 @@ -37,8 +37,12 @@ */ int pud_huge(pud_t pud) { +#if CONFIG_PGTABLE_LEVELS > 2 return !pud_none(pud) && (pud_val(pud) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT; +#else + return 0; +#endif } #ifdef CONFIG_HUGETLB_PAGE diff -Nru linux-6.0.6/arch/x86/mm/ioremap.c linux-6.0.12/arch/x86/mm/ioremap.c --- linux-6.0.6/arch/x86/mm/ioremap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/mm/ioremap.c 2023-01-18 18:27:39.000000000 +0000 @@ -216,9 +216,15 @@ * Mappings have to be page-aligned */ offset = phys_addr & ~PAGE_MASK; - phys_addr &= PHYSICAL_PAGE_MASK; + phys_addr &= PAGE_MASK; size = PAGE_ALIGN(last_addr+1) - phys_addr; + /* + * Mask out any bits not part of the actual physical + * address, like memory encryption bits. + */ + phys_addr &= PHYSICAL_PAGE_MASK; + retval = memtype_reserve(phys_addr, (u64)phys_addr + size, pcm, &new_pcm); if (retval) { diff -Nru linux-6.0.6/arch/x86/power/cpu.c linux-6.0.12/arch/x86/power/cpu.c --- linux-6.0.6/arch/x86/power/cpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/arch/x86/power/cpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -513,15 +513,23 @@ static void pm_save_spec_msr(void) { - u32 spec_msr_id[] = { - MSR_IA32_SPEC_CTRL, - MSR_IA32_TSX_CTRL, - MSR_TSX_FORCE_ABORT, - MSR_IA32_MCU_OPT_CTRL, - MSR_AMD64_LS_CFG, + struct msr_enumeration { + u32 msr_no; + u32 feature; + } msr_enum[] = { + { MSR_IA32_SPEC_CTRL, X86_FEATURE_MSR_SPEC_CTRL }, + { MSR_IA32_TSX_CTRL, X86_FEATURE_MSR_TSX_CTRL }, + { MSR_TSX_FORCE_ABORT, X86_FEATURE_TSX_FORCE_ABORT }, + { MSR_IA32_MCU_OPT_CTRL, X86_FEATURE_SRBDS_CTRL }, + { MSR_AMD64_LS_CFG, X86_FEATURE_LS_CFG_SSBD }, + { MSR_AMD64_DE_CFG, X86_FEATURE_LFENCE_RDTSC }, }; + int i; - msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id)); + for (i = 0; i < ARRAY_SIZE(msr_enum); i++) { + if (boot_cpu_has(msr_enum[i].feature)) + msr_build_context(&msr_enum[i].msr_no, 1); + } } static int pm_check_save_msr(void) diff -Nru linux-6.0.6/block/bfq-cgroup.c linux-6.0.12/block/bfq-cgroup.c --- linux-6.0.6/block/bfq-cgroup.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/bfq-cgroup.c 2023-01-18 18:27:39.000000000 +0000 @@ -615,6 +615,10 @@ struct bfq_group *bfqg; while (blkg) { + if (!blkg->online) { + blkg = blkg->parent; + continue; + } bfqg = blkg_to_bfqg(blkg); if (bfqg->online) { bio_associate_blkg_from_css(bio, &blkg->blkcg->css); diff -Nru linux-6.0.6/block/bio.c linux-6.0.12/block/bio.c --- linux-6.0.6/block/bio.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/bio.c 2023-01-18 18:27:39.000000000 +0000 @@ -741,7 +741,7 @@ return; } - if (bio->bi_opf & REQ_ALLOC_CACHE) { + if ((bio->bi_opf & REQ_ALLOC_CACHE) && !WARN_ON_ONCE(in_interrupt())) { struct bio_alloc_cache *cache; bio_uninit(bio); diff -Nru linux-6.0.6/block/blk-cgroup.c linux-6.0.12/block/blk-cgroup.c --- linux-6.0.6/block/blk-cgroup.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/blk-cgroup.c 2023-01-18 18:27:39.000000000 +0000 @@ -1251,7 +1251,7 @@ * parent so that offline always happens towards the root. */ if (parent) - blkcg_pin_online(css); + blkcg_pin_online(&parent->css); return 0; } diff -Nru linux-6.0.6/block/blk-core.c linux-6.0.12/block/blk-core.c --- linux-6.0.6/block/blk-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/blk-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -426,7 +426,6 @@ PERCPU_REF_INIT_ATOMIC, GFP_KERNEL)) goto fail_stats; - blk_queue_dma_alignment(q, 511); blk_set_default_limits(&q->limits); q->nr_requests = BLKDEV_DEFAULT_RQ; diff -Nru linux-6.0.6/block/blk.h linux-6.0.12/block/blk.h --- linux-6.0.6/block/blk.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/blk.h 2023-01-18 18:27:39.000000000 +0000 @@ -324,6 +324,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio); enum elv_merge blk_try_merge(struct request *rq, struct bio *bio); +void blk_set_default_limits(struct queue_limits *lim); int blk_dev_init(void); /* diff -Nru linux-6.0.6/block/blk-mq.c linux-6.0.12/block/blk-mq.c --- linux-6.0.6/block/blk-mq.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/blk-mq.c 2023-01-18 18:27:39.000000000 +0000 @@ -1183,6 +1183,7 @@ (!blk_queue_nomerges(rq->q) && blk_rq_bytes(last) >= BLK_PLUG_FLUSH_SIZE)) { blk_mq_flush_plug_list(plug, false); + last = NULL; trace_block_plug(rq->q); } @@ -3955,9 +3956,14 @@ struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q, struct lock_class_key *lkclass) { + struct gendisk *disk; + if (!blk_get_queue(q)) return NULL; - return __alloc_disk_node(q, NUMA_NO_NODE, lkclass); + disk = __alloc_disk_node(q, NUMA_NO_NODE, lkclass); + if (!disk) + blk_put_queue(q); + return disk; } EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue); @@ -4104,9 +4110,7 @@ return 0; err_hctxs: - xa_destroy(&q->hctx_table); - q->nr_hw_queues = 0; - blk_mq_sysfs_deinit(q); + blk_mq_release(q); err_poll: blk_stat_free_callback(q->poll_cb); q->poll_cb = NULL; diff -Nru linux-6.0.6/block/blk-settings.c linux-6.0.12/block/blk-settings.c --- linux-6.0.6/block/blk-settings.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/blk-settings.c 2023-01-18 18:27:39.000000000 +0000 @@ -57,8 +57,8 @@ lim->misaligned = 0; lim->zoned = BLK_ZONED_NONE; lim->zone_write_granularity = 0; + lim->dma_alignment = 511; } -EXPORT_SYMBOL(blk_set_default_limits); /** * blk_set_stacking_limits - set default limits for stacking devices @@ -600,6 +600,7 @@ t->io_min = max(t->io_min, b->io_min); t->io_opt = lcm_not_zero(t->io_opt, b->io_opt); + t->dma_alignment = max(t->dma_alignment, b->dma_alignment); /* Set non-power-of-2 compatible chunk_sectors boundary */ if (b->chunk_sectors) @@ -773,7 +774,7 @@ **/ void blk_queue_dma_alignment(struct request_queue *q, int mask) { - q->dma_alignment = mask; + q->limits.dma_alignment = mask; } EXPORT_SYMBOL(blk_queue_dma_alignment); @@ -795,8 +796,8 @@ { BUG_ON(mask > PAGE_SIZE); - if (mask > q->dma_alignment) - q->dma_alignment = mask; + if (mask > q->limits.dma_alignment) + q->limits.dma_alignment = mask; } EXPORT_SYMBOL(blk_queue_update_dma_alignment); diff -Nru linux-6.0.6/block/genhd.c linux-6.0.12/block/genhd.c --- linux-6.0.6/block/genhd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/genhd.c 2023-01-18 18:27:39.000000000 +0000 @@ -519,6 +519,7 @@ bdi_unregister(disk->bdi); out_unregister_queue: blk_unregister_queue(disk); + rq_qos_exit(disk->queue); out_put_slave_dir: kobject_put(disk->slave_dir); out_put_holder_dir: diff -Nru linux-6.0.6/block/sed-opal.c linux-6.0.12/block/sed-opal.c --- linux-6.0.6/block/sed-opal.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/block/sed-opal.c 2023-01-18 18:27:39.000000000 +0000 @@ -88,8 +88,8 @@ u64 lowest_lba; size_t pos; - u8 cmd[IO_BUFFER_LENGTH]; - u8 resp[IO_BUFFER_LENGTH]; + u8 *cmd; + u8 *resp; struct parsed_resp parsed; size_t prev_d_len; @@ -2134,6 +2134,8 @@ return; clean_opal_dev(dev); + kfree(dev->resp); + kfree(dev->cmd); kfree(dev); } EXPORT_SYMBOL(free_opal_dev); @@ -2146,17 +2148,39 @@ if (!dev) return NULL; + /* + * Presumably DMA-able buffers must be cache-aligned. Kmalloc makes + * sure the allocated buffer is DMA-safe in that regard. + */ + dev->cmd = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL); + if (!dev->cmd) + goto err_free_dev; + + dev->resp = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL); + if (!dev->resp) + goto err_free_cmd; + INIT_LIST_HEAD(&dev->unlk_lst); mutex_init(&dev->dev_lock); dev->data = data; dev->send_recv = send_recv; if (check_opal_support(dev) != 0) { pr_debug("Opal is not supported on this device\n"); - kfree(dev); - return NULL; + goto err_free_resp; } return dev; + +err_free_resp: + kfree(dev->resp); + +err_free_cmd: + kfree(dev->cmd); + +err_free_dev: + kfree(dev); + + return NULL; } EXPORT_SYMBOL(init_opal_dev); diff -Nru linux-6.0.6/debian/changelog linux-6.0.12/debian/changelog --- linux-6.0.6/debian/changelog 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian/changelog 2023-01-18 18:27:39.000000000 +0000 @@ -1,8 +1,8 @@ -linux (6.0.6-76060006.202210290932~1669062050~20.04~d94609a) focal; urgency=medium +linux (6.0.12-76060012.202212290932~1674066459~20.04~3cd2bf3) focal; urgency=medium * Auto Build [ Mainline Build ] - Mainline build at commit: v6.0.6 + Mainline build at commit: v6.0.12 - -- Pop OS (ISO Signing Key) Mon, 21 Nov 2022 13:20:50 -0700 + -- Pop OS (ISO Signing Key) Wed, 18 Jan 2023 11:27:39 -0700 diff -Nru linux-6.0.6/debian/control linux-6.0.12/debian/control --- linux-6.0.6/debian/control 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian/control 2023-01-18 18:27:39.000000000 +0000 @@ -4,7 +4,7 @@ Maintainer: Ubuntu Kernel Team Standards-Version: 3.9.4.0 Build-Depends: - gcc-11, gcc-11-aarch64-linux-gnu [arm64] , gcc-11-arm-linux-gnueabihf [armhf] , gcc-11-powerpc64le-linux-gnu [ppc64el] , gcc-11-riscv64-linux-gnu [riscv64] , gcc-11-s390x-linux-gnu [s390x] , gcc-11-x86-64-linux-gnu [amd64] , + gcc-10, gcc-10-aarch64-linux-gnu [arm64] , gcc-10-arm-linux-gnueabihf [armhf] , gcc-10-powerpc64le-linux-gnu [ppc64el] , gcc-10-riscv64-linux-gnu [riscv64] , gcc-10-s390x-linux-gnu [s390x] , gcc-10-x86-64-linux-gnu [amd64] , debhelper-compat (= 10), cpio, kmod , @@ -62,7 +62,7 @@ XS-Testsuite: autopkgtest #XS-Testsuite-Depends: gcc-4.7 binutils -Package: linux-source-6.0.6 +Package: linux-source-6.0.12 Build-Profiles: Architecture: all Section: devel @@ -71,9 +71,9 @@ Depends: ${misc:Depends}, binutils, bzip2, coreutils Recommends: libc-dev, gcc, make Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev -Description: Linux kernel source for version 6.0.6 with Ubuntu patches +Description: Linux kernel source for version 6.0.12 with Ubuntu patches This package provides the source code for the Linux kernel version - 6.0.6. + 6.0.12. . This package is mainly meant for other packages to use, in order to build custom flavours. @@ -86,17 +86,17 @@ you do not want this package. Install the appropriate linux-headers package instead. -Package: linux-headers-6.0.6-76060006 +Package: linux-headers-6.0.12-76060012 Build-Profiles: Architecture: all Multi-Arch: foreign Section: devel Priority: optional Depends: ${misc:Depends}, coreutils -Description: Header files related to Linux kernel version 6.0.6 - This package provides kernel header files for version 6.0.6, for sites +Description: Header files related to Linux kernel version 6.0.12 + This package provides kernel header files for version 6.0.12, for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.0.6-76060006/debian.README.gz for details + /usr/share/doc/linux-headers-6.0.12-76060012/debian.README.gz for details Package: linux-tools-common Build-Profiles: @@ -105,23 +105,23 @@ Section: kernel Priority: optional Depends: ${misc:Depends}, lsb-release -Description: Linux kernel version specific tools for version 6.0.6 +Description: Linux kernel version specific tools for version 6.0.12 This package provides the architecture independent parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.0.6. + version 6.0.12. -Package: linux-tools-6.0.6-76060006 +Package: linux-tools-6.0.12-76060012 Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common -Description: Linux kernel version specific tools for version 6.0.6-76060006 +Description: Linux kernel version specific tools for version 6.0.12-76060012 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.0.6-76060006 on + version 6.0.12-76060012 on 64 bit x86. - You probably want to install linux-tools-6.0.6-76060006-. + You probably want to install linux-tools-6.0.12-76060012-. Package: linux-cloud-tools-common Build-Profiles: @@ -130,21 +130,21 @@ Section: kernel Priority: optional Depends: ${misc:Depends} -Description: Linux kernel version specific cloud tools for version 6.0.6 +Description: Linux kernel version specific cloud tools for version 6.0.12 This package provides the architecture independent parts for kernel - version locked tools for cloud tools for version 6.0.6. + version locked tools for cloud tools for version 6.0.12. -Package: linux-cloud-tools-6.0.6-76060006 +Package: linux-cloud-tools-6.0.12-76060012 Build-Profiles: Architecture: amd64 armhf Section: devel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends}, linux-cloud-tools-common -Description: Linux kernel version specific cloud tools for version 6.0.6-76060006 +Description: Linux kernel version specific cloud tools for version 6.0.12-76060012 This package provides the architecture dependant parts for kernel - version locked tools for cloud tools for version 6.0.6-76060006 on + version locked tools for cloud tools for version 6.0.12-76060012 on 64 bit x86. - You probably want to install linux-cloud-tools-6.0.6-76060006-. + You probably want to install linux-cloud-tools-6.0.12-76060012-. Package: linux-tools-host Build-Profiles: @@ -164,7 +164,7 @@ Section: kernel Depends: ${misc:Depends}, - linux-headers-6.0.6-76060006-generic (= ${source:Version}) + linux-headers-6.0.12-76060012-generic (= ${source:Version}) Description: Generic Linux kernel headers This package will always depend on the latest generic kernel headers available. @@ -175,7 +175,7 @@ Section: kernel Depends: ${misc:Depends}, - linux-image-6.0.6-76060006-generic (= ${source:Version}), + linux-image-6.0.12-76060012-generic (= ${source:Version}), linux-firmware, intel-microcode [amd64], amd64-microcode [amd64] @@ -191,7 +191,7 @@ Provides: linux-tools Depends: ${misc:Depends}, - linux-tools-6.0.6-76060006-generic (= ${source:Version}) + linux-tools-6.0.12-76060012-generic (= ${source:Version}) Description: Generic Linux kernel tools This package will always depend on the latest generic kernel tools available. @@ -203,7 +203,7 @@ Provides: linux-cloud-tools Depends: ${misc:Depends}, - linux-cloud-tools-6.0.6-76060006-generic (= ${source:Version}) + linux-cloud-tools-6.0.12-76060012-generic (= ${source:Version}) Description: Generic Linux kernel cloud tools This package will always depend on the latest generic kernel cloud tools available. @@ -237,19 +237,19 @@ # } linux-system76 -Package: linux-image-6.0.6-76060006-generic +Package: linux-image-6.0.12-76060012-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel Priority: optional Provides: linux-image, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64], ${linux:rprovides} -Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.0.6-76060006-generic +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.0.12-76060012-generic Recommends: kernelstub [amd64] | grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-efi-arm64 [arm64] | grub-efi-arm [armhf] | grub-ieee1275 [ppc64el], initramfs-tools | linux-initramfs-tool Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x] -Conflicts: linux-image-unsigned-6.0.6-76060006-generic -Suggests: fdutils, linux-doc | linux-source-6.0.6, linux-tools, linux-headers-6.0.6-76060006-generic, linux-modules-extra-6.0.6-76060006-generic -Description: Linux kernel image for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel image for version 6.0.6 on +Conflicts: linux-image-unsigned-6.0.12-76060012-generic +Suggests: fdutils, linux-doc | linux-source-6.0.12, linux-tools, linux-headers-6.0.12-76060012-generic, linux-modules-extra-6.0.12-76060012-generic +Description: Linux kernel image for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel image for version 6.0.12 on 64 bit x86 SMP. . Supports Generic processors. @@ -260,14 +260,14 @@ the linux-generic meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-6.0.6-76060006-generic +Package: linux-modules-6.0.12-76060012-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends} Built-Using: ${linux:BuiltUsing} -Description: Linux kernel extra modules for version 6.0.6 on 64 bit x86 SMP +Description: Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP Contains the corresponding System.map file, the modules built by the packager, and scripts that try to ensure that the system is not left in an unbootable state after an update. @@ -280,14 +280,14 @@ the linux-generic meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-extra-6.0.6-76060006-generic +Package: linux-modules-extra-6.0.12-76060012-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel Priority: optional -Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.0.6-76060006-generic, wireless-regdb -Description: Linux kernel extra modules for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel extra modules for version 6.0.6 on +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.0.12-76060012-generic, wireless-regdb +Description: Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP. . Also includes the corresponding System.map file, the modules built by the @@ -302,29 +302,29 @@ the linux-generic meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-headers-6.0.6-76060006-generic +Package: linux-headers-6.0.12-76060012-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional -Depends: ${misc:Depends}, linux-headers-6.0.6-76060006, ${shlibs:Depends} +Depends: ${misc:Depends}, linux-headers-6.0.12-76060012, ${shlibs:Depends} Provides: linux-headers, linux-headers-3.0 -Description: Linux kernel headers for version 6.0.6 on 64 bit x86 SMP - This package provides kernel header files for version 6.0.6 on +Description: Linux kernel headers for version 6.0.12 on 64 bit x86 SMP + This package provides kernel header files for version 6.0.12 on 64 bit x86 SMP. . This is for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.0.6-76060006/debian.README.gz for details. + /usr/share/doc/linux-headers-6.0.12-76060012/debian.README.gz for details. -Package: linux-image-6.0.6-76060006-generic-dbgsym +Package: linux-image-6.0.12-76060012-generic-dbgsym Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional Depends: ${misc:Depends} Provides: linux-debug -Description: Linux kernel debug image for version 6.0.6 on 64 bit x86 SMP - This package provides the kernel debug image for version 6.0.6 on +Description: Linux kernel debug image for version 6.0.12 on 64 bit x86 SMP + This package provides the kernel debug image for version 6.0.12 on 64 bit x86 SMP. . This is for sites that wish to debug the kernel. @@ -333,57 +333,57 @@ is uncompressed, and unstripped. This package also includes the unstripped modules. -Package: linux-tools-6.0.6-76060006-generic +Package: linux-tools-6.0.12-76060012-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional -Depends: ${misc:Depends}, linux-tools-6.0.6-76060006 -Description: Linux kernel version specific tools for version 6.0.6-76060006 +Depends: ${misc:Depends}, linux-tools-6.0.12-76060012 +Description: Linux kernel version specific tools for version 6.0.12-76060012 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.0.6-76060006 on + version 6.0.12-76060012 on 64 bit x86. -Package: linux-cloud-tools-6.0.6-76060006-generic +Package: linux-cloud-tools-6.0.12-76060012-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional -Depends: ${misc:Depends}, linux-cloud-tools-6.0.6-76060006 -Description: Linux kernel version specific cloud tools for version 6.0.6-76060006 +Depends: ${misc:Depends}, linux-cloud-tools-6.0.12-76060012 +Description: Linux kernel version specific cloud tools for version 6.0.12-76060012 This package provides the architecture dependant parts for kernel - version locked tools for cloud for version 6.0.6-76060006 on + version locked tools for cloud for version 6.0.12-76060012 on 64 bit x86. -Package: linux-buildinfo-6.0.6-76060006-generic +Package: linux-buildinfo-6.0.12-76060012-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends} Built-Using: ${linux:BuiltUsing} -Description: Linux kernel buildinfo for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel buildinfo for version 6.0.6 on +Description: Linux kernel buildinfo for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel buildinfo for version 6.0.12 on 64 bit x86 SMP. . You likely do not want to install this package. -Package: linux-image-6.0.6-76060006-generic-64k +Package: linux-image-6.0.12-76060012-generic-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional Provides: linux-image, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, ${linux:rprovides} -Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.0.6-76060006-generic-64k +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.0.12-76060012-generic-64k Recommends: grub-efi-arm64 [arm64] | flash-kernel [arm64], initramfs-tools | linux-initramfs-tool Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x] -Conflicts: linux-image-unsigned-6.0.6-76060006-generic-64k -Suggests: fdutils, linux-doc | linux-source-6.0.6, linux-tools, linux-headers-6.0.6-76060006-generic-64k, linux-modules-extra-6.0.6-76060006-generic-64k -Description: Linux kernel image for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel image for version 6.0.6 on +Conflicts: linux-image-unsigned-6.0.12-76060012-generic-64k +Suggests: fdutils, linux-doc | linux-source-6.0.12, linux-tools, linux-headers-6.0.12-76060012-generic-64k, linux-modules-extra-6.0.12-76060012-generic-64k +Description: Linux kernel image for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel image for version 6.0.12 on 64 bit x86 SMP. . Supports Generic 64K pages processors. @@ -394,14 +394,14 @@ the linux-generic-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-6.0.6-76060006-generic-64k +Package: linux-modules-6.0.12-76060012-generic-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends} Built-Using: ${linux:BuiltUsing} -Description: Linux kernel extra modules for version 6.0.6 on 64 bit x86 SMP +Description: Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP Contains the corresponding System.map file, the modules built by the packager, and scripts that try to ensure that the system is not left in an unbootable state after an update. @@ -414,14 +414,14 @@ the linux-generic-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-extra-6.0.6-76060006-generic-64k +Package: linux-modules-extra-6.0.12-76060012-generic-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional -Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.0.6-76060006-generic-64k, wireless-regdb -Description: Linux kernel extra modules for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel extra modules for version 6.0.6 on +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.0.12-76060012-generic-64k, wireless-regdb +Description: Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP. . Also includes the corresponding System.map file, the modules built by the @@ -436,29 +436,29 @@ the linux-generic-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-headers-6.0.6-76060006-generic-64k +Package: linux-headers-6.0.12-76060012-generic-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-headers-6.0.6-76060006, ${shlibs:Depends} +Depends: ${misc:Depends}, linux-headers-6.0.12-76060012, ${shlibs:Depends} Provides: linux-headers, linux-headers-3.0 -Description: Linux kernel headers for version 6.0.6 on 64 bit x86 SMP - This package provides kernel header files for version 6.0.6 on +Description: Linux kernel headers for version 6.0.12 on 64 bit x86 SMP + This package provides kernel header files for version 6.0.12 on 64 bit x86 SMP. . This is for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.0.6-76060006/debian.README.gz for details. + /usr/share/doc/linux-headers-6.0.12-76060012/debian.README.gz for details. -Package: linux-image-6.0.6-76060006-generic-64k-dbgsym +Package: linux-image-6.0.12-76060012-generic-64k-dbgsym Build-Profiles: Architecture: arm64 Section: devel Priority: optional Depends: ${misc:Depends} Provides: linux-debug -Description: Linux kernel debug image for version 6.0.6 on 64 bit x86 SMP - This package provides the kernel debug image for version 6.0.6 on +Description: Linux kernel debug image for version 6.0.12 on 64 bit x86 SMP + This package provides the kernel debug image for version 6.0.12 on 64 bit x86 SMP. . This is for sites that wish to debug the kernel. @@ -467,57 +467,57 @@ is uncompressed, and unstripped. This package also includes the unstripped modules. -Package: linux-tools-6.0.6-76060006-generic-64k +Package: linux-tools-6.0.12-76060012-generic-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-tools-6.0.6-76060006 -Description: Linux kernel version specific tools for version 6.0.6-76060006 +Depends: ${misc:Depends}, linux-tools-6.0.12-76060012 +Description: Linux kernel version specific tools for version 6.0.12-76060012 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.0.6-76060006 on + version 6.0.12-76060012 on 64 bit x86. -Package: linux-cloud-tools-6.0.6-76060006-generic-64k +Package: linux-cloud-tools-6.0.12-76060012-generic-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-cloud-tools-6.0.6-76060006 -Description: Linux kernel version specific cloud tools for version 6.0.6-76060006 +Depends: ${misc:Depends}, linux-cloud-tools-6.0.12-76060012 +Description: Linux kernel version specific cloud tools for version 6.0.12-76060012 This package provides the architecture dependant parts for kernel - version locked tools for cloud for version 6.0.6-76060006 on + version locked tools for cloud for version 6.0.12-76060012 on 64 bit x86. -Package: linux-buildinfo-6.0.6-76060006-generic-64k +Package: linux-buildinfo-6.0.12-76060012-generic-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends} Built-Using: ${linux:BuiltUsing} -Description: Linux kernel buildinfo for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel buildinfo for version 6.0.6 on +Description: Linux kernel buildinfo for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel buildinfo for version 6.0.12 on 64 bit x86 SMP. . You likely do not want to install this package. -Package: linux-image-6.0.6-76060006-generic-lpae +Package: linux-image-6.0.12-76060012-generic-lpae Build-Profiles: Architecture: armhf Section: kernel Priority: optional Provides: linux-image, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, ${linux:rprovides} -Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.0.6-76060006-generic-lpae +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.0.12-76060012-generic-lpae Recommends: flash-kernel [armhf] | grub-efi-arm [armhf], initramfs-tools | linux-initramfs-tool Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x] -Conflicts: linux-image-unsigned-6.0.6-76060006-generic-lpae -Suggests: fdutils, linux-doc | linux-source-6.0.6, linux-tools, linux-headers-6.0.6-76060006-generic-lpae, linux-modules-extra-6.0.6-76060006-generic-lpae -Description: Linux kernel image for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel image for version 6.0.6 on +Conflicts: linux-image-unsigned-6.0.12-76060012-generic-lpae +Suggests: fdutils, linux-doc | linux-source-6.0.12, linux-tools, linux-headers-6.0.12-76060012-generic-lpae, linux-modules-extra-6.0.12-76060012-generic-lpae +Description: Linux kernel image for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel image for version 6.0.12 on 64 bit x86 SMP. . Supports Generic LPAE processors. @@ -528,14 +528,14 @@ the linux-generic-lpae meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-6.0.6-76060006-generic-lpae +Package: linux-modules-6.0.12-76060012-generic-lpae Build-Profiles: Architecture: armhf Section: kernel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends} Built-Using: ${linux:BuiltUsing} -Description: Linux kernel extra modules for version 6.0.6 on 64 bit x86 SMP +Description: Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP Contains the corresponding System.map file, the modules built by the packager, and scripts that try to ensure that the system is not left in an unbootable state after an update. @@ -548,14 +548,14 @@ the linux-generic-lpae meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-extra-6.0.6-76060006-generic-lpae +Package: linux-modules-extra-6.0.12-76060012-generic-lpae Build-Profiles: Architecture: armhf Section: kernel Priority: optional -Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.0.6-76060006-generic-lpae, wireless-regdb -Description: Linux kernel extra modules for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel extra modules for version 6.0.6 on +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.0.12-76060012-generic-lpae, wireless-regdb +Description: Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel extra modules for version 6.0.12 on 64 bit x86 SMP. . Also includes the corresponding System.map file, the modules built by the @@ -570,29 +570,29 @@ the linux-generic-lpae meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-headers-6.0.6-76060006-generic-lpae +Package: linux-headers-6.0.12-76060012-generic-lpae Build-Profiles: Architecture: armhf Section: devel Priority: optional -Depends: ${misc:Depends}, linux-headers-6.0.6-76060006, ${shlibs:Depends} +Depends: ${misc:Depends}, linux-headers-6.0.12-76060012, ${shlibs:Depends} Provides: linux-headers, linux-headers-3.0 -Description: Linux kernel headers for version 6.0.6 on 64 bit x86 SMP - This package provides kernel header files for version 6.0.6 on +Description: Linux kernel headers for version 6.0.12 on 64 bit x86 SMP + This package provides kernel header files for version 6.0.12 on 64 bit x86 SMP. . This is for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.0.6-76060006/debian.README.gz for details. + /usr/share/doc/linux-headers-6.0.12-76060012/debian.README.gz for details. -Package: linux-image-6.0.6-76060006-generic-lpae-dbgsym +Package: linux-image-6.0.12-76060012-generic-lpae-dbgsym Build-Profiles: Architecture: armhf Section: devel Priority: optional Depends: ${misc:Depends} Provides: linux-debug -Description: Linux kernel debug image for version 6.0.6 on 64 bit x86 SMP - This package provides the kernel debug image for version 6.0.6 on +Description: Linux kernel debug image for version 6.0.12 on 64 bit x86 SMP + This package provides the kernel debug image for version 6.0.12 on 64 bit x86 SMP. . This is for sites that wish to debug the kernel. @@ -601,39 +601,39 @@ is uncompressed, and unstripped. This package also includes the unstripped modules. -Package: linux-tools-6.0.6-76060006-generic-lpae +Package: linux-tools-6.0.12-76060012-generic-lpae Build-Profiles: Architecture: armhf Section: devel Priority: optional -Depends: ${misc:Depends}, linux-tools-6.0.6-76060006 -Description: Linux kernel version specific tools for version 6.0.6-76060006 +Depends: ${misc:Depends}, linux-tools-6.0.12-76060012 +Description: Linux kernel version specific tools for version 6.0.12-76060012 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.0.6-76060006 on + version 6.0.12-76060012 on 64 bit x86. -Package: linux-cloud-tools-6.0.6-76060006-generic-lpae +Package: linux-cloud-tools-6.0.12-76060012-generic-lpae Build-Profiles: Architecture: armhf Section: devel Priority: optional -Depends: ${misc:Depends}, linux-cloud-tools-6.0.6-76060006 -Description: Linux kernel version specific cloud tools for version 6.0.6-76060006 +Depends: ${misc:Depends}, linux-cloud-tools-6.0.12-76060012 +Description: Linux kernel version specific cloud tools for version 6.0.12-76060012 This package provides the architecture dependant parts for kernel - version locked tools for cloud for version 6.0.6-76060006 on + version locked tools for cloud for version 6.0.12-76060012 on 64 bit x86. -Package: linux-buildinfo-6.0.6-76060006-generic-lpae +Package: linux-buildinfo-6.0.12-76060012-generic-lpae Build-Profiles: Architecture: armhf Section: kernel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends} Built-Using: ${linux:BuiltUsing} -Description: Linux kernel buildinfo for version 6.0.6 on 64 bit x86 SMP - This package contains the Linux kernel buildinfo for version 6.0.6 on +Description: Linux kernel buildinfo for version 6.0.12 on 64 bit x86 SMP + This package contains the Linux kernel buildinfo for version 6.0.12 on 64 bit x86 SMP. . You likely do not want to install this package. diff -Nru linux-6.0.6/debian/rules.d/0-common-vars.mk linux-6.0.12/debian/rules.d/0-common-vars.mk --- linux-6.0.6/debian/rules.d/0-common-vars.mk 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian/rules.d/0-common-vars.mk 2023-01-18 18:27:39.000000000 +0000 @@ -119,7 +119,7 @@ # If a given kernel wants to change this, they can do so via their own # $(DEBIAN)/rules.d/hooks.mk and $(DEBIAN)/rules.d/$(arch).mk files # -export gcc?=gcc-11 +export gcc?=gcc-10 GCC_BUILD_DEPENDS=\ $(gcc), $(gcc)-aarch64-linux-gnu [arm64] , $(gcc)-arm-linux-gnueabihf [armhf] , $(gcc)-powerpc64le-linux-gnu [ppc64el] , $(gcc)-riscv64-linux-gnu [riscv64] , $(gcc)-s390x-linux-gnu [s390x] , $(gcc)-x86-64-linux-gnu [amd64] , abidir := $(CURDIR)/$(DEBIAN)/__abi.current/$(arch) diff -Nru linux-6.0.6/debian/rules.d/3-binary-indep.mk linux-6.0.12/debian/rules.d/3-binary-indep.mk --- linux-6.0.6/debian/rules.d/3-binary-indep.mk 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian/rules.d/3-binary-indep.mk 2023-01-18 18:27:39.000000000 +0000 @@ -148,7 +148,6 @@ install -m755 debian/cloud-tools/hv_set_ifconfig $(cloudsbin) install -d $(cloudman)/man8 - install -m644 $(CURDIR)/tools/hv/*.8 $(cloudman)/man8 endif endif diff -Nru linux-6.0.6/debian.master/changelog linux-6.0.12/debian.master/changelog --- linux-6.0.6/debian.master/changelog 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/changelog 2023-01-18 18:27:39.000000000 +0000 @@ -1,8 +1,8 @@ -linux (6.0.6-76060006.202210290932~1669062050~20.04~d94609a) focal; urgency=medium +linux (6.0.12-76060012.202212290932~1674066459~20.04~3cd2bf3) focal; urgency=medium * Auto Build [ Mainline Build ] - Mainline build at commit: v6.0.6 + Mainline build at commit: v6.0.12 - -- Pop OS (ISO Signing Key) Mon, 21 Nov 2022 13:20:50 -0700 + -- Pop OS (ISO Signing Key) Wed, 18 Jan 2023 11:27:39 -0700 diff -Nru linux-6.0.6/debian.master/config/amd64/config.common.amd64 linux-6.0.12/debian.master/config/amd64/config.common.amd64 --- linux-6.0.6/debian.master/config/amd64/config.common.amd64 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/amd64/config.common.amd64 2023-01-18 18:27:39.000000000 +0000 @@ -16,6 +16,7 @@ CONFIG_ALTERA_STAPL=m CONFIG_ALTERA_TSE=m CONFIG_AMIGA_PARTITION=y +CONFIG_ANDROID_BINDER_IPC=m CONFIG_APDS9802ALS=m CONFIG_APPLICOM=m CONFIG_AQTION=m @@ -191,6 +192,7 @@ CONFIG_GPIO_TWL4030=m CONFIG_GPIO_TWL6040=m CONFIG_GPIO_VIRTIO=m +CONFIG_GP_PCI1XXXX=m CONFIG_GREYBUS=m CONFIG_HABANA_AI=m CONFIG_HAMACHI=m @@ -238,6 +240,7 @@ CONFIG_I2C_NVIDIA_GPU=m CONFIG_I2C_OCORES=m CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PCI1XXXX=m CONFIG_I2C_PIIX4=m CONFIG_I2C_SIMTEC=m CONFIG_I2C_SIS5595=m @@ -330,7 +333,6 @@ CONFIG_MFD_AXP20X_I2C=m CONFIG_MFD_BCM590XX=m CONFIG_MFD_BD9571MWV=m -CONFIG_MFD_CORE=y CONFIG_MFD_DA9062=m CONFIG_MFD_DA9063=y CONFIG_MFD_DA9150=m @@ -347,15 +349,18 @@ CONFIG_MFD_MENF21BMC=m CONFIG_MFD_MP2629=m CONFIG_MFD_MT6360=m +CONFIG_MFD_MT6370=m CONFIG_MFD_MT6397=m CONFIG_MFD_PCF50633=m CONFIG_MFD_RDC321X=m CONFIG_MFD_RETU=m CONFIG_MFD_RT4831=m CONFIG_MFD_RT5033=m +CONFIG_MFD_RT5120=m CONFIG_MFD_SI476X_CORE=m CONFIG_MFD_SKY81452=m CONFIG_MFD_SM501=m +CONFIG_MFD_SY7636A=m CONFIG_MFD_SYSCON=y CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_TI_LMU=m @@ -499,6 +504,7 @@ CONFIG_PPS_CLIENT_LDISC=m # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PSE_CONTROLLER=y # CONFIG_PSI_DEFAULT_DISABLED is not set CONFIG_PSTORE=y # CONFIG_PSTORE_CONSOLE is not set @@ -516,7 +522,6 @@ CONFIG_RAVE_SP_CORE=m CONFIG_RC_CORE=m CONFIG_REED_SOLOMON=m -CONFIG_REGMAP_I2C=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=m CONFIG_REGULATOR_TWL4030=m diff -Nru linux-6.0.6/debian.master/config/arm64/config.common.arm64 linux-6.0.12/debian.master/config/arm64/config.common.arm64 --- linux-6.0.6/debian.master/config/arm64/config.common.arm64 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/arm64/config.common.arm64 2023-01-18 18:27:39.000000000 +0000 @@ -16,6 +16,7 @@ CONFIG_ALTERA_STAPL=m CONFIG_ALTERA_TSE=m CONFIG_AMIGA_PARTITION=y +CONFIG_ANDROID_BINDER_IPC=m CONFIG_APDS9802ALS=m CONFIG_APPLICOM=m CONFIG_AQTION=m @@ -202,6 +203,7 @@ CONFIG_GPIO_TWL6040=m CONFIG_GPIO_VIRTIO=m CONFIG_GPIO_XILINX=y +CONFIG_GP_PCI1XXXX=m CONFIG_GREYBUS=m CONFIG_HABANA_AI=m CONFIG_HAMACHI=m @@ -252,6 +254,7 @@ CONFIG_I2C_NVIDIA_GPU=m CONFIG_I2C_OCORES=m CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PCI1XXXX=m CONFIG_I2C_PIIX4=m CONFIG_I2C_SIMTEC=m CONFIG_I2C_SIS5595=m @@ -306,6 +309,7 @@ CONFIG_JME=m CONFIG_JUMP_LABEL=y CONFIG_KARMA_PARTITION=y +# CONFIG_KERNEL_GZIP is not set CONFIG_KVM=y CONFIG_LAPB=m CONFIG_LCD_CLASS_DEVICE=m @@ -342,7 +346,6 @@ CONFIG_MFD_AXP20X_I2C=m CONFIG_MFD_BCM590XX=m CONFIG_MFD_BD9571MWV=m -CONFIG_MFD_CORE=y CONFIG_MFD_DA9062=m CONFIG_MFD_DA9063=y CONFIG_MFD_DA9150=m @@ -359,15 +362,18 @@ CONFIG_MFD_MENF21BMC=m CONFIG_MFD_MP2629=m CONFIG_MFD_MT6360=m +CONFIG_MFD_MT6370=m CONFIG_MFD_MT6397=m CONFIG_MFD_PCF50633=m CONFIG_MFD_RDC321X=m CONFIG_MFD_RETU=m CONFIG_MFD_RT4831=m CONFIG_MFD_RT5033=m +CONFIG_MFD_RT5120=m CONFIG_MFD_SI476X_CORE=m CONFIG_MFD_SKY81452=m CONFIG_MFD_SM501=m +CONFIG_MFD_SY7636A=m CONFIG_MFD_SYSCON=y CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_TI_LMU=m @@ -518,6 +524,7 @@ CONFIG_PPS_CLIENT_LDISC=m # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PSE_CONTROLLER=y # CONFIG_PSI_DEFAULT_DISABLED is not set CONFIG_PSTORE=y # CONFIG_PSTORE_CONSOLE is not set @@ -535,7 +542,6 @@ CONFIG_RAVE_SP_CORE=m CONFIG_RC_CORE=m CONFIG_REED_SOLOMON=m -CONFIG_REGMAP_I2C=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=m CONFIG_REGULATOR_TPS65217=m diff -Nru linux-6.0.6/debian.master/config/arm64/config.flavour.generic linux-6.0.12/debian.master/config/arm64/config.flavour.generic --- linux-6.0.6/debian.master/config/arm64/config.flavour.generic 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/arm64/config.flavour.generic 2023-01-18 18:27:39.000000000 +0000 @@ -1,6 +1,7 @@ # # Config options for config.flavour.generic automatically generated by splitconfig.pl # +CONFIG_ARCH_FORCE_MAX_ORDER=13 CONFIG_ARCH_MMAP_RND_BITS_MAX=33 CONFIG_ARCH_MMAP_RND_BITS_MIN=18 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 @@ -10,5 +11,4 @@ CONFIG_ARM64_CONT_PTE_SHIFT=4 CONFIG_ARM64_PAGE_SHIFT=12 CONFIG_ARM_SMMU_QCOM_DEBUG=y -CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PGTABLE_LEVELS=4 diff -Nru linux-6.0.6/debian.master/config/arm64/config.flavour.generic-64k linux-6.0.12/debian.master/config/arm64/config.flavour.generic-64k --- linux-6.0.6/debian.master/config/arm64/config.flavour.generic-64k 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/arm64/config.flavour.generic-64k 2023-01-18 18:27:39.000000000 +0000 @@ -1,6 +1,7 @@ # # Config options for config.flavour.generic-64k automatically generated by splitconfig.pl # +CONFIG_ARCH_FORCE_MAX_ORDER=14 CONFIG_ARCH_MMAP_RND_BITS_MAX=29 CONFIG_ARCH_MMAP_RND_BITS_MIN=14 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=7 @@ -10,5 +11,4 @@ CONFIG_ARM64_CONT_PTE_SHIFT=5 CONFIG_ARM64_PAGE_SHIFT=16 # CONFIG_ARM_SMMU_QCOM_DEBUG is not set -CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_PGTABLE_LEVELS=3 diff -Nru linux-6.0.6/debian.master/config/armhf/config.common.armhf linux-6.0.12/debian.master/config/armhf/config.common.armhf --- linux-6.0.6/debian.master/config/armhf/config.common.armhf 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/armhf/config.common.armhf 2023-01-18 18:27:39.000000000 +0000 @@ -13,6 +13,7 @@ CONFIG_ALTERA_STAPL=m CONFIG_ALTERA_TSE=m CONFIG_AMIGA_PARTITION=y +CONFIG_ANDROID_BINDER_IPC=m CONFIG_APDS9802ALS=m CONFIG_APPLICOM=m CONFIG_AQTION=m @@ -195,6 +196,7 @@ CONFIG_GPIO_TWL6040=y CONFIG_GPIO_VIRTIO=m CONFIG_GPIO_XILINX=y +CONFIG_GP_PCI1XXXX=m CONFIG_GREYBUS=m CONFIG_HABANA_AI=m CONFIG_HAMACHI=m @@ -243,6 +245,7 @@ CONFIG_I2C_NVIDIA_GPU=m CONFIG_I2C_OCORES=m CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PCI1XXXX=m CONFIG_I2C_PIIX4=m CONFIG_I2C_SIMTEC=m CONFIG_I2C_SIS5595=m @@ -329,7 +332,6 @@ CONFIG_MFD_AXP20X_I2C=m CONFIG_MFD_BCM590XX=m CONFIG_MFD_BD9571MWV=m -CONFIG_MFD_CORE=y CONFIG_MFD_DA9062=m CONFIG_MFD_DA9063=y CONFIG_MFD_DA9150=m @@ -346,15 +348,18 @@ CONFIG_MFD_MENF21BMC=m CONFIG_MFD_MP2629=m CONFIG_MFD_MT6360=m +CONFIG_MFD_MT6370=m CONFIG_MFD_MT6397=m CONFIG_MFD_PCF50633=m CONFIG_MFD_RDC321X=m CONFIG_MFD_RETU=m CONFIG_MFD_RT4831=m CONFIG_MFD_RT5033=m +CONFIG_MFD_RT5120=m CONFIG_MFD_SI476X_CORE=m CONFIG_MFD_SKY81452=m CONFIG_MFD_SM501=y +CONFIG_MFD_SY7636A=m CONFIG_MFD_SYSCON=y CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_TI_LMU=m @@ -503,6 +508,7 @@ CONFIG_PPS_CLIENT_LDISC=m # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PSE_CONTROLLER=y # CONFIG_PSI_DEFAULT_DISABLED is not set CONFIG_PSTORE=y CONFIG_PSTORE_CONSOLE=y @@ -519,7 +525,6 @@ CONFIG_RAVE_SP_CORE=m CONFIG_RC_CORE=m CONFIG_REED_SOLOMON=y -CONFIG_REGMAP_I2C=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_TPS65217=y diff -Nru linux-6.0.6/debian.master/config/armhf/config.flavour.generic linux-6.0.12/debian.master/config/armhf/config.flavour.generic --- linux-6.0.6/debian.master/config/armhf/config.flavour.generic 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/armhf/config.flavour.generic 2023-01-18 18:27:39.000000000 +0000 @@ -2,6 +2,7 @@ # Config options for config.flavour.generic automatically generated by splitconfig.pl # CONFIG_ARCH_ALPINE=y +CONFIG_ARCH_FORCE_MAX_ORDER=12 CONFIG_ARCH_OMAP3=y CONFIG_ARCH_OMAP4=y CONFIG_ARCH_UNIPHIER=y @@ -9,7 +10,6 @@ # CONFIG_ARM_HIGHBANK_CPUIDLE is not set CONFIG_ARM_L1_CACHE_SHIFT=7 # CONFIG_ARM_LPAE is not set -CONFIG_FORCE_MAX_ZONEORDER=12 CONFIG_PGTABLE_LEVELS=2 CONFIG_SOC_AM33XX=y # CONFIG_VIDEO_TI_CAL_MC is not set diff -Nru linux-6.0.6/debian.master/config/armhf/config.flavour.generic-lpae linux-6.0.12/debian.master/config/armhf/config.flavour.generic-lpae --- linux-6.0.6/debian.master/config/armhf/config.flavour.generic-lpae 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/armhf/config.flavour.generic-lpae 2023-01-18 18:27:39.000000000 +0000 @@ -2,6 +2,7 @@ # Config options for config.flavour.generic-lpae automatically generated by splitconfig.pl # # CONFIG_ARCH_ALPINE is not set +CONFIG_ARCH_FORCE_MAX_ORDER=11 # CONFIG_ARCH_OMAP3 is not set # CONFIG_ARCH_OMAP4 is not set # CONFIG_ARCH_UNIPHIER is not set @@ -9,7 +10,6 @@ CONFIG_ARM_HIGHBANK_CPUIDLE=y CONFIG_ARM_L1_CACHE_SHIFT=6 CONFIG_ARM_LPAE=y -CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PGTABLE_LEVELS=3 # CONFIG_SOC_AM33XX is not set CONFIG_VIDEO_TI_CAL_MC=y diff -Nru linux-6.0.6/debian.master/config/config.common.ubuntu linux-6.0.12/debian.master/config/config.common.ubuntu --- linux-6.0.6/debian.master/config/config.common.ubuntu 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/config.common.ubuntu 2023-01-18 18:27:39.000000000 +0000 @@ -188,6 +188,7 @@ CONFIG_ADF4350=m CONFIG_ADF4371=m # CONFIG_ADFS_FS_RW is not set +CONFIG_ADIN1110=m CONFIG_ADIN_PHY=m CONFIG_ADIS16080=m CONFIG_ADIS16130=m @@ -252,6 +253,7 @@ CONFIG_AGP_VIA=y CONFIG_AHCI_CEVA=m CONFIG_AHCI_DM816=m +CONFIG_AHCI_DWC=m CONFIG_AHCI_IMX=y CONFIG_AHCI_MTK=m CONFIG_AHCI_MVEBU=m @@ -279,6 +281,7 @@ CONFIG_AL3010=m CONFIG_AL3320A=m CONFIG_ALIBABA_ENI_VDPA=m +CONFIG_ALIBABA_UNCORE_DRW_PMU=m CONFIG_ALIENWARE_WMI=m CONFIG_ALIGNMENT_TRAP=y CONFIG_ALIM1535_WDT=m @@ -308,6 +311,7 @@ CONFIG_AMD_NUMA=y CONFIG_AMD_PHY=m CONFIG_AMD_PMC=m +CONFIG_AMD_PMF=m CONFIG_AMD_PTDMA=m CONFIG_AMD_SFH_HID=m CONFIG_AMD_XGBE=m @@ -316,7 +320,10 @@ CONFIG_AMILO_RFKILL=m CONFIG_AMLOGIC_THERMAL=m CONFIG_AMT=m -# CONFIG_ANDROID_BINDER_IPC is not set +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDERFS=y +CONFIG_ANDROID_BINDER_DEVICES="" +# CONFIG_ANDROID_BINDER_IPC_SELFTEST is not set CONFIG_ANON_VMA_NAME=y CONFIG_APDS9300=m CONFIG_APDS9960=m @@ -352,15 +359,10 @@ # CONFIG_ARCH_AT91 is not set CONFIG_ARCH_AXXIA=y # CONFIG_ARCH_BCM is not set -# CONFIG_ARCH_BCM2835 is not set -# CONFIG_ARCH_BCM4908 is not set -# CONFIG_ARCH_BCMBCA is not set -# CONFIG_ARCH_BCM_IPROC is not set CONFIG_ARCH_BERLIN=y CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y CONFIG_ARCH_BINFMT_ELF_STATE=y CONFIG_ARCH_BITMAIN=y -# CONFIG_ARCH_BRCMSTB is not set CONFIG_ARCH_CLOCKSOURCE_INIT=y CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y CONFIG_ARCH_CPUIDLE_HALTPOLL=y @@ -379,7 +381,6 @@ # CONFIG_ARCH_EXYNOS4 is not set # CONFIG_ARCH_EXYNOS5 is not set CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_ARCH_FOOTBRIDGE is not set CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y CONFIG_ARCH_HAS_ADD_PAGES=y CONFIG_ARCH_HAS_BANDGAP=y @@ -412,6 +413,7 @@ CONFIG_ARCH_HAS_MEMREMAP_COMPAT_ALIGN=y CONFIG_ARCH_HAS_MEM_ENCRYPT=y CONFIG_ARCH_HAS_MMIOWB=y +CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y CONFIG_ARCH_HAS_PHYS_TO_DMA=y @@ -515,6 +517,7 @@ CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y CONFIG_ARCH_NPCM=y CONFIG_ARCH_NPCM7XX=y +CONFIG_ARCH_NXP=y CONFIG_ARCH_OMAP=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_ARCH_OMAP2PLUS_TYPICAL=y @@ -573,7 +576,6 @@ CONFIG_ARCH_RZN1=y CONFIG_ARCH_S32=y # CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_SA1100 is not set CONFIG_ARCH_SEATTLE=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_SH73A0=y @@ -671,7 +673,6 @@ CONFIG_ARM64_AS_HAS_MTE=y CONFIG_ARM64_BTI=y CONFIG_ARM64_CNP=y -CONFIG_ARM64_CRYPTO=y # CONFIG_ARM64_DEBUG_PRIORITY_MASKING is not set CONFIG_ARM64_E0PD=y CONFIG_ARM64_EPAN=y @@ -692,6 +693,7 @@ CONFIG_ARM64_ERRATUM_2441007=y CONFIG_ARM64_ERRATUM_2441009=y CONFIG_ARM64_ERRATUM_2457168=y +CONFIG_ARM64_ERRATUM_2658417=y CONFIG_ARM64_ERRATUM_819472=y CONFIG_ARM64_ERRATUM_824069=y CONFIG_ARM64_ERRATUM_826319=y @@ -771,7 +773,6 @@ CONFIG_ARM_CPUIDLE=y CONFIG_ARM_CPU_SUSPEND=y CONFIG_ARM_CPU_TOPOLOGY=y -CONFIG_ARM_CRYPTO=y CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 CONFIG_ARM_DMA_MEM_BUFFERABLE=y CONFIG_ARM_DMA_USE_IOMMU=y @@ -810,7 +811,6 @@ CONFIG_ARM_GLOBAL_TIMER=y CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=1 CONFIG_ARM_HAS_GROUP_RELOCS=y -CONFIG_ARM_HAS_SG_CHAIN=y CONFIG_ARM_HEAVY_MB=y CONFIG_ARM_HIGHBANK_CPUFREQ=m CONFIG_ARM_IMX6Q_CPUFREQ=m @@ -924,6 +924,7 @@ CONFIG_AS_HAS_ARMV8_4=y CONFIG_AS_HAS_ARMV8_5=y CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y +CONFIG_AS_HAS_INSN=y CONFIG_AS_HAS_LDAPR=y CONFIG_AS_HAS_LSE_ATOMICS=y CONFIG_AS_HAS_NON_CONST_LEB128=y @@ -1109,6 +1110,7 @@ CONFIG_BACKLIGHT_LP8788=m CONFIG_BACKLIGHT_LV5207LP=m CONFIG_BACKLIGHT_MAX8925=m +CONFIG_BACKLIGHT_MT6370=m CONFIG_BACKLIGHT_PANDORA=m CONFIG_BACKLIGHT_PCF50633=m CONFIG_BACKLIGHT_PWM=m @@ -1314,6 +1316,9 @@ # CONFIG_BOOT_CONFIG_EMBED is not set CONFIG_BOOT_PRINTK_DELAY=y CONFIG_BOOT_VESA_SUPPORT=y +CONFIG_BOSCH_BNO055=m +CONFIG_BOSCH_BNO055_I2C=m +CONFIG_BOSCH_BNO055_SERIAL=m CONFIG_BOUNCE=y CONFIG_BPF=y CONFIG_BPFILTER=y @@ -1671,8 +1676,10 @@ CONFIG_CHARGER_MAX8998=m CONFIG_CHARGER_MP2629=m CONFIG_CHARGER_MT6360=m +CONFIG_CHARGER_MT6370=m CONFIG_CHARGER_PCF50633=m CONFIG_CHARGER_QCOM_SMBB=m +CONFIG_CHARGER_RK817=m CONFIG_CHARGER_RT9455=m CONFIG_CHARGER_SBS=m CONFIG_CHARGER_SC2731=m @@ -1822,6 +1829,7 @@ CONFIG_CLK_RK3399=y CONFIG_CLK_RK3568=y CONFIG_CLK_RV110X=y +CONFIG_CLK_RV1126=y CONFIG_CLK_RZA1=y CONFIG_CLK_RZG2L=y CONFIG_CLK_SH73A0=y @@ -2079,6 +2087,11 @@ CONFIG_COMMON_CLK_MT6779_MMSYS=y CONFIG_COMMON_CLK_MT6779_VDECSYS=y CONFIG_COMMON_CLK_MT6779_VENCSYS=y +CONFIG_COMMON_CLK_MT6795=m +CONFIG_COMMON_CLK_MT6795_MFGCFG=m +CONFIG_COMMON_CLK_MT6795_MMSYS=m +CONFIG_COMMON_CLK_MT6795_VDECSYS=m +CONFIG_COMMON_CLK_MT6795_VENCSYS=m CONFIG_COMMON_CLK_MT6797=y CONFIG_COMMON_CLK_MT6797_IMGSYS=y CONFIG_COMMON_CLK_MT6797_MMSYS=y @@ -2129,6 +2142,13 @@ CONFIG_COMMON_CLK_MT8192_VDECSYS=y CONFIG_COMMON_CLK_MT8192_VENCSYS=y CONFIG_COMMON_CLK_MT8195=y +CONFIG_COMMON_CLK_MT8365=m +CONFIG_COMMON_CLK_MT8365_APU=m +CONFIG_COMMON_CLK_MT8365_CAM=m +CONFIG_COMMON_CLK_MT8365_MFG=m +CONFIG_COMMON_CLK_MT8365_MMSYS=m +CONFIG_COMMON_CLK_MT8365_VDEC=m +CONFIG_COMMON_CLK_MT8365_VENC=m CONFIG_COMMON_CLK_MT8516=y CONFIG_COMMON_CLK_MT8516_AUDSYS=y CONFIG_COMMON_CLK_PALMAS=m @@ -2149,6 +2169,7 @@ CONFIG_COMMON_CLK_TI_ADPLL=y CONFIG_COMMON_CLK_TPS68470=m CONFIG_COMMON_CLK_VC5=m +CONFIG_COMMON_CLK_VC7=m CONFIG_COMMON_CLK_VISCONTI=y CONFIG_COMMON_CLK_WM831X=m CONFIG_COMMON_CLK_XGENE=y @@ -2156,9 +2177,11 @@ CONFIG_COMMON_RESET_HI3660=m CONFIG_COMMON_RESET_HI6220=m CONFIG_COMPACTION=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAL_LAPTOP=m CONFIG_COMPAT_32=y CONFIG_COMPAT_32BIT_TIME=y +# CONFIG_COMPAT_ALIGNMENT_FIXUPS is not set CONFIG_COMPAT_BINFMT_ELF=y # CONFIG_COMPAT_BRK is not set CONFIG_COMPAT_FOR_U64_ALIGNMENT=y @@ -2279,6 +2302,7 @@ CONFIG_CROS_EC_TYPEC=m CONFIG_CROS_EC_VBC=m CONFIG_CROS_KBD_LED_BACKLIGHT=m +CONFIG_CROS_TYPEC_SWITCH=m CONFIG_CROS_USBPD_LOGGER=m CONFIG_CROS_USBPD_NOTIFY=m CONFIG_CRYPTO=y @@ -2312,6 +2336,7 @@ CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64=m CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_BLAKE2B=m CONFIG_CRYPTO_BLAKE2B_NEON=m @@ -2365,6 +2390,10 @@ CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m # CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG is not set CONFIG_CRYPTO_DEV_ARTPEC6=m +CONFIG_CRYPTO_DEV_ASPEED=m +# CONFIG_CRYPTO_DEV_ASPEED_DEBUG is not set +CONFIG_CRYPTO_DEV_ASPEED_HACE_CRYPTO=y +CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH=y CONFIG_CRYPTO_DEV_ATMEL_I2C=m CONFIG_CRYPTO_DEV_CAVIUM_ZIP=m CONFIG_CRYPTO_DEV_CCP=y @@ -2510,6 +2539,7 @@ CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m CONFIG_CRYPTO_LIB_SHA1=y CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_LZ4=m CONFIG_CRYPTO_LZ4HC=m @@ -2701,6 +2731,7 @@ CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MAPLE_TREE is not set # CONFIG_DEBUG_MEMORY_INIT is not set CONFIG_DEBUG_MISC=y # CONFIG_DEBUG_MUTEXES is not set @@ -2766,6 +2797,7 @@ CONFIG_DELL_SMBIOS_SMM=y CONFIG_DELL_SMBIOS_WMI=y CONFIG_DELL_SMO8800=m +CONFIG_DELL_UART_BACKLIGHT=m CONFIG_DELL_WMI=m CONFIG_DELL_WMI_AIO=m CONFIG_DELL_WMI_DESCRIPTOR=m @@ -2945,7 +2977,6 @@ CONFIG_DRM_DW_HDMI_I2S_AUDIO=m CONFIG_DRM_DW_MIPI_DSI=m CONFIG_DRM_ETNAVIV_THERMAL=y -CONFIG_DRM_EXPORT_FOR_TESTS=y CONFIG_DRM_EXYNOS=m CONFIG_DRM_EXYNOS5433_DECON=y # CONFIG_DRM_EXYNOS7_DECON is not set @@ -2966,7 +2997,7 @@ CONFIG_DRM_FBDEV_OVERALLOC=100 CONFIG_DRM_FSL_DCU=m CONFIG_DRM_FSL_LDB=m -CONFIG_DRM_GEM_CMA_HELPER=m +CONFIG_DRM_GEM_DMA_HELPER=m CONFIG_DRM_GEM_SHMEM_HELPER=m CONFIG_DRM_GM12U320=m CONFIG_DRM_GMA500=m @@ -3023,7 +3054,6 @@ CONFIG_DRM_KMS_HELPER=m CONFIG_DRM_KOMEDA=m # CONFIG_DRM_LEGACY is not set -CONFIG_DRM_LIB_RANDOM=y CONFIG_DRM_LIMA=m CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_LOGICVC=m @@ -3035,6 +3065,7 @@ CONFIG_DRM_MALI_DISPLAY=m CONFIG_DRM_MCDE=m CONFIG_DRM_MEDIATEK=m +CONFIG_DRM_MEDIATEK_DP=m CONFIG_DRM_MEDIATEK_HDMI=m CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW=m CONFIG_DRM_MESON=m @@ -3171,9 +3202,6 @@ CONFIG_DRM_STM=m CONFIG_DRM_STM_DSI=m CONFIG_DRM_SUN4I=m -CONFIG_DRM_SUN4I_BACKEND=m -CONFIG_DRM_SUN4I_HDMI=m -# CONFIG_DRM_SUN4I_HDMI_CEC is not set CONFIG_DRM_SUN6I_DSI=m CONFIG_DRM_SUN8I_DW_HDMI=m CONFIG_DRM_SUN8I_MIXER=m @@ -3198,6 +3226,7 @@ CONFIG_DRM_TTM_HELPER=m CONFIG_DRM_TVE200=m CONFIG_DRM_UDL=m +# CONFIG_DRM_USE_DYNAMIC_DEBUG is not set CONFIG_DRM_VBOXVIDEO=m CONFIG_DRM_VIRTIO_GPU=m CONFIG_DRM_VMWGFX=m @@ -3336,7 +3365,6 @@ CONFIG_DVB_SI21XX=m CONFIG_DVB_SMIPCIE=m CONFIG_DVB_SP2=m -CONFIG_DVB_SP8870=m CONFIG_DVB_SP887X=m CONFIG_DVB_STB0899=m CONFIG_DVB_STB6000=m @@ -3509,6 +3537,7 @@ CONFIG_EDAC_PND2=m CONFIG_EDAC_QCOM=m CONFIG_EDAC_SBRIDGE=m +CONFIG_EDAC_SIFIVE=y CONFIG_EDAC_SKX=m CONFIG_EDAC_SUPPORT=y CONFIG_EDAC_SYNOPSYS=m @@ -3553,6 +3582,7 @@ CONFIG_EFI_TEST=m CONFIG_EFI_VARS_PSTORE=m # CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set +CONFIG_EFI_ZBOOT=y CONFIG_EINT_MTK=y CONFIG_EISA=y CONFIG_EISA_NAMES=y @@ -3600,6 +3630,7 @@ CONFIG_EVM_ATTR_FSUUID=y CONFIG_EVM_EXTRA_SMACK_XATTRS=y CONFIG_EVM_X509_PATH="/etc/keys/x509_evm.der" +CONFIG_EXAR_WDT=m CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" CONFIG_EXPERT=y @@ -3852,6 +3883,7 @@ CONFIG_FONT_SUPPORT=y CONFIG_FONT_TER16x32=y CONFIG_FORCEDETH=m +# CONFIG_FORCE_NR_CPUS is not set CONFIG_FORCE_PCI=y CONFIG_FORCE_SMP=y CONFIG_FPGA=m @@ -3875,6 +3907,7 @@ CONFIG_FPGA_MGR_XILINX_SPI=m CONFIG_FPGA_MGR_ZYNQMP_FPGA=m CONFIG_FPGA_REGION=m +CONFIG_FPGA_M10_BMC_SEC_UPDATE=m CONFIG_FPROBE=y CONFIG_FPU=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -4103,6 +4136,7 @@ CONFIG_GPIO_104_IDI_48=m CONFIG_GPIO_74X164=m CONFIG_GPIO_74XX_MMIO=m +CONFIG_GPIO_AAEON=m CONFIG_GPIO_ACPI=y CONFIG_GPIO_ADNP=m CONFIG_GPIO_ADP5520=m @@ -4140,6 +4174,7 @@ CONFIG_GPIO_HLWD=m CONFIG_GPIO_I8255=m CONFIG_GPIO_ICH=m +CONFIG_GPIO_IMX_SCU=y CONFIG_GPIO_IT87=m CONFIG_GPIO_JANZ_TTL=m CONFIG_GPIO_KEMPLD=m @@ -4283,6 +4318,7 @@ CONFIG_HAVE_ARCH_KFENCE=y CONFIG_HAVE_ARCH_KGDB=y CONFIG_HAVE_ARCH_KGDB_QXFER_PKT=y +CONFIG_HAVE_ARCH_KMSAN=y CONFIG_HAVE_ARCH_MMAP_RND_BITS=y CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y CONFIG_HAVE_ARCH_NODE_DEV_GROUP=y @@ -4321,6 +4357,7 @@ CONFIG_HAVE_DEBUG_STACKOVERFLOW=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y @@ -4367,6 +4404,8 @@ CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y CONFIG_HAVE_KVM_DIRTY_RING=y +CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y +CONFIG_HAVE_KVM_DIRTY_RING_TSO=y CONFIG_HAVE_KVM_EVENTFD=y CONFIG_HAVE_KVM_INVALID_WAKEUPS=y CONFIG_HAVE_KVM_IRQCHIP=y @@ -4400,7 +4439,6 @@ CONFIG_HAVE_OBJTOOL=y CONFIG_HAVE_OBJTOOL_MCOUNT=y CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PATA_PLATFORM=y CONFIG_HAVE_PCI=y CONFIG_HAVE_PCSPKR_PLATFORM=y CONFIG_HAVE_PERF_EVENTS=y @@ -4417,6 +4455,7 @@ CONFIG_HAVE_RELIABLE_STACKTRACE=y CONFIG_HAVE_RETHOOK=y CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_RUST=y CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y @@ -4541,6 +4580,7 @@ CONFIG_HID_PLAYSTATION=m CONFIG_HID_PRIMAX=m CONFIG_HID_PRODIKEYS=m +CONFIG_HID_PXRC=m CONFIG_HID_RAZER=m CONFIG_HID_REDRAGON=m CONFIG_HID_RETRODE=m @@ -4583,6 +4623,7 @@ CONFIG_HID_VIEWSONIC=m CONFIG_HID_VIVALDI=m CONFIG_HID_VIVALDI_COMMON=m +CONFIG_HID_VRC2=m CONFIG_HID_WACOM=m CONFIG_HID_WALTOP=m CONFIG_HID_WIIMOTE=m @@ -4605,6 +4646,7 @@ CONFIG_HISI_FEMAC=m CONFIG_HISI_PCIE_PMU=m CONFIG_HISI_PMU=m +CONFIG_HISI_PTT=m CONFIG_HISI_THERMAL=m CONFIG_HIST_TRIGGERS=y # CONFIG_HIST_TRIGGERS_DEBUG is not set @@ -4971,6 +5013,7 @@ CONFIG_IMX_IPUV3_CORE=m CONFIG_IMX_IRQSTEER=y CONFIG_IMX_MBOX=m +CONFIG_IMX_MU_MSI=m CONFIG_IMX_REMOTEPROC=m CONFIG_IMX_SCU=y CONFIG_IMX_SCU_PD=y @@ -5004,6 +5047,7 @@ CONFIG_INET_TUNNEL=m CONFIG_INET_UDP_DIAG=m CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TABLE_PERTURB_ORDER=16 CONFIG_INFINIBAND=m CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y @@ -5110,6 +5154,7 @@ CONFIG_INPUT_GPIO_ROTARY_ENCODER=m CONFIG_INPUT_GPIO_VIBRA=m CONFIG_INPUT_HISI_POWERKEY=m +CONFIG_INPUT_IBM_PANEL=m CONFIG_INPUT_IDEAPAD_SLIDEBAR=m CONFIG_INPUT_IMS_PCU=m CONFIG_INPUT_IQS269A=m @@ -5142,6 +5187,7 @@ CONFIG_INPUT_REGULATOR_HAPTIC=m CONFIG_INPUT_RETU_PWRBUTTON=m CONFIG_INPUT_RK805_PWRKEY=m +CONFIG_INPUT_RT5120_PWRKEY=m CONFIG_INPUT_SC27XX_VIBRA=m CONFIG_INPUT_SOC_BUTTON_ARRAY=m CONFIG_INPUT_STPMIC1_ONKEY=m @@ -5303,6 +5349,7 @@ CONFIG_IOMMU_HELPER=y CONFIG_IOMMU_IO_PGTABLE=y # CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +CONFIG_IOMMU_IO_PGTABLE_DART=y CONFIG_IOMMU_IO_PGTABLE_LPAE=y # CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set CONFIG_IOMMU_SUPPORT=y @@ -5720,6 +5767,7 @@ CONFIG_KEYBOARD_NVEC=m CONFIG_KEYBOARD_OMAP4=m CONFIG_KEYBOARD_OPENCORES=m +CONFIG_KEYBOARD_PINEPHONE=m CONFIG_KEYBOARD_PMIC8XXX=m CONFIG_KEYBOARD_QT1050=m CONFIG_KEYBOARD_QT1070=m @@ -5842,6 +5890,7 @@ CONFIG_LD_ORPHAN_WARN=y CONFIG_LD_VERSION=23900 CONFIG_LEDS_88PM860X=m +CONFIG_LEDS_AAEON=m CONFIG_LEDS_AAT1290=m CONFIG_LEDS_ACER_A500=m CONFIG_LEDS_ADP5520=m @@ -5971,7 +6020,6 @@ CONFIG_LIBFDT=y CONFIG_LIBIPW=m # CONFIG_LIBIPW_DEBUG is not set -CONFIG_LIB_MEMNEQ=y CONFIG_LIDAR_LITE_V2=m CONFIG_LINEAR_RANGES=y CONFIG_LINEDISP=m @@ -5998,6 +6046,7 @@ CONFIG_LOCKD_V4=y CONFIG_LOCKUP_DETECTOR=y CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_DOWN_IN_SECURE_BOOT=y # CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set # CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y @@ -6016,6 +6065,9 @@ CONFIG_LPARCFG=y # CONFIG_LP_CONSOLE is not set CONFIG_LRU_CACHE=m +CONFIG_LRU_GEN=y +# CONFIG_LRU_GEN_ENABLED is not set +# CONFIG_LRU_GEN_STATS is not set CONFIG_LSI_ET1011C_PHY=m CONFIG_LSM="landlock,lockdown,yama,integrity,apparmor" CONFIG_LSM_MMAP_MIN_ADDR=0 @@ -6032,6 +6084,7 @@ CONFIG_LTE_GDM724X=m CONFIG_LTO_NONE=y CONFIG_LTR501=m +CONFIG_LTRF216A=m CONFIG_LV0104CS=m CONFIG_LWTUNNEL=y CONFIG_LWTUNNEL_BPF=y @@ -6115,6 +6168,7 @@ CONFIG_MAX1027=m CONFIG_MAX11100=m CONFIG_MAX1118=m +CONFIG_MAX11205=m CONFIG_MAX1241=m CONFIG_MAX1363=m CONFIG_MAX30100=m @@ -6254,7 +6308,6 @@ CONFIG_MEMBARRIER=y CONFIG_MEMCG=y CONFIG_MEMCG_KMEM=y -CONFIG_MEMCG_SWAP=y CONFIG_MEMFD_CREATE=y CONFIG_MEMORY_BALLOON=y CONFIG_MEMORY_FAILURE=y @@ -6280,14 +6333,12 @@ CONFIG_MESON_CANVAS=m CONFIG_MESON_CLK_MEASURE=y CONFIG_MESON_EE_PM_DOMAINS=y -CONFIG_MESON_EFUSE=m CONFIG_MESON_GXBB_WATCHDOG=m CONFIG_MESON_GXL_PHY=m CONFIG_MESON_GX_PM_DOMAINS=y CONFIG_MESON_GX_SOCINFO=y CONFIG_MESON_IRQ_GPIO=y CONFIG_MESON_MX_AO_ARC_REMOTEPROC=m -CONFIG_MESON_MX_EFUSE=m CONFIG_MESON_MX_SOCINFO=y CONFIG_MESON_SARADC=m CONFIG_MESON_SECURE_PM_DOMAINS=y @@ -6295,6 +6346,7 @@ CONFIG_MESON_WATCHDOG=m CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 CONFIG_MFD_88PM860X=y +CONFIG_MFD_AAEON=m CONFIG_MFD_AAT2870_CORE=y # CONFIG_MFD_AC100 is not set CONFIG_MFD_ACER_A500_EC=m @@ -6311,6 +6363,7 @@ CONFIG_MFD_ATMEL_HLCDC=m CONFIG_MFD_AXP20X=m CONFIG_MFD_AXP20X_RSB=m +CONFIG_MFD_CORE=y CONFIG_MFD_CPCAP=m CONFIG_MFD_CROS_EC_DEV=m CONFIG_MFD_CS47L15=y @@ -6351,6 +6404,7 @@ CONFIG_MFD_MC13XXX_SPI=m CONFIG_MFD_NTXEC=m CONFIG_MFD_NVEC=m +CONFIG_MFD_OCELOT=m CONFIG_MFD_OMAP_USB_HOST=y CONFIG_MFD_PALMAS=y CONFIG_MFD_PM8XXX=m @@ -6458,6 +6512,7 @@ CONFIG_MLX5_CORE_IPOIB=y CONFIG_MLX5_EN_ARFS=y CONFIG_MLX5_EN_IPSEC=y +# CONFIG_MLX5_EN_MACSEC is not set CONFIG_MLX5_EN_RXNFC=y CONFIG_MLX5_EN_TLS=y CONFIG_MLX5_ESWITCH=y @@ -6676,6 +6731,7 @@ CONFIG_MS5611_I2C=m CONFIG_MS5611_SPI=m CONFIG_MS5637=m +CONFIG_MSA311=m CONFIG_MSC313E_WATCHDOG=m CONFIG_MSCC_OCELOT_SWITCH=m CONFIG_MSCC_OCELOT_SWITCH_LIB=m @@ -6686,6 +6742,7 @@ CONFIG_MSI_LAPTOP=m CONFIG_MSI_WMI=m CONFIG_MSM_GCC_8660=m +CONFIG_MSM_GCC_8909=m CONFIG_MSM_GCC_8916=m CONFIG_MSM_GCC_8939=m CONFIG_MSM_GCC_8953=m @@ -6775,6 +6832,10 @@ CONFIG_MTD_MTDRAM=m CONFIG_MTD_NAND_ARASAN=m CONFIG_MTD_NAND_BRCMNAND=m +CONFIG_MTD_NAND_BRCMNAND_BCM63XX=m +CONFIG_MTD_NAND_BRCMNAND_BCMBCA=m +CONFIG_MTD_NAND_BRCMNAND_BRCMSTB=m +CONFIG_MTD_NAND_BRCMNAND_IPROC=m CONFIG_MTD_NAND_CADENCE=m CONFIG_MTD_NAND_CAFE=m CONFIG_MTD_NAND_DENALI=m @@ -6872,7 +6933,6 @@ CONFIG_MTK_CMDQ_MBOX=m CONFIG_MTK_CQDMA=m CONFIG_MTK_DEVAPC=m -CONFIG_MTK_EFUSE=m CONFIG_MTK_HSDMA=m CONFIG_MTK_INFRACFG=y # CONFIG_MTK_IOMMU is not set @@ -7249,6 +7309,7 @@ CONFIG_NET_UDP_TUNNEL=m CONFIG_NET_VENDOR_8390=y CONFIG_NET_VENDOR_ACTIONS=y +CONFIG_NET_VENDOR_ADI=y CONFIG_NET_VENDOR_ALACRITECH=y CONFIG_NET_VENDOR_ALLWINNER=y CONFIG_NET_VENDOR_AMAZON=y @@ -7454,6 +7515,7 @@ CONFIG_NF_TABLES_NETDEV=y CONFIG_NF_TPROXY_IPV4=m CONFIG_NF_TPROXY_IPV6=m +CONFIG_NGBE=m CONFIG_NI903X_WDT=m CONFIG_NIC7018_WDT=m CONFIG_NILFS2_FS=m @@ -7578,13 +7640,24 @@ CONFIG_NVMEM_IMX_OCOTP=m CONFIG_NVMEM_IMX_OCOTP_SCU=m CONFIG_NVMEM_LAYERSCAPE_SFP=m +CONFIG_NVMEM_MESON_EFUSE=m +CONFIG_NVMEM_MESON_MX_EFUSE=m +CONFIG_NVMEM_MTK_EFUSE=m +CONFIG_NVMEM_QCOM_QFPROM=m +CONFIG_NVMEM_RAVE_SP_EEPROM=m CONFIG_NVMEM_REBOOT_MODE=m CONFIG_NVMEM_RMEM=m +CONFIG_NVMEM_ROCKCHIP_EFUSE=m +CONFIG_NVMEM_ROCKCHIP_OTP=m +CONFIG_NVMEM_SC27XX_EFUSE=m CONFIG_NVMEM_SNVS_LPGPR=m CONFIG_NVMEM_SPMI_SDAM=m +CONFIG_NVMEM_SPRD_EFUSE=m CONFIG_NVMEM_SUNPLUS_OCOTP=m CONFIG_NVMEM_SUNXI_SID=m CONFIG_NVMEM_SYSFS=y +CONFIG_NVMEM_UNIPHIER_EFUSE=m +CONFIG_NVMEM_U_BOOT_ENV=m # CONFIG_NVMEM_VF610_OCOTP is not set CONFIG_NVMEM_ZYNQMP=y CONFIG_NVME_APPLE=m @@ -7972,6 +8045,7 @@ CONFIG_PCNET32=m CONFIG_PCPU_DEV_REFCNT=y CONFIG_PCSPKR_PLATFORM=y +CONFIG_PCS_ALTERA_TSE=m CONFIG_PCS_LYNX=m CONFIG_PCS_RZN1_MIIC=m CONFIG_PCS_XPCS=m @@ -8078,6 +8152,7 @@ CONFIG_PHY_ROCKCHIP_INNO_USB2=m CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=m CONFIG_PHY_ROCKCHIP_PCIE=m +CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=m CONFIG_PHY_ROCKCHIP_TYPEC=m CONFIG_PHY_ROCKCHIP_USB=m # CONFIG_PHY_SAMSUNG_UFS is not set @@ -8087,6 +8162,7 @@ CONFIG_PHY_SUN50I_USB3=m CONFIG_PHY_SUN6I_MIPI_DPHY=m # CONFIG_PHY_SUN9I_USB is not set +CONFIG_PHY_SUNPLUS_USB=m CONFIG_PHY_TEGRA194_P2U=m CONFIG_PHY_TEGRA_XUSB=m CONFIG_PHY_TUSB1210=m @@ -8135,6 +8211,7 @@ CONFIG_PINCTRL_CS47L85=y CONFIG_PINCTRL_CS47L90=y CONFIG_PINCTRL_CS47L92=y +CONFIG_PINCTRL_CY8C95X0=m CONFIG_PINCTRL_DA9062=m CONFIG_PINCTRL_DENVERTON=m CONFIG_PINCTRL_DOVE=y @@ -8227,6 +8304,7 @@ CONFIG_PINCTRL_MT8173=y CONFIG_PINCTRL_MT8183=y CONFIG_PINCTRL_MT8186=y +CONFIG_PINCTRL_MT8188=y CONFIG_PINCTRL_MT8192=y CONFIG_PINCTRL_MT8195=y CONFIG_PINCTRL_MT8365=y @@ -8293,6 +8371,7 @@ CONFIG_PINCTRL_SC7280_LPASS_LPI=m CONFIG_PINCTRL_SC8180X=m CONFIG_PINCTRL_SC8280XP=m +CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m CONFIG_PINCTRL_SDM660=m CONFIG_PINCTRL_SDM845=m CONFIG_PINCTRL_SDX55=m @@ -8309,10 +8388,11 @@ CONFIG_PINCTRL_SM8250_LPASS_LPI=m CONFIG_PINCTRL_SM8350=m CONFIG_PINCTRL_SM8450=m +CONFIG_PINCTRL_SM8450_LPASS_LPI=m CONFIG_PINCTRL_SPPCTL=y CONFIG_PINCTRL_SPRD=y CONFIG_PINCTRL_SPRD_SC9860=y -CONFIG_PINCTRL_STARFIVE=y +CONFIG_PINCTRL_STARFIVE_JH7100=m CONFIG_PINCTRL_STMFX=m CONFIG_PINCTRL_SUN20I_D1=y CONFIG_PINCTRL_SUN4I_A10=y @@ -8424,6 +8504,7 @@ CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_POSIX_TIMERS=y +# CONFIG_POWER10_CPU is not set # CONFIG_POWER7_CPU is not set # CONFIG_POWER8_CPU is not set # CONFIG_POWER9_CPU is not set @@ -8563,7 +8644,7 @@ CONFIG_PRESTERA=m CONFIG_PRESTERA_PCI=m CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_PRIME_NUMBERS=m +# CONFIG_PRIME_NUMBERS is not set CONFIG_PRINTER=m CONFIG_PRINTK=y # CONFIG_PRINTK_CALLER is not set @@ -8599,6 +8680,7 @@ CONFIG_PSERIES_ENERGY=m CONFIG_PSERIES_PLPKS=y CONFIG_PSERIES_WDT=m +CONFIG_PSE_REGULATOR=m CONFIG_PSI=y # CONFIG_PSTORE_842_COMPRESS is not set CONFIG_PSTORE_BLK=m @@ -8736,7 +8818,6 @@ CONFIG_QCOM_Q6V5_PAS=m CONFIG_QCOM_Q6V5_WCSS=m CONFIG_QCOM_QDF2400_ERRATUM_0065=y -CONFIG_QCOM_QFPROM=m CONFIG_QCOM_QMI_HELPERS=m CONFIG_QCOM_RMTFS_MEM=m CONFIG_QCOM_RPMCC=y @@ -8909,6 +8990,7 @@ # CONFIG_REED_SOLOMON_TEST is not set CONFIG_REGMAP=y CONFIG_REGMAP_AC97=m +CONFIG_REGMAP_I2C=y CONFIG_REGMAP_I3C=m CONFIG_REGMAP_IRQ=y CONFIG_REGMAP_MMIO=y @@ -9001,9 +9083,12 @@ CONFIG_REGULATOR_MT6311=m CONFIG_REGULATOR_MT6315=m CONFIG_REGULATOR_MT6323=m +CONFIG_REGULATOR_MT6331=m +CONFIG_REGULATOR_MT6332=m CONFIG_REGULATOR_MT6358=m CONFIG_REGULATOR_MT6359=m CONFIG_REGULATOR_MT6360=m +CONFIG_REGULATOR_MT6370=m CONFIG_REGULATOR_MT6380=m CONFIG_REGULATOR_MT6397=m CONFIG_REGULATOR_PALMAS=m @@ -9031,6 +9116,7 @@ CONFIG_REGULATOR_RT4801=m CONFIG_REGULATOR_RT4831=m CONFIG_REGULATOR_RT5033=m +CONFIG_REGULATOR_RT5120=m CONFIG_REGULATOR_RT5190A=m CONFIG_REGULATOR_RT5759=m CONFIG_REGULATOR_RT6160=m @@ -9093,6 +9179,7 @@ CONFIG_RENESAS_RZA1_IRQC=y CONFIG_RENESAS_RZAWDT=m CONFIG_RENESAS_RZG2LWDT=m +CONFIG_RENESAS_RZG2L_IRQC=y CONFIG_RENESAS_RZN1WDT=m CONFIG_RENESAS_USB_DMAC=m CONFIG_RENESAS_WDT=m @@ -9105,6 +9192,7 @@ CONFIG_RESET_MESON=y CONFIG_RESET_MESON_AUDIO_ARB=m CONFIG_RESET_NPCM=y +CONFIG_RESET_POLARFIRE_SOC=y CONFIG_RESET_QCOM_AOSS=y CONFIG_RESET_QCOM_PDC=m CONFIG_RESET_RZG2L_USBPHY_CTRL=m @@ -9130,6 +9218,7 @@ CONFIG_RFKILL_INPUT=y CONFIG_RFKILL_LEDS=y CONFIG_RFS_ACCEL=y +CONFIG_RICHTEK_RTQ6056=m CONFIG_RING_BUFFER=y # CONFIG_RING_BUFFER_BENCHMARK is not set # CONFIG_RING_BUFFER_STARTUP_TEST is not set @@ -9174,14 +9263,12 @@ CONFIG_ROCKCHIP_DTPM=m CONFIG_ROCKCHIP_DW_HDMI=y CONFIG_ROCKCHIP_DW_MIPI_DSI=y -CONFIG_ROCKCHIP_EFUSE=m CONFIG_ROCKCHIP_GRF=y CONFIG_ROCKCHIP_INNO_HDMI=y CONFIG_ROCKCHIP_IODOMAIN=m CONFIG_ROCKCHIP_IOMMU=y CONFIG_ROCKCHIP_LVDS=y CONFIG_ROCKCHIP_MBOX=y -CONFIG_ROCKCHIP_OTP=m CONFIG_ROCKCHIP_PHY=m CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_ROCKCHIP_RGB=y @@ -9541,7 +9628,6 @@ CONFIG_SBP_TARGET=m CONFIG_SC1200_WDT=m CONFIG_SC27XX_ADC=m -CONFIG_SC27XX_EFUSE=m CONFIG_SC92031=m CONFIG_SCA3000=m CONFIG_SCA3300=m @@ -9667,6 +9753,7 @@ CONFIG_SC_GCC_8280XP=m CONFIG_SC_GPUCC_7180=m CONFIG_SC_GPUCC_7280=m +CONFIG_SC_GPUCC_8280XP=m CONFIG_SC_LPASSCC_7280=m CONFIG_SC_LPASS_CORECC_7180=m CONFIG_SC_LPASS_CORECC_7280=m @@ -9713,6 +9800,7 @@ CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_PATH=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY_SAFESETID=y CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_AVC_STATS=y @@ -9737,6 +9825,7 @@ CONFIG_SENSEAIR_SUNRISE_CO2=m CONFIG_SENSIRION_SGP30=m CONFIG_SENSIRION_SGP40=m +CONFIG_SENSORS_AAEON=m CONFIG_SENSORS_ABITUGURU=m CONFIG_SENSORS_ABITUGURU3=m CONFIG_SENSORS_ACPI_POWER=m @@ -9793,6 +9882,7 @@ CONFIG_SENSORS_DS620=m CONFIG_SENSORS_EMC1403=m CONFIG_SENSORS_EMC2103=m +CONFIG_SENSORS_EMC2305=m CONFIG_SENSORS_EMC6W201=m CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m @@ -9889,6 +9979,7 @@ CONFIG_SENSORS_MAX20751=m CONFIG_SENSORS_MAX31722=m CONFIG_SENSORS_MAX31730=m +CONFIG_SENSORS_MAX31760=m CONFIG_SENSORS_MAX31785=m CONFIG_SENSORS_MAX31790=m CONFIG_SENSORS_MAX34440=m @@ -9968,6 +10059,7 @@ CONFIG_SENSORS_TPS23861=m CONFIG_SENSORS_TPS40422=m CONFIG_SENSORS_TPS53679=m +CONFIG_SENSORS_TPS546D24=m CONFIG_SENSORS_TSL2563=m CONFIG_SENSORS_UCD9000=m CONFIG_SENSORS_UCD9200=m @@ -10036,6 +10128,7 @@ CONFIG_SERIAL_DEV_CTRL_TTYPORT=y CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y CONFIG_SERIAL_ICOM=m CONFIG_SERIAL_IMX=y CONFIG_SERIAL_IMX_CONSOLE=y @@ -10126,6 +10219,8 @@ CONFIG_SG_POOL=y CONFIG_SG_SPLIT=y CONFIG_SHADOW_CALL_STACK=y +CONFIG_SHIFT_FS=m +CONFIG_SHIFT_FS_POSIX_ACL=y CONFIG_SHMEM=y # CONFIG_SHRINKER_DEBUG is not set CONFIG_SHUFFLE_PAGE_ALLOCATOR=y @@ -10139,7 +10234,7 @@ CONFIG_SI7020=m CONFIG_SIEMENS_SIMATIC_IPC=m CONFIG_SIEMENS_SIMATIC_IPC_WDT=m -# CONFIG_SIFIVE_L2 is not set +CONFIG_SIFIVE_CCACHE=y CONFIG_SIFIVE_PLIC=y CONFIG_SIGNALFD=y CONFIG_SIGNATURE=y @@ -10202,13 +10297,16 @@ CONFIG_SMS_USB_DRV=m CONFIG_SM_CAMCC_8250=m CONFIG_SM_CAMCC_8450=m +CONFIG_SM_DISPCC_6115=m CONFIG_SM_DISPCC_6125=m CONFIG_SM_DISPCC_6350=m CONFIG_SM_DISPCC_8250=m +CONFIG_SM_DISPCC_8450=m CONFIG_SM_FTL=m CONFIG_SM_GCC_6115=m CONFIG_SM_GCC_6125=m CONFIG_SM_GCC_6350=m +CONFIG_SM_GCC_6375=m CONFIG_SM_GCC_8150=m CONFIG_SM_GCC_8250=m CONFIG_SM_GCC_8350=m @@ -10462,6 +10560,8 @@ CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=m CONFIG_SND_SOC_AMD_LEGACY_MACH=m CONFIG_SND_SOC_AMD_MACH_COMMON=m +CONFIG_SND_SOC_AMD_PS=m +CONFIG_SND_SOC_AMD_PS_MACH=m CONFIG_SND_SOC_AMD_RENOIR=m CONFIG_SND_SOC_AMD_RENOIR_MACH=m CONFIG_SND_SOC_AMD_RPL_ACP6x=m @@ -10470,6 +10570,7 @@ CONFIG_SND_SOC_AMD_ST_ES8336_MACH=m CONFIG_SND_SOC_AMD_VANGOGH_MACH=m CONFIG_SND_SOC_AMD_YC_MACH=m +CONFIG_SND_SOC_APPLE_MCA=m CONFIG_SND_SOC_APQ8016_SBC=m CONFIG_SND_SOC_ARIZONA=m CONFIG_SND_SOC_AW8738=m @@ -10498,11 +10599,13 @@ CONFIG_SND_SOC_CS4271_I2C=m CONFIG_SND_SOC_CS4271_SPI=m CONFIG_SND_SOC_CS42L42=m +CONFIG_SND_SOC_CS42L42_CORE=m CONFIG_SND_SOC_CS42L51=m CONFIG_SND_SOC_CS42L51_I2C=m CONFIG_SND_SOC_CS42L52=m CONFIG_SND_SOC_CS42L56=m CONFIG_SND_SOC_CS42L73=m +CONFIG_SND_SOC_CS42L83=m CONFIG_SND_SOC_CS42XX8=m CONFIG_SND_SOC_CS42XX8_I2C=m CONFIG_SND_SOC_CS43130=m @@ -10517,6 +10620,7 @@ CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m CONFIG_SND_SOC_ES8316=m +CONFIG_SND_SOC_ES8326=m CONFIG_SND_SOC_ES8328=m CONFIG_SND_SOC_ES8328_I2C=m CONFIG_SND_SOC_ES8328_SPI=m @@ -10795,6 +10899,7 @@ # CONFIG_SND_SOC_SAMSUNG is not set CONFIG_SND_SOC_SC7180=m CONFIG_SND_SOC_SC7280=m +CONFIG_SND_SOC_SC8280XP=m CONFIG_SND_SOC_SDM845=m CONFIG_SND_SOC_SDW_MOCKUP=m CONFIG_SND_SOC_SH4_FSI=m @@ -10810,6 +10915,7 @@ CONFIG_SND_SOC_SOF_ACPI_DEV=m CONFIG_SND_SOC_SOF_ALDERLAKE=m CONFIG_SND_SOC_SOF_AMD_COMMON=m +CONFIG_SND_SOC_SOF_AMD_REMBRANDT=m CONFIG_SND_SOC_SOF_AMD_RENOIR=m CONFIG_SND_SOC_SOF_AMD_TOPLEVEL=m CONFIG_SND_SOC_SOF_APOLLOLAKE=m @@ -10833,6 +10939,7 @@ CONFIG_SND_SOC_SOF_ICELAKE=m CONFIG_SND_SOC_SOF_IMX8=m CONFIG_SND_SOC_SOF_IMX8M=m +CONFIG_SND_SOC_SOF_IMX8ULP=m CONFIG_SND_SOC_SOF_IMX_COMMON=m CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y CONFIG_SND_SOC_SOF_INTEL_APL=m @@ -10843,12 +10950,14 @@ CONFIG_SND_SOC_SOF_INTEL_ICL=m CONFIG_SND_SOC_SOF_INTEL_IPC4=y CONFIG_SND_SOC_SOF_INTEL_MTL=m +CONFIG_SND_SOC_SOF_INTEL_SKL=m CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE=m CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE=m CONFIG_SND_SOC_SOF_INTEL_TGL=m CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y CONFIG_SND_SOC_SOF_IPC3=y CONFIG_SND_SOC_SOF_JASPERLAKE=m +CONFIG_SND_SOC_SOF_KABYLAKE=m CONFIG_SND_SOC_SOF_MERRIFIELD=m CONFIG_SND_SOC_SOF_METEORLAKE=m CONFIG_SND_SOC_SOF_MT8186=m @@ -10860,12 +10969,15 @@ CONFIG_SND_SOC_SOF_PCI=m CONFIG_SND_SOC_SOF_PCI_DEV=m CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE=y +CONFIG_SND_SOC_SOF_SKYLAKE=m CONFIG_SND_SOC_SOF_TIGERLAKE=m CONFIG_SND_SOC_SOF_TOPLEVEL=y CONFIG_SND_SOC_SOF_XTENSA=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_SPRD=m CONFIG_SND_SOC_SPRD_MCDT=m +CONFIG_SND_SOC_SRC4XXX=m +CONFIG_SND_SOC_SRC4XXX_I2C=m CONFIG_SND_SOC_SSM2305=m CONFIG_SND_SOC_SSM2518=m CONFIG_SND_SOC_SSM2602=m @@ -10996,6 +11108,7 @@ # CONFIG_SND_SUN4I_I2S is not set # CONFIG_SND_SUN4I_SPDIF is not set CONFIG_SND_SUN50I_CODEC_ANALOG=m +CONFIG_SND_SUN50I_DMIC=m CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m CONFIG_SND_SUN8I_CODEC=m CONFIG_SND_SUN8I_CODEC_ANALOG=m @@ -11058,6 +11171,7 @@ CONFIG_SOC_IMX7D=y CONFIG_SOC_IMX7D_CA7=y CONFIG_SOC_IMX7ULP=y +CONFIG_SOC_IMX9=m # CONFIG_SOC_LS1021A is not set CONFIG_SOC_MICROCHIP_POLARFIRE=y CONFIG_SOC_OMAP3430=y @@ -11069,6 +11183,7 @@ CONFIG_SOC_STARFIVE=y CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER=y CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER=y +CONFIG_SOC_TEGRA_CBB=m CONFIG_SOC_TEGRA_FLOWCTRL=y CONFIG_SOC_TEGRA_FUSE=y CONFIG_SOC_TEGRA_PMC=y @@ -11158,6 +11273,7 @@ CONFIG_SPI_MESON_SPICC=m CONFIG_SPI_MESON_SPIFC=m CONFIG_SPI_MICROCHIP_CORE=m +CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MT65XX=m CONFIG_SPI_MTK_NOR=m CONFIG_SPI_MTK_SNFI=m @@ -11212,13 +11328,13 @@ CONFIG_SPMI_PMIC_CLKDIV=m CONFIG_SPRD_COMMON_CLK=m CONFIG_SPRD_DMA=m -CONFIG_SPRD_EFUSE=m CONFIG_SPRD_IOMMU=m CONFIG_SPRD_MBOX=m CONFIG_SPRD_SC9860_CLK=m CONFIG_SPRD_SC9863A_CLK=m CONFIG_SPRD_THERMAL=m CONFIG_SPRD_TIMER=y +CONFIG_SPRD_UMS512_CLK=m CONFIG_SPRD_WATCHDOG=m CONFIG_SPS30=m CONFIG_SPS30_I2C=m @@ -11268,6 +11384,7 @@ CONFIG_STACK_VALIDATION=y # CONFIG_STAGING_BOARD is not set CONFIG_STAGING_MEDIA=y +# CONFIG_STAGING_MEDIA_DEPRECATED is not set # CONFIG_STATIC_CALL_SELFTEST is not set # CONFIG_STATIC_KEYS_SELFTEST is not set # CONFIG_STATIC_USERMODEHELPER is not set @@ -11540,6 +11657,7 @@ CONFIG_TEST_BPF=m # CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set # CONFIG_TEST_DIV64 is not set +# CONFIG_TEST_DYNAMIC_DEBUG is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_FPU is not set # CONFIG_TEST_FREE_PAGES is not set @@ -11664,6 +11782,7 @@ CONFIG_TI_DAVINCI_EMAC=m CONFIG_TI_DAVINCI_MDIO=y CONFIG_TI_DMA_CROSSBAR=y +CONFIG_TI_ECAP_CAPTURE=m CONFIG_TI_EDMA=y CONFIG_TI_EMIF=m CONFIG_TI_EMIF_SRAM=m @@ -11910,6 +12029,7 @@ CONFIG_TYPEC_STUSB160X=m CONFIG_TYPEC_TCPCI=m CONFIG_TYPEC_TCPCI_MAXIM=m +CONFIG_TYPEC_TCPCI_MT6370=m CONFIG_TYPEC_TCPM=m CONFIG_TYPEC_TPS6598X=m CONFIG_TYPEC_UCSI=m @@ -11936,6 +12056,8 @@ CONFIG_UBSAN_SHIFT=y # CONFIG_UBSAN_TRAP is not set # CONFIG_UBSAN_UNREACHABLE is not set +CONFIG_UBUNTU_HOST=m +CONFIG_UBUNTU_ODM_DRIVERS=y CONFIG_UCB1400_CORE=m CONFIG_UCC=y CONFIG_UCC_FAST=y @@ -11969,7 +12091,6 @@ CONFIG_UNICODE=y # CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set CONFIG_UNINLINE_SPIN_UNLOCK=y -CONFIG_UNIPHIER_EFUSE=m # CONFIG_UNIPHIER_MDMAC is not set # CONFIG_UNIPHIER_SYSTEM_BUS is not set # CONFIG_UNIPHIER_THERMAL is not set @@ -12509,6 +12630,7 @@ CONFIG_VDSO32=y CONFIG_VEML6030=m CONFIG_VEML6070=m +CONFIG_VERSION_SIGNATURE="" CONFIG_VETH=m CONFIG_VEXPRESS_CONFIG=y CONFIG_VF610_ADC=m @@ -12635,6 +12757,7 @@ CONFIG_VIDEO_CX88_VP3054=m CONFIG_VIDEO_DEV=m CONFIG_VIDEO_DT3155=m +CONFIG_VIDEO_DW100=m CONFIG_VIDEO_DW9714=m CONFIG_VIDEO_DW9768=m CONFIG_VIDEO_DW9807_VCM=m @@ -12786,8 +12909,6 @@ CONFIG_VIDEO_SAA7134_DVB=m CONFIG_VIDEO_SAA7134_GO7007=m CONFIG_VIDEO_SAA7134_RC=y -CONFIG_VIDEO_SAA7146=m -CONFIG_VIDEO_SAA7146_VV=m CONFIG_VIDEO_SAA7164=m CONFIG_VIDEO_SAA717X=m CONFIG_VIDEO_SAA7185=m @@ -13078,6 +13199,7 @@ CONFIG_X86_AMD_FREQ_SENSITIVITY=m CONFIG_X86_AMD_PLATFORM_DEVICE=y CONFIG_X86_AMD_PSTATE=y +# CONFIG_X86_AMD_PSTATE_UT is not set CONFIG_X86_ANDROID_TABLETS=m CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y CONFIG_X86_CHECK_BIOS_CORRUPTION=y @@ -13191,6 +13313,7 @@ CONFIG_XEN_PVHVM_GUEST=y CONFIG_XEN_PVHVM_SMP=y CONFIG_XEN_PV_DOM0=y +CONFIG_XEN_PV_MSR_SAFE=y CONFIG_XEN_PV_SMP=y CONFIG_XEN_SAVE_RESTORE=y CONFIG_XEN_SCRUB_PAGES_DEFAULT=y @@ -13301,6 +13424,7 @@ CONFIG_ZRAM_WRITEBACK=y CONFIG_ZSMALLOC=y # CONFIG_ZSMALLOC_STAT is not set +CONFIG_ZSTD_COMMON=y CONFIG_ZSTD_COMPRESS=m CONFIG_ZSTD_DECOMPRESS=y CONFIG_ZSWAP=y diff -Nru linux-6.0.6/debian.master/config/ppc64el/config.common.ppc64el linux-6.0.12/debian.master/config/ppc64el/config.common.ppc64el --- linux-6.0.6/debian.master/config/ppc64el/config.common.ppc64el 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/ppc64el/config.common.ppc64el 2023-01-18 18:27:39.000000000 +0000 @@ -13,9 +13,11 @@ CONFIG_ALTERA_STAPL=m CONFIG_ALTERA_TSE=m CONFIG_AMIGA_PARTITION=y +CONFIG_ANDROID_BINDER_IPC=m CONFIG_APDS9802ALS=m CONFIG_APPLICOM=m CONFIG_AQTION=m +CONFIG_ARCH_FORCE_MAX_ORDER=9 CONFIG_ARCH_MMAP_RND_BITS=28 CONFIG_ARCH_MMAP_RND_BITS_MAX=29 CONFIG_ARCH_MMAP_RND_BITS_MIN=14 @@ -167,7 +169,6 @@ CONFIG_FIREWIRE=m CONFIG_FIREWIRE_NOSY=m CONFIG_FIRMWARE_MEMMAP=y -CONFIG_FORCE_MAX_ZONEORDER=9 CONFIG_FORTIFY_SOURCE=y CONFIG_FPGA_BRIDGE=m CONFIG_FPGA_DFL=m @@ -194,6 +195,7 @@ CONFIG_GPIO_TWL6040=m CONFIG_GPIO_VIRTIO=m CONFIG_GPIO_XILINX=y +CONFIG_GP_PCI1XXXX=m CONFIG_GREYBUS=m CONFIG_HABANA_AI=m CONFIG_HAMACHI=m @@ -242,6 +244,7 @@ CONFIG_I2C_NVIDIA_GPU=m CONFIG_I2C_OCORES=m CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PCI1XXXX=m CONFIG_I2C_PIIX4=m CONFIG_I2C_SIMTEC=m CONFIG_I2C_SIS5595=m @@ -334,7 +337,6 @@ CONFIG_MFD_AXP20X_I2C=m CONFIG_MFD_BCM590XX=m CONFIG_MFD_BD9571MWV=m -CONFIG_MFD_CORE=y CONFIG_MFD_DA9062=m CONFIG_MFD_DA9063=y CONFIG_MFD_DA9150=m @@ -351,15 +353,18 @@ CONFIG_MFD_MENF21BMC=m CONFIG_MFD_MP2629=m CONFIG_MFD_MT6360=m +CONFIG_MFD_MT6370=m CONFIG_MFD_MT6397=m CONFIG_MFD_PCF50633=m CONFIG_MFD_RDC321X=m CONFIG_MFD_RETU=m CONFIG_MFD_RT4831=m CONFIG_MFD_RT5033=m +CONFIG_MFD_RT5120=m CONFIG_MFD_SI476X_CORE=m CONFIG_MFD_SKY81452=m CONFIG_MFD_SM501=m +CONFIG_MFD_SY7636A=m CONFIG_MFD_SYSCON=y CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_TI_LMU=m @@ -505,6 +510,7 @@ CONFIG_PPS_CLIENT_LDISC=m # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PSE_CONTROLLER=y # CONFIG_PSI_DEFAULT_DISABLED is not set CONFIG_PSTORE=y # CONFIG_PSTORE_CONSOLE is not set @@ -522,7 +528,6 @@ CONFIG_RAVE_SP_CORE=m CONFIG_RC_CORE=m CONFIG_REED_SOLOMON=m -CONFIG_REGMAP_I2C=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=m CONFIG_REGULATOR_TWL4030=m diff -Nru linux-6.0.6/debian.master/config/riscv64/config.common.riscv64 linux-6.0.12/debian.master/config/riscv64/config.common.riscv64 --- linux-6.0.6/debian.master/config/riscv64/config.common.riscv64 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/riscv64/config.common.riscv64 2023-01-18 18:27:39.000000000 +0000 @@ -13,6 +13,7 @@ CONFIG_ALTERA_STAPL=m CONFIG_ALTERA_TSE=m CONFIG_AMIGA_PARTITION=y +CONFIG_ANDROID_BINDER_IPC=m CONFIG_APDS9802ALS=m CONFIG_APPLICOM=m CONFIG_AQTION=m @@ -191,6 +192,7 @@ CONFIG_GPIO_TWL6040=m CONFIG_GPIO_VIRTIO=m # CONFIG_GPIO_XILINX is not set +CONFIG_GP_PCI1XXXX=m # CONFIG_GREYBUS is not set # CONFIG_HABANA_AI is not set CONFIG_HAMACHI=m @@ -238,6 +240,7 @@ CONFIG_I2C_NVIDIA_GPU=m CONFIG_I2C_OCORES=m CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PCI1XXXX=m CONFIG_I2C_PIIX4=m CONFIG_I2C_SIMTEC=m CONFIG_I2C_SIS5595=m @@ -291,6 +294,7 @@ CONFIG_JME=m CONFIG_JUMP_LABEL=y CONFIG_KARMA_PARTITION=y +# CONFIG_KERNEL_GZIP is not set CONFIG_KVM=m CONFIG_LAPB=m CONFIG_LCD_CLASS_DEVICE=m @@ -326,7 +330,6 @@ CONFIG_MFD_AXP20X_I2C=m CONFIG_MFD_BCM590XX=m CONFIG_MFD_BD9571MWV=m -CONFIG_MFD_CORE=y CONFIG_MFD_DA9062=m CONFIG_MFD_DA9063=y CONFIG_MFD_DA9150=m @@ -343,15 +346,18 @@ CONFIG_MFD_MENF21BMC=m CONFIG_MFD_MP2629=m CONFIG_MFD_MT6360=m +CONFIG_MFD_MT6370=m CONFIG_MFD_MT6397=m CONFIG_MFD_PCF50633=m CONFIG_MFD_RDC321X=m CONFIG_MFD_RETU=m CONFIG_MFD_RT4831=m CONFIG_MFD_RT5033=m +CONFIG_MFD_RT5120=m CONFIG_MFD_SI476X_CORE=m CONFIG_MFD_SKY81452=m CONFIG_MFD_SM501=m +CONFIG_MFD_SY7636A=m CONFIG_MFD_SYSCON=y CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_TI_LMU=m @@ -495,6 +501,7 @@ CONFIG_PPS_CLIENT_LDISC=m # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PSE_CONTROLLER=y # CONFIG_PSI_DEFAULT_DISABLED is not set CONFIG_PSTORE=y # CONFIG_PSTORE_CONSOLE is not set @@ -512,7 +519,6 @@ CONFIG_RAVE_SP_CORE=m CONFIG_RC_CORE=m CONFIG_REED_SOLOMON=m -CONFIG_REGMAP_I2C=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=m CONFIG_REGULATOR_TWL4030=m diff -Nru linux-6.0.6/debian.master/config/s390x/config.common.s390x linux-6.0.12/debian.master/config/s390x/config.common.s390x --- linux-6.0.6/debian.master/config/s390x/config.common.s390x 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/debian.master/config/s390x/config.common.s390x 2023-01-18 18:27:39.000000000 +0000 @@ -12,6 +12,7 @@ # CONFIG_ALTERA_STAPL is not set # CONFIG_ALTERA_TSE is not set # CONFIG_AMIGA_PARTITION is not set +# CONFIG_ANDROID_BINDER_IPC is not set # CONFIG_APDS9802ALS is not set # CONFIG_APPLICOM is not set # CONFIG_AQTION is not set @@ -176,6 +177,7 @@ # CONFIG_GPIO_SIOX is not set # CONFIG_GPIO_TPIC2810 is not set # CONFIG_GPIO_VIRTIO is not set +# CONFIG_GP_PCI1XXXX is not set # CONFIG_GREYBUS is not set # CONFIG_HABANA_AI is not set # CONFIG_HAMACHI is not set @@ -221,6 +223,7 @@ # CONFIG_I2C_NVIDIA_GPU is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PCI1XXXX is not set # CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set @@ -311,7 +314,6 @@ # CONFIG_MFD_AXP20X_I2C is not set # CONFIG_MFD_BCM590XX is not set # CONFIG_MFD_BD9571MWV is not set -CONFIG_MFD_CORE=m # CONFIG_MFD_DA9062 is not set # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set @@ -328,15 +330,18 @@ # CONFIG_MFD_MENF21BMC is not set # CONFIG_MFD_MP2629 is not set # CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6370 is not set # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_RDC321X is not set # CONFIG_MFD_RETU is not set # CONFIG_MFD_RT4831 is not set # CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RT5120 is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SY7636A is not set # CONFIG_MFD_SYSCON is not set # CONFIG_MFD_TI_AM335X_TSCADC is not set # CONFIG_MFD_TI_LMU is not set @@ -458,6 +463,7 @@ # CONFIG_PPS_CLIENT_LDISC is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PSE_CONTROLLER is not set CONFIG_PSI_DEFAULT_DISABLED=y # CONFIG_PSTORE is not set CONFIG_PTDUMP_DEBUGFS=y @@ -472,7 +478,6 @@ # CONFIG_RAPIDIO is not set # CONFIG_RAVE_SP_CORE is not set # CONFIG_RC_CORE is not set -CONFIG_REGMAP_I2C=m # CONFIG_REGULATOR is not set # CONFIG_REISERFS_FS is not set # CONFIG_REMOTEPROC is not set diff -Nru linux-6.0.6/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml linux-6.0.12/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml --- linux-6.0.6/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml 2023-01-18 18:27:39.000000000 +0000 @@ -62,13 +62,6 @@ description: Inform the driver that last channel will be used to sensor battery. - aspeed,trim-data-valid: - type: boolean - description: | - The ADC reference voltage can be calibrated to obtain the trimming - data which will be stored in otp. This property informs the driver that - the data store in the otp is valid. - required: - compatible - reg diff -Nru linux-6.0.6/Documentation/devicetree/bindings/net/engleder,tsnep.yaml linux-6.0.12/Documentation/devicetree/bindings/net/engleder,tsnep.yaml --- linux-6.0.6/Documentation/devicetree/bindings/net/engleder,tsnep.yaml 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/devicetree/bindings/net/engleder,tsnep.yaml 2023-01-18 18:27:39.000000000 +0000 @@ -28,7 +28,7 @@ nvmem-cells: true - nvmem-cells-names: true + nvmem-cell-names: true phy-connection-type: enum: diff -Nru linux-6.0.6/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml linux-6.0.12/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml --- linux-6.0.6/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml 2023-01-18 18:27:39.000000000 +0000 @@ -274,10 +274,6 @@ slew-rate: enum: [0, 1] - output-enable: - description: - This will internally disable the tri-state for MIO pins. - drive-strength: description: Selects the drive strength for MIO pins, in mA. diff -Nru linux-6.0.6/Documentation/driver-api/miscellaneous.rst linux-6.0.12/Documentation/driver-api/miscellaneous.rst --- linux-6.0.6/Documentation/driver-api/miscellaneous.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/driver-api/miscellaneous.rst 2023-01-18 18:27:39.000000000 +0000 @@ -16,12 +16,11 @@ 16x50 UART Driver ================= -.. kernel-doc:: drivers/tty/serial/serial_core.c - :export: - .. kernel-doc:: drivers/tty/serial/8250/8250_core.c :export: +See serial/driver.rst for related APIs. + Pulse-Width Modulation (PWM) ============================ diff -Nru linux-6.0.6/Documentation/process/code-of-conduct-interpretation.rst linux-6.0.12/Documentation/process/code-of-conduct-interpretation.rst --- linux-6.0.6/Documentation/process/code-of-conduct-interpretation.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/process/code-of-conduct-interpretation.rst 2023-01-18 18:27:39.000000000 +0000 @@ -51,7 +51,7 @@ uncertain how to handle situations that come up. It will not be considered a violation report unless you want it to be. If you are uncertain about approaching the TAB or any other maintainers, please -reach out to our conflict mediator, Joanna Lee . +reach out to our conflict mediator, Joanna Lee . In the end, "be kind to each other" is really what the end goal is for everybody. We know everyone is human and we all fail at times, but the diff -Nru linux-6.0.6/Documentation/process/howto.rst linux-6.0.12/Documentation/process/howto.rst --- linux-6.0.6/Documentation/process/howto.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/process/howto.rst 2023-01-18 18:27:39.000000000 +0000 @@ -36,7 +36,7 @@ - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] The kernel is written using GNU C and the GNU toolchain. While it -adheres to the ISO C89 standard, it uses a number of extensions that are +adheres to the ISO C11 standard, it uses a number of extensions that are not featured in the standard. The kernel is a freestanding C environment, with no reliance on the standard C library, so some portions of the C standard are not supported. Arbitrary long long diff -Nru linux-6.0.6/Documentation/trace/histogram.rst linux-6.0.12/Documentation/trace/histogram.rst --- linux-6.0.6/Documentation/trace/histogram.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/trace/histogram.rst 2023-01-18 18:27:39.000000000 +0000 @@ -39,7 +39,7 @@ will use the event's kernel stacktrace as the key. The keywords 'keys' or 'key' can be used to specify keys, and the keywords 'values', 'vals', or 'val' can be used to specify values. Compound - keys consisting of up to two fields can be specified by the 'keys' + keys consisting of up to three fields can be specified by the 'keys' keyword. Hashing a compound key produces a unique entry in the table for each unique combination of component keys, and can be useful for providing more fine-grained summaries of event data. diff -Nru linux-6.0.6/Documentation/translations/it_IT/process/howto.rst linux-6.0.12/Documentation/translations/it_IT/process/howto.rst --- linux-6.0.6/Documentation/translations/it_IT/process/howto.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/translations/it_IT/process/howto.rst 2023-01-18 18:27:39.000000000 +0000 @@ -44,7 +44,7 @@ - "C: A Reference Manual" di Harbison and Steele [Prentice Hall] Il kernel è stato scritto usando GNU C e la toolchain GNU. -Sebbene si attenga allo standard ISO C89, esso utilizza una serie di +Sebbene si attenga allo standard ISO C11, esso utilizza una serie di estensioni che non sono previste in questo standard. Il kernel è un ambiente C indipendente, che non ha alcuna dipendenza dalle librerie C standard, così alcune parti del C standard non sono supportate. diff -Nru linux-6.0.6/Documentation/translations/ja_JP/howto.rst linux-6.0.12/Documentation/translations/ja_JP/howto.rst --- linux-6.0.6/Documentation/translations/ja_JP/howto.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/translations/ja_JP/howto.rst 2023-01-18 18:27:39.000000000 +0000 @@ -65,7 +65,7 @@ - 『新・詳説 C 言語 H&S リファレンス』 (サミュエル P ハービソン/ガイ L スティール共著 斉藤 信男監訳)[ソフトバンク] カーネルは GNU C と GNU ツールチェインを使って書かれています。カーネル -は ISO C89 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って +は ISO C11 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って います。カーネルは標準 C ライブラリに依存しない、C 言語非依存環境です。 そのため、C の標準の中で使えないものもあります。特に任意の long long の除算や浮動小数点は使えません。カーネルがツールチェインや C 言語拡張 diff -Nru linux-6.0.6/Documentation/translations/ko_KR/howto.rst linux-6.0.12/Documentation/translations/ko_KR/howto.rst --- linux-6.0.6/Documentation/translations/ko_KR/howto.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/translations/ko_KR/howto.rst 2023-01-18 18:27:39.000000000 +0000 @@ -62,7 +62,7 @@ - "Practical C Programming" by Steve Oualline [O'Reilly] - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] -커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C89 표준을 +커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C11 표준을 따르는 반면 표준에 있지 않은 많은 확장기능도 가지고 있다. 커널은 표준 C 라이브러리와는 관계없이 freestanding C 환경이어서 C 표준의 일부는 지원되지 않는다. 임의의 long long 나누기나 floating point는 지원되지 않는다. diff -Nru linux-6.0.6/Documentation/translations/zh_CN/process/howto.rst linux-6.0.12/Documentation/translations/zh_CN/process/howto.rst --- linux-6.0.6/Documentation/translations/zh_CN/process/howto.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/translations/zh_CN/process/howto.rst 2023-01-18 18:27:39.000000000 +0000 @@ -45,7 +45,7 @@ - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] 《C语言参考手册(原书第5版)》(邱仲潘 等译)[机械工业出版社] -Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C89标准,但也用到了一些 +Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C11标准,但也用到了一些 标准中没有定义的扩展。内核是自给自足的C环境,不依赖于标准C库的支持,所以 并不支持C标准中的部分定义。比如long long类型的大数除法和浮点运算就不允许 使用。有时候确实很难弄清楚内核对工具链的要求和它所使用的扩展,不幸的是目 diff -Nru linux-6.0.6/Documentation/translations/zh_TW/process/howto.rst linux-6.0.12/Documentation/translations/zh_TW/process/howto.rst --- linux-6.0.6/Documentation/translations/zh_TW/process/howto.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/translations/zh_TW/process/howto.rst 2023-01-18 18:27:39.000000000 +0000 @@ -48,7 +48,7 @@ - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] 《C語言參考手冊(原書第5版)》(邱仲潘 等譯)[機械工業出版社] -Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C89標準,但也用到了一些 +Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C11標準,但也用到了一些 標準中沒有定義的擴展。內核是自給自足的C環境,不依賴於標準C庫的支持,所以 並不支持C標準中的部分定義。比如long long類型的大數除法和浮點運算就不允許 使用。有時候確實很難弄清楚內核對工具鏈的要求和它所使用的擴展,不幸的是目 diff -Nru linux-6.0.6/Documentation/virt/kvm/devices/vm.rst linux-6.0.12/Documentation/virt/kvm/devices/vm.rst --- linux-6.0.6/Documentation/virt/kvm/devices/vm.rst 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Documentation/virt/kvm/devices/vm.rst 2023-01-18 18:27:39.000000000 +0000 @@ -215,6 +215,7 @@ :Parameters: address of a buffer in user space to store the data (u8) to :Returns: -EFAULT if the given address is not accessible from kernel space; -EINVAL if setting the TOD clock extension to != 0 is not supported + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) 3.2. ATTRIBUTE: KVM_S390_VM_TOD_LOW ----------------------------------- @@ -224,6 +225,7 @@ :Parameters: address of a buffer in user space to store the data (u64) to :Returns: -EFAULT if the given address is not accessible from kernel space + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) 3.3. ATTRIBUTE: KVM_S390_VM_TOD_EXT ----------------------------------- @@ -237,6 +239,7 @@ (kvm_s390_vm_tod_clock) to :Returns: -EFAULT if the given address is not accessible from kernel space; -EINVAL if setting the TOD clock extension to != 0 is not supported + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) 4. GROUP: KVM_S390_VM_CRYPTO ============================ diff -Nru linux-6.0.6/drivers/accessibility/speakup/main.c linux-6.0.12/drivers/accessibility/speakup/main.c --- linux-6.0.6/drivers/accessibility/speakup/main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/accessibility/speakup/main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1778,7 +1778,7 @@ { unsigned long flags; - if (!speakup_console[vc->vc_num] || spk_parked) + if (!speakup_console[vc->vc_num] || spk_parked || !synth) return; if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) /* Speakup output, discard */ diff -Nru linux-6.0.6/drivers/accessibility/speakup/utils.h linux-6.0.12/drivers/accessibility/speakup/utils.h --- linux-6.0.6/drivers/accessibility/speakup/utils.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/accessibility/speakup/utils.h 2023-01-18 18:27:39.000000000 +0000 @@ -54,7 +54,7 @@ static inline struct st_key *hash_name(char *name) { - u_char *pn = (u_char *)name; + unsigned char *pn = (unsigned char *)name; int hash = 0; while (*pn) { diff -Nru linux-6.0.6/drivers/acpi/acpi_pcc.c linux-6.0.12/drivers/acpi/acpi_pcc.c --- linux-6.0.6/drivers/acpi/acpi_pcc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/acpi/acpi_pcc.c 2023-01-18 18:27:39.000000000 +0000 @@ -27,7 +27,7 @@ * Arbitrary retries in case the remote processor is slow to respond * to PCC commands */ -#define PCC_CMD_WAIT_RETRIES_NUM 500 +#define PCC_CMD_WAIT_RETRIES_NUM 500ULL struct pcc_data { struct pcc_mbox_chan *pcc_chan; diff -Nru linux-6.0.6/drivers/acpi/apei/ghes.c linux-6.0.12/drivers/acpi/apei/ghes.c --- linux-6.0.6/drivers/acpi/apei/ghes.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/acpi/apei/ghes.c 2023-01-18 18:27:39.000000000 +0000 @@ -163,7 +163,7 @@ clear_fixmap(fixmap_idx); } -int ghes_estatus_pool_init(int num_ghes) +int ghes_estatus_pool_init(unsigned int num_ghes) { unsigned long addr, len; int rc; diff -Nru linux-6.0.6/drivers/acpi/numa/hmat.c linux-6.0.12/drivers/acpi/numa/hmat.c --- linux-6.0.6/drivers/acpi/numa/hmat.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/acpi/numa/hmat.c 2023-01-18 18:27:39.000000000 +0000 @@ -563,17 +563,26 @@ { struct memory_initiator *ia; struct memory_initiator *ib; - unsigned long *p_nodes = priv; ia = list_entry(a, struct memory_initiator, node); ib = list_entry(b, struct memory_initiator, node); - set_bit(ia->processor_pxm, p_nodes); - set_bit(ib->processor_pxm, p_nodes); - return ia->processor_pxm - ib->processor_pxm; } +static int initiators_to_nodemask(unsigned long *p_nodes) +{ + struct memory_initiator *initiator; + + if (list_empty(&initiators)) + return -ENXIO; + + list_for_each_entry(initiator, &initiators, node) + set_bit(initiator->processor_pxm, p_nodes); + + return 0; +} + static void hmat_register_target_initiators(struct memory_target *target) { static DECLARE_BITMAP(p_nodes, MAX_NUMNODES); @@ -610,7 +619,10 @@ * initiators. */ bitmap_zero(p_nodes, MAX_NUMNODES); - list_sort(p_nodes, &initiators, initiator_cmp); + list_sort(NULL, &initiators, initiator_cmp); + if (initiators_to_nodemask(p_nodes) < 0) + return; + if (!access0done) { for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { loc = localities_types[i]; @@ -644,8 +656,9 @@ /* Access 1 ignores Generic Initiators */ bitmap_zero(p_nodes, MAX_NUMNODES); - list_sort(p_nodes, &initiators, initiator_cmp); - best = 0; + if (initiators_to_nodemask(p_nodes) < 0) + return; + for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { loc = localities_types[i]; if (!loc) diff -Nru linux-6.0.6/drivers/acpi/numa/srat.c linux-6.0.12/drivers/acpi/numa/srat.c --- linux-6.0.6/drivers/acpi/numa/srat.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/acpi/numa/srat.c 2023-01-18 18:27:39.000000000 +0000 @@ -327,6 +327,7 @@ pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n", node, start, end); } + node_set(node, numa_nodes_parsed); /* Set the next available fake_pxm value */ (*fake_pxm)++; diff -Nru linux-6.0.6/drivers/acpi/scan.c linux-6.0.12/drivers/acpi/scan.c --- linux-6.0.6/drivers/acpi/scan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/acpi/scan.c 2023-01-18 18:27:39.000000000 +0000 @@ -796,6 +796,7 @@ static const char * const acpi_ignore_dep_ids[] = { "PNP0D80", /* Windows-compatible System Power Management Controller */ "INT33BD", /* Intel Baytrail Mailbox Device */ + "LATT2021", /* Lattice FW Update Client Driver */ NULL }; diff -Nru linux-6.0.6/drivers/acpi/video_detect.c linux-6.0.12/drivers/acpi/video_detect.c --- linux-6.0.6/drivers/acpi/video_detect.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/acpi/video_detect.c 2023-01-18 18:27:39.000000000 +0000 @@ -579,6 +579,20 @@ }, }, /* + * Models which have nvidia-ec-wmi support, but should not use it. + * Note this indicates a likely firmware bug on these models and should + * be revisited if/when Linux gets support for dynamic mux mode. + */ + { + .callback = video_detect_force_native, + /* Dell G15 5515 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"), + }, + }, + + /* * Desktops which falsely report a backlight and which our heuristics * for this do not catch. */ diff -Nru linux-6.0.6/drivers/acpi/x86/utils.c linux-6.0.12/drivers/acpi/x86/utils.c --- linux-6.0.6/drivers/acpi/x86/utils.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/acpi/x86/utils.c 2023-01-18 18:27:39.000000000 +0000 @@ -219,6 +219,12 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"), } }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5625"), + } + }, {} }; diff -Nru linux-6.0.6/drivers/android/binder_alloc.c linux-6.0.12/drivers/android/binder_alloc.c --- linux-6.0.6/drivers/android/binder_alloc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/android/binder_alloc.c 2023-01-18 18:27:39.000000000 +0000 @@ -760,6 +760,12 @@ const char *failure_string; struct binder_buffer *buffer; + if (unlikely(vma->vm_mm != alloc->vma_vm_mm)) { + ret = -EINVAL; + failure_string = "invalid vma->vm_mm"; + goto err_invalid_mm; + } + mutex_lock(&binder_alloc_mmap_lock); if (alloc->buffer_size) { ret = -EBUSY; @@ -806,6 +812,7 @@ alloc->buffer_size = 0; err_already_mapped: mutex_unlock(&binder_alloc_mmap_lock); +err_invalid_mm: binder_alloc_debug(BINDER_DEBUG_USER_ERROR, "%s: %d %lx-%lx %s failed %d\n", __func__, alloc->pid, vma->vm_start, vma->vm_end, diff -Nru linux-6.0.6/drivers/ata/libata-scsi.c linux-6.0.12/drivers/ata/libata-scsi.c --- linux-6.0.6/drivers/ata/libata-scsi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/ata/libata-scsi.c 2023-01-18 18:27:39.000000000 +0000 @@ -3266,6 +3266,7 @@ case REPORT_LUNS: case REQUEST_SENSE: case SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE_16: case REZERO_UNIT: case SEEK_6: case SEEK_10: @@ -3924,6 +3925,7 @@ return ata_scsi_write_same_xlat; case SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE_16: if (ata_try_flush_cache(dev)) return ata_scsi_flush_xlat; break; @@ -3964,9 +3966,19 @@ int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) { + struct ata_port *ap = dev->link->ap; u8 scsi_op = scmd->cmnd[0]; ata_xlat_func_t xlat_func; + /* + * scsi_queue_rq() will defer commands if scsi_host_in_recovery(). + * However, this check is done without holding the ap->lock (a libata + * specific lock), so we can have received an error irq since then, + * therefore we must check if EH is pending, while holding ap->lock. + */ + if (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS)) + return SCSI_MLQUEUE_DEVICE_BUSY; + if (unlikely(!scmd->cmd_len)) goto bad_cdb_len; @@ -4147,6 +4159,7 @@ * turning this into a no-op. */ case SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE_16: fallthrough; /* no-op's, complete with success */ diff -Nru linux-6.0.6/drivers/ata/libata-transport.c linux-6.0.12/drivers/ata/libata-transport.c --- linux-6.0.6/drivers/ata/libata-transport.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/ata/libata-transport.c 2023-01-18 18:27:39.000000000 +0000 @@ -301,7 +301,9 @@ pm_runtime_enable(dev); pm_runtime_forbid(dev); - transport_add_device(dev); + error = transport_add_device(dev); + if (error) + goto tport_transport_add_err; transport_configure_device(dev); error = ata_tlink_add(&ap->link); @@ -312,12 +314,12 @@ tport_link_err: transport_remove_device(dev); + tport_transport_add_err: device_del(dev); tport_err: transport_destroy_device(dev); put_device(dev); - ata_host_put(ap->host); return error; } @@ -456,7 +458,9 @@ goto tlink_err; } - transport_add_device(dev); + error = transport_add_device(dev); + if (error) + goto tlink_transport_err; transport_configure_device(dev); ata_for_each_dev(ata_dev, link, ALL) { @@ -471,6 +475,7 @@ ata_tdev_delete(ata_dev); } transport_remove_device(dev); + tlink_transport_err: device_del(dev); tlink_err: transport_destroy_device(dev); @@ -708,7 +713,13 @@ return error; } - transport_add_device(dev); + error = transport_add_device(dev); + if (error) { + device_del(dev); + ata_tdev_free(ata_dev); + return error; + } + transport_configure_device(dev); return 0; } diff -Nru linux-6.0.6/drivers/ata/pata_legacy.c linux-6.0.12/drivers/ata/pata_legacy.c --- linux-6.0.6/drivers/ata/pata_legacy.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/ata/pata_legacy.c 2023-01-18 18:27:39.000000000 +0000 @@ -315,9 +315,10 @@ outb(inb(0x1F4) & 0x07, 0x1F4); rt = inb(0x1F3); - rt &= 0x07 << (3 * adev->devno); + rt &= ~(0x07 << (3 * !adev->devno)); if (pio) - rt |= (1 + 3 * pio) << (3 * adev->devno); + rt |= (1 + 3 * pio) << (3 * !adev->devno); + outb(rt, 0x1F3); udelay(100); outb(inb(0x1F2) | 0x01, 0x1F2); diff -Nru linux-6.0.6/drivers/ata/pata_palmld.c linux-6.0.12/drivers/ata/pata_palmld.c --- linux-6.0.6/drivers/ata/pata_palmld.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/ata/pata_palmld.c 2023-01-18 18:27:39.000000000 +0000 @@ -63,8 +63,8 @@ /* remap drive's physical memory address */ mem = devm_platform_ioremap_resource(pdev, 0); - if (!mem) - return -ENOMEM; + if (IS_ERR(mem)) + return PTR_ERR(mem); /* request and activate power and reset GPIOs */ lda->power = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH); diff -Nru linux-6.0.6/drivers/base/power/domain.c linux-6.0.12/drivers/base/power/domain.c --- linux-6.0.6/drivers/base/power/domain.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/base/power/domain.c 2023-01-18 18:27:39.000000000 +0000 @@ -2950,6 +2950,10 @@ np = it.node; if (!of_match_node(idle_state_match, np)) continue; + + if (!of_device_is_available(np)) + continue; + if (states) { ret = genpd_parse_state(&states[i], np); if (ret) { diff -Nru linux-6.0.6/drivers/block/drbd/drbd_main.c linux-6.0.12/drivers/block/drbd/drbd_main.c --- linux-6.0.6/drivers/block/drbd/drbd_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/block/drbd/drbd_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -2672,7 +2672,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor) { struct drbd_resource *resource = adm_ctx->resource; - struct drbd_connection *connection; + struct drbd_connection *connection, *n; struct drbd_device *device; struct drbd_peer_device *peer_device, *tmp_peer_device; struct gendisk *disk; @@ -2789,7 +2789,7 @@ return NO_ERROR; out_idr_remove_from_resource: - for_each_connection(connection, resource) { + for_each_connection_safe(connection, n, resource) { peer_device = idr_remove(&connection->peer_devices, vnr); if (peer_device) kref_put(&connection->kref, drbd_destroy_connection); diff -Nru linux-6.0.6/drivers/block/ublk_drv.c linux-6.0.12/drivers/block/ublk_drv.c --- linux-6.0.6/drivers/block/ublk_drv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/block/ublk_drv.c 2023-01-18 18:27:39.000000000 +0000 @@ -1507,6 +1507,9 @@ */ ub->dev_info.flags &= UBLK_F_ALL; + if (!IS_BUILTIN(CONFIG_BLK_DEV_UBLK)) + ub->dev_info.flags |= UBLK_F_URING_CMD_COMP_IN_TASK; + /* We are not ready to support zero copy */ ub->dev_info.flags &= ~UBLK_F_SUPPORT_ZERO_COPY; diff -Nru linux-6.0.6/drivers/bluetooth/virtio_bt.c linux-6.0.12/drivers/bluetooth/virtio_bt.c --- linux-6.0.6/drivers/bluetooth/virtio_bt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/bluetooth/virtio_bt.c 2023-01-18 18:27:39.000000000 +0000 @@ -219,7 +219,7 @@ if (!skb) return; - skb->len = len; + skb_put(skb, len); virtbt_rx_handle(vbt, skb); if (virtbt_add_inbuf(vbt) < 0) diff -Nru linux-6.0.6/drivers/bus/intel-ixp4xx-eb.c linux-6.0.12/drivers/bus/intel-ixp4xx-eb.c --- linux-6.0.6/drivers/bus/intel-ixp4xx-eb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/bus/intel-ixp4xx-eb.c 2023-01-18 18:27:39.000000000 +0000 @@ -49,7 +49,7 @@ #define IXP4XX_EXP_SIZE_SHIFT 10 #define IXP4XX_EXP_CNFG_0 BIT(9) /* Always zero */ #define IXP43X_EXP_SYNC_INTEL BIT(8) /* Only on IXP43x */ -#define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x */ +#define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x, dangerous to touch on IXP42x */ #define IXP4XX_EXP_BYTE_RD16 BIT(6) #define IXP4XX_EXP_HRDY_POL BIT(5) /* Only on IXP42x */ #define IXP4XX_EXP_MUX_EN BIT(4) @@ -57,8 +57,6 @@ #define IXP4XX_EXP_WORD BIT(2) /* Always zero */ #define IXP4XX_EXP_WR_EN BIT(1) #define IXP4XX_EXP_BYTE_EN BIT(0) -#define IXP42X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(8)|BIT(7)|IXP4XX_EXP_WORD) -#define IXP43X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(5)|IXP4XX_EXP_WORD) #define IXP4XX_EXP_CNFG0 0x20 #define IXP4XX_EXP_CNFG0_MEM_MAP BIT(31) @@ -252,10 +250,9 @@ cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT; } - if (eb->is_42x) - cs_cfg &= ~IXP42X_RESERVED; if (eb->is_43x) { - cs_cfg &= ~IXP43X_RESERVED; + /* Should always be zero */ + cs_cfg &= ~IXP4XX_EXP_WORD; /* * This bit for Intel strata flash is currently unused, but let's * report it if we find one. diff -Nru linux-6.0.6/drivers/bus/sunxi-rsb.c linux-6.0.12/drivers/bus/sunxi-rsb.c --- linux-6.0.6/drivers/bus/sunxi-rsb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/bus/sunxi-rsb.c 2023-01-18 18:27:39.000000000 +0000 @@ -267,6 +267,9 @@ /* common code that starts a transfer */ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) { + u32 int_mask, status; + bool timeout; + if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { dev_dbg(rsb->dev, "RSB transfer still in progress\n"); return -EBUSY; @@ -274,13 +277,23 @@ reinit_completion(&rsb->complete); - writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER, - rsb->regs + RSB_INTE); + int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; + writel(int_mask, rsb->regs + RSB_INTE); writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, rsb->regs + RSB_CTRL); - if (!wait_for_completion_io_timeout(&rsb->complete, - msecs_to_jiffies(100))) { + if (irqs_disabled()) { + timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, + status, (status & int_mask), + 10, 100000); + writel(status, rsb->regs + RSB_INTS); + } else { + timeout = !wait_for_completion_io_timeout(&rsb->complete, + msecs_to_jiffies(100)); + status = rsb->status; + } + + if (timeout) { dev_dbg(rsb->dev, "RSB timeout\n"); /* abort the transfer */ @@ -292,18 +305,18 @@ return -ETIMEDOUT; } - if (rsb->status & RSB_INTS_LOAD_BSY) { + if (status & RSB_INTS_LOAD_BSY) { dev_dbg(rsb->dev, "RSB busy\n"); return -EBUSY; } - if (rsb->status & RSB_INTS_TRANS_ERR) { - if (rsb->status & RSB_INTS_TRANS_ERR_ACK) { + if (status & RSB_INTS_TRANS_ERR) { + if (status & RSB_INTS_TRANS_ERR_ACK) { dev_dbg(rsb->dev, "RSB slave nack\n"); return -EINVAL; } - if (rsb->status & RSB_INTS_TRANS_ERR_DATA) { + if (status & RSB_INTS_TRANS_ERR_DATA) { dev_dbg(rsb->dev, "RSB transfer data error\n"); return -EIO; } @@ -812,14 +825,6 @@ return 0; } -static void sunxi_rsb_shutdown(struct platform_device *pdev) -{ - struct sunxi_rsb *rsb = platform_get_drvdata(pdev); - - pm_runtime_disable(&pdev->dev); - sunxi_rsb_hw_exit(rsb); -} - static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = { SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend, sunxi_rsb_runtime_resume, NULL) @@ -835,7 +840,6 @@ static struct platform_driver sunxi_rsb_driver = { .probe = sunxi_rsb_probe, .remove = sunxi_rsb_remove, - .shutdown = sunxi_rsb_shutdown, .driver = { .name = RSB_CTRL_NAME, .of_match_table = sunxi_rsb_of_match_table, diff -Nru linux-6.0.6/drivers/char/hw_random/bcm2835-rng.c linux-6.0.12/drivers/char/hw_random/bcm2835-rng.c --- linux-6.0.6/drivers/char/hw_random/bcm2835-rng.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/char/hw_random/bcm2835-rng.c 2023-01-18 18:27:39.000000000 +0000 @@ -71,7 +71,7 @@ while ((rng_readl(priv, RNG_STATUS) >> 24) == 0) { if (!wait) return 0; - cpu_relax(); + hwrng_msleep(rng, 1000); } num_words = rng_readl(priv, RNG_STATUS) >> 24; diff -Nru linux-6.0.6/drivers/char/random.c linux-6.0.12/drivers/char/random.c --- linux-6.0.6/drivers/char/random.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/char/random.c 2023-01-18 18:27:39.000000000 +0000 @@ -793,13 +793,13 @@ #endif for (i = 0, arch_bits = sizeof(entropy) * 8; i < ARRAY_SIZE(entropy);) { - longs = arch_get_random_seed_longs(entropy, ARRAY_SIZE(entropy) - i); + longs = arch_get_random_seed_longs_early(entropy, ARRAY_SIZE(entropy) - i); if (longs) { _mix_pool_bytes(entropy, sizeof(*entropy) * longs); i += longs; continue; } - longs = arch_get_random_longs(entropy, ARRAY_SIZE(entropy) - i); + longs = arch_get_random_longs_early(entropy, ARRAY_SIZE(entropy) - i); if (longs) { _mix_pool_bytes(entropy, sizeof(*entropy) * longs); i += longs; diff -Nru linux-6.0.6/drivers/char/tpm/tpm-interface.c linux-6.0.12/drivers/char/tpm/tpm-interface.c --- linux-6.0.6/drivers/char/tpm/tpm-interface.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/char/tpm/tpm-interface.c 2023-01-18 18:27:39.000000000 +0000 @@ -401,13 +401,14 @@ !pm_suspend_via_firmware()) goto suspended; - if (!tpm_chip_start(chip)) { + rc = tpm_try_get_ops(chip); + if (!rc) { if (chip->flags & TPM_CHIP_FLAG_TPM2) tpm2_shutdown(chip, TPM2_SU_STATE); else rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); - tpm_chip_stop(chip); + tpm_put_ops(chip); } suspended: diff -Nru linux-6.0.6/drivers/clk/at91/at91rm9200.c linux-6.0.12/drivers/clk/at91/at91rm9200.c --- linux-6.0.6/drivers/clk/at91/at91rm9200.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/at91/at91rm9200.c 2023-01-18 18:27:39.000000000 +0000 @@ -40,7 +40,7 @@ }; static const struct sck at91rm9200_systemck[] = { - { .n = "udpck", .p = "usbck", .id = 2 }, + { .n = "udpck", .p = "usbck", .id = 1 }, { .n = "uhpck", .p = "usbck", .id = 4 }, { .n = "pck0", .p = "prog0", .id = 8 }, { .n = "pck1", .p = "prog1", .id = 9 }, diff -Nru linux-6.0.6/drivers/clk/clk-renesas-pcie.c linux-6.0.12/drivers/clk/clk-renesas-pcie.c --- linux-6.0.6/drivers/clk/clk-renesas-pcie.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/clk-renesas-pcie.c 2023-01-18 18:27:39.000000000 +0000 @@ -90,13 +90,66 @@ .n_yes_ranges = ARRAY_SIZE(rs9_writeable_ranges), }; +static int rs9_regmap_i2c_write(void *context, + unsigned int reg, unsigned int val) +{ + struct i2c_client *i2c = context; + const u8 data[3] = { reg, 1, val }; + const int count = ARRAY_SIZE(data); + int ret; + + ret = i2c_master_send(i2c, data, count); + if (ret == count) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + +static int rs9_regmap_i2c_read(void *context, + unsigned int reg, unsigned int *val) +{ + struct i2c_client *i2c = context; + struct i2c_msg xfer[2]; + u8 txdata = reg; + u8 rxdata[2]; + int ret; + + xfer[0].addr = i2c->addr; + xfer[0].flags = 0; + xfer[0].len = 1; + xfer[0].buf = (void *)&txdata; + + xfer[1].addr = i2c->addr; + xfer[1].flags = I2C_M_RD; + xfer[1].len = 2; + xfer[1].buf = (void *)rxdata; + + ret = i2c_transfer(i2c->adapter, xfer, 2); + if (ret < 0) + return ret; + if (ret != 2) + return -EIO; + + /* + * Byte 0 is transfer length, which is always 1 due + * to BCP register programming to 1 in rs9_probe(), + * ignore it and use data from Byte 1. + */ + *val = rxdata[1]; + return 0; +} + static const struct regmap_config rs9_regmap_config = { .reg_bits = 8, .val_bits = 8, - .cache_type = REGCACHE_FLAT, - .max_register = 0x8, + .cache_type = REGCACHE_NONE, + .max_register = RS9_REG_BCP, .rd_table = &rs9_readable_table, .wr_table = &rs9_writeable_table, + .reg_write = rs9_regmap_i2c_write, + .reg_read = rs9_regmap_i2c_read, }; static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx) @@ -242,11 +295,17 @@ return ret; } - rs9->regmap = devm_regmap_init_i2c(client, &rs9_regmap_config); + rs9->regmap = devm_regmap_init(&client->dev, NULL, + client, &rs9_regmap_config); if (IS_ERR(rs9->regmap)) return dev_err_probe(&client->dev, PTR_ERR(rs9->regmap), "Failed to allocate register map\n"); + /* Always read back 1 Byte via I2C */ + ret = regmap_write(rs9->regmap, RS9_REG_BCP, 1); + if (ret < 0) + return ret; + /* Register clock */ for (i = 0; i < rs9->chip_info->num_clks; i++) { snprintf(name, 5, "DIF%d", i); diff -Nru linux-6.0.6/drivers/clk/qcom/gcc-sc7280.c linux-6.0.12/drivers/clk/qcom/gcc-sc7280.c --- linux-6.0.6/drivers/clk/qcom/gcc-sc7280.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/qcom/gcc-sc7280.c 2023-01-18 18:27:39.000000000 +0000 @@ -3467,6 +3467,7 @@ regmap_update_bits(regmap, 0x28004, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x28014, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13)); ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, ARRAY_SIZE(gcc_dfs_clocks)); diff -Nru linux-6.0.6/drivers/clk/qcom/gcc-sc8280xp.c linux-6.0.12/drivers/clk/qcom/gcc-sc8280xp.c --- linux-6.0.6/drivers/clk/qcom/gcc-sc8280xp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/qcom/gcc-sc8280xp.c 2023-01-18 18:27:39.000000000 +0000 @@ -5364,6 +5364,8 @@ .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_1_card_clkref_clk", + .parent_data = &gcc_parent_data_tcxo, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -5432,6 +5434,8 @@ .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_card_clkref_clk", + .parent_data = &gcc_parent_data_tcxo, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -5848,6 +5852,8 @@ .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_ref_clkref_clk", + .parent_data = &gcc_parent_data_tcxo, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, diff -Nru linux-6.0.6/drivers/clk/qcom/gdsc.c linux-6.0.12/drivers/clk/qcom/gdsc.c --- linux-6.0.6/drivers/clk/qcom/gdsc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/qcom/gdsc.c 2023-01-18 18:27:39.000000000 +0000 @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -56,22 +55,6 @@ GDSC_ON }; -static int gdsc_pm_runtime_get(struct gdsc *sc) -{ - if (!sc->dev) - return 0; - - return pm_runtime_resume_and_get(sc->dev); -} - -static int gdsc_pm_runtime_put(struct gdsc *sc) -{ - if (!sc->dev) - return 0; - - return pm_runtime_put_sync(sc->dev); -} - /* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */ static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status) { @@ -271,8 +254,9 @@ regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); } -static int _gdsc_enable(struct gdsc *sc) +static int gdsc_enable(struct generic_pm_domain *domain) { + struct gdsc *sc = domain_to_gdsc(domain); int ret; if (sc->pwrsts == PWRSTS_ON) @@ -328,22 +312,11 @@ return 0; } -static int gdsc_enable(struct generic_pm_domain *domain) +static int gdsc_disable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; - ret = gdsc_pm_runtime_get(sc); - if (ret) - return ret; - - return _gdsc_enable(sc); -} - -static int _gdsc_disable(struct gdsc *sc) -{ - int ret; - if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -378,18 +351,6 @@ return 0; } -static int gdsc_disable(struct generic_pm_domain *domain) -{ - struct gdsc *sc = domain_to_gdsc(domain); - int ret; - - ret = _gdsc_disable(sc); - - gdsc_pm_runtime_put(sc); - - return ret; -} - static int gdsc_init(struct gdsc *sc) { u32 mask, val; @@ -437,14 +398,6 @@ return ret; } - /* ...and the power-domain */ - ret = gdsc_pm_runtime_get(sc); - if (ret) { - if (sc->rsupply) - regulator_disable(sc->rsupply); - return ret; - } - /* * Votable GDSCs can be ON due to Vote from other masters. * If a Votable GDSC is ON, make sure we have a Vote. @@ -452,14 +405,14 @@ if (sc->flags & VOTABLE) { ret = gdsc_update_collapse_bit(sc, false); if (ret) - return ret; + goto err_disable_supply; } /* Turn on HW trigger mode if supported */ if (sc->flags & HW_CTRL) { ret = gdsc_hwctrl(sc, true); if (ret < 0) - return ret; + goto err_disable_supply; } /* @@ -486,9 +439,18 @@ sc->pd.power_off = gdsc_disable; if (!sc->pd.power_on) sc->pd.power_on = gdsc_enable; - pm_genpd_init(&sc->pd, NULL, !on); + + ret = pm_genpd_init(&sc->pd, NULL, !on); + if (ret) + goto err_disable_supply; return 0; + +err_disable_supply: + if (on && sc->rsupply) + regulator_disable(sc->rsupply); + + return ret; } int gdsc_register(struct gdsc_desc *desc, @@ -522,8 +484,6 @@ for (i = 0; i < num; i++) { if (!scs[i]) continue; - if (pm_runtime_enabled(dev)) - scs[i]->dev = dev; scs[i]->regmap = regmap; scs[i]->rcdev = rcdev; ret = gdsc_init(scs[i]); diff -Nru linux-6.0.6/drivers/clk/qcom/gdsc.h linux-6.0.12/drivers/clk/qcom/gdsc.h --- linux-6.0.6/drivers/clk/qcom/gdsc.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/qcom/gdsc.h 2023-01-18 18:27:39.000000000 +0000 @@ -30,7 +30,6 @@ * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller - * @dev: the device holding the GDSC, used for pm_runtime calls */ struct gdsc { struct generic_pm_domain pd; @@ -69,7 +68,6 @@ const char *supply; struct regulator *rsupply; - struct device *dev; }; struct gdsc_desc { diff -Nru linux-6.0.6/drivers/clk/qcom/gpucc-sc7280.c linux-6.0.12/drivers/clk/qcom/gpucc-sc7280.c --- linux-6.0.6/drivers/clk/qcom/gpucc-sc7280.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/qcom/gpucc-sc7280.c 2023-01-18 18:27:39.000000000 +0000 @@ -463,6 +463,7 @@ */ regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0)); regmap_update_bits(regmap, 0x1098, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13)); return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap); } diff -Nru linux-6.0.6/drivers/clk/renesas/r8a779g0-cpg-mssr.c linux-6.0.12/drivers/clk/renesas/r8a779g0-cpg-mssr.c --- linux-6.0.6/drivers/clk/renesas/r8a779g0-cpg-mssr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/renesas/r8a779g0-cpg-mssr.c 2023-01-18 18:27:39.000000000 +0000 @@ -47,6 +47,7 @@ CLK_S0_VIO, CLK_S0_VC, CLK_S0_HSC, + CLK_SASYNCPER, CLK_SV_VIP, CLK_SV_IR, CLK_SDSRC, @@ -84,6 +85,7 @@ DEF_FIXED(".s0_vio", CLK_S0_VIO, CLK_PLL1_DIV2, 2, 1), DEF_FIXED(".s0_vc", CLK_S0_VC, CLK_PLL1_DIV2, 2, 1), DEF_FIXED(".s0_hsc", CLK_S0_HSC, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".sasyncper", CLK_SASYNCPER, CLK_PLL5_DIV4, 3, 1), DEF_FIXED(".sv_vip", CLK_SV_VIP, CLK_PLL1, 5, 1), DEF_FIXED(".sv_ir", CLK_SV_IR, CLK_PLL1, 5, 1), DEF_BASE(".sdsrc", CLK_SDSRC, CLK_TYPE_GEN4_SDSRC, CLK_PLL5), @@ -128,6 +130,9 @@ DEF_FIXED("s0d4_hsc", R8A779G0_CLK_S0D4_HSC, CLK_S0_HSC, 4, 1), DEF_FIXED("cl16m_hsc", R8A779G0_CLK_CL16M_HSC, CLK_S0_HSC, 48, 1), DEF_FIXED("s0d2_cc", R8A779G0_CLK_S0D2_CC, CLK_S0, 2, 1), + DEF_FIXED("sasyncperd1",R8A779G0_CLK_SASYNCPERD1, CLK_SASYNCPER,1, 1), + DEF_FIXED("sasyncperd2",R8A779G0_CLK_SASYNCPERD2, CLK_SASYNCPER,2, 1), + DEF_FIXED("sasyncperd4",R8A779G0_CLK_SASYNCPERD4, CLK_SASYNCPER,4, 1), DEF_FIXED("svd1_ir", R8A779G0_CLK_SVD1_IR, CLK_SV_IR, 1, 1), DEF_FIXED("svd2_ir", R8A779G0_CLK_SVD2_IR, CLK_SV_IR, 2, 1), DEF_FIXED("svd1_vip", R8A779G0_CLK_SVD1_VIP, CLK_SV_VIP, 1, 1), @@ -150,10 +155,10 @@ }; static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = { - DEF_MOD("hscif0", 514, R8A779G0_CLK_S0D3_PER), - DEF_MOD("hscif1", 515, R8A779G0_CLK_S0D3_PER), - DEF_MOD("hscif2", 516, R8A779G0_CLK_S0D3_PER), - DEF_MOD("hscif3", 517, R8A779G0_CLK_S0D3_PER), + DEF_MOD("hscif0", 514, R8A779G0_CLK_SASYNCPERD1), + DEF_MOD("hscif1", 515, R8A779G0_CLK_SASYNCPERD1), + DEF_MOD("hscif2", 516, R8A779G0_CLK_SASYNCPERD1), + DEF_MOD("hscif3", 517, R8A779G0_CLK_SASYNCPERD1), }; /* diff -Nru linux-6.0.6/drivers/clk/samsung/clk-exynos7885.c linux-6.0.12/drivers/clk/samsung/clk-exynos7885.c --- linux-6.0.6/drivers/clk/samsung/clk-exynos7885.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clk/samsung/clk-exynos7885.c 2023-01-18 18:27:39.000000000 +0000 @@ -182,7 +182,7 @@ CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1), DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll", CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2), - DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll", + DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2", CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1), DIV(CLK_DOUT_SHARED0_DIV5, "dout_shared0_div5", "fout_shared0_pll", CLK_CON_DIV_PLL_SHARED0_DIV5, 0, 3), @@ -190,7 +190,7 @@ CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1), DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll", CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2), - DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll", + DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2", CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1), /* CORE */ diff -Nru linux-6.0.6/drivers/clocksource/arm_arch_timer.c linux-6.0.12/drivers/clocksource/arm_arch_timer.c --- linux-6.0.6/drivers/clocksource/arm_arch_timer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clocksource/arm_arch_timer.c 2023-01-18 18:27:39.000000000 +0000 @@ -806,6 +806,9 @@ /* * XGene-1 implements CVAL in terms of TVAL, meaning * that the maximum timer range is 32bit. Shame on them. + * + * Note that TVAL is signed, thus has only 31 of its + * 32 bits to express magnitude. */ MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, APM_CPU_PART_POTENZA)), @@ -813,8 +816,8 @@ }; if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) { - pr_warn_once("Broken CNTx_CVAL_EL1, limiting width to 32bits"); - return CLOCKSOURCE_MASK(32); + pr_warn_once("Broken CNTx_CVAL_EL1, using 31 bit TVAL instead.\n"); + return CLOCKSOURCE_MASK(31); } #endif return CLOCKSOURCE_MASK(arch_counter_get_width()); diff -Nru linux-6.0.6/drivers/clocksource/timer-riscv.c linux-6.0.12/drivers/clocksource/timer-riscv.c --- linux-6.0.6/drivers/clocksource/timer-riscv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/clocksource/timer-riscv.c 2023-01-18 18:27:39.000000000 +0000 @@ -51,7 +51,7 @@ static unsigned int riscv_clock_event_irq; static DEFINE_PER_CPU(struct clock_event_device, riscv_clock_event) = { .name = "riscv_timer_clockevent", - .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP, + .features = CLOCK_EVT_FEAT_ONESHOT, .rating = 100, .set_next_event = riscv_clock_next_event, }; diff -Nru linux-6.0.6/drivers/counter/104-quad-8.c linux-6.0.12/drivers/counter/104-quad-8.c --- linux-6.0.6/drivers/counter/104-quad-8.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/counter/104-quad-8.c 2023-01-18 18:27:39.000000000 +0000 @@ -231,34 +231,45 @@ COUNTER_FUNCTION_QUADRATURE_X4, }; +static int quad8_function_get(const struct quad8 *const priv, const size_t id, + enum counter_function *const function) +{ + if (!priv->quadrature_mode[id]) { + *function = COUNTER_FUNCTION_PULSE_DIRECTION; + return 0; + } + + switch (priv->quadrature_scale[id]) { + case 0: + *function = COUNTER_FUNCTION_QUADRATURE_X1_A; + return 0; + case 1: + *function = COUNTER_FUNCTION_QUADRATURE_X2_A; + return 0; + case 2: + *function = COUNTER_FUNCTION_QUADRATURE_X4; + return 0; + default: + /* should never reach this path */ + return -EINVAL; + } +} + static int quad8_function_read(struct counter_device *counter, struct counter_count *count, enum counter_function *function) { struct quad8 *const priv = counter_priv(counter); - const int id = count->id; unsigned long irqflags; + int retval; spin_lock_irqsave(&priv->lock, irqflags); - if (priv->quadrature_mode[id]) - switch (priv->quadrature_scale[id]) { - case 0: - *function = COUNTER_FUNCTION_QUADRATURE_X1_A; - break; - case 1: - *function = COUNTER_FUNCTION_QUADRATURE_X2_A; - break; - case 2: - *function = COUNTER_FUNCTION_QUADRATURE_X4; - break; - } - else - *function = COUNTER_FUNCTION_PULSE_DIRECTION; + retval = quad8_function_get(priv, count->id, function); spin_unlock_irqrestore(&priv->lock, irqflags); - return 0; + return retval; } static int quad8_function_write(struct counter_device *counter, @@ -358,6 +369,7 @@ enum counter_synapse_action *action) { struct quad8 *const priv = counter_priv(counter); + unsigned long irqflags; int err; enum counter_function function; const size_t signal_a_id = count->synapses[0].signal->id; @@ -373,9 +385,21 @@ return 0; } - err = quad8_function_read(counter, count, &function); - if (err) + spin_lock_irqsave(&priv->lock, irqflags); + + /* Get Count function and direction atomically */ + err = quad8_function_get(priv, count->id, &function); + if (err) { + spin_unlock_irqrestore(&priv->lock, irqflags); return err; + } + err = quad8_direction_read(counter, count, &direction); + if (err) { + spin_unlock_irqrestore(&priv->lock, irqflags); + return err; + } + + spin_unlock_irqrestore(&priv->lock, irqflags); /* Default action mode */ *action = COUNTER_SYNAPSE_ACTION_NONE; @@ -388,10 +412,6 @@ return 0; case COUNTER_FUNCTION_QUADRATURE_X1_A: if (synapse->signal->id == signal_a_id) { - err = quad8_direction_read(counter, count, &direction); - if (err) - return err; - if (direction == COUNTER_COUNT_DIRECTION_FORWARD) *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; else diff -Nru linux-6.0.6/drivers/counter/microchip-tcb-capture.c linux-6.0.12/drivers/counter/microchip-tcb-capture.c --- linux-6.0.6/drivers/counter/microchip-tcb-capture.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/counter/microchip-tcb-capture.c 2023-01-18 18:27:39.000000000 +0000 @@ -28,7 +28,6 @@ int qdec_mode; int num_channels; int channel[2]; - bool trig_inverted; }; static const enum counter_function mchp_tc_count_functions[] = { @@ -153,7 +152,7 @@ regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], SR), &sr); - if (priv->trig_inverted) + if (signal->id == 1) sigstatus = (sr & ATMEL_TC_MTIOB); else sigstatus = (sr & ATMEL_TC_MTIOA); @@ -171,6 +170,17 @@ struct mchp_tc_data *const priv = counter_priv(counter); u32 cmr; + if (priv->qdec_mode) { + *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + return 0; + } + + /* Only TIOA signal is evaluated in non-QDEC mode */ + if (synapse->signal->id != 0) { + *action = COUNTER_SYNAPSE_ACTION_NONE; + return 0; + } + regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr); switch (cmr & ATMEL_TC_ETRGEDG) { @@ -199,8 +209,8 @@ struct mchp_tc_data *const priv = counter_priv(counter); u32 edge = ATMEL_TC_ETRGEDG_NONE; - /* QDEC mode is rising edge only */ - if (priv->qdec_mode) + /* QDEC mode is rising edge only; only TIOA handled in non-QDEC mode */ + if (priv->qdec_mode || synapse->signal->id != 0) return -EINVAL; switch (action) { diff -Nru linux-6.0.6/drivers/cpufreq/amd-pstate.c linux-6.0.12/drivers/cpufreq/amd-pstate.c --- linux-6.0.6/drivers/cpufreq/amd-pstate.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cpufreq/amd-pstate.c 2023-01-18 18:27:39.000000000 +0000 @@ -483,12 +483,22 @@ amd_pstate_driver.boost_enabled = true; } +static void amd_perf_ctl_reset(unsigned int cpu) +{ + wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0); +} + static int amd_pstate_cpu_init(struct cpufreq_policy *policy) { int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; struct device *dev; struct amd_cpudata *cpudata; + /* + * Resetting PERF_CTL_MSR will put the CPU in P0 frequency, + * which is ideal for initialization process. + */ + amd_perf_ctl_reset(policy->cpu); dev = get_cpu_device(policy->cpu); if (!dev) return -ENODEV; @@ -718,16 +728,7 @@ return ret; } - -static void __exit amd_pstate_exit(void) -{ - cpufreq_unregister_driver(&amd_pstate_driver); - - amd_pstate_enable(false); -} - -module_init(amd_pstate_init); -module_exit(amd_pstate_exit); +device_initcall(amd_pstate_init); MODULE_AUTHOR("Huang Rui "); MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver"); diff -Nru linux-6.0.6/drivers/cpufreq/intel_pstate.c linux-6.0.12/drivers/cpufreq/intel_pstate.c --- linux-6.0.6/drivers/cpufreq/intel_pstate.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cpufreq/intel_pstate.c 2023-01-18 18:27:39.000000000 +0000 @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -280,10 +281,10 @@ * structure is used to store those callbacks. */ struct pstate_funcs { - int (*get_max)(void); - int (*get_max_physical)(void); - int (*get_min)(void); - int (*get_turbo)(void); + int (*get_max)(int cpu); + int (*get_max_physical)(int cpu); + int (*get_min)(int cpu); + int (*get_turbo)(int cpu); int (*get_scaling)(void); int (*get_cpu_scaling)(int cpu); int (*get_aperf_mperf_shift)(void); @@ -398,16 +399,6 @@ return cppc_perf.nominal_perf; } - -static u32 intel_pstate_cppc_nominal(int cpu) -{ - u64 nominal_perf; - - if (cppc_get_nominal_perf(cpu, &nominal_perf)) - return 0; - - return nominal_perf; -} #else /* CONFIG_ACPI_CPPC_LIB */ static inline void intel_pstate_set_itmt_prio(int cpu) { @@ -531,35 +522,18 @@ { int perf_ctl_max_phys = cpu->pstate.max_pstate_physical; int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling; - int perf_ctl_turbo = pstate_funcs.get_turbo(); - int turbo_freq = perf_ctl_turbo * perf_ctl_scaling; + int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu); int scaling = cpu->pstate.scaling; pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys); - pr_debug("CPU%d: perf_ctl_max = %d\n", cpu->cpu, pstate_funcs.get_max()); pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo); pr_debug("CPU%d: perf_ctl_scaling = %d\n", cpu->cpu, perf_ctl_scaling); pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpu->cpu, cpu->pstate.max_pstate); pr_debug("CPU%d: HWP_CAP highest = %d\n", cpu->cpu, cpu->pstate.turbo_pstate); pr_debug("CPU%d: HWP-to-frequency scaling factor: %d\n", cpu->cpu, scaling); - /* - * If the product of the HWP performance scaling factor and the HWP_CAP - * highest performance is greater than the maximum turbo frequency - * corresponding to the pstate_funcs.get_turbo() return value, the - * scaling factor is too high, so recompute it to make the HWP_CAP - * highest performance correspond to the maximum turbo frequency. - */ - cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling; - if (turbo_freq < cpu->pstate.turbo_freq) { - cpu->pstate.turbo_freq = turbo_freq; - scaling = DIV_ROUND_UP(turbo_freq, cpu->pstate.turbo_pstate); - cpu->pstate.scaling = scaling; - - pr_debug("CPU%d: refined HWP-to-frequency scaling factor: %d\n", - cpu->cpu, scaling); - } - + cpu->pstate.turbo_freq = rounddown(cpu->pstate.turbo_pstate * scaling, + perf_ctl_scaling); cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling, perf_ctl_scaling); @@ -1740,7 +1714,7 @@ intel_pstate_update_epp_defaults(cpudata); } -static int atom_get_min_pstate(void) +static int atom_get_min_pstate(int not_used) { u64 value; @@ -1748,7 +1722,7 @@ return (value >> 8) & 0x7F; } -static int atom_get_max_pstate(void) +static int atom_get_max_pstate(int not_used) { u64 value; @@ -1756,7 +1730,7 @@ return (value >> 16) & 0x7F; } -static int atom_get_turbo_pstate(void) +static int atom_get_turbo_pstate(int not_used) { u64 value; @@ -1834,23 +1808,23 @@ cpudata->vid.turbo = value & 0x7f; } -static int core_get_min_pstate(void) +static int core_get_min_pstate(int cpu) { u64 value; - rdmsrl(MSR_PLATFORM_INFO, value); + rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value); return (value >> 40) & 0xFF; } -static int core_get_max_pstate_physical(void) +static int core_get_max_pstate_physical(int cpu) { u64 value; - rdmsrl(MSR_PLATFORM_INFO, value); + rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value); return (value >> 8) & 0xFF; } -static int core_get_tdp_ratio(u64 plat_info) +static int core_get_tdp_ratio(int cpu, u64 plat_info) { /* Check how many TDP levels present */ if (plat_info & 0x600000000) { @@ -1860,13 +1834,13 @@ int err; /* Get the TDP level (0, 1, 2) to get ratios */ - err = rdmsrl_safe(MSR_CONFIG_TDP_CONTROL, &tdp_ctrl); + err = rdmsrl_safe_on_cpu(cpu, MSR_CONFIG_TDP_CONTROL, &tdp_ctrl); if (err) return err; /* TDP MSR are continuous starting at 0x648 */ tdp_msr = MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl & 0x03); - err = rdmsrl_safe(tdp_msr, &tdp_ratio); + err = rdmsrl_safe_on_cpu(cpu, tdp_msr, &tdp_ratio); if (err) return err; @@ -1883,7 +1857,7 @@ return -ENXIO; } -static int core_get_max_pstate(void) +static int core_get_max_pstate(int cpu) { u64 tar; u64 plat_info; @@ -1891,10 +1865,10 @@ int tdp_ratio; int err; - rdmsrl(MSR_PLATFORM_INFO, plat_info); + rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &plat_info); max_pstate = (plat_info >> 8) & 0xFF; - tdp_ratio = core_get_tdp_ratio(plat_info); + tdp_ratio = core_get_tdp_ratio(cpu, plat_info); if (tdp_ratio <= 0) return max_pstate; @@ -1903,7 +1877,7 @@ return tdp_ratio; } - err = rdmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, &tar); + err = rdmsrl_safe_on_cpu(cpu, MSR_TURBO_ACTIVATION_RATIO, &tar); if (!err) { int tar_levels; @@ -1918,13 +1892,13 @@ return max_pstate; } -static int core_get_turbo_pstate(void) +static int core_get_turbo_pstate(int cpu) { u64 value; int nont, ret; - rdmsrl(MSR_TURBO_RATIO_LIMIT, value); - nont = core_get_max_pstate(); + rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value); + nont = core_get_max_pstate(cpu); ret = (value) & 255; if (ret <= nont) ret = nont; @@ -1952,50 +1926,37 @@ return 10; } -static int knl_get_turbo_pstate(void) +static int knl_get_turbo_pstate(int cpu) { u64 value; int nont, ret; - rdmsrl(MSR_TURBO_RATIO_LIMIT, value); - nont = core_get_max_pstate(); + rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value); + nont = core_get_max_pstate(cpu); ret = (((value) >> 8) & 0xFF); if (ret <= nont) ret = nont; return ret; } -#ifdef CONFIG_ACPI_CPPC_LIB -static u32 hybrid_ref_perf; - -static int hybrid_get_cpu_scaling(int cpu) +static void hybrid_get_type(void *data) { - return DIV_ROUND_UP(core_get_scaling() * hybrid_ref_perf, - intel_pstate_cppc_nominal(cpu)); + u8 *cpu_type = data; + + *cpu_type = get_this_hybrid_cpu_type(); } -static void intel_pstate_cppc_set_cpu_scaling(void) +static int hybrid_get_cpu_scaling(int cpu) { - u32 min_nominal_perf = U32_MAX; - int cpu; + u8 cpu_type = 0; - for_each_present_cpu(cpu) { - u32 nominal_perf = intel_pstate_cppc_nominal(cpu); + smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1); + /* P-cores have a smaller perf level-to-freqency scaling factor. */ + if (cpu_type == 0x40) + return 78741; - if (nominal_perf && nominal_perf < min_nominal_perf) - min_nominal_perf = nominal_perf; - } - - if (min_nominal_perf < U32_MAX) { - hybrid_ref_perf = min_nominal_perf; - pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling; - } + return core_get_scaling(); } -#else -static inline void intel_pstate_cppc_set_cpu_scaling(void) -{ -} -#endif /* CONFIG_ACPI_CPPC_LIB */ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) { @@ -2025,10 +1986,10 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) { - int perf_ctl_max_phys = pstate_funcs.get_max_physical(); + int perf_ctl_max_phys = pstate_funcs.get_max_physical(cpu->cpu); int perf_ctl_scaling = pstate_funcs.get_scaling(); - cpu->pstate.min_pstate = pstate_funcs.get_min(); + cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu); cpu->pstate.max_pstate_physical = perf_ctl_max_phys; cpu->pstate.perf_ctl_scaling = perf_ctl_scaling; @@ -2044,8 +2005,8 @@ } } else { cpu->pstate.scaling = perf_ctl_scaling; - cpu->pstate.max_pstate = pstate_funcs.get_max(); - cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); + cpu->pstate.max_pstate = pstate_funcs.get_max(cpu->cpu); + cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu); } if (cpu->pstate.scaling == perf_ctl_scaling) { @@ -3221,9 +3182,9 @@ static int __init intel_pstate_msrs_not_valid(void) { - if (!pstate_funcs.get_max() || - !pstate_funcs.get_min() || - !pstate_funcs.get_turbo()) + if (!pstate_funcs.get_max(0) || + !pstate_funcs.get_min(0) || + !pstate_funcs.get_turbo(0)) return -ENODEV; return 0; @@ -3450,7 +3411,7 @@ default_driver = &intel_pstate; if (boot_cpu_has(X86_FEATURE_HYBRID_CPU)) - intel_pstate_cppc_set_cpu_scaling(); + pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling; goto hwp_cpu_matched; } diff -Nru linux-6.0.6/drivers/cpufreq/Kconfig.x86 linux-6.0.12/drivers/cpufreq/Kconfig.x86 --- linux-6.0.6/drivers/cpufreq/Kconfig.x86 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cpufreq/Kconfig.x86 2023-01-18 18:27:39.000000000 +0000 @@ -35,7 +35,7 @@ If in doubt, say N. config X86_AMD_PSTATE - tristate "AMD Processor P-State driver" + bool "AMD Processor P-State driver" depends on X86 && ACPI select ACPI_PROCESSOR select ACPI_CPPC_LIB if X86_64 diff -Nru linux-6.0.6/drivers/cxl/core/mbox.c linux-6.0.12/drivers/cxl/core/mbox.c --- linux-6.0.6/drivers/cxl/core/mbox.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cxl/core/mbox.c 2023-01-18 18:27:39.000000000 +0000 @@ -174,7 +174,7 @@ }; int rc; - if (out_size > cxlds->payload_size) + if (in_size > cxlds->payload_size || out_size > cxlds->payload_size) return -E2BIG; rc = cxlds->mbox_send(cxlds, &mbox_cmd); diff -Nru linux-6.0.6/drivers/cxl/core/pmem.c linux-6.0.12/drivers/cxl/core/pmem.c --- linux-6.0.6/drivers/cxl/core/pmem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cxl/core/pmem.c 2023-01-18 18:27:39.000000000 +0000 @@ -188,6 +188,7 @@ { struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); + xa_destroy(&cxl_nvd->pmem_regions); kfree(cxl_nvd); } @@ -230,6 +231,7 @@ dev = &cxl_nvd->dev; cxl_nvd->cxlmd = cxlmd; + xa_init(&cxl_nvd->pmem_regions); device_initialize(dev); lockdep_set_class(&dev->mutex, &cxl_nvdimm_key); device_set_pm_not_required(dev); diff -Nru linux-6.0.6/drivers/cxl/core/port.c linux-6.0.12/drivers/cxl/core/port.c --- linux-6.0.6/drivers/cxl/core/port.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cxl/core/port.c 2023-01-18 18:27:39.000000000 +0000 @@ -811,6 +811,7 @@ static int add_dport(struct cxl_port *port, struct cxl_dport *new) { struct cxl_dport *dup; + int rc; device_lock_assert(&port->dev); dup = find_dport(port, new->port_id); @@ -821,8 +822,14 @@ dev_name(dup->dport)); return -EBUSY; } - return xa_insert(&port->dports, (unsigned long)new->dport, new, - GFP_KERNEL); + + rc = xa_insert(&port->dports, (unsigned long)new->dport, new, + GFP_KERNEL); + if (rc) + return rc; + + port->nr_dports++; + return 0; } /* diff -Nru linux-6.0.6/drivers/cxl/core/region.c linux-6.0.12/drivers/cxl/core/region.c --- linux-6.0.6/drivers/cxl/core/region.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cxl/core/region.c 2023-01-18 18:27:39.000000000 +0000 @@ -657,6 +657,9 @@ xa_for_each(&port->regions, index, iter) { struct cxl_region_params *ip = &iter->region->params; + if (!ip->res) + continue; + if (ip->res->start > p->res->start) { dev_dbg(&cxlr->dev, "%s: HPA order violation %s:%pr vs %pr\n", @@ -686,18 +689,27 @@ return cxl_rr; } -static void free_region_ref(struct cxl_region_ref *cxl_rr) +static void cxl_rr_free_decoder(struct cxl_region_ref *cxl_rr) { - struct cxl_port *port = cxl_rr->port; struct cxl_region *cxlr = cxl_rr->region; struct cxl_decoder *cxld = cxl_rr->decoder; + if (!cxld) + return; + dev_WARN_ONCE(&cxlr->dev, cxld->region != cxlr, "region mismatch\n"); if (cxld->region == cxlr) { cxld->region = NULL; put_device(&cxlr->dev); } +} +static void free_region_ref(struct cxl_region_ref *cxl_rr) +{ + struct cxl_port *port = cxl_rr->port; + struct cxl_region *cxlr = cxl_rr->region; + + cxl_rr_free_decoder(cxl_rr); xa_erase(&port->regions, (unsigned long)cxlr); xa_destroy(&cxl_rr->endpoints); kfree(cxl_rr); @@ -728,6 +740,33 @@ return 0; } +static int cxl_rr_alloc_decoder(struct cxl_port *port, struct cxl_region *cxlr, + struct cxl_endpoint_decoder *cxled, + struct cxl_region_ref *cxl_rr) +{ + struct cxl_decoder *cxld; + + if (port == cxled_to_port(cxled)) + cxld = &cxled->cxld; + else + cxld = cxl_region_find_decoder(port, cxlr); + if (!cxld) { + dev_dbg(&cxlr->dev, "%s: no decoder available\n", + dev_name(&port->dev)); + return -EBUSY; + } + + if (cxld->region) { + dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n", + dev_name(&port->dev), dev_name(&cxld->dev), + dev_name(&cxld->region->dev)); + return -EBUSY; + } + + cxl_rr->decoder = cxld; + return 0; +} + /** * cxl_port_attach_region() - track a region's interest in a port by endpoint * @port: port to add a new region reference 'struct cxl_region_ref' @@ -794,12 +833,6 @@ cxl_rr->nr_targets++; nr_targets_inc = true; } - - /* - * The decoder for @cxlr was allocated when the region was first - * attached to @port. - */ - cxld = cxl_rr->decoder; } else { cxl_rr = alloc_region_ref(port, cxlr); if (IS_ERR(cxl_rr)) { @@ -810,26 +843,11 @@ } nr_targets_inc = true; - if (port == cxled_to_port(cxled)) - cxld = &cxled->cxld; - else - cxld = cxl_region_find_decoder(port, cxlr); - if (!cxld) { - dev_dbg(&cxlr->dev, "%s: no decoder available\n", - dev_name(&port->dev)); - goto out_erase; - } - - if (cxld->region) { - dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n", - dev_name(&port->dev), dev_name(&cxld->dev), - dev_name(&cxld->region->dev)); - rc = -EBUSY; + rc = cxl_rr_alloc_decoder(port, cxlr, cxled, cxl_rr); + if (rc) goto out_erase; - } - - cxl_rr->decoder = cxld; } + cxld = cxl_rr->decoder; rc = cxl_rr_ep_add(cxl_rr, cxled); if (rc) { @@ -971,7 +989,14 @@ if (cxl_rr->nr_targets_set) { int i, distance; - distance = p->nr_targets / cxl_rr->nr_targets; + /* + * Passthrough ports impose no distance requirements between + * peers + */ + if (port->nr_dports == 1) + distance = 0; + else + distance = p->nr_targets / cxl_rr->nr_targets; for (i = 0; i < cxl_rr->nr_targets_set; i++) if (ep->dport == cxlsd->target[i]) { rc = check_last_peer(cxled, ep, cxl_rr, @@ -1508,9 +1533,24 @@ static void cxl_region_release(struct device *dev) { + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent); struct cxl_region *cxlr = to_cxl_region(dev); + int id = atomic_read(&cxlrd->region_id); + + /* + * Try to reuse the recently idled id rather than the cached + * next id to prevent the region id space from increasing + * unnecessarily. + */ + if (cxlr->id < id) + if (atomic_try_cmpxchg(&cxlrd->region_id, &id, cxlr->id)) { + memregion_free(id); + goto out; + } memregion_free(cxlr->id); +out: + put_device(dev->parent); kfree(cxlr); } @@ -1538,8 +1578,19 @@ static void unregister_region(void *dev) { struct cxl_region *cxlr = to_cxl_region(dev); + struct cxl_region_params *p = &cxlr->params; + int i; device_del(dev); + + /* + * Now that region sysfs is shutdown, the parameter block is now + * read-only, so no need to hold the region rwsem to access the + * region parameters. + */ + for (i = 0; i < p->interleave_ways; i++) + detach_target(cxlr, i); + cxl_region_iomem_release(cxlr); put_device(dev); } @@ -1561,6 +1612,11 @@ device_initialize(dev); lockdep_set_class(&dev->mutex, &cxl_region_key); dev->parent = &cxlrd->cxlsd.cxld.dev; + /* + * Keep root decoder pinned through cxl_region_release to fixup + * region id allocations + */ + get_device(dev->parent); device_set_pm_not_required(dev); dev->bus = &cxl_bus_type; dev->type = &cxl_region_type; diff -Nru linux-6.0.6/drivers/cxl/cxl.h linux-6.0.12/drivers/cxl/cxl.h --- linux-6.0.6/drivers/cxl/cxl.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cxl/cxl.h 2023-01-18 18:27:39.000000000 +0000 @@ -423,7 +423,7 @@ struct device dev; struct cxl_memdev *cxlmd; struct cxl_nvdimm_bridge *bridge; - struct cxl_pmem_region *region; + struct xarray pmem_regions; }; struct cxl_pmem_region_mapping { @@ -457,6 +457,7 @@ * @regions: cxl_region_ref instances, regions mapped by this port * @parent_dport: dport that points to this port in the parent * @decoder_ida: allocator for decoder ids + * @nr_dports: number of entries in @dports * @hdm_end: track last allocated HDM decoder instance for allocation ordering * @commit_end: cursor to track highest committed decoder for commit ordering * @component_reg_phys: component register capability base address (optional) @@ -475,6 +476,7 @@ struct xarray regions; struct cxl_dport *parent_dport; struct ida decoder_ida; + int nr_dports; int hdm_end; int commit_end; resource_size_t component_reg_phys; diff -Nru linux-6.0.6/drivers/cxl/pmem.c linux-6.0.12/drivers/cxl/pmem.c --- linux-6.0.6/drivers/cxl/pmem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/cxl/pmem.c 2023-01-18 18:27:39.000000000 +0000 @@ -30,17 +30,20 @@ struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); struct cxl_nvdimm_bridge *cxl_nvb = cxl_nvd->bridge; struct cxl_pmem_region *cxlr_pmem; + unsigned long index; device_lock(&cxl_nvb->dev); - cxlr_pmem = cxl_nvd->region; dev_set_drvdata(&cxl_nvd->dev, NULL); - cxl_nvd->region = NULL; - device_unlock(&cxl_nvb->dev); + xa_for_each(&cxl_nvd->pmem_regions, index, cxlr_pmem) { + get_device(&cxlr_pmem->dev); + device_unlock(&cxl_nvb->dev); - if (cxlr_pmem) { device_release_driver(&cxlr_pmem->dev); put_device(&cxlr_pmem->dev); + + device_lock(&cxl_nvb->dev); } + device_unlock(&cxl_nvb->dev); nvdimm_delete(nvdimm); cxl_nvd->bridge = NULL; @@ -148,7 +151,7 @@ return -EINVAL; /* 4-byte status follows the input data in the payload */ - if (struct_size(cmd, in_buf, cmd->in_length) + 4 > buf_len) + if (size_add(struct_size(cmd, in_buf, cmd->in_length), 4) > buf_len) return -EINVAL; set_lsa = @@ -366,25 +369,49 @@ static void unregister_nvdimm_region(void *nd_region) { - struct cxl_nvdimm_bridge *cxl_nvb; - struct cxl_pmem_region *cxlr_pmem; + nvdimm_region_delete(nd_region); +} + +static int cxl_nvdimm_add_region(struct cxl_nvdimm *cxl_nvd, + struct cxl_pmem_region *cxlr_pmem) +{ + int rc; + + rc = xa_insert(&cxl_nvd->pmem_regions, (unsigned long)cxlr_pmem, + cxlr_pmem, GFP_KERNEL); + if (rc) + return rc; + + get_device(&cxlr_pmem->dev); + return 0; +} + +static void cxl_nvdimm_del_region(struct cxl_nvdimm *cxl_nvd, + struct cxl_pmem_region *cxlr_pmem) +{ + /* + * It is possible this is called without a corresponding + * cxl_nvdimm_add_region for @cxlr_pmem + */ + cxlr_pmem = xa_erase(&cxl_nvd->pmem_regions, (unsigned long)cxlr_pmem); + if (cxlr_pmem) + put_device(&cxlr_pmem->dev); +} + +static void release_mappings(void *data) +{ int i; + struct cxl_pmem_region *cxlr_pmem = data; + struct cxl_nvdimm_bridge *cxl_nvb = cxlr_pmem->bridge; - cxlr_pmem = nd_region_provider_data(nd_region); - cxl_nvb = cxlr_pmem->bridge; device_lock(&cxl_nvb->dev); for (i = 0; i < cxlr_pmem->nr_mappings; i++) { struct cxl_pmem_region_mapping *m = &cxlr_pmem->mapping[i]; struct cxl_nvdimm *cxl_nvd = m->cxl_nvd; - if (cxl_nvd->region) { - put_device(&cxlr_pmem->dev); - cxl_nvd->region = NULL; - } + cxl_nvdimm_del_region(cxl_nvd, cxlr_pmem); } device_unlock(&cxl_nvb->dev); - - nvdimm_region_delete(nd_region); } static void cxlr_pmem_remove_resource(void *res) @@ -422,7 +449,7 @@ if (!cxl_nvb->nvdimm_bus) { dev_dbg(dev, "nvdimm bus not found\n"); rc = -ENXIO; - goto err; + goto out_nvb; } memset(&mappings, 0, sizeof(mappings)); @@ -431,7 +458,7 @@ res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); if (!res) { rc = -ENOMEM; - goto err; + goto out_nvb; } res->name = "Persistent Memory"; @@ -442,11 +469,11 @@ rc = insert_resource(&iomem_resource, res); if (rc) - goto err; + goto out_nvb; rc = devm_add_action_or_reset(dev, cxlr_pmem_remove_resource, res); if (rc) - goto err; + goto out_nvb; ndr_desc.res = res; ndr_desc.provider_data = cxlr_pmem; @@ -462,7 +489,7 @@ nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL); if (!nd_set) { rc = -ENOMEM; - goto err; + goto out_nvb; } ndr_desc.memregion = cxlr->id; @@ -472,9 +499,13 @@ info = kmalloc_array(cxlr_pmem->nr_mappings, sizeof(*info), GFP_KERNEL); if (!info) { rc = -ENOMEM; - goto err; + goto out_nvb; } + rc = devm_add_action_or_reset(dev, release_mappings, cxlr_pmem); + if (rc) + goto out_nvd; + for (i = 0; i < cxlr_pmem->nr_mappings; i++) { struct cxl_pmem_region_mapping *m = &cxlr_pmem->mapping[i]; struct cxl_memdev *cxlmd = m->cxlmd; @@ -486,7 +517,7 @@ dev_dbg(dev, "[%d]: %s: no cxl_nvdimm found\n", i, dev_name(&cxlmd->dev)); rc = -ENODEV; - goto err; + goto out_nvd; } /* safe to drop ref now with bridge lock held */ @@ -498,10 +529,17 @@ dev_dbg(dev, "[%d]: %s: no nvdimm found\n", i, dev_name(&cxlmd->dev)); rc = -ENODEV; - goto err; + goto out_nvd; } - cxl_nvd->region = cxlr_pmem; - get_device(&cxlr_pmem->dev); + + /* + * Pin the region per nvdimm device as those may be released + * out-of-order with respect to the region, and a single nvdimm + * maybe associated with multiple regions + */ + rc = cxl_nvdimm_add_region(cxl_nvd, cxlr_pmem); + if (rc) + goto out_nvd; m->cxl_nvd = cxl_nvd; mappings[i] = (struct nd_mapping_desc) { .nvdimm = nvdimm, @@ -527,27 +565,18 @@ nvdimm_pmem_region_create(cxl_nvb->nvdimm_bus, &ndr_desc); if (!cxlr_pmem->nd_region) { rc = -ENOMEM; - goto err; + goto out_nvd; } rc = devm_add_action_or_reset(dev, unregister_nvdimm_region, cxlr_pmem->nd_region); -out: +out_nvd: kfree(info); +out_nvb: device_unlock(&cxl_nvb->dev); put_device(&cxl_nvb->dev); return rc; - -err: - dev_dbg(dev, "failed to create nvdimm region\n"); - for (i--; i >= 0; i--) { - nvdimm = mappings[i].nvdimm; - cxl_nvd = nvdimm_provider_data(nvdimm); - put_device(&cxl_nvd->region->dev); - cxl_nvd->region = NULL; - } - goto out; } static struct cxl_driver cxl_pmem_region_driver = { diff -Nru linux-6.0.6/drivers/dma/apple-admac.c linux-6.0.12/drivers/dma/apple-admac.c --- linux-6.0.6/drivers/dma/apple-admac.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/apple-admac.c 2023-01-18 18:27:39.000000000 +0000 @@ -490,7 +490,7 @@ return NULL; } - return &ad->channels[index].chan; + return dma_get_slave_channel(&ad->channels[index].chan); } static int admac_drain_reports(struct admac_data *ad, int channo) diff -Nru linux-6.0.6/drivers/dma/at_hdmac.c linux-6.0.12/drivers/dma/at_hdmac.c --- linux-6.0.6/drivers/dma/at_hdmac.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/at_hdmac.c 2023-01-18 18:27:39.000000000 +0000 @@ -256,6 +256,8 @@ ATC_SPIP_BOUNDARY(first->boundary)); channel_writel(atchan, DPIP, ATC_DPIP_HOLE(first->dst_hole) | ATC_DPIP_BOUNDARY(first->boundary)); + /* Don't allow CPU to reorder channel enable. */ + wmb(); dma_writel(atdma, CHER, atchan->mask); vdbg_dump_regs(atchan); @@ -316,7 +318,8 @@ struct at_desc *desc_first = atc_first_active(atchan); struct at_desc *desc; int ret; - u32 ctrla, dscr, trials; + u32 ctrla, dscr; + unsigned int i; /* * If the cookie doesn't match to the currently running transfer then @@ -386,7 +389,7 @@ dscr = channel_readl(atchan, DSCR); rmb(); /* ensure DSCR is read before CTRLA */ ctrla = channel_readl(atchan, CTRLA); - for (trials = 0; trials < ATC_MAX_DSCR_TRIALS; ++trials) { + for (i = 0; i < ATC_MAX_DSCR_TRIALS; ++i) { u32 new_dscr; rmb(); /* ensure DSCR is read after CTRLA */ @@ -412,7 +415,7 @@ rmb(); /* ensure DSCR is read before CTRLA */ ctrla = channel_readl(atchan, CTRLA); } - if (unlikely(trials >= ATC_MAX_DSCR_TRIALS)) + if (unlikely(i == ATC_MAX_DSCR_TRIALS)) return -ETIMEDOUT; /* for the first descriptor we can be more accurate */ @@ -462,18 +465,6 @@ if (!atc_chan_is_cyclic(atchan)) dma_cookie_complete(txd); - /* If the transfer was a memset, free our temporary buffer */ - if (desc->memset_buffer) { - dma_pool_free(atdma->memset_pool, desc->memset_vaddr, - desc->memset_paddr); - desc->memset_buffer = false; - } - - /* move children to free_list */ - list_splice_init(&desc->tx_list, &atchan->free_list); - /* move myself to free_list */ - list_move(&desc->desc_node, &atchan->free_list); - spin_unlock_irqrestore(&atchan->lock, flags); dma_descriptor_unmap(txd); @@ -483,42 +474,20 @@ dmaengine_desc_get_callback_invoke(txd, NULL); dma_run_dependencies(txd); -} - -/** - * atc_complete_all - finish work for all transactions - * @atchan: channel to complete transactions for - * - * Eventually submit queued descriptors if any - * - * Assume channel is idle while calling this function - * Called with atchan->lock held and bh disabled - */ -static void atc_complete_all(struct at_dma_chan *atchan) -{ - struct at_desc *desc, *_desc; - LIST_HEAD(list); - unsigned long flags; - - dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n"); spin_lock_irqsave(&atchan->lock, flags); - - /* - * Submit queued descriptors ASAP, i.e. before we go through - * the completed ones. - */ - if (!list_empty(&atchan->queue)) - atc_dostart(atchan, atc_first_queued(atchan)); - /* empty active_list now it is completed */ - list_splice_init(&atchan->active_list, &list); - /* empty queue list by moving descriptors (if any) to active_list */ - list_splice_init(&atchan->queue, &atchan->active_list); - + /* move children to free_list */ + list_splice_init(&desc->tx_list, &atchan->free_list); + /* add myself to free_list */ + list_add(&desc->desc_node, &atchan->free_list); spin_unlock_irqrestore(&atchan->lock, flags); - list_for_each_entry_safe(desc, _desc, &list, desc_node) - atc_chain_complete(atchan, desc); + /* If the transfer was a memset, free our temporary buffer */ + if (desc->memset_buffer) { + dma_pool_free(atdma->memset_pool, desc->memset_vaddr, + desc->memset_paddr); + desc->memset_buffer = false; + } } /** @@ -527,26 +496,28 @@ */ static void atc_advance_work(struct at_dma_chan *atchan) { + struct at_desc *desc; unsigned long flags; - int ret; dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n"); spin_lock_irqsave(&atchan->lock, flags); - ret = atc_chan_is_enabled(atchan); - spin_unlock_irqrestore(&atchan->lock, flags); - if (ret) - return; - - if (list_empty(&atchan->active_list) || - list_is_singular(&atchan->active_list)) - return atc_complete_all(atchan); + if (atc_chan_is_enabled(atchan) || list_empty(&atchan->active_list)) + return spin_unlock_irqrestore(&atchan->lock, flags); - atc_chain_complete(atchan, atc_first_active(atchan)); + desc = atc_first_active(atchan); + /* Remove the transfer node from the active list. */ + list_del_init(&desc->desc_node); + spin_unlock_irqrestore(&atchan->lock, flags); + atc_chain_complete(atchan, desc); /* advance work */ spin_lock_irqsave(&atchan->lock, flags); - atc_dostart(atchan, atc_first_active(atchan)); + if (!list_empty(&atchan->active_list)) { + desc = atc_first_queued(atchan); + list_move_tail(&desc->desc_node, &atchan->active_list); + atc_dostart(atchan, desc); + } spin_unlock_irqrestore(&atchan->lock, flags); } @@ -558,6 +529,7 @@ static void atc_handle_error(struct at_dma_chan *atchan) { struct at_desc *bad_desc; + struct at_desc *desc; struct at_desc *child; unsigned long flags; @@ -570,13 +542,12 @@ bad_desc = atc_first_active(atchan); list_del_init(&bad_desc->desc_node); - /* As we are stopped, take advantage to push queued descriptors - * in active_list */ - list_splice_init(&atchan->queue, atchan->active_list.prev); - /* Try to restart the controller */ - if (!list_empty(&atchan->active_list)) - atc_dostart(atchan, atc_first_active(atchan)); + if (!list_empty(&atchan->active_list)) { + desc = atc_first_queued(atchan); + list_move_tail(&desc->desc_node, &atchan->active_list); + atc_dostart(atchan, desc); + } /* * KERN_CRITICAL may seem harsh, but since this only happens @@ -691,19 +662,11 @@ spin_lock_irqsave(&atchan->lock, flags); cookie = dma_cookie_assign(tx); - if (list_empty(&atchan->active_list)) { - dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n", - desc->txd.cookie); - atc_dostart(atchan, desc); - list_add_tail(&desc->desc_node, &atchan->active_list); - } else { - dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n", - desc->txd.cookie); - list_add_tail(&desc->desc_node, &atchan->queue); - } - + list_add_tail(&desc->desc_node, &atchan->queue); spin_unlock_irqrestore(&atchan->lock, flags); + dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n", + desc->txd.cookie); return cookie; } @@ -1445,11 +1408,8 @@ struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); int chan_id = atchan->chan_common.chan_id; - struct at_desc *desc, *_desc; unsigned long flags; - LIST_HEAD(list); - dev_vdbg(chan2dev(chan), "%s\n", __func__); /* @@ -1468,19 +1428,15 @@ cpu_relax(); /* active_list entries will end up before queued entries */ - list_splice_init(&atchan->queue, &list); - list_splice_init(&atchan->active_list, &list); - - spin_unlock_irqrestore(&atchan->lock, flags); - - /* Flush all pending and queued descriptors */ - list_for_each_entry_safe(desc, _desc, &list, desc_node) - atc_chain_complete(atchan, desc); + list_splice_tail_init(&atchan->queue, &atchan->free_list); + list_splice_tail_init(&atchan->active_list, &atchan->free_list); clear_bit(ATC_IS_PAUSED, &atchan->status); /* if channel dedicated to cyclic operations, free it */ clear_bit(ATC_IS_CYCLIC, &atchan->status); + spin_unlock_irqrestore(&atchan->lock, flags); + return 0; } @@ -1535,20 +1491,26 @@ } /** - * atc_issue_pending - try to finish work + * atc_issue_pending - takes the first transaction descriptor in the pending + * queue and starts the transfer. * @chan: target DMA channel */ static void atc_issue_pending(struct dma_chan *chan) { - struct at_dma_chan *atchan = to_at_dma_chan(chan); + struct at_dma_chan *atchan = to_at_dma_chan(chan); + struct at_desc *desc; + unsigned long flags; dev_vdbg(chan2dev(chan), "issue_pending\n"); - /* Not needed for cyclic transfers */ - if (atc_chan_is_cyclic(atchan)) - return; + spin_lock_irqsave(&atchan->lock, flags); + if (atc_chan_is_enabled(atchan) || list_empty(&atchan->queue)) + return spin_unlock_irqrestore(&atchan->lock, flags); - atc_advance_work(atchan); + desc = atc_first_queued(atchan); + list_move_tail(&desc->desc_node, &atchan->active_list); + atc_dostart(atchan, desc); + spin_unlock_irqrestore(&atchan->lock, flags); } /** @@ -1966,7 +1928,11 @@ dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "", plat_dat->nr_channels); - dma_async_device_register(&atdma->dma_common); + err = dma_async_device_register(&atdma->dma_common); + if (err) { + dev_err(&pdev->dev, "Unable to register: %d.\n", err); + goto err_dma_async_device_register; + } /* * Do not return an error if the dmac node is not present in order to @@ -1986,6 +1952,7 @@ err_of_dma_controller_register: dma_async_device_unregister(&atdma->dma_common); +err_dma_async_device_register: dma_pool_destroy(atdma->memset_pool); err_memset_pool_create: dma_pool_destroy(atdma->dma_desc_pool); diff -Nru linux-6.0.6/drivers/dma/at_hdmac_regs.h linux-6.0.12/drivers/dma/at_hdmac_regs.h --- linux-6.0.6/drivers/dma/at_hdmac_regs.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/at_hdmac_regs.h 2023-01-18 18:27:39.000000000 +0000 @@ -186,13 +186,13 @@ /* LLI == Linked List Item; aka DMA buffer descriptor */ struct at_lli { /* values that are not changed by hardware */ - dma_addr_t saddr; - dma_addr_t daddr; + u32 saddr; + u32 daddr; /* value that may get written back: */ - u32 ctrla; + u32 ctrla; /* more values that are not changed by hardware */ - u32 ctrlb; - dma_addr_t dscr; /* chain to next lli */ + u32 ctrlb; + u32 dscr; /* chain to next lli */ }; /** diff -Nru linux-6.0.6/drivers/dma/idxd/cdev.c linux-6.0.12/drivers/dma/idxd/cdev.c --- linux-6.0.6/drivers/dma/idxd/cdev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/idxd/cdev.c 2023-01-18 18:27:39.000000000 +0000 @@ -312,6 +312,24 @@ if (idxd->state != IDXD_DEV_ENABLED) return -ENXIO; + /* + * User type WQ is enabled only when SVA is enabled for two reasons: + * - If no IOMMU or IOMMU Passthrough without SVA, userspace + * can directly access physical address through the WQ. + * - The IDXD cdev driver does not provide any ways to pin + * user pages and translate the address from user VA to IOVA or + * PA without IOMMU SVA. Therefore the application has no way + * to instruct the device to perform DMA function. This makes + * the cdev not usable for normal application usage. + */ + if (!device_user_pasid_enabled(idxd)) { + idxd->cmd_status = IDXD_SCMD_WQ_USER_NO_IOMMU; + dev_dbg(&idxd->pdev->dev, + "User type WQ cannot be enabled without SVA.\n"); + + return -EOPNOTSUPP; + } + mutex_lock(&wq->wq_lock); wq->type = IDXD_WQT_USER; rc = drv_enable_wq(wq); diff -Nru linux-6.0.6/drivers/dma/idxd/device.c linux-6.0.12/drivers/dma/idxd/device.c --- linux-6.0.6/drivers/dma/idxd/device.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/idxd/device.c 2023-01-18 18:27:39.000000000 +0000 @@ -388,7 +388,7 @@ clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags); memset(wq->name, 0, WQ_NAME_SIZE); wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER; - wq->max_batch_size = WQ_DEFAULT_MAX_BATCH; + idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH); } static void idxd_wq_device_reset_cleanup(struct idxd_wq *wq) @@ -724,13 +724,21 @@ void idxd_device_clear_state(struct idxd_device *idxd) { - if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) - return; + /* IDXD is always disabled. Other states are cleared only when IDXD is configurable. */ + if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) { + /* + * Clearing wq state is protected by wq lock. + * So no need to be protected by device lock. + */ + idxd_device_wqs_clear_state(idxd); + + spin_lock(&idxd->dev_lock); + idxd_groups_clear_state(idxd); + idxd_engines_clear_state(idxd); + } else { + spin_lock(&idxd->dev_lock); + } - idxd_device_wqs_clear_state(idxd); - spin_lock(&idxd->dev_lock); - idxd_groups_clear_state(idxd); - idxd_engines_clear_state(idxd); idxd->state = IDXD_DEV_DISABLED; spin_unlock(&idxd->dev_lock); } @@ -863,7 +871,7 @@ /* bytes 12-15 */ wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes); - wq->wqcfg->max_batch_shift = ilog2(wq->max_batch_size); + idxd_wqcfg_set_max_batch_shift(idxd->data->type, wq->wqcfg, ilog2(wq->max_batch_size)); dev_dbg(dev, "WQ %d CFGs\n", wq->id); for (i = 0; i < WQCFG_STRIDES(idxd); i++) { @@ -1031,7 +1039,7 @@ wq->priority = wq->wqcfg->priority; wq->max_xfer_bytes = 1ULL << wq->wqcfg->max_xfer_shift; - wq->max_batch_size = 1ULL << wq->wqcfg->max_batch_shift; + idxd_wq_set_max_batch_size(idxd->data->type, wq, 1U << wq->wqcfg->max_batch_shift); for (i = 0; i < WQCFG_STRIDES(idxd); i++) { wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, i); diff -Nru linux-6.0.6/drivers/dma/idxd/idxd.h linux-6.0.12/drivers/dma/idxd/idxd.h --- linux-6.0.6/drivers/dma/idxd/idxd.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/idxd/idxd.h 2023-01-18 18:27:39.000000000 +0000 @@ -308,6 +308,8 @@ struct work_struct work; struct idxd_pmu *idxd_pmu; + + unsigned long *opcap_bmap; }; /* IDXD software descriptor */ @@ -540,6 +542,38 @@ return wq->client_count; }; +/* + * Intel IAA does not support batch processing. + * The max batch size of device, max batch size of wq and + * max batch shift of wqcfg should be always 0 on IAA. + */ +static inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd, + u32 max_batch_size) +{ + if (idxd_type == IDXD_TYPE_IAX) + idxd->max_batch_size = 0; + else + idxd->max_batch_size = max_batch_size; +} + +static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq, + u32 max_batch_size) +{ + if (idxd_type == IDXD_TYPE_IAX) + wq->max_batch_size = 0; + else + wq->max_batch_size = max_batch_size; +} + +static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg, + u32 max_batch_shift) +{ + if (idxd_type == IDXD_TYPE_IAX) + wqcfg->max_batch_shift = 0; + else + wqcfg->max_batch_shift = max_batch_shift; +} + int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, struct module *module, const char *mod_name); #define idxd_driver_register(driver) \ diff -Nru linux-6.0.6/drivers/dma/idxd/init.c linux-6.0.12/drivers/dma/idxd/init.c --- linux-6.0.6/drivers/dma/idxd/init.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/idxd/init.c 2023-01-18 18:27:39.000000000 +0000 @@ -177,7 +177,7 @@ init_completion(&wq->wq_dead); init_completion(&wq->wq_resurrect); wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER; - wq->max_batch_size = WQ_DEFAULT_MAX_BATCH; + idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH); wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES; wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev)); if (!wq->wqcfg) { @@ -369,6 +369,19 @@ dev_dbg(dev, "IDXD Perfmon Offset: %#x\n", idxd->perfmon_offset); } +static void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count) +{ + int i, j, nr; + + for (i = 0, nr = 0; i < count; i++) { + for (j = 0; j < BITS_PER_LONG_LONG; j++) { + if (val[i] & BIT(j)) + set_bit(nr, bmap); + nr++; + } + } +} + static void idxd_read_caps(struct idxd_device *idxd) { struct device *dev = &idxd->pdev->dev; @@ -389,7 +402,7 @@ idxd->max_xfer_bytes = 1ULL << idxd->hw.gen_cap.max_xfer_shift; dev_dbg(dev, "max xfer size: %llu bytes\n", idxd->max_xfer_bytes); - idxd->max_batch_size = 1U << idxd->hw.gen_cap.max_batch_shift; + idxd_set_max_batch_size(idxd->data->type, idxd, 1U << idxd->hw.gen_cap.max_batch_shift); dev_dbg(dev, "max batch size: %u\n", idxd->max_batch_size); if (idxd->hw.gen_cap.config_en) set_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags); @@ -427,6 +440,7 @@ IDXD_OPCAP_OFFSET + i * sizeof(u64)); dev_dbg(dev, "opcap[%d]: %#llx\n", i, idxd->hw.opcap.bits[i]); } + multi_u64_to_bmap(idxd->opcap_bmap, &idxd->hw.opcap.bits[0], 4); } static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data) @@ -448,6 +462,12 @@ if (idxd->id < 0) return NULL; + idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev)); + if (!idxd->opcap_bmap) { + ida_free(&idxd_ida, idxd->id); + return NULL; + } + device_initialize(conf_dev); conf_dev->parent = dev; conf_dev->bus = &dsa_bus_type; diff -Nru linux-6.0.6/drivers/dma/idxd/registers.h linux-6.0.12/drivers/dma/idxd/registers.h --- linux-6.0.6/drivers/dma/idxd/registers.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/idxd/registers.h 2023-01-18 18:27:39.000000000 +0000 @@ -90,6 +90,8 @@ u64 bits[4]; }; +#define IDXD_MAX_OPCAP_BITS 256U + #define IDXD_OPCAP_OFFSET 0x40 #define IDXD_TABLE_OFFSET 0x60 diff -Nru linux-6.0.6/drivers/dma/idxd/sysfs.c linux-6.0.12/drivers/dma/idxd/sysfs.c --- linux-6.0.6/drivers/dma/idxd/sysfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/idxd/sysfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -961,7 +961,7 @@ if (batch_size > idxd->max_batch_size) return -EINVAL; - wq->max_batch_size = (u32)batch_size; + idxd_wq_set_max_batch_size(idxd->data->type, wq, (u32)batch_size); return count; } @@ -1177,14 +1177,8 @@ struct device_attribute *attr, char *buf) { struct idxd_device *idxd = confdev_to_idxd(dev); - int i, rc = 0; - for (i = 0; i < 4; i++) - rc += sysfs_emit_at(buf, rc, "%#llx ", idxd->hw.opcap.bits[i]); - - rc--; - rc += sysfs_emit_at(buf, rc, "\n"); - return rc; + return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, idxd->opcap_bmap); } static DEVICE_ATTR_RO(op_cap); @@ -1408,6 +1402,7 @@ kfree(idxd->wqs); kfree(idxd->engines); ida_free(&idxd_ida, idxd->id); + bitmap_free(idxd->opcap_bmap); kfree(idxd); } diff -Nru linux-6.0.6/drivers/dma/mv_xor_v2.c linux-6.0.12/drivers/dma/mv_xor_v2.c --- linux-6.0.6/drivers/dma/mv_xor_v2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/mv_xor_v2.c 2023-01-18 18:27:39.000000000 +0000 @@ -893,6 +893,7 @@ tasklet_kill(&xor_dev->irq_tasklet); clk_disable_unprepare(xor_dev->clk); + clk_disable_unprepare(xor_dev->reg_clk); return 0; } diff -Nru linux-6.0.6/drivers/dma/pxa_dma.c linux-6.0.12/drivers/dma/pxa_dma.c --- linux-6.0.6/drivers/dma/pxa_dma.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/pxa_dma.c 2023-01-18 18:27:39.000000000 +0000 @@ -1247,14 +1247,14 @@ return -ENOMEM; for (i = 0; i < nb_phy_chans; i++) - if (platform_get_irq(op, i) > 0) + if (platform_get_irq_optional(op, i) > 0) nr_irq++; for (i = 0; i < nb_phy_chans; i++) { phy = &pdev->phys[i]; phy->base = pdev->base; phy->idx = i; - irq = platform_get_irq(op, i); + irq = platform_get_irq_optional(op, i); if ((nr_irq > 1) && (irq > 0)) ret = devm_request_irq(&op->dev, irq, pxad_chan_handler, diff -Nru linux-6.0.6/drivers/dma/stm32-dma.c linux-6.0.12/drivers/dma/stm32-dma.c --- linux-6.0.6/drivers/dma/stm32-dma.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/stm32-dma.c 2023-01-18 18:27:39.000000000 +0000 @@ -663,6 +663,8 @@ chan->chan_reg.dma_sndtr = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id)); + chan->status = DMA_PAUSED; + dev_dbg(chan2dev(chan), "vchan %pK: paused\n", &chan->vchan); } @@ -775,9 +777,7 @@ if (status & STM32_DMA_TCI) { stm32_dma_irq_clear(chan, STM32_DMA_TCI); if (scr & STM32_DMA_SCR_TCIE) { - if (chan->status == DMA_PAUSED && !(scr & STM32_DMA_SCR_EN)) - stm32_dma_handle_chan_paused(chan); - else + if (chan->status != DMA_PAUSED) stm32_dma_handle_chan_done(chan, scr); } status &= ~STM32_DMA_TCI; @@ -824,13 +824,11 @@ return -EPERM; spin_lock_irqsave(&chan->vchan.lock, flags); + ret = stm32_dma_disable_chan(chan); - /* - * A transfer complete flag is set to indicate the end of transfer due to the stream - * interruption, so wait for interrupt - */ if (!ret) - chan->status = DMA_PAUSED; + stm32_dma_handle_chan_paused(chan); + spin_unlock_irqrestore(&chan->vchan.lock, flags); return ret; diff -Nru linux-6.0.6/drivers/dma/ti/k3-udma-glue.c linux-6.0.12/drivers/dma/ti/k3-udma-glue.c --- linux-6.0.6/drivers/dma/ti/k3-udma-glue.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma/ti/k3-udma-glue.c 2023-01-18 18:27:39.000000000 +0000 @@ -299,6 +299,7 @@ ret = device_register(&tx_chn->common.chan_dev); if (ret) { dev_err(dev, "Channel Device registration failed %d\n", ret); + put_device(&tx_chn->common.chan_dev); tx_chn->common.chan_dev.parent = NULL; goto err; } @@ -917,6 +918,7 @@ ret = device_register(&rx_chn->common.chan_dev); if (ret) { dev_err(dev, "Channel Device registration failed %d\n", ret); + put_device(&rx_chn->common.chan_dev); rx_chn->common.chan_dev.parent = NULL; goto err; } @@ -1048,6 +1050,7 @@ ret = device_register(&rx_chn->common.chan_dev); if (ret) { dev_err(dev, "Channel Device registration failed %d\n", ret); + put_device(&rx_chn->common.chan_dev); rx_chn->common.chan_dev.parent = NULL; goto err; } diff -Nru linux-6.0.6/drivers/dma-buf/dma-buf.c linux-6.0.12/drivers/dma-buf/dma-buf.c --- linux-6.0.6/drivers/dma-buf/dma-buf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma-buf/dma-buf.c 2023-01-18 18:27:39.000000000 +0000 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -391,8 +392,10 @@ const void __user *user_data) { struct dma_buf_import_sync_file arg; - struct dma_fence *fence; + struct dma_fence *fence, *f; enum dma_resv_usage usage; + struct dma_fence_unwrap iter; + unsigned int num_fences; int ret = 0; if (copy_from_user(&arg, user_data, sizeof(arg))) @@ -411,13 +414,21 @@ usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ; - dma_resv_lock(dmabuf->resv, NULL); - - ret = dma_resv_reserve_fences(dmabuf->resv, 1); - if (!ret) - dma_resv_add_fence(dmabuf->resv, fence, usage); + num_fences = 0; + dma_fence_unwrap_for_each(f, &iter, fence) + ++num_fences; + + if (num_fences > 0) { + dma_resv_lock(dmabuf->resv, NULL); + + ret = dma_resv_reserve_fences(dmabuf->resv, num_fences); + if (!ret) { + dma_fence_unwrap_for_each(f, &iter, fence) + dma_resv_add_fence(dmabuf->resv, f, usage); + } - dma_resv_unlock(dmabuf->resv); + dma_resv_unlock(dmabuf->resv); + } dma_fence_put(fence); diff -Nru linux-6.0.6/drivers/dma-buf/dma-heap.c linux-6.0.12/drivers/dma-buf/dma-heap.c --- linux-6.0.6/drivers/dma-buf/dma-heap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/dma-buf/dma-heap.c 2023-01-18 18:27:39.000000000 +0000 @@ -233,18 +233,6 @@ return ERR_PTR(-EINVAL); } - /* check the name is unique */ - mutex_lock(&heap_list_lock); - list_for_each_entry(h, &heap_list, list) { - if (!strcmp(h->name, exp_info->name)) { - mutex_unlock(&heap_list_lock); - pr_err("dma_heap: Already registered heap named %s\n", - exp_info->name); - return ERR_PTR(-EINVAL); - } - } - mutex_unlock(&heap_list_lock); - heap = kzalloc(sizeof(*heap), GFP_KERNEL); if (!heap) return ERR_PTR(-ENOMEM); @@ -283,13 +271,27 @@ err_ret = ERR_CAST(dev_ret); goto err2; } - /* Add heap to the list */ + mutex_lock(&heap_list_lock); + /* check the name is unique */ + list_for_each_entry(h, &heap_list, list) { + if (!strcmp(h->name, exp_info->name)) { + mutex_unlock(&heap_list_lock); + pr_err("dma_heap: Already registered heap named %s\n", + exp_info->name); + err_ret = ERR_PTR(-EINVAL); + goto err3; + } + } + + /* Add heap to the list */ list_add(&heap->list, &heap_list); mutex_unlock(&heap_list_lock); return heap; +err3: + device_destroy(dma_heap_class, heap->heap_devt); err2: cdev_del(&heap->heap_cdev); err1: diff -Nru linux-6.0.6/drivers/firmware/arm_scmi/bus.c linux-6.0.12/drivers/firmware/arm_scmi/bus.c --- linux-6.0.6/drivers/firmware/arm_scmi/bus.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/arm_scmi/bus.c 2023-01-18 18:27:39.000000000 +0000 @@ -216,9 +216,20 @@ device_unregister(&scmi_dev->dev); } +void scmi_device_link_add(struct device *consumer, struct device *supplier) +{ + struct device_link *link; + + link = device_link_add(consumer, supplier, DL_FLAG_AUTOREMOVE_CONSUMER); + + WARN_ON(!link); +} + void scmi_set_handle(struct scmi_device *scmi_dev) { scmi_dev->handle = scmi_handle_get(&scmi_dev->dev); + if (scmi_dev->handle) + scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev); } int scmi_protocol_register(const struct scmi_protocol *proto) diff -Nru linux-6.0.6/drivers/firmware/arm_scmi/common.h linux-6.0.12/drivers/firmware/arm_scmi/common.h --- linux-6.0.6/drivers/firmware/arm_scmi/common.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/arm_scmi/common.h 2023-01-18 18:27:39.000000000 +0000 @@ -97,6 +97,7 @@ struct scmi_revision_info * scmi_revision_area_get(const struct scmi_protocol_handle *ph); int scmi_handle_put(const struct scmi_handle *handle); +void scmi_device_link_add(struct device *consumer, struct device *supplier); struct scmi_handle *scmi_handle_get(struct device *dev); void scmi_set_handle(struct scmi_device *scmi_dev); void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph, @@ -117,6 +118,7 @@ * * @dev: Reference to device in the SCMI hierarchy corresponding to this * channel + * @rx_timeout_ms: The configured RX timeout in milliseconds. * @handle: Pointer to SCMI entity handle * @no_completion_irq: Flag to indicate that this channel has no completion * interrupt mechanism for synchronous commands. @@ -126,6 +128,7 @@ */ struct scmi_chan_info { struct device *dev; + unsigned int rx_timeout_ms; struct scmi_handle *handle; bool no_completion_irq; void *transport_info; @@ -232,7 +235,7 @@ struct scmi_shared_mem; void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, - struct scmi_xfer *xfer); + struct scmi_xfer *xfer, struct scmi_chan_info *cinfo); u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem); void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, struct scmi_xfer *xfer); diff -Nru linux-6.0.6/drivers/firmware/arm_scmi/driver.c linux-6.0.12/drivers/firmware/arm_scmi/driver.c --- linux-6.0.6/drivers/firmware/arm_scmi/driver.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/arm_scmi/driver.c 2023-01-18 18:27:39.000000000 +0000 @@ -2013,6 +2013,7 @@ return -ENOMEM; cinfo->dev = dev; + cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms; ret = info->desc->ops->chan_setup(cinfo, info->dev, tx); if (ret) @@ -2044,8 +2045,12 @@ { int ret = scmi_chan_setup(info, dev, prot_id, true); - if (!ret) /* Rx is optional, hence no error check */ - scmi_chan_setup(info, dev, prot_id, false); + if (!ret) { + /* Rx is optional, report only memory errors */ + ret = scmi_chan_setup(info, dev, prot_id, false); + if (ret && ret != -ENOMEM) + ret = 0; + } return ret; } @@ -2273,10 +2278,16 @@ sdev = scmi_get_protocol_device(child, info, id_table->protocol_id, id_table->name); - /* Set handle if not already set: device existed */ - if (sdev && !sdev->handle) - sdev->handle = - scmi_handle_get_from_info_unlocked(info); + if (sdev) { + /* Set handle if not already set: device existed */ + if (!sdev->handle) + sdev->handle = + scmi_handle_get_from_info_unlocked(info); + /* Relink consumer and suppliers */ + if (sdev->handle) + scmi_device_link_add(&sdev->dev, + sdev->handle->dev); + } } else { dev_err(info->dev, "Failed. SCMI protocol %d not active.\n", @@ -2475,20 +2486,17 @@ static int scmi_remove(struct platform_device *pdev) { - int ret = 0, id; + int ret, id; struct scmi_info *info = platform_get_drvdata(pdev); struct device_node *child; mutex_lock(&scmi_list_mutex); if (info->users) - ret = -EBUSY; - else - list_del(&info->node); + dev_warn(&pdev->dev, + "Still active SCMI users will be forcibly unbound.\n"); + list_del(&info->node); mutex_unlock(&scmi_list_mutex); - if (ret) - return ret; - scmi_notification_exit(&info->handle); mutex_lock(&info->protocols_mtx); @@ -2500,7 +2508,11 @@ idr_destroy(&info->active_protocols); /* Safe to free channels since no more users */ - return scmi_cleanup_txrx_channels(info); + ret = scmi_cleanup_txrx_channels(info); + if (ret) + dev_warn(&pdev->dev, "Failed to cleanup SCMI channels.\n"); + + return 0; } static ssize_t protocol_version_show(struct device *dev, @@ -2571,6 +2583,7 @@ static struct platform_driver scmi_driver = { .driver = { .name = "arm-scmi", + .suppress_bind_attrs = true, .of_match_table = scmi_of_match, .dev_groups = versions_groups, }, diff -Nru linux-6.0.6/drivers/firmware/arm_scmi/mailbox.c linux-6.0.12/drivers/firmware/arm_scmi/mailbox.c --- linux-6.0.6/drivers/firmware/arm_scmi/mailbox.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/arm_scmi/mailbox.c 2023-01-18 18:27:39.000000000 +0000 @@ -36,7 +36,7 @@ { struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl); - shmem_tx_prepare(smbox->shmem, m); + shmem_tx_prepare(smbox->shmem, m, smbox->cinfo); } static void rx_callback(struct mbox_client *cl, void *m) diff -Nru linux-6.0.6/drivers/firmware/arm_scmi/optee.c linux-6.0.12/drivers/firmware/arm_scmi/optee.c --- linux-6.0.6/drivers/firmware/arm_scmi/optee.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/arm_scmi/optee.c 2023-01-18 18:27:39.000000000 +0000 @@ -498,7 +498,7 @@ msg_tx_prepare(channel->req.msg, xfer); ret = invoke_process_msg_channel(channel, msg_command_size(xfer)); } else { - shmem_tx_prepare(channel->req.shmem, xfer); + shmem_tx_prepare(channel->req.shmem, xfer, cinfo); ret = invoke_process_smt_channel(channel); } diff -Nru linux-6.0.6/drivers/firmware/arm_scmi/shmem.c linux-6.0.12/drivers/firmware/arm_scmi/shmem.c --- linux-6.0.6/drivers/firmware/arm_scmi/shmem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/arm_scmi/shmem.c 2023-01-18 18:27:39.000000000 +0000 @@ -5,10 +5,13 @@ * Copyright (C) 2019 ARM Ltd. */ +#include #include #include #include +#include + #include "common.h" /* @@ -30,16 +33,36 @@ }; void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, - struct scmi_xfer *xfer) + struct scmi_xfer *xfer, struct scmi_chan_info *cinfo) { + ktime_t stop; + /* * Ideally channel must be free by now unless OS timeout last * request and platform continued to process the same, wait * until it releases the shared memory, otherwise we may endup - * overwriting its response with new message payload or vice-versa + * overwriting its response with new message payload or vice-versa. + * Giving up anyway after twice the expected channel timeout so as + * not to bail-out on intermittent issues where the platform is + * occasionally a bit slower to answer. + * + * Note that after a timeout is detected we bail-out and carry on but + * the transport functionality is probably permanently compromised: + * this is just to ease debugging and avoid complete hangs on boot + * due to a misbehaving SCMI firmware. */ - spin_until_cond(ioread32(&shmem->channel_status) & - SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); + stop = ktime_add_ms(ktime_get(), 2 * cinfo->rx_timeout_ms); + spin_until_cond((ioread32(&shmem->channel_status) & + SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE) || + ktime_after(ktime_get(), stop)); + if (!(ioread32(&shmem->channel_status) & + SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) { + WARN_ON_ONCE(1); + dev_err(cinfo->dev, + "Timeout waiting for a free TX channel !\n"); + return; + } + /* Mark channel busy + clear error */ iowrite32(0x0, &shmem->channel_status); iowrite32(xfer->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED, diff -Nru linux-6.0.6/drivers/firmware/arm_scmi/smc.c linux-6.0.12/drivers/firmware/arm_scmi/smc.c --- linux-6.0.6/drivers/firmware/arm_scmi/smc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/arm_scmi/smc.c 2023-01-18 18:27:39.000000000 +0000 @@ -188,7 +188,7 @@ */ smc_channel_lock_acquire(scmi_info, xfer); - shmem_tx_prepare(scmi_info->shmem, xfer); + shmem_tx_prepare(scmi_info->shmem, xfer, cinfo); arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res); diff -Nru linux-6.0.6/drivers/firmware/arm_scmi/virtio.c linux-6.0.12/drivers/firmware/arm_scmi/virtio.c --- linux-6.0.6/drivers/firmware/arm_scmi/virtio.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/arm_scmi/virtio.c 2023-01-18 18:27:39.000000000 +0000 @@ -148,7 +148,6 @@ { unsigned long flags; DECLARE_COMPLETION_ONSTACK(vioch_shutdown_done); - void *deferred_wq = NULL; /* * Prepare to wait for the last release if not already released @@ -162,16 +161,11 @@ vioch->shutdown_done = &vioch_shutdown_done; virtio_break_device(vioch->vqueue->vdev); - if (!vioch->is_rx && vioch->deferred_tx_wq) { - deferred_wq = vioch->deferred_tx_wq; + if (!vioch->is_rx && vioch->deferred_tx_wq) /* Cannot be kicked anymore after this...*/ vioch->deferred_tx_wq = NULL; - } spin_unlock_irqrestore(&vioch->lock, flags); - if (deferred_wq) - destroy_workqueue(deferred_wq); - scmi_vio_channel_release(vioch); /* Let any possibly concurrent RX path release the channel */ @@ -416,6 +410,11 @@ return vioch && !vioch->cinfo; } +static void scmi_destroy_tx_workqueue(void *deferred_tx_wq) +{ + destroy_workqueue(deferred_tx_wq); +} + static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, bool tx) { @@ -430,6 +429,8 @@ /* Setup a deferred worker for polling. */ if (tx && !vioch->deferred_tx_wq) { + int ret; + vioch->deferred_tx_wq = alloc_workqueue(dev_name(&scmi_vdev->dev), WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS, @@ -437,6 +438,11 @@ if (!vioch->deferred_tx_wq) return -ENOMEM; + ret = devm_add_action_or_reset(dev, scmi_destroy_tx_workqueue, + vioch->deferred_tx_wq); + if (ret) + return ret; + INIT_WORK(&vioch->deferred_tx_work, scmi_vio_deferred_tx_worker); } @@ -444,12 +450,12 @@ for (i = 0; i < vioch->max_msg; i++) { struct scmi_vio_msg *msg; - msg = devm_kzalloc(cinfo->dev, sizeof(*msg), GFP_KERNEL); + msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL); if (!msg) return -ENOMEM; if (tx) { - msg->request = devm_kzalloc(cinfo->dev, + msg->request = devm_kzalloc(dev, VIRTIO_SCMI_MAX_PDU_SIZE, GFP_KERNEL); if (!msg->request) @@ -458,7 +464,7 @@ refcount_set(&msg->users, 1); } - msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE, + msg->input = devm_kzalloc(dev, VIRTIO_SCMI_MAX_PDU_SIZE, GFP_KERNEL); if (!msg->input) return -ENOMEM; diff -Nru linux-6.0.6/drivers/firmware/efi/efi.c linux-6.0.12/drivers/firmware/efi/efi.c --- linux-6.0.6/drivers/firmware/efi/efi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/efi/efi.c 2023-01-18 18:27:39.000000000 +0000 @@ -608,7 +608,7 @@ seed = early_memremap(efi_rng_seed, sizeof(*seed)); if (seed != NULL) { - size = READ_ONCE(seed->size); + size = min(seed->size, EFI_RANDOM_SEED_SIZE); early_memunmap(seed, sizeof(*seed)); } else { pr_err("Could not map UEFI random seed!\n"); diff -Nru linux-6.0.6/drivers/firmware/efi/libstub/random.c linux-6.0.12/drivers/firmware/efi/libstub/random.c --- linux-6.0.6/drivers/firmware/efi/libstub/random.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/efi/libstub/random.c 2023-01-18 18:27:39.000000000 +0000 @@ -75,7 +75,12 @@ if (status != EFI_SUCCESS) return status; - status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA, + /* + * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the + * allocation will survive a kexec reboot (although we refresh the seed + * beforehand) + */ + status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, sizeof(*seed) + EFI_RANDOM_SEED_SIZE, (void **)&seed); if (status != EFI_SUCCESS) diff -Nru linux-6.0.6/drivers/firmware/efi/tpm.c linux-6.0.12/drivers/firmware/efi/tpm.c --- linux-6.0.6/drivers/firmware/efi/tpm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/efi/tpm.c 2023-01-18 18:27:39.000000000 +0000 @@ -97,7 +97,7 @@ goto out_calc; } - memblock_reserve((unsigned long)final_tbl, + memblock_reserve(efi.tpm_final_log, tbl_size + sizeof(*final_tbl)); efi_tpm_final_log_size = tbl_size; diff -Nru linux-6.0.6/drivers/firmware/efi/vars.c linux-6.0.12/drivers/firmware/efi/vars.c --- linux-6.0.6/drivers/firmware/efi/vars.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/efi/vars.c 2023-01-18 18:27:39.000000000 +0000 @@ -21,29 +21,22 @@ static DEFINE_SEMAPHORE(efivars_lock); -static efi_status_t check_var_size(u32 attributes, unsigned long size) -{ - const struct efivar_operations *fops; - - fops = __efivars->ops; - - if (!fops->query_variable_store) - return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES; - - return fops->query_variable_store(attributes, size, false); -} - -static -efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size) +static efi_status_t check_var_size(bool nonblocking, u32 attributes, + unsigned long size) { const struct efivar_operations *fops; + efi_status_t status; fops = __efivars->ops; if (!fops->query_variable_store) + status = EFI_UNSUPPORTED; + else + status = fops->query_variable_store(attributes, size, + nonblocking); + if (status == EFI_UNSUPPORTED) return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES; - - return fops->query_variable_store(attributes, size, true); + return status; } /** @@ -196,26 +189,6 @@ EXPORT_SYMBOL_NS_GPL(efivar_get_next_variable, EFIVAR); /* - * efivar_set_variable_blocking() - local helper function for set_variable - * - * Must be called with efivars_lock held. - */ -static efi_status_t -efivar_set_variable_blocking(efi_char16_t *name, efi_guid_t *vendor, - u32 attr, unsigned long data_size, void *data) -{ - efi_status_t status; - - if (data_size > 0) { - status = check_var_size(attr, data_size + - ucs2_strsize(name, 1024)); - if (status != EFI_SUCCESS) - return status; - } - return __efivars->ops->set_variable(name, vendor, attr, data_size, data); -} - -/* * efivar_set_variable_locked() - set a variable identified by name/vendor * * Must be called with efivars_lock held. If @nonblocking is set, it will use @@ -228,23 +201,21 @@ efi_set_variable_t *setvar; efi_status_t status; - if (!nonblocking) - return efivar_set_variable_blocking(name, vendor, attr, - data_size, data); + if (data_size > 0) { + status = check_var_size(nonblocking, attr, + data_size + ucs2_strsize(name, 1024)); + if (status != EFI_SUCCESS) + return status; + } /* * If no _nonblocking variant exists, the ordinary one * is assumed to be non-blocking. */ - setvar = __efivars->ops->set_variable_nonblocking ?: - __efivars->ops->set_variable; + setvar = __efivars->ops->set_variable_nonblocking; + if (!setvar || !nonblocking) + setvar = __efivars->ops->set_variable; - if (data_size > 0) { - status = check_var_size_nonblocking(attr, data_size + - ucs2_strsize(name, 1024)); - if (status != EFI_SUCCESS) - return status; - } return setvar(name, vendor, attr, data_size, data); } EXPORT_SYMBOL_NS_GPL(efivar_set_variable_locked, EFIVAR); @@ -264,7 +235,8 @@ if (efivar_lock()) return EFI_ABORTED; - status = efivar_set_variable_blocking(name, vendor, attr, data_size, data); + status = efivar_set_variable_locked(name, vendor, attr, data_size, + data, false); efivar_unlock(); return status; } diff -Nru linux-6.0.6/drivers/firmware/google/coreboot_table.c linux-6.0.12/drivers/firmware/google/coreboot_table.c --- linux-6.0.6/drivers/firmware/google/coreboot_table.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/firmware/google/coreboot_table.c 2023-01-18 18:27:39.000000000 +0000 @@ -149,12 +149,8 @@ if (!ptr) return -ENOMEM; - ret = bus_register(&coreboot_bus_type); - if (!ret) { - ret = coreboot_table_populate(dev, ptr); - if (ret) - bus_unregister(&coreboot_bus_type); - } + ret = coreboot_table_populate(dev, ptr); + memunmap(ptr); return ret; @@ -169,7 +165,6 @@ static int coreboot_table_remove(struct platform_device *pdev) { bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister); - bus_unregister(&coreboot_bus_type); return 0; } @@ -199,6 +194,32 @@ .of_match_table = of_match_ptr(coreboot_of_match), }, }; -module_platform_driver(coreboot_table_driver); + +static int __init coreboot_table_driver_init(void) +{ + int ret; + + ret = bus_register(&coreboot_bus_type); + if (ret) + return ret; + + ret = platform_driver_register(&coreboot_table_driver); + if (ret) { + bus_unregister(&coreboot_bus_type); + return ret; + } + + return 0; +} + +static void __exit coreboot_table_driver_exit(void) +{ + platform_driver_unregister(&coreboot_table_driver); + bus_unregister(&coreboot_bus_type); +} + +module_init(coreboot_table_driver_init); +module_exit(coreboot_table_driver_exit); + MODULE_AUTHOR("Google, Inc."); MODULE_LICENSE("GPL"); diff -Nru linux-6.0.6/drivers/fpga/Kconfig linux-6.0.12/drivers/fpga/Kconfig --- linux-6.0.6/drivers/fpga/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/fpga/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -246,7 +246,9 @@ config FPGA_M10_BMC_SEC_UPDATE tristate "Intel MAX10 BMC Secure Update driver" - depends on MFD_INTEL_M10_BMC && FW_UPLOAD + depends on MFD_INTEL_M10_BMC + select FW_LOADER + select FW_UPLOAD help Secure update support for the Intel MAX10 board management controller. diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c 2023-01-18 18:27:39.000000000 +0000 @@ -41,5 +41,6 @@ .get_atc_vmid_pasid_mapping_info = kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, .set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base, + .get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy, .program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings }; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c 2023-01-18 18:27:39.000000000 +0000 @@ -703,6 +703,13 @@ void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle) { + /* Temporary workaround to fix issues observed in some + * compute applications when GFXOFF is enabled on GFX11. + */ + if (IP_VERSION_MAJ(adev->ip_versions[GC_HWIP][0]) == 11) { + pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled"); + amdgpu_gfx_off_ctrl(adev, idle); + } amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_COMPUTE, !idle); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c 2023-01-18 18:27:39.000000000 +0000 @@ -111,7 +111,7 @@ lock_srbm(adev, mec, pipe, 0, 0); - WREG32(SOC15_REG_OFFSET(GC, 0, regCPC_INT_CNTL), + WREG32_SOC15(GC, 0, regCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK | CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 2023-01-18 18:27:39.000000000 +0000 @@ -170,9 +170,7 @@ (kfd_mem_limit.ttm_mem_used + ttm_mem_needed > kfd_mem_limit.max_ttm_mem_limit) || (adev && adev->kfd.vram_used + vram_needed > - adev->gmc.real_vram_size - - atomic64_read(&adev->vram_pin_size) - - reserved_for_pt)) { + adev->gmc.real_vram_size - reserved_for_pt)) { ret = -ENOMEM; goto release; } @@ -509,13 +507,13 @@ struct ttm_tt *ttm = bo->tbo.ttm; int ret; + if (WARN_ON(ttm->num_pages != src_ttm->num_pages)) + return -EINVAL; + ttm->sg = kmalloc(sizeof(*ttm->sg), GFP_KERNEL); if (unlikely(!ttm->sg)) return -ENOMEM; - if (WARN_ON(ttm->num_pages != src_ttm->num_pages)) - return -EINVAL; - /* Same sequence as in amdgpu_ttm_tt_pin_userptr */ ret = sg_alloc_table_from_pages(ttm->sg, src_ttm->pages, ttm->num_pages, 0, @@ -987,6 +985,7 @@ struct amdkfd_process_info *process_info = mem->process_info; struct amdgpu_bo *bo = mem->bo; struct ttm_operation_ctx ctx = { true, false }; + struct hmm_range *range; int ret = 0; mutex_lock(&process_info->lock); @@ -1016,7 +1015,7 @@ return 0; } - ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); + ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, &range); if (ret) { pr_err("%s: Failed to get user pages: %d\n", __func__, ret); goto unregister_out; @@ -1034,7 +1033,7 @@ amdgpu_bo_unreserve(bo); release_out: - amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range); unregister_out: if (ret) amdgpu_mn_unregister(bo); @@ -2369,6 +2368,8 @@ /* Go through userptr_inval_list and update any invalid user_pages */ list_for_each_entry(mem, &process_info->userptr_inval_list, validate_list.head) { + struct hmm_range *range; + invalid = atomic_read(&mem->invalid); if (!invalid) /* BO hasn't been invalidated since the last @@ -2379,7 +2380,8 @@ bo = mem->bo; /* Get updated user pages */ - ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); + ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, + &range); if (ret) { pr_debug("Failed %d to get user pages\n", ret); @@ -2398,7 +2400,7 @@ * FIXME: Cannot ignore the return code, must hold * notifier_lock */ - amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range); } /* Mark the BO as valid unless it was invalidated diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c 2023-01-18 18:27:39.000000000 +0000 @@ -209,6 +209,7 @@ list_add_tail(&e->tv.head, &bucket[priority]); e->user_pages = NULL; + e->range = NULL; } /* Connect the sorted buckets in the output list. */ diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h 2023-01-18 18:27:39.000000000 +0000 @@ -26,6 +26,8 @@ #include #include +struct hmm_range; + struct amdgpu_device; struct amdgpu_bo; struct amdgpu_bo_va; @@ -36,6 +38,7 @@ struct amdgpu_bo_va *bo_va; uint32_t priority; struct page **user_pages; + struct hmm_range *range; bool user_invalidated; }; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c 2023-01-18 18:27:39.000000000 +0000 @@ -328,7 +328,6 @@ kfree(amdgpu_connector->edid); amdgpu_connector->edid = NULL; - drm_connector_update_edid_property(connector, NULL); } static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 2023-01-18 18:27:39.000000000 +0000 @@ -495,9 +495,6 @@ struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_bo_list_entry *e; struct list_head duplicates; - struct amdgpu_bo *gds; - struct amdgpu_bo *gws; - struct amdgpu_bo *oa; int r; INIT_LIST_HEAD(&p->validated); @@ -551,7 +548,7 @@ goto out_free_user_pages; } - r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages); + r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages, &e->range); if (r) { kvfree(e->user_pages); e->user_pages = NULL; @@ -611,49 +608,35 @@ if (r) goto error_validate; - amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved, - p->bytes_moved_vis); - - gds = p->bo_list->gds_obj; - gws = p->bo_list->gws_obj; - oa = p->bo_list->oa_obj; - - if (gds) { - p->job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT; - p->job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT; - } - if (gws) { - p->job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT; - p->job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT; - } - if (oa) { - p->job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT; - p->job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT; - } - - if (!r && p->uf_entry.tv.bo) { + if (p->uf_entry.tv.bo) { struct amdgpu_bo *uf = ttm_to_amdgpu_bo(p->uf_entry.tv.bo); r = amdgpu_ttm_alloc_gart(&uf->tbo); + if (r) + goto error_validate; + p->job->uf_addr += amdgpu_bo_gpu_offset(uf); } + amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved, + p->bytes_moved_vis); + amdgpu_job_set_resources(p->job, p->bo_list->gds_obj, + p->bo_list->gws_obj, p->bo_list->oa_obj); + return 0; + error_validate: - if (r) - ttm_eu_backoff_reservation(&p->ticket, &p->validated); + ttm_eu_backoff_reservation(&p->ticket, &p->validated); out_free_user_pages: - if (r) { - amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { - struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo); + amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { + struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo); - if (!e->user_pages) - continue; - amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); - kvfree(e->user_pages); - e->user_pages = NULL; - } - mutex_unlock(&p->bo_list->bo_list_mutex); + if (!e->user_pages) + continue; + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range); + kvfree(e->user_pages); + e->user_pages = NULL; + e->range = NULL; } return r; } @@ -1248,7 +1231,8 @@ amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo); - r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); + r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range); + e->range = NULL; } if (r) { r = -EAGAIN; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 2023-01-18 18:27:39.000000000 +0000 @@ -327,7 +327,10 @@ if (r) return r; - ctx->stable_pstate = current_stable_pstate; + if (mgr->adev->pm.stable_pstate_ctx) + ctx->stable_pstate = mgr->adev->pm.stable_pstate_ctx->stable_pstate; + else + ctx->stable_pstate = current_stable_pstate; return 0; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 2023-01-18 18:27:39.000000000 +0000 @@ -3208,6 +3208,15 @@ return r; } adev->ip_blocks[i].status.hw = true; + + if (adev->in_s0ix && adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) { + /* disable gfxoff for IP resume. The gfxoff will be re-enabled in + * amdgpu_device_resume() after IP resume. + */ + amdgpu_gfx_off_ctrl(adev, false); + DRM_DEBUG("will disable gfxoff for re-initializing other blocks\n"); + } + } return 0; @@ -4046,15 +4055,18 @@ * at suspend time. * */ -static void amdgpu_device_evict_resources(struct amdgpu_device *adev) +static int amdgpu_device_evict_resources(struct amdgpu_device *adev) { + int ret; + /* No need to evict vram on APUs for suspend to ram or s2idle */ if ((adev->in_s3 || adev->in_s0ix) && (adev->flags & AMD_IS_APU)) - return; + return 0; - if (amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM)) + ret = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM); + if (ret) DRM_WARN("evicting device resources failed\n"); - + return ret; } /* @@ -4104,7 +4116,9 @@ if (!adev->in_s0ix) amdgpu_amdkfd_suspend(adev, adev->in_runpm); - amdgpu_device_evict_resources(adev); + r = amdgpu_device_evict_resources(adev); + if (r) + return r; amdgpu_fence_driver_hw_fini(adev); @@ -4180,6 +4194,13 @@ /* Make sure IB tests flushed */ flush_delayed_work(&adev->delayed_init_work); + if (adev->in_s0ix) { + /* re-enable gfxoff after IP resume. This re-enables gfxoff after + * it was disabled for IP resume in amdgpu_device_ip_resume_phase2(). + */ + amdgpu_gfx_off_ctrl(adev, true); + DRM_DEBUG("will enable gfxoff for the mission mode\n"); + } if (fbcon) drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 2023-01-18 18:27:39.000000000 +0000 @@ -378,6 +378,7 @@ struct amdgpu_device *adev = drm_to_adev(dev); struct drm_amdgpu_gem_userptr *args = data; struct drm_gem_object *gobj; + struct hmm_range *range; struct amdgpu_bo *bo; uint32_t handle; int r; @@ -413,14 +414,13 @@ if (r) goto release_object; - if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) { - r = amdgpu_mn_register(bo, args->addr); - if (r) - goto release_object; - } + r = amdgpu_mn_register(bo, args->addr); + if (r) + goto release_object; if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { - r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); + r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, + &range); if (r) goto release_object; @@ -443,7 +443,7 @@ user_pages_done: if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) - amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range); release_object: drm_gem_object_put(gobj); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 2023-01-18 18:27:39.000000000 +0000 @@ -479,6 +479,12 @@ unsigned i; unsigned vmhub, inv_eng; + if (adev->enable_mes) { + /* reserve engine 5 for firmware */ + for (vmhub = 0; vmhub < AMDGPU_MAX_VMHUBS; vmhub++) + vm_inv_engs[vmhub] &= ~(1 << 5); + } + for (i = 0; i < adev->num_rings; ++i) { ring = adev->rings[i]; vmhub = ring->funcs->vmhub; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 2023-01-18 18:27:39.000000000 +0000 @@ -129,6 +129,23 @@ return r; } +void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds, + struct amdgpu_bo *gws, struct amdgpu_bo *oa) +{ + if (gds) { + job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT; + job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT; + } + if (gws) { + job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT; + job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT; + } + if (oa) { + job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT; + job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT; + } +} + void amdgpu_job_free_resources(struct amdgpu_job *job) { struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h 2023-01-18 18:27:39.000000000 +0000 @@ -76,6 +76,8 @@ struct amdgpu_job **job, struct amdgpu_vm *vm); int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, enum amdgpu_ib_pool_type pool, struct amdgpu_job **job); +void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds, + struct amdgpu_bo *gws, struct amdgpu_bo *oa); void amdgpu_job_free_resources(struct amdgpu_job *job); void amdgpu_job_free(struct amdgpu_job *job); int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 2023-01-18 18:27:39.000000000 +0000 @@ -171,6 +171,7 @@ { amdgpu_bo_free_kernel(&mem_ctx->shared_bo, &mem_ctx->shared_mc_addr, &mem_ctx->shared_buf); + mem_ctx->shared_bo = NULL; } static void psp_free_shared_bufs(struct psp_context *psp) @@ -181,6 +182,7 @@ /* free TMR memory buffer */ pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr); + psp->tmr_bo = NULL; /* free xgmi shared memory */ psp_ta_free_shared_buf(&psp->xgmi_context.context.mem_context); @@ -728,7 +730,7 @@ /* Set up Trusted Memory Region */ static int psp_tmr_init(struct psp_context *psp) { - int ret; + int ret = 0; int tmr_size; void *tmr_buf; void **pptr; @@ -755,10 +757,12 @@ } } - pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; - ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT, - AMDGPU_GEM_DOMAIN_VRAM, - &psp->tmr_bo, &psp->tmr_mc_addr, pptr); + if (!psp->tmr_bo) { + pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; + ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT, + AMDGPU_GEM_DOMAIN_VRAM, + &psp->tmr_bo, &psp->tmr_mc_addr, pptr); + } return ret; } @@ -2720,8 +2724,6 @@ } out: - psp_free_shared_bufs(psp); - return ret; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 2023-01-18 18:27:39.000000000 +0000 @@ -424,8 +424,9 @@ static bool amdgpu_mem_visible(struct amdgpu_device *adev, struct ttm_resource *mem) { - uint64_t mem_size = (u64)mem->num_pages << PAGE_SHIFT; + u64 mem_size = (u64)mem->num_pages << PAGE_SHIFT; struct amdgpu_res_cursor cursor; + u64 end; if (mem->mem_type == TTM_PL_SYSTEM || mem->mem_type == TTM_PL_TT) @@ -434,12 +435,21 @@ return false; amdgpu_res_first(mem, 0, mem_size, &cursor); + end = cursor.start + cursor.size; + while (cursor.remaining) { + amdgpu_res_next(&cursor, cursor.size); - /* ttm_resource_ioremap only supports contiguous memory */ - if (cursor.size != mem_size) - return false; + if (!cursor.remaining) + break; + + /* ttm_resource_ioremap only supports contiguous memory */ + if (end != cursor.start) + return false; + + end = cursor.start + cursor.size; + } - return cursor.start + cursor.size <= adev->gmc.visible_vram_size; + return end <= adev->gmc.visible_vram_size; } /* @@ -632,9 +642,6 @@ struct task_struct *usertask; uint32_t userflags; bool bound; -#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) - struct hmm_range *range; -#endif }; #define ttm_to_amdgpu_ttm_tt(ptr) container_of(ptr, struct amdgpu_ttm_tt, ttm) @@ -647,7 +654,8 @@ * Calling function must call amdgpu_ttm_tt_userptr_range_done() once and only * once afterwards to stop HMM tracking */ -int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages) +int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages, + struct hmm_range **range) { struct ttm_tt *ttm = bo->tbo.ttm; struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm); @@ -657,16 +665,15 @@ bool readonly; int r = 0; + /* Make sure get_user_pages_done() can cleanup gracefully */ + *range = NULL; + mm = bo->notifier.mm; if (unlikely(!mm)) { DRM_DEBUG_DRIVER("BO is not registered?\n"); return -EFAULT; } - /* Another get_user_pages is running at the same time?? */ - if (WARN_ON(gtt->range)) - return -EFAULT; - if (!mmget_not_zero(mm)) /* Happens during process shutdown */ return -ESRCH; @@ -684,7 +691,7 @@ readonly = amdgpu_ttm_tt_is_readonly(ttm); r = amdgpu_hmm_range_get_pages(&bo->notifier, mm, pages, start, - ttm->num_pages, >t->range, readonly, + ttm->num_pages, range, readonly, true, NULL); out_unlock: mmap_read_unlock(mm); @@ -702,30 +709,24 @@ * * Returns: true if pages are still valid */ -bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm) +bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm, + struct hmm_range *range) { struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm); - bool r = false; - if (!gtt || !gtt->userptr) + if (!gtt || !gtt->userptr || !range) return false; DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%x\n", gtt->userptr, ttm->num_pages); - WARN_ONCE(!gtt->range || !gtt->range->hmm_pfns, - "No user pages to check\n"); + WARN_ONCE(!range->hmm_pfns, "No user pages to check\n"); - if (gtt->range) { - /* - * FIXME: Must always hold notifier_lock for this, and must - * not ignore the return code. - */ - r = amdgpu_hmm_range_get_pages_done(gtt->range); - gtt->range = NULL; - } - - return !r; + /* + * FIXME: Must always hold notifier_lock for this, and must + * not ignore the return code. + */ + return !amdgpu_hmm_range_get_pages_done(range); } #endif @@ -802,20 +803,6 @@ /* unmap the pages mapped to the device */ dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0); sg_free_table(ttm->sg); - -#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) - if (gtt->range) { - unsigned long i; - - for (i = 0; i < ttm->num_pages; i++) { - if (ttm->pages[i] != - hmm_pfn_to_page(gtt->range->hmm_pfns[i])) - break; - } - - WARN((i == ttm->num_pages), "Missing get_user_page_done\n"); - } -#endif } static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h 2023-01-18 18:27:39.000000000 +0000 @@ -39,6 +39,8 @@ #define AMDGPU_POISON 0xd0bed0be +struct hmm_range; + struct amdgpu_gtt_mgr { struct ttm_resource_manager manager; struct drm_mm mm; @@ -149,15 +151,19 @@ uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type); #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) -int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages); -bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm); +int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages, + struct hmm_range **range); +bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm, + struct hmm_range *range); #else static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, - struct page **pages) + struct page **pages, + struct hmm_range **range) { return -EPERM; } -static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm) +static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm, + struct hmm_range *range) { return false; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 2023-01-18 18:27:39.000000000 +0000 @@ -156,6 +156,9 @@ break; case IP_VERSION(3, 0, 2): fw_name = FIRMWARE_VANGOGH; + if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && + (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) + adev->vcn.indirect_sram = true; break; case IP_VERSION(3, 0, 16): fw_name = FIRMWARE_DIMGREY_CAVEFISH; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c 2023-01-18 18:27:39.000000000 +0000 @@ -726,6 +726,12 @@ adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE; } + if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID) + /* VF MMIO access (except mailbox range) from CPU + * will be blocked during sriov runtime + */ + adev->virt.caps |= AMDGPU_VF_MMIO_ACCESS_PROTECT; + /* we have the ability to check now */ if (amdgpu_sriov_vf(adev)) { switch (adev->asic_type) { diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h 2023-01-18 18:27:39.000000000 +0000 @@ -31,6 +31,7 @@ #define AMDGPU_SRIOV_CAPS_IS_VF (1 << 2) /* this GPU is a virtual function */ #define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */ #define AMDGPU_SRIOV_CAPS_RUNTIME (1 << 4) /* is out of full access mode */ +#define AMDGPU_VF_MMIO_ACCESS_PROTECT (1 << 5) /* MMIO write access is not allowed in sriov runtime */ /* flags for indirect register access path supported by rlcg for sriov */ #define AMDGPU_RLCG_GC_WRITE_LEGACY (0x8 << 28) @@ -294,6 +295,9 @@ #define amdgpu_passthrough(adev) \ ((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE) +#define amdgpu_sriov_vf_mmio_access_protection(adev) \ +((adev)->virt.caps & AMDGPU_VF_MMIO_ACCESS_PROTECT) + static inline bool is_virtual_machine(void) { #if defined(CONFIG_X86) diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c 2023-01-18 18:27:39.000000000 +0000 @@ -500,6 +500,8 @@ adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base; + adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true; + r = amdgpu_display_modeset_create_props(adev); if (r) return r; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 2023-01-18 18:27:39.000000000 +0000 @@ -143,32 +143,6 @@ return 0; } -/* - * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS - * happens while holding this lock anywhere to prevent deadlocks when - * an MMU notifier runs in reclaim-FS context. - */ -static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm) -{ - mutex_lock(&vm->eviction_lock); - vm->saved_flags = memalloc_noreclaim_save(); -} - -static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm) -{ - if (mutex_trylock(&vm->eviction_lock)) { - vm->saved_flags = memalloc_noreclaim_save(); - return 1; - } - return 0; -} - -static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm) -{ - memalloc_noreclaim_restore(vm->saved_flags); - mutex_unlock(&vm->eviction_lock); -} - /** * amdgpu_vm_bo_evicted - vm_bo is evicted * @@ -2301,7 +2275,11 @@ */ #ifdef CONFIG_X86_64 if (amdgpu_vm_update_mode == -1) { - if (amdgpu_gmc_vram_full_visible(&adev->gmc)) + /* For asic with VF MMIO access protection + * avoid using CPU for VM table updates + */ + if (amdgpu_gmc_vram_full_visible(&adev->gmc) && + !amdgpu_sriov_vf_mmio_access_protection(adev)) adev->vm_manager.vm_update_mode = AMDGPU_VM_USE_CPU_FOR_COMPUTE; else diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 2023-01-18 18:27:39.000000000 +0000 @@ -485,7 +485,48 @@ */ static inline uint64_t amdgpu_vm_tlb_seq(struct amdgpu_vm *vm) { + unsigned long flags; + spinlock_t *lock; + + /* + * Workaround to stop racing between the fence signaling and handling + * the cb. The lock is static after initially setting it up, just make + * sure that the dma_fence structure isn't freed up. + */ + rcu_read_lock(); + lock = vm->last_tlb_flush->lock; + rcu_read_unlock(); + + spin_lock_irqsave(lock, flags); + spin_unlock_irqrestore(lock, flags); + return atomic64_read(&vm->tlb_seq); } +/* + * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS + * happens while holding this lock anywhere to prevent deadlocks when + * an MMU notifier runs in reclaim-FS context. + */ +static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm) +{ + mutex_lock(&vm->eviction_lock); + vm->saved_flags = memalloc_noreclaim_save(); +} + +static inline bool amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm) +{ + if (mutex_trylock(&vm->eviction_lock)) { + vm->saved_flags = memalloc_noreclaim_save(); + return true; + } + return false; +} + +static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm) +{ + memalloc_noreclaim_restore(vm->saved_flags); + mutex_unlock(&vm->eviction_lock); +} + #endif diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c 2023-01-18 18:27:39.000000000 +0000 @@ -597,7 +597,9 @@ if (entry->bo) return 0; + amdgpu_vm_eviction_unlock(vm); r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt); + amdgpu_vm_eviction_lock(vm); if (r) return r; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c 2023-01-18 18:27:39.000000000 +0000 @@ -435,7 +435,7 @@ if (place->flags & TTM_PL_FLAG_TOPDOWN) vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION; - if (fpfn || lpfn != man->size) + if (fpfn || lpfn != mgr->mm.size) /* Allocate blocks in desired range */ vres->flags |= DRM_BUDDY_RANGE_ALLOCATION; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 2023-01-18 18:27:39.000000000 +0000 @@ -1729,7 +1729,7 @@ WREG32_SOC15(GC, 0, regSH_MEM_BASES, sh_mem_bases); /* Enable trap for each kfd vmid. */ - data = RREG32(SOC15_REG_OFFSET(GC, 0, regSPI_GDBG_PER_VMID_CNTL)); + data = RREG32_SOC15(GC, 0, regSPI_GDBG_PER_VMID_CNTL); data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1); } soc21_grbm_select(adev, 0, 0, 0, 0); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 2023-01-18 18:27:39.000000000 +0000 @@ -185,6 +185,10 @@ /* Use register 17 for GART */ const unsigned eng = 17; unsigned int i; + unsigned char hub_ip = 0; + + hub_ip = (vmhub == AMDGPU_GFXHUB_0) ? + GC_HWIP : MMHUB_HWIP; spin_lock(&adev->gmc.invalidate_lock); /* @@ -198,8 +202,8 @@ if (use_semaphore) { for (i = 0; i < adev->usec_timeout; i++) { /* a read return value of 1 means semaphore acuqire */ - tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + - hub->eng_distance * eng); + tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem + + hub->eng_distance * eng, hub_ip); if (tmp & 0x1) break; udelay(1); @@ -209,12 +213,12 @@ DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); } - WREG32_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, inv_req); + WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, inv_req, hub_ip); /* Wait for ACK with a delay.*/ for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + - hub->eng_distance * eng); + tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_ack + + hub->eng_distance * eng, hub_ip); tmp &= 1 << vmid; if (tmp) break; @@ -228,8 +232,8 @@ * add semaphore release after invalidation, * write with 0 means semaphore release */ - WREG32_NO_KIQ(hub->vm_inv_eng0_sem + - hub->eng_distance * eng, 0); + WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem + + hub->eng_distance * eng, 0, hub_ip); /* Issue additional private vm invalidation to MMHUB */ if ((vmhub != AMDGPU_GFXHUB_0) && diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c 2023-01-18 18:27:39.000000000 +0000 @@ -96,7 +96,14 @@ struct amdgpu_device *adev = mes->adev; struct amdgpu_ring *ring = &mes->ring; unsigned long flags; + signed long timeout = adev->usec_timeout; + if (amdgpu_emu_mode) { + timeout *= 100; + } else if (amdgpu_sriov_vf(adev)) { + /* Worst case in sriov where all other 15 VF timeout, each VF needs about 600ms */ + timeout = 15 * 600 * 1000; + } BUG_ON(size % 4 != 0); spin_lock_irqsave(&mes->ring_lock, flags); @@ -116,7 +123,7 @@ DRM_DEBUG("MES msg=%d was emitted\n", x_pkt->header.opcode); r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq, - adev->usec_timeout * (amdgpu_emu_mode ? 100 : 1)); + timeout); if (r < 1) { DRM_ERROR("MES failed to response msg=%d\n", x_pkt->header.opcode); @@ -183,7 +190,11 @@ mes_add_queue_pkt.trap_handler_addr = input->tba_addr; mes_add_queue_pkt.tma_addr = input->tma_addr; mes_add_queue_pkt.is_kfd_process = input->is_kfd_process; - mes_add_queue_pkt.trap_en = 1; + + if (!(((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 4) && + (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0)) && + (adev->ip_versions[GC_HWIP][0] <= IP_VERSION(11, 0, 3)))) + mes_add_queue_pkt.trap_en = 1; /* For KFD, gds_size is re-used for queue size (needed in MES for AQL queues) */ mes_add_queue_pkt.is_aql_queue = input->is_aql_queue; @@ -1145,6 +1156,42 @@ return 0; } +static void mes_v11_0_kiq_dequeue_sched(struct amdgpu_device *adev) +{ + uint32_t data; + int i; + + mutex_lock(&adev->srbm_mutex); + soc21_grbm_select(adev, 3, AMDGPU_MES_SCHED_PIPE, 0, 0); + + /* disable the queue if it's active */ + if (RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1) { + WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 1); + for (i = 0; i < adev->usec_timeout; i++) { + if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1)) + break; + udelay(1); + } + } + data = RREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL); + data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL, + DOORBELL_EN, 0); + data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL, + DOORBELL_HIT, 1); + WREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL, data); + + WREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL, 0); + + WREG32_SOC15(GC, 0, regCP_HQD_PQ_WPTR_LO, 0); + WREG32_SOC15(GC, 0, regCP_HQD_PQ_WPTR_HI, 0); + WREG32_SOC15(GC, 0, regCP_HQD_PQ_RPTR, 0); + + soc21_grbm_select(adev, 0, 0, 0, 0); + mutex_unlock(&adev->srbm_mutex); + + adev->mes.ring.sched.ready = false; +} + static void mes_v11_0_kiq_setting(struct amdgpu_ring *ring) { uint32_t tmp; @@ -1196,6 +1243,9 @@ static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev) { + if (adev->mes.ring.sched.ready) + mes_v11_0_kiq_dequeue_sched(adev); + mes_v11_0_enable(adev, false); return 0; } @@ -1251,9 +1301,6 @@ static int mes_v11_0_hw_fini(void *handle) { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - - adev->mes.ring.sched.ready = false; return 0; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c linux-6.0.12/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c --- linux-6.0.6/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c 2023-01-18 18:27:39.000000000 +0000 @@ -32,8 +32,6 @@ #include "gc/gc_10_1_0_offset.h" #include "soc15_common.h" -#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid 0x064d -#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid_BASE_IDX 0 #define mmDAGB0_CNTL_MISC2_Sienna_Cichlid 0x0070 #define mmDAGB0_CNTL_MISC2_Sienna_Cichlid_BASE_IDX 0 @@ -574,7 +572,6 @@ case IP_VERSION(2, 1, 0): case IP_VERSION(2, 1, 1): case IP_VERSION(2, 1, 2): - def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); break; default: @@ -608,8 +605,6 @@ case IP_VERSION(2, 1, 0): case IP_VERSION(2, 1, 1): case IP_VERSION(2, 1, 2): - if (def != data) - WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); if (def1 != data1) WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid, data1); break; @@ -634,8 +629,8 @@ case IP_VERSION(2, 1, 0): case IP_VERSION(2, 1, 1): case IP_VERSION(2, 1, 2): - def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); - break; + /* There is no ATCL2 in MMHUB for 2.1.x */ + return; default: def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG); break; @@ -646,18 +641,8 @@ else data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; - if (def != data) { - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 1, 2): - WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); - break; - default: - WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data); - break; - } - } + if (def != data) + WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data); } static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev, @@ -695,7 +680,10 @@ case IP_VERSION(2, 1, 0): case IP_VERSION(2, 1, 1): case IP_VERSION(2, 1, 2): - data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); + /* There is no ATCL2 in MMHUB for 2.1.x. Keep the status + * based on DAGB + */ + data = MM_ATC_L2_MISC_CG__ENABLE_MASK; data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); break; default: diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm linux-6.0.12/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm --- linux-6.0.6/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm 2023-01-18 18:27:39.000000000 +0000 @@ -43,12 +43,14 @@ #define HAVE_XNACK (ASIC_FAMILY < CHIP_SIENNA_CICHLID) #define HAVE_SENDMSG_RTN (ASIC_FAMILY >= CHIP_PLUM_BONITO) #define HAVE_BUFFER_LDS_LOAD (ASIC_FAMILY < CHIP_PLUM_BONITO) +#define SW_SA_TRAP (ASIC_FAMILY >= CHIP_PLUM_BONITO) var SINGLE_STEP_MISSED_WORKAROUND = 1 //workaround for lost MODE.DEBUG_EN exception when SAVECTX raised var SQ_WAVE_STATUS_SPI_PRIO_MASK = 0x00000006 var SQ_WAVE_STATUS_HALT_MASK = 0x2000 var SQ_WAVE_STATUS_ECC_ERR_MASK = 0x20000 +var SQ_WAVE_STATUS_TRAP_EN_SHIFT = 6 var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT = 12 var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE = 9 @@ -183,6 +185,19 @@ s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS) +#if SW_SA_TRAP + // If ttmp1[30] is set then issue s_barrier to unblock dependent waves. + s_bitcmp1_b32 s_save_pc_hi, 30 + s_cbranch_scc0 L_TRAP_NO_BARRIER + s_barrier + +L_TRAP_NO_BARRIER: + // If ttmp1[31] is set then trap may occur early. + // Spin wait until SAVECTX exception is raised. + s_bitcmp1_b32 s_save_pc_hi, 31 + s_cbranch_scc1 L_CHECK_SAVE +#endif + s_and_b32 ttmp2, s_save_status, SQ_WAVE_STATUS_HALT_MASK s_cbranch_scc0 L_NOT_HALTED @@ -1061,8 +1076,20 @@ s_and_b32 s_restore_pc_hi, s_restore_pc_hi, 0x0000ffff //pc[47:32] //Do it here in order not to affect STATUS s_and_b64 exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32 s_and_b64 vcc, vcc, vcc // Restore STATUS.VCCZ, not writable by s_setreg_b32 + +#if SW_SA_TRAP + // If traps are enabled then return to the shader with PRIV=0. + // Otherwise retain PRIV=1 for subsequent context save requests. + s_getreg_b32 s_restore_tmp, hwreg(HW_REG_STATUS) + s_bitcmp1_b32 s_restore_tmp, SQ_WAVE_STATUS_TRAP_EN_SHIFT + s_cbranch_scc1 L_RETURN_WITHOUT_PRIV + s_setreg_b32 hwreg(HW_REG_STATUS), s_restore_status // SCC is included, which is changed by previous salu + s_setpc_b64 [s_restore_pc_lo, s_restore_pc_hi] +L_RETURN_WITHOUT_PRIV: +#endif + s_setreg_b32 hwreg(HW_REG_STATUS), s_restore_status // SCC is included, which is changed by previous salu s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution L_END_PGM: diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h linux-6.0.12/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h --- linux-6.0.6/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h 2023-01-18 18:27:39.000000000 +0000 @@ -742,7 +742,7 @@ 0xbf88fffe, 0x877aff7f, 0x04000000, 0x8f7a857a, 0x886d7a6d, 0xb97b02dc, - 0x8f7b997b, 0xb97a2a05, + 0x8f7b997b, 0xb97a3a05, 0x807a817a, 0xbf0d997b, 0xbf850002, 0x8f7a897a, 0xbf820001, 0x8f7a8a7a, @@ -819,7 +819,7 @@ 0xbefe037c, 0xbefc0370, 0xf4611c7a, 0xf8000000, 0x80708470, 0xbefc037e, - 0xb9702a05, 0x80708170, + 0xb9703a05, 0x80708170, 0xbf0d9973, 0xbf850002, 0x8f708970, 0xbf820001, 0x8f708a70, 0xb97a1e06, @@ -1069,7 +1069,7 @@ 0xb9f9f816, 0x876f7bff, 0xfffff800, 0x906f8b6f, 0xb9efa2c3, 0xb9f3f801, - 0xb96e2a05, 0x806e816e, + 0xb96e3a05, 0x806e816e, 0xbf0d9972, 0xbf850002, 0x8f6e896e, 0xbf820001, 0x8f6e8a6e, 0xb96f1e06, @@ -2114,7 +2114,7 @@ 0x007a0000, 0x7e000280, 0xbefe037a, 0xbeff037b, 0xb97b02dc, 0x8f7b997b, - 0xb97a2a05, 0x807a817a, + 0xb97a3a05, 0x807a817a, 0xbf0d997b, 0xbf850002, 0x8f7a897a, 0xbf820001, 0x8f7a8a7a, 0xb97b1e06, @@ -2157,7 +2157,7 @@ 0x01000000, 0xe0704100, 0x705d0100, 0xe0704200, 0x705d0200, 0xe0704300, - 0x705d0300, 0xb9702a05, + 0x705d0300, 0xb9703a05, 0x80708170, 0xbf0d9973, 0xbf850002, 0x8f708970, 0xbf820001, 0x8f708a70, @@ -2189,7 +2189,7 @@ 0xbefe03ff, 0x0000ffff, 0xbeff0380, 0xe0704000, 0x705d0200, 0xbefe03c1, - 0xb9702a05, 0x80708170, + 0xb9703a05, 0x80708170, 0xbf0d9973, 0xbf850002, 0x8f708970, 0xbf820001, 0x8f708a70, 0xb97a1e06, @@ -2475,7 +2475,7 @@ 0xb9ef4803, 0x876f7bff, 0xfffff800, 0x906f8b6f, 0xb9efa2c3, 0xb9f3f801, - 0xb96e2a05, 0x806e816e, + 0xb96e3a05, 0x806e816e, 0xbf0d9972, 0xbf850002, 0x8f6e896e, 0xbf820001, 0x8f6e8a6e, 0xb96f1e06, @@ -2494,11 +2494,13 @@ 0xbf9f0000, 0xbf9f0000, 0xbf9f0000, 0x00000000, }; - static const uint32_t cwsr_trap_gfx11_hex[] = { - 0xbfa00001, 0xbfa0021b, + 0xbfa00001, 0xbfa00221, 0xb0804006, 0xb8f8f802, - 0x91788678, 0xb8fbf803, + 0x9178ff78, 0x00020006, + 0xb8fbf803, 0xbf0d9e6d, + 0xbfa10001, 0xbfbd0000, + 0xbf0d9f6d, 0xbfa20006, 0x8b6eff78, 0x00002000, 0xbfa10009, 0x8b6eff6d, 0x00ff0000, 0xbfa2001e, @@ -2766,7 +2768,7 @@ 0x701d0000, 0x807d817d, 0x8070ff70, 0x00000080, 0xbf0a7b7d, 0xbfa2fff8, - 0xbfa00141, 0xbef4007e, + 0xbfa00146, 0xbef4007e, 0x8b75ff7f, 0x0000ffff, 0x8c75ff75, 0x00040000, 0xbef60080, 0xbef700ff, @@ -2926,8 +2928,11 @@ 0xf8000074, 0xbf89fc07, 0x8b6dff6d, 0x0000ffff, 0x8bfe7e7e, 0x8bea6a6a, - 0xb97af802, 0xbe804a6c, - 0xbfb00000, 0xbf9f0000, + 0xb8eef802, 0xbf0d866e, + 0xbfa20002, 0xb97af802, + 0xbe80486c, 0xb97af802, + 0xbe804a6c, 0xbfb00000, 0xbf9f0000, 0xbf9f0000, 0xbf9f0000, 0xbf9f0000, + 0xbf9f0000, 0x00000000, }; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c linux-6.0.12/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c --- linux-6.0.6/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 2023-01-18 18:27:39.000000000 +0000 @@ -1928,7 +1928,7 @@ { int ret; uint32_t num_devices, num_bos, num_objects; - uint64_t priv_size, priv_offset = 0; + uint64_t priv_size, priv_offset = 0, bo_priv_offset; if (!args->devices || !args->bos || !args->priv_data) return -EINVAL; @@ -1972,38 +1972,34 @@ if (ret) goto exit_unlock; - ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos, - (uint8_t __user *)args->priv_data, &priv_offset); - if (ret) - goto exit_unlock; + /* Leave room for BOs in the private data. They need to be restored + * before events, but we checkpoint them last to simplify the error + * handling. + */ + bo_priv_offset = priv_offset; + priv_offset += num_bos * sizeof(struct kfd_criu_bo_priv_data); if (num_objects) { ret = kfd_criu_checkpoint_queues(p, (uint8_t __user *)args->priv_data, &priv_offset); if (ret) - goto close_bo_fds; + goto exit_unlock; ret = kfd_criu_checkpoint_events(p, (uint8_t __user *)args->priv_data, &priv_offset); if (ret) - goto close_bo_fds; + goto exit_unlock; ret = kfd_criu_checkpoint_svm(p, (uint8_t __user *)args->priv_data, &priv_offset); if (ret) - goto close_bo_fds; + goto exit_unlock; } -close_bo_fds: - if (ret) { - /* If IOCTL returns err, user assumes all FDs opened in criu_dump_bos are closed */ - uint32_t i; - struct kfd_criu_bo_bucket *bo_buckets = (struct kfd_criu_bo_bucket *) args->bos; - - for (i = 0; i < num_bos; i++) { - if (bo_buckets[i].alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) - close_fd(bo_buckets[i].dmabuf_fd); - } - } + /* This must be the last thing in this function that can fail. + * Otherwise we leak dmabuf file descriptors. + */ + ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos, + (uint8_t __user *)args->priv_data, &bo_priv_offset); exit_unlock: mutex_unlock(&p->mutex); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdkfd/kfd_crat.c linux-6.0.12/drivers/gpu/drm/amd/amdkfd/kfd_crat.c --- linux-6.0.6/drivers/gpu/drm/amd/amdkfd/kfd_crat.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdkfd/kfd_crat.c 2023-01-18 18:27:39.000000000 +0000 @@ -795,6 +795,102 @@ }, }; +static struct kfd_gpu_cache_info gfx1037_cache_info[] = { + { + /* TCP L1 Cache per CU */ + .cache_size = 16, + .cache_level = 1, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_DATA_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 1, + }, + { + /* Scalar L1 Instruction Cache per SQC */ + .cache_size = 32, + .cache_level = 1, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_INST_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 2, + }, + { + /* Scalar L1 Data Cache per SQC */ + .cache_size = 16, + .cache_level = 1, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_DATA_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 2, + }, + { + /* GL1 Data Cache per SA */ + .cache_size = 128, + .cache_level = 1, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_DATA_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 2, + }, + { + /* L2 Data Cache per GPU (Total Tex Cache) */ + .cache_size = 256, + .cache_level = 2, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_DATA_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 2, + }, +}; + +static struct kfd_gpu_cache_info gc_10_3_6_cache_info[] = { + { + /* TCP L1 Cache per CU */ + .cache_size = 16, + .cache_level = 1, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_DATA_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 1, + }, + { + /* Scalar L1 Instruction Cache per SQC */ + .cache_size = 32, + .cache_level = 1, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_INST_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 2, + }, + { + /* Scalar L1 Data Cache per SQC */ + .cache_size = 16, + .cache_level = 1, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_DATA_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 2, + }, + { + /* GL1 Data Cache per SA */ + .cache_size = 128, + .cache_level = 1, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_DATA_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 2, + }, + { + /* L2 Data Cache per GPU (Total Tex Cache) */ + .cache_size = 256, + .cache_level = 2, + .flags = (CRAT_CACHE_FLAGS_ENABLED | + CRAT_CACHE_FLAGS_DATA_CACHE | + CRAT_CACHE_FLAGS_SIMD_CACHE), + .num_cu_shared = 2, + }, +}; + static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, struct crat_subtype_computeunit *cu) { @@ -1514,11 +1610,17 @@ num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info); break; case IP_VERSION(10, 3, 3): - case IP_VERSION(10, 3, 6): /* TODO: Double check these on production silicon */ - case IP_VERSION(10, 3, 7): /* TODO: Double check these on production silicon */ pcache_info = yellow_carp_cache_info; num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info); break; + case IP_VERSION(10, 3, 6): + pcache_info = gc_10_3_6_cache_info; + num_of_cache_types = ARRAY_SIZE(gc_10_3_6_cache_info); + break; + case IP_VERSION(10, 3, 7): + pcache_info = gfx1037_cache_info; + num_of_cache_types = ARRAY_SIZE(gfx1037_cache_info); + break; case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 2): diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdkfd/kfd_events.c linux-6.0.12/drivers/gpu/drm/amd/amdkfd/kfd_events.c --- linux-6.0.6/drivers/gpu/drm/amd/amdkfd/kfd_events.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdkfd/kfd_events.c 2023-01-18 18:27:39.000000000 +0000 @@ -506,6 +506,7 @@ ret = create_other_event(p, ev, &ev_priv->event_id); break; } + mutex_unlock(&p->event_mutex); exit: if (ret) @@ -513,8 +514,6 @@ kfree(ev_priv); - mutex_unlock(&p->event_mutex); - return ret; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c linux-6.0.12/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c --- linux-6.0.6/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 2023-01-18 18:27:39.000000000 +0000 @@ -886,7 +886,7 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf) { unsigned long addr = vmf->address; - struct vm_area_struct *vma; + struct svm_range_bo *svm_bo; enum svm_work_list_ops op; struct svm_range *parent; struct svm_range *prange; @@ -894,29 +894,42 @@ struct mm_struct *mm; int r = 0; - vma = vmf->vma; - mm = vma->vm_mm; + svm_bo = vmf->page->zone_device_data; + if (!svm_bo) { + pr_debug("failed get device page at addr 0x%lx\n", addr); + return VM_FAULT_SIGBUS; + } + if (!mmget_not_zero(svm_bo->eviction_fence->mm)) { + pr_debug("addr 0x%lx of process mm is detroyed\n", addr); + return VM_FAULT_SIGBUS; + } - p = kfd_lookup_process_by_mm(vma->vm_mm); + mm = svm_bo->eviction_fence->mm; + if (mm != vmf->vma->vm_mm) + pr_debug("addr 0x%lx is COW mapping in child process\n", addr); + + p = kfd_lookup_process_by_mm(mm); if (!p) { pr_debug("failed find process at fault address 0x%lx\n", addr); - return VM_FAULT_SIGBUS; + r = VM_FAULT_SIGBUS; + goto out_mmput; } if (READ_ONCE(p->svms.faulting_task) == current) { pr_debug("skipping ram migration\n"); - kfd_unref_process(p); - return 0; + r = 0; + goto out_unref_process; } - addr >>= PAGE_SHIFT; + pr_debug("CPU page fault svms 0x%p address 0x%lx\n", &p->svms, addr); + addr >>= PAGE_SHIFT; mutex_lock(&p->svms.lock); prange = svm_range_from_addr(&p->svms, addr, &parent); if (!prange) { - pr_debug("cannot find svm range at 0x%lx\n", addr); + pr_debug("failed get range svms 0x%p addr 0x%lx\n", &p->svms, addr); r = -EFAULT; - goto out; + goto out_unlock_svms; } mutex_lock(&parent->migrate_mutex); @@ -938,10 +951,11 @@ goto out_unlock_prange; } - r = svm_migrate_vram_to_ram(prange, mm, KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU); + r = svm_migrate_vram_to_ram(prange, vmf->vma->vm_mm, + KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU); if (r) - pr_debug("failed %d migrate 0x%p [0x%lx 0x%lx] to ram\n", r, - prange, prange->start, prange->last); + pr_debug("failed %d migrate svms 0x%p range 0x%p [0x%lx 0x%lx]\n", + r, prange->svms, prange, prange->start, prange->last); /* xnack on, update mapping on GPUs with ACCESS_IN_PLACE */ if (p->xnack_enabled && parent == prange) @@ -955,12 +969,13 @@ if (prange != parent) mutex_unlock(&prange->migrate_mutex); mutex_unlock(&parent->migrate_mutex); -out: +out_unlock_svms: mutex_unlock(&p->svms.lock); - kfd_unref_process(p); - +out_unref_process: pr_debug("CPU fault svms 0x%p address 0x%lx done\n", &p->svms, addr); - + kfd_unref_process(p); +out_mmput: + mmput(mm); return r ? VM_FAULT_SIGBUS : 0; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c linux-6.0.12/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c --- linux-6.0.6/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 2023-01-18 18:27:39.000000000 +0000 @@ -146,6 +146,14 @@ /* Number of bytes in PSP footer for firmware. */ #define PSP_FOOTER_BYTES 0x100 +/* + * DMUB Async to Sync Mechanism Status + */ +#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1 +#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2 +#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3 +#define DMUB_ASYNC_TO_SYNC_ACCESS_INVALID 4 + /** * DOC: overview * @@ -1363,7 +1371,44 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"), + }, + }, {} + /* TODO: refactor this from a fixed table to a dynamic option */ }; static void retrieve_dmi_info(struct amdgpu_display_manager *dm) @@ -1549,6 +1594,9 @@ adev->dm.dc->debug.visual_confirm = amdgpu_dc_visual_confirm; + /* TODO: Remove after DP2 receiver gets proper support of Cable ID feature */ + adev->dm.dc->debug.ignore_cable_id = true; + r = dm_dmub_hw_init(adev); if (r) { DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); @@ -1634,12 +1682,6 @@ } } - if (amdgpu_dm_initialize_drm_device(adev)) { - DRM_ERROR( - "amdgpu: failed to initialize sw for display support.\n"); - goto error; - } - /* Enable outbox notification only after IRQ handlers are registered and DMUB is alive. * It is expected that DMUB will resend any pending notifications at this point, for * example HPD from DPIA. @@ -1647,6 +1689,12 @@ if (dc_is_dmub_outbox_supported(adev->dm.dc)) dc_enable_dmub_outbox(adev->dm.dc); + if (amdgpu_dm_initialize_drm_device(adev)) { + DRM_ERROR( + "amdgpu: failed to initialize sw for display support.\n"); + goto error; + } + /* create fake encoders for MST */ dm_dp_create_fake_mst_encoders(adev); @@ -7639,9 +7687,10 @@ bundle->surface_updates[planes_count].plane_info = &bundle->plane_infos[planes_count]; - fill_dc_dirty_rects(plane, old_plane_state, new_plane_state, - new_crtc_state, - &bundle->flip_addrs[planes_count]); + if (acrtc_state->stream->link->psr_settings.psr_feature_enabled) + fill_dc_dirty_rects(plane, old_plane_state, + new_plane_state, new_crtc_state, + &bundle->flip_addrs[planes_count]); /* * Only allow immediate flips for fast updates that don't @@ -10146,6 +10195,8 @@ *operation_result = AUX_RET_ERROR_TIMEOUT; } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL) { *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE; + } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_INVALID) { + *operation_result = AUX_RET_ERROR_INVALID_REPLY; } else { *operation_result = AUX_RET_ERROR_UNKNOWN; } @@ -10193,6 +10244,16 @@ payload->reply[0] = adev->dm.dmub_notify->aux_reply.command; if (!payload->write && adev->dm.dmub_notify->aux_reply.length && payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK) { + + if (payload->length != adev->dm.dmub_notify->aux_reply.length) { + DRM_WARN("invalid read from DPIA AUX %x(%d) got length %d!\n", + payload->address, payload->length, + adev->dm.dmub_notify->aux_reply.length); + return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux, ctx, + DMUB_ASYNC_TO_SYNC_ACCESS_INVALID, + (uint32_t *)operation_result); + } + memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data, adev->dm.dmub_notify->aux_reply.length); } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c linux-6.0.12/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c --- linux-6.0.6/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 2023-01-18 18:27:39.000000000 +0000 @@ -412,7 +412,7 @@ { struct amdgpu_crtc *acrtc = NULL; struct drm_plane *cursor_plane; - + bool is_dcn; int res = -ENOMEM; cursor_plane = kzalloc(sizeof(*cursor_plane), GFP_KERNEL); @@ -450,8 +450,14 @@ acrtc->otg_inst = -1; dm->adev->mode_info.crtcs[crtc_index] = acrtc; - drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES, + + /* Don't enable DRM CRTC degamma property for DCE since it doesn't + * support programmable degamma anywhere. + */ + is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch; + drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0, true, MAX_COLOR_LUT_ENTRIES); + drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); return 0; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h linux-6.0.12/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h --- linux-6.0.6/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 2023-01-18 18:27:39.000000000 +0000 @@ -51,12 +51,6 @@ #define AMDGPU_DMUB_NOTIFICATION_MAX 5 /* - * DMUB Async to Sync Mechanism Status - */ -#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1 -#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2 -#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3 -/* #include "include/amdgpu_dal_power_if.h" #include "amdgpu_dm_irq.h" */ diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c linux-6.0.12/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c --- linux-6.0.6/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 2023-01-18 18:27:39.000000000 +0000 @@ -1369,7 +1369,7 @@ { struct amdgpu_device *adev = drm_to_adev(plane->dev); const struct drm_format_info *info = drm_format_info(format); - struct hw_asic_id asic_id = adev->dm.dc->ctx->asic_id; + int i; enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3; @@ -1386,49 +1386,13 @@ return true; } - /* check if swizzle mode is supported by this version of DCN */ - switch (asic_id.chip_family) { - case FAMILY_SI: - case FAMILY_CI: - case FAMILY_KV: - case FAMILY_CZ: - case FAMILY_VI: - /* asics before AI does not have modifier support */ - return false; - case FAMILY_AI: - case FAMILY_RV: - case FAMILY_NV: - case FAMILY_VGH: - case FAMILY_YELLOW_CARP: - case AMDGPU_FAMILY_GC_10_3_6: - case AMDGPU_FAMILY_GC_10_3_7: - switch (AMD_FMT_MOD_GET(TILE, modifier)) { - case AMD_FMT_MOD_TILE_GFX9_64K_R_X: - case AMD_FMT_MOD_TILE_GFX9_64K_D_X: - case AMD_FMT_MOD_TILE_GFX9_64K_S_X: - case AMD_FMT_MOD_TILE_GFX9_64K_D: - return true; - default: - return false; - } - break; - case AMDGPU_FAMILY_GC_11_0_0: - case AMDGPU_FAMILY_GC_11_0_1: - switch (AMD_FMT_MOD_GET(TILE, modifier)) { - case AMD_FMT_MOD_TILE_GFX11_256K_R_X: - case AMD_FMT_MOD_TILE_GFX9_64K_R_X: - case AMD_FMT_MOD_TILE_GFX9_64K_D_X: - case AMD_FMT_MOD_TILE_GFX9_64K_S_X: - case AMD_FMT_MOD_TILE_GFX9_64K_D: - return true; - default: - return false; - } - break; - default: - ASSERT(0); /* Unknown asic */ - break; + /* Check that the modifier is on the list of the plane's supported modifiers. */ + for (i = 0; i < plane->modifier_count; i++) { + if (modifier == plane->modifiers[i]) + break; } + if (i == plane->modifier_count) + return false; /* * For D swizzle the canonical modifier depends on the bpp, so check diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c 2023-01-18 18:27:39.000000000 +0000 @@ -2392,6 +2392,26 @@ return result; } +static enum bp_result get_vram_info_v30( + struct bios_parser *bp, + struct dc_vram_info *info) +{ + struct atom_vram_info_header_v3_0 *info_v30; + enum bp_result result = BP_RESULT_OK; + + info_v30 = GET_IMAGE(struct atom_vram_info_header_v3_0, + DATA_TABLES(vram_info)); + + if (info_v30 == NULL) + return BP_RESULT_BADBIOSTABLE; + + info->num_chans = info_v30->channel_num; + info->dram_channel_width_bytes = (1 << info_v30->channel_width) / 8; + + return result; +} + + /* * get_integrated_info_v11 * @@ -3022,6 +3042,16 @@ break; default: break; + } + break; + + case 3: + switch (revision.minor) { + case 0: + result = get_vram_info_v30(bp, info); + break; + default: + break; } break; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c 2023-01-18 18:27:39.000000000 +0000 @@ -356,32 +356,32 @@ .wm_inst = WM_A, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 9, - .sr_enter_plus_exit_time_us = 11, + .sr_exit_time_us = 12.5, + .sr_enter_plus_exit_time_us = 14.5, .valid = true, }, { .wm_inst = WM_B, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 9, - .sr_enter_plus_exit_time_us = 11, + .sr_exit_time_us = 12.5, + .sr_enter_plus_exit_time_us = 14.5, .valid = true, }, { .wm_inst = WM_C, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 9, - .sr_enter_plus_exit_time_us = 11, + .sr_exit_time_us = 12.5, + .sr_enter_plus_exit_time_us = 14.5, .valid = true, }, { .wm_inst = WM_D, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 9, - .sr_enter_plus_exit_time_us = 11, + .sr_exit_time_us = 12.5, + .sr_enter_plus_exit_time_us = 14.5, .valid = true, }, } @@ -393,32 +393,32 @@ .wm_inst = WM_A, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.65333, - .sr_exit_time_us = 11.5, - .sr_enter_plus_exit_time_us = 14.5, + .sr_exit_time_us = 16.5, + .sr_enter_plus_exit_time_us = 18.5, .valid = true, }, { .wm_inst = WM_B, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.65333, - .sr_exit_time_us = 11.5, - .sr_enter_plus_exit_time_us = 14.5, + .sr_exit_time_us = 16.5, + .sr_enter_plus_exit_time_us = 18.5, .valid = true, }, { .wm_inst = WM_C, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.65333, - .sr_exit_time_us = 11.5, - .sr_enter_plus_exit_time_us = 14.5, + .sr_exit_time_us = 16.5, + .sr_enter_plus_exit_time_us = 18.5, .valid = true, }, { .wm_inst = WM_D, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.65333, - .sr_exit_time_us = 11.5, - .sr_enter_plus_exit_time_us = 14.5, + .sr_exit_time_us = 16.5, + .sr_enter_plus_exit_time_us = 18.5, .valid = true, }, } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c 2023-01-18 18:27:39.000000000 +0000 @@ -156,7 +156,8 @@ { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); unsigned int num_levels; - unsigned int num_dcfclk_levels, num_dtbclk_levels, num_dispclk_levels; + struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk; + unsigned int i; memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks)); clk_mgr_base->clks.p_state_change_support = true; @@ -180,42 +181,42 @@ /* DCFCLK */ dcn32_init_single_clock(clk_mgr, PPCLK_DCFCLK, &clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz, - &num_levels); - num_dcfclk_levels = num_levels; + &num_entries_per_clk->num_dcfclk_levels); /* SOCCLK */ dcn32_init_single_clock(clk_mgr, PPCLK_SOCCLK, &clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz, - &num_levels); + &num_entries_per_clk->num_socclk_levels); + /* DTBCLK */ if (!clk_mgr->base.ctx->dc->debug.disable_dtb_ref_clk_switch) dcn32_init_single_clock(clk_mgr, PPCLK_DTBCLK, &clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz, - &num_levels); - num_dtbclk_levels = num_levels; + &num_entries_per_clk->num_dtbclk_levels); /* DISPCLK */ dcn32_init_single_clock(clk_mgr, PPCLK_DISPCLK, &clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz, - &num_levels); - num_dispclk_levels = num_levels; + &num_entries_per_clk->num_dispclk_levels); + num_levels = num_entries_per_clk->num_dispclk_levels; - if (num_dcfclk_levels && num_dtbclk_levels && num_dispclk_levels) + if (num_entries_per_clk->num_dcfclk_levels && + num_entries_per_clk->num_dtbclk_levels && + num_entries_per_clk->num_dispclk_levels) clk_mgr->dpm_present = true; if (clk_mgr_base->ctx->dc->debug.min_disp_clk_khz) { - unsigned int i; - for (i = 0; i < num_levels; i++) if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz < khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz)) clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz = khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz); } + for (i = 0; i < num_levels; i++) + if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz > 1950) + clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz = 1950; if (clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz) { - unsigned int i; - for (i = 0; i < num_levels; i++) if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz < khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz)) @@ -370,7 +371,7 @@ /* to disable P-State switching, set UCLK min = max */ if (!clk_mgr_base->clks.p_state_change_support) dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, - clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz); + clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz); } if (should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_p_state_change_support) && @@ -632,7 +633,7 @@ khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz)); else dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, - clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz); + clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz); } else { dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz); @@ -648,22 +649,37 @@ return; dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, - clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz); + clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz); } /* Get current memclk states, update bounding box */ static void dcn32_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); + struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk; unsigned int num_levels; if (!clk_mgr->smu_present) return; - /* Refresh memclk states */ + /* Refresh memclk and fclk states */ dcn32_init_single_clock(clk_mgr, PPCLK_UCLK, &clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz, - &num_levels); + &num_entries_per_clk->num_memclk_levels); + + /* memclk must have at least one level */ + num_entries_per_clk->num_memclk_levels = num_entries_per_clk->num_memclk_levels ? num_entries_per_clk->num_memclk_levels : 1; + + dcn32_init_single_clock(clk_mgr, PPCLK_FCLK, + &clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz, + &num_entries_per_clk->num_fclk_levels); + + if (num_entries_per_clk->num_memclk_levels >= num_entries_per_clk->num_fclk_levels) { + num_levels = num_entries_per_clk->num_memclk_levels; + } else { + num_levels = num_entries_per_clk->num_fclk_levels; + } + clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1; if (clk_mgr->dpm_present && !num_levels) diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c 2023-01-18 18:27:39.000000000 +0000 @@ -359,7 +359,8 @@ audio_regs(2), audio_regs(3), audio_regs(4), - audio_regs(5) + audio_regs(5), + audio_regs(6), }; #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dc.h linux-6.0.12/drivers/gpu/drm/amd/display/dc/dc.h --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dc.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dc.h 2023-01-18 18:27:39.000000000 +0000 @@ -746,6 +746,9 @@ bool force_disable_subvp; bool force_subvp_mclk_switch; bool allow_sw_cursor_fallback; + unsigned int force_subvp_num_ways; + unsigned int force_mall_ss_num_ways; + bool alloc_extra_way_for_cursor; bool force_usr_allow; /* uses value at boot and disables switch */ bool disable_dtb_ref_clk_switch; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c 2023-01-18 18:27:39.000000000 +0000 @@ -1262,16 +1262,6 @@ lock, &hw_locks, &inst_flags); - } else if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) { - union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 }; - hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK; - hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER; - hw_lock_cmd.bits.lock_pipe = 1; - hw_lock_cmd.bits.otg_inst = pipe->stream_res.tg->inst; - hw_lock_cmd.bits.lock = lock; - if (!lock) - hw_lock_cmd.bits.should_release = 1; - dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd); } else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) { if (lock) pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg); @@ -1848,7 +1838,7 @@ for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000 && hubp->funcs->hubp_is_flip_pending(hubp); j++) - mdelay(1); + udelay(1); } } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c 2023-01-18 18:27:39.000000000 +0000 @@ -87,6 +87,7 @@ .hubp_init = hubp3_init, .set_unbounded_requesting = hubp31_set_unbounded_requesting, .hubp_soft_reset = hubp31_soft_reset, + .hubp_set_flip_int = hubp1_set_flip_int, .hubp_in_blank = hubp1_in_blank, .program_extended_blank = hubp31_program_extended_blank, }; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c 2023-01-18 18:27:39.000000000 +0000 @@ -49,18 +49,30 @@ #define CTX \ enc1->base.ctx +static void enc314_reset_fifo(struct stream_encoder *enc, bool reset) +{ + struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); + uint32_t reset_val = reset ? 1 : 0; + uint32_t is_symclk_on; + + REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, reset_val); + REG_GET(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, &is_symclk_on); + + if (is_symclk_on) + REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, reset_val, 10, 5000); + else + udelay(10); +} static void enc314_enable_fifo(struct stream_encoder *enc) { struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); - /* TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON */ - REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000); REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7); - REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1); - REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000); - REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0); - REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000); + + enc314_reset_fifo(enc, true); + enc314_reset_fifo(enc, false); + REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1); } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c 2023-01-18 18:27:39.000000000 +0000 @@ -237,7 +237,7 @@ .clear_optc_underflow = optc1_clear_optc_underflow, .setup_global_swap_lock = NULL, .get_crc = optc1_get_crc, - .configure_crc = optc2_configure_crc, + .configure_crc = optc1_configure_crc, .set_dsc_config = optc3_set_dsc_config, .get_dsc_status = optc2_get_dsc_status, .set_dwb_source = NULL, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c 2023-01-18 18:27:39.000000000 +0000 @@ -847,7 +847,7 @@ .num_ddc = 5, .num_vmid = 16, .num_mpc_3dlut = 2, - .num_dsc = 3, + .num_dsc = 4, }; static const struct dc_plane_cap plane_cap = { diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c 2023-01-18 18:27:39.000000000 +0000 @@ -49,6 +49,7 @@ #include "dcn20/dcn20_optc.h" #include "dmub_subvp_state.h" #include "dce/dmub_hw_lock_mgr.h" +#include "dcn32_resource.h" #include "dc_link_dp.h" #include "dmub/inc/dmub_subvp_state.h" @@ -198,42 +199,6 @@ return false; } -/* This function takes in the start address and surface size to be cached in CAB - * and calculates the total number of cache lines required to store the surface. - * The number of cache lines used for each surface is calculated independently of - * one another. For example, if there is a primary surface(1), meta surface(2), and - * cursor(3), this function should be called 3 times to calculate the number of cache - * lines used for each of those surfaces. - */ -static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_size, uint64_t start_address) -{ - uint32_t lines_used = 1; - uint32_t num_cached_bytes = 0; - uint32_t remaining_size = 0; - uint32_t cache_line_size = dc->caps.cache_line_size; - uint32_t remainder = 0; - - /* 1. Calculate surface size minus the number of bytes stored - * in the first cache line (all bytes in first cache line might - * not be fully used). - */ - div_u64_rem(start_address, cache_line_size, &remainder); - num_cached_bytes = cache_line_size - remainder; - remaining_size = surface_size - num_cached_bytes; - - /* 2. Calculate number of cache lines that will be fully used with - * the remaining number of bytes to be stored. - */ - lines_used += (remaining_size / cache_line_size); - - /* 3. Check if we need an extra line due to the remaining size not being - * a multiple of CACHE_LINE_SIZE. - */ - if (remaining_size % cache_line_size > 0) - lines_used++; - - return lines_used; -} /* This function loops through every surface that needs to be cached in CAB for SS, * and calculates the total number of ways required to store all surfaces (primary, @@ -241,94 +206,115 @@ */ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx) { - uint8_t i, j; + uint8_t i; + int j; struct dc_stream_state *stream = NULL; struct dc_plane_state *plane = NULL; - uint32_t surface_size = 0; uint32_t cursor_size = 0; - uint32_t cache_lines_used = 0; uint32_t total_lines = 0; uint32_t lines_per_way = 0; - uint32_t num_ways = 0; - uint32_t prev_addr_low = 0; - - for (i = 0; i < ctx->stream_count; i++) { - stream = ctx->streams[i]; + uint8_t num_ways = 0; + uint8_t bytes_per_pixel = 0; + uint8_t cursor_bpp = 0; + uint16_t mblk_width = 0; + uint16_t mblk_height = 0; + uint16_t mall_alloc_width_blk_aligned = 0; + uint16_t mall_alloc_height_blk_aligned = 0; + uint16_t num_mblks = 0; + uint32_t bytes_in_mall = 0; + uint32_t cache_lines_used = 0; + uint32_t cache_lines_per_plane = 0; - // Don't include PSR surface in the total surface size for CAB allocation - if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED) - continue; + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; - if (ctx->stream_status[i].plane_count == 0) + if (!pipe->stream || !pipe->plane_state || + pipe->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED || + pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) continue; - // For each stream, loop through each plane to calculate the number of cache - // lines required to store the surface in CAB - for (j = 0; j < ctx->stream_status[i].plane_count; j++) { - plane = ctx->stream_status[i].plane_states[j]; - - // Calculate total surface size - if (prev_addr_low != plane->address.grph.addr.u.low_part) { - /* if plane address are different from prev FB, then userspace allocated separate FBs*/ - surface_size += plane->plane_size.surface_pitch * - plane->plane_size.surface_size.height * - (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4); - - prev_addr_low = plane->address.grph.addr.u.low_part; - } else { - /* We have the same fb for all the planes. - * Xorg always creates one giant fb that holds all surfaces, - * so allocating it once is sufficient. - * */ - continue; - } - // Convert surface size + starting address to number of cache lines required - // (alignment accounted for) - cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size, - plane->address.grph.addr.quad_part); - - if (plane->address.grph.meta_addr.quad_part) { - // Meta surface - cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size, - plane->address.grph.meta_addr.quad_part); - } - } + bytes_per_pixel = pipe->plane_state->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4; + mblk_width = DCN3_2_MBLK_WIDTH; + mblk_height = bytes_per_pixel == 4 ? DCN3_2_MBLK_HEIGHT_4BPE : DCN3_2_MBLK_HEIGHT_8BPE; + + /* full_vp_width_blk_aligned = FLOOR(vp_x_start + full_vp_width + blk_width - 1, blk_width) - + * FLOOR(vp_x_start, blk_width) + * + * mall_alloc_width_blk_aligned_l/c = full_vp_width_blk_aligned_l/c + */ + mall_alloc_width_blk_aligned = ((pipe->plane_res.scl_data.viewport.x + + pipe->plane_res.scl_data.viewport.width + mblk_width - 1) / mblk_width * mblk_width) + + (pipe->plane_res.scl_data.viewport.x / mblk_width * mblk_width); + + /* full_vp_height_blk_aligned = FLOOR(vp_y_start + full_vp_height + blk_height - 1, blk_height) - + * FLOOR(vp_y_start, blk_height) + * + * mall_alloc_height_blk_aligned_l/c = full_vp_height_blk_aligned_l/c + */ + mall_alloc_height_blk_aligned = ((pipe->plane_res.scl_data.viewport.y + + pipe->plane_res.scl_data.viewport.height + mblk_height - 1) / mblk_height * mblk_height) + + (pipe->plane_res.scl_data.viewport.y / mblk_height * mblk_height); + + num_mblks = ((mall_alloc_width_blk_aligned + mblk_width - 1) / mblk_width) * + ((mall_alloc_height_blk_aligned + mblk_height - 1) / mblk_height); + + /* For DCC: + * meta_num_mblk = CEILING(full_mblk_width_ub_l*full_mblk_height_ub_l*Bpe/256/mblk_bytes, 1) + */ + if (pipe->plane_state->dcc.enable) + num_mblks += (mall_alloc_width_blk_aligned * mall_alloc_width_blk_aligned * bytes_per_pixel + + (256 * DCN3_2_MALL_MBLK_SIZE_BYTES) - 1) / (256 * DCN3_2_MALL_MBLK_SIZE_BYTES); + + bytes_in_mall = num_mblks * DCN3_2_MALL_MBLK_SIZE_BYTES; + + /* (cache lines used is total bytes / cache_line size. Add +2 for worst case alignment + * (MALL is 64-byte aligned) + */ + cache_lines_per_plane = bytes_in_mall / dc->caps.cache_line_size + 2; + cache_lines_used += cache_lines_per_plane; + } + + // Include cursor size for CAB allocation + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j]; + struct hubp *hubp = pipe->plane_res.hubp; - // Include cursor size for CAB allocation - for (j = 0; j < dc->res_pool->pipe_count; j++) { - struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j]; - struct hubp *hubp = pipe->plane_res.hubp; + if (pipe->stream && pipe->plane_state && hubp) + /* Find the cursor plane and use the exact size instead of + using the max for calculation */ + + if (hubp->curs_attr.width > 0) { + cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height; + + switch (pipe->stream->cursor_attributes.color_format) { + case CURSOR_MODE_MONO: + cursor_size /= 2; + cursor_bpp = 4; + break; + case CURSOR_MODE_COLOR_1BIT_AND: + case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA: + case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA: + cursor_size *= 4; + cursor_bpp = 4; + break; - if (pipe->stream && pipe->plane_state && hubp) - /* Find the cursor plane and use the exact size instead of - * using the max for calculation - */ - if (hubp->curs_attr.width > 0) { - cursor_size = hubp->curs_attr.width * hubp->curs_attr.height; + case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED: + case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED: + cursor_size *= 8; + cursor_bpp = 8; break; } - } - - switch (stream->cursor_attributes.color_format) { - case CURSOR_MODE_MONO: - cursor_size /= 2; - break; - case CURSOR_MODE_COLOR_1BIT_AND: - case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA: - case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA: - cursor_size *= 4; - break; - case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED: - case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED: - cursor_size *= 8; - break; - } - - if (stream->cursor_position.enable && plane->address.grph.cursor_cache_addr.quad_part) { - cache_lines_used += dcn32_cache_lines_for_surface(dc, cursor_size, - plane->address.grph.cursor_cache_addr.quad_part); - } + if (pipe->stream->cursor_position.enable && !dc->debug.alloc_extra_way_for_cursor && + cursor_size > 16384) { + /* cursor_num_mblk = CEILING(num_cursors*cursor_width*cursor_width*cursor_Bpe/mblk_bytes, 1) + */ + cache_lines_used += (((cursor_size + DCN3_2_MALL_MBLK_SIZE_BYTES - 1) / + DCN3_2_MALL_MBLK_SIZE_BYTES) * DCN3_2_MALL_MBLK_SIZE_BYTES) / + dc->caps.cache_line_size + 2; + } + break; + } } // Convert number of cache lines required to number of ways @@ -345,8 +331,8 @@ plane = ctx->stream_status[i].plane_states[j]; if (stream->cursor_position.enable && plane && - !plane->address.grph.cursor_cache_addr.quad_part && - cursor_size > 16384) { + dc->debug.alloc_extra_way_for_cursor && + cursor_size > 16384) { /* Cursor caching is not supported since it won't be on the same line. * So we need an extra line to accommodate it. With large cursors and a single 4k monitor * this case triggers corruption. If we're at the edge, then dont trigger display refresh @@ -358,7 +344,9 @@ } } } - + if (dc->debug.force_mall_ss_num_ways > 0) { + num_ways = dc->debug.force_mall_ss_num_ways; + } return num_ways; } @@ -741,10 +729,7 @@ struct hubp *hubp = pipe->plane_res.hubp; if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) { - //Round cursor width up to next multiple of 64 - int cursor_width = ((hubp->curs_attr.width + 63) / 64) * 64; - int cursor_height = hubp->curs_attr.height; - int cursor_size = cursor_width * cursor_height; + int cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height; switch (hubp->curs_attr.color_format) { case CURSOR_MODE_MONO: diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c 2023-01-18 18:27:39.000000000 +0000 @@ -872,6 +872,7 @@ .enable_single_display_2to1_odm_policy = true, .enable_dp_dig_pixel_rate_div_policy = 1, .allow_sw_cursor_fallback = false, + .alloc_extra_way_for_cursor = true, }; static const struct dc_debug_options debug_defaults_diags = { diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c 2023-01-18 18:27:39.000000000 +0000 @@ -54,13 +54,14 @@ uint32_t num_mblks = 0; uint32_t cache_lines_per_plane = 0; uint32_t i = 0, j = 0; - uint32_t mblk_width = 0; - uint32_t mblk_height = 0; + uint16_t mblk_width = 0; + uint16_t mblk_height = 0; uint32_t full_vp_width_blk_aligned = 0; uint32_t full_vp_height_blk_aligned = 0; uint32_t mall_alloc_width_blk_aligned = 0; uint32_t mall_alloc_height_blk_aligned = 0; - uint32_t full_vp_height = 0; + uint16_t full_vp_height = 0; + bool subvp_in_use = false; for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; @@ -70,6 +71,7 @@ pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { struct pipe_ctx *main_pipe = NULL; + subvp_in_use = true; /* Get full viewport height from main pipe (required for MBLK calculation) */ for (j = 0; j < dc->res_pool->pipe_count; j++) { main_pipe = &context->res_ctx.pipe_ctx[j]; @@ -129,6 +131,9 @@ if (cache_lines_used % lines_per_way > 0) num_ways++; + if (subvp_in_use && dc->debug.force_subvp_num_ways > 0) + num_ways = dc->debug.force_subvp_num_ways; + return num_ways; } @@ -187,7 +192,7 @@ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; if (!pipe->stream) - return false; + continue; if (!pipe->plane_state) return false; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c 2023-01-18 18:27:39.000000000 +0000 @@ -873,6 +873,7 @@ .enable_single_display_2to1_odm_policy = true, .enable_dp_dig_pixel_rate_div_policy = 1, .allow_sw_cursor_fallback = false, + .alloc_extra_way_for_cursor = true, }; static const struct dc_debug_options debug_defaults_diags = { diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -1228,6 +1228,7 @@ pipes[pipe_cnt].pipe.src.dcc = false; pipes[pipe_cnt].pipe.src.dcc_rate = 1; pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank; + pipes[pipe_cnt].pipe.dest.synchronize_timings = synchronized_vblank; pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch; pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start - timing->h_addressable diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -146,8 +146,8 @@ }, }, .num_states = 5, - .sr_exit_time_us = 9.0, - .sr_enter_plus_exit_time_us = 11.0, + .sr_exit_time_us = 16.5, + .sr_enter_plus_exit_time_us = 18.5, .sr_exit_z8_time_us = 442.0, .sr_enter_plus_exit_z8_time_us = 560.0, .writeback_latency_us = 12.0, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -157,7 +157,7 @@ .dispclk_dppclk_vco_speed_mhz = 4300.0, .do_urgent_latency_adjustment = true, .urgent_latency_adjustment_fabric_clock_component_us = 1.0, - .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, + .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000, }; void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr) @@ -211,7 +211,7 @@ /* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */ if (clk_mgr->base.ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) { clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true; - clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 38; + clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 50; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; @@ -221,7 +221,7 @@ clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; clk_mgr->base.bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz * 16; - clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38; + clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 50; clk_mgr->base.bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[1].memclk_mhz * 16; clk_mgr->base.bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9; clk_mgr->base.bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[2].memclk_mhz * 16; @@ -1700,6 +1700,12 @@ */ context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; + /* For DCN32/321 need to validate with fclk pstate change latency equal to dummy so + * prefetch is scheduled correctly to account for dummy pstate. + */ + if (dummy_latency_index == 0) + context->bw_ctx.dml.soc.fclk_change_latency_us = + dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us; dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false); maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb; dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; @@ -1879,6 +1885,10 @@ context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod; + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && dummy_latency_index == 0) + context->bw_ctx.dml.soc.fclk_change_latency_us = + dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us; + dcn32_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); if (!pstate_en) @@ -1886,8 +1896,12 @@ context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; - if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context); + if (dummy_latency_index == 0) + context->bw_ctx.dml.soc.fclk_change_latency_us = + dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us; + } } static void dcn32_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c 2023-01-18 18:27:39.000000000 +0000 @@ -364,7 +364,8 @@ for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) { v->DSCDelay[k] = dml32_DSCDelayRequirement(mode_lib->vba.DSCEnabled[k], mode_lib->vba.ODMCombineEnabled[k], mode_lib->vba.DSCInputBitPerComponent[k], - mode_lib->vba.OutputBpp[k], mode_lib->vba.HActive[k], mode_lib->vba.HTotal[k], + mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k], + mode_lib->vba.HActive[k], mode_lib->vba.HTotal[k], mode_lib->vba.NumberOfDSCSlices[k], mode_lib->vba.OutputFormat[k], mode_lib->vba.Output[k], mode_lib->vba.PixelClock[k], mode_lib->vba.PixelClockBackEnd[k]); @@ -717,6 +718,8 @@ do { MaxTotalRDBandwidth = 0; + DestinationLineTimesForPrefetchLessThan2 = false; + VRatioPrefetchMoreThanMax = false; #ifdef __DML_VBA_DEBUG__ dml_print("DML::%s: Start loop: VStartup = %d\n", __func__, mode_lib->vba.VStartupLines); #endif @@ -1627,7 +1630,7 @@ && !mode_lib->vba.MSOOrODMSplitWithNonDPLink && !mode_lib->vba.NotEnoughLanesForMSO && mode_lib->vba.LinkCapacitySupport[i] == true && !mode_lib->vba.P2IWith420 - && !mode_lib->vba.DSCOnlyIfNecessaryWithBPP + //&& !mode_lib->vba.DSCOnlyIfNecessaryWithBPP && !mode_lib->vba.DSC422NativeNotSupported && !mode_lib->vba.MPCCombineMethodIncompatible && mode_lib->vba.ODMCombine2To1SupportCheckOK[i] == true @@ -3194,6 +3197,7 @@ mode_lib->vba.FCLKChangeLatency, mode_lib->vba.UrgLatency[i], mode_lib->vba.SREnterPlusExitTime); + memset(&v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull, 0, sizeof(DmlPipe)); v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dppclk = mode_lib->vba.RequiredDPPCLK[i][j][k]; v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dispclk = mode_lib->vba.RequiredDISPCLK[i][j]; v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.PixelClock = mode_lib->vba.PixelClock[k]; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c 2023-01-18 18:27:39.000000000 +0000 @@ -1746,7 +1746,7 @@ } DSCDelayRequirement_val = DSCDelayRequirement_val + (HTotal - HActive) * - dml_ceil(DSCDelayRequirement_val / HActive, 1); + dml_ceil((double)DSCDelayRequirement_val / HActive, 1); DSCDelayRequirement_val = DSCDelayRequirement_val * PixelClock / PixelClockBackEnd; @@ -4396,7 +4396,7 @@ if (v->NumberOfActiveSurfaces > 1) { ActiveClockChangeLatencyHidingY = ActiveClockChangeLatencyHidingY - - (1 - 1 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k] + - (1.0 - 1.0 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k] / v->PixelClock[k] / v->VRatio[k]; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h 2023-01-18 18:27:39.000000000 +0000 @@ -30,7 +30,7 @@ #include "os_types.h" #include "../dc_features.h" #include "../display_mode_structs.h" -#include "dml/display_mode_vba.h" +#include "../display_mode_vba.h" unsigned int dml32_dscceComputeDelay( unsigned int bpc, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c 2023-01-18 18:27:39.000000000 +0000 @@ -291,8 +291,8 @@ dml_print("DML_DLG: %s: vready_after_vcount0 = %d\n", __func__, dlg_regs->vready_after_vcount0); - dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); - dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); + dst_x_after_scaler = dml_ceil(get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1); + dst_y_after_scaler = dml_ceil(get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1); // do some adjustment on the dst_after scaler to account for odm combine mode dml_print("DML_DLG: %s: input dst_x_after_scaler = %d\n", __func__, dst_x_after_scaler); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -119,15 +119,15 @@ }, }, .num_states = 1, - .sr_exit_time_us = 12.36, - .sr_enter_plus_exit_time_us = 16.72, + .sr_exit_time_us = 19.95, + .sr_enter_plus_exit_time_us = 24.36, .sr_exit_z8_time_us = 285.0, .sr_enter_plus_exit_z8_time_us = 320, .writeback_latency_us = 12.0, .round_trip_ping_latency_dcfclk_cycles = 263, - .urgent_latency_pixel_data_only_us = 4.0, - .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, - .urgent_latency_vm_data_only_us = 4.0, + .urgent_latency_pixel_data_only_us = 4, + .urgent_latency_pixel_mixed_with_vm_data_us = 4, + .urgent_latency_vm_data_only_us = 4, .fclk_change_latency_us = 20, .usr_retraining_latency_us = 2, .smn_latency_us = 2, @@ -155,7 +155,7 @@ .dispclk_dppclk_vco_speed_mhz = 4300.0, .do_urgent_latency_adjustment = true, .urgent_latency_adjustment_fabric_clock_component_us = 1.0, - .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, + .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000, }; static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry) diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c 2023-01-18 18:27:39.000000000 +0000 @@ -624,7 +624,7 @@ mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] = dout->is_virtual; - if (!dout->dsc_enable) + if (dout->dsc_enable) mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp; else mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0; diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c 2023-01-18 18:27:39.000000000 +0000 @@ -108,6 +108,13 @@ ddc_data_regs_dcn2(4), ddc_data_regs_dcn2(5), { + // add a dummy entry for cases no such port + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + .ddc_setup = 0, + .phy_aux_cntl = 0, + .dc_gpio_aux_ctrl_5 = 0 + }, + { DDC_GPIO_VGA_REG_LIST(DATA), .ddc_setup = 0, .phy_aux_cntl = 0, @@ -122,6 +129,13 @@ ddc_clk_regs_dcn2(4), ddc_clk_regs_dcn2(5), { + // add a dummy entry for cases no such port + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + .ddc_setup = 0, + .phy_aux_cntl = 0, + .dc_gpio_aux_ctrl_5 = 0 + }, + { DDC_GPIO_VGA_REG_LIST(CLK), .ddc_setup = 0, .phy_aux_cntl = 0, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c linux-6.0.12/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c 2023-01-18 18:27:39.000000000 +0000 @@ -94,11 +94,14 @@ * is required for detection of AUX mode */ if (hw_gpio->base.en != GPIO_DDC_LINE_VIP_PAD) { if (!ddc_data_pd_en || !ddc_clk_pd_en) { - - REG_SET_2(gpio.MASK_reg, regval, + if (hw_gpio->base.en == GPIO_DDC_LINE_DDC_VGA) { + // bit 4 of mask has different usage in some cases + REG_SET(gpio.MASK_reg, regval, DC_GPIO_DDC1DATA_PD_EN, 1); + } else { + REG_SET_2(gpio.MASK_reg, regval, DC_GPIO_DDC1DATA_PD_EN, 1, DC_GPIO_DDC1CLK_PD_EN, 1); - + } if (config_data->type == GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE) msleep(3); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h linux-6.0.12/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h --- linux-6.0.6/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h 2023-01-18 18:27:39.000000000 +0000 @@ -95,10 +95,23 @@ unsigned int wck_ratio; }; +struct clk_limit_num_entries { + unsigned int num_dcfclk_levels; + unsigned int num_fclk_levels; + unsigned int num_memclk_levels; + unsigned int num_socclk_levels; + unsigned int num_dtbclk_levels; + unsigned int num_dispclk_levels; + unsigned int num_dppclk_levels; + unsigned int num_phyclk_levels; + unsigned int num_phyclk_d18_levels; +}; + /* This table is contiguous */ struct clk_limit_table { struct clk_limit_table_entry entries[MAX_NUM_DPM_LVL]; - unsigned int num_entries; + struct clk_limit_num_entries num_entries_per_clk; + unsigned int num_entries; /* highest populated dpm level for back compatibility */ }; struct wm_range_table_entry { diff -Nru linux-6.0.6/drivers/gpu/drm/amd/display/Kconfig linux-6.0.12/drivers/gpu/drm/amd/display/Kconfig --- linux-6.0.6/drivers/gpu/drm/amd/display/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/display/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -5,6 +5,7 @@ config DRM_AMD_DC bool "AMD DC - Enable new display engine" default y + depends on BROKEN || !CC_IS_CLANG || X86_64 || SPARC64 || ARM64 select SND_HDA_COMPONENT if SND_HDA_CORE select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128) help @@ -12,6 +13,12 @@ support for AMDGPU. This adds required support for Vega and Raven ASICs. + calculate_bandwidth() is presently broken on all !(X86_64 || SPARC64 || ARM64) + architectures built with Clang (all released versions), whereby the stack + frame gets blown up to well over 5k. This would cause an immediate kernel + panic on most architectures. We'll revert this when the following bug report + has been resolved: https://github.com/llvm/llvm-project/issues/41896. + config DRM_AMD_DC_DCN def_bool n help diff -Nru linux-6.0.6/drivers/gpu/drm/amd/include/kgd_kfd_interface.h linux-6.0.12/drivers/gpu/drm/amd/include/kgd_kfd_interface.h --- linux-6.0.6/drivers/gpu/drm/amd/include/kgd_kfd_interface.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/include/kgd_kfd_interface.h 2023-01-18 18:27:39.000000000 +0000 @@ -262,8 +262,9 @@ uint32_t queue_id); int (*hqd_destroy)(struct amdgpu_device *adev, void *mqd, - uint32_t reset_type, unsigned int timeout, - uint32_t pipe_id, uint32_t queue_id); + enum kfd_preempt_type reset_type, + unsigned int timeout, uint32_t pipe_id, + uint32_t queue_id); bool (*hqd_sdma_is_occupied)(struct amdgpu_device *adev, void *mqd); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c linux-6.0.12/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c --- linux-6.0.6/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c 2023-01-18 18:27:39.000000000 +0000 @@ -67,22 +67,21 @@ int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr, uint32_t *speed) { - uint32_t current_rpm; - uint32_t percent = 0; + struct amdgpu_device *adev = hwmgr->adev; + uint32_t duty100, duty; + uint64_t tmp64; - if (hwmgr->thermal_controller.fanInfo.bNoFan) - return 0; + duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), + CG_FDO_CTRL1, FMAX_DUTY100); + duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS), + CG_THERMAL_STATUS, FDO_PWM_DUTY); - if (vega10_get_current_rpm(hwmgr, ¤t_rpm)) - return -1; + if (!duty100) + return -EINVAL; - if (hwmgr->thermal_controller. - advanceFanControlParameters.usMaxFanRPM != 0) - percent = current_rpm * 255 / - hwmgr->thermal_controller. - advanceFanControlParameters.usMaxFanRPM; - - *speed = MIN(percent, 255); + tmp64 = (uint64_t)duty * 255; + do_div(tmp64, duty100); + *speed = MIN((uint32_t)tmp64, 255); return 0; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c 2023-01-18 18:27:39.000000000 +0000 @@ -1131,22 +1131,21 @@ uint64_t features_supported; int ret = 0; - if (adev->in_suspend && smu_is_dpm_running(smu)) { - dev_info(adev->dev, "dpm has been enabled\n"); - /* this is needed specifically */ - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 5, 0): - case IP_VERSION(11, 0, 12): + switch (adev->ip_versions[MP1_HWIP][0]) { + case IP_VERSION(11, 0, 7): + case IP_VERSION(11, 0, 11): + case IP_VERSION(11, 5, 0): + case IP_VERSION(11, 0, 12): + if (adev->in_suspend && smu_is_dpm_running(smu)) { + dev_info(adev->dev, "dpm has been enabled\n"); ret = smu_system_features_control(smu, true); if (ret) dev_err(adev->dev, "Failed system features control!\n"); - break; - default: - break; + return ret; } - return ret; + break; + default: + break; } ret = smu_init_display_count(smu, 0); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h 2023-01-18 18:27:39.000000000 +0000 @@ -1372,6 +1372,14 @@ CMN2ASIC_MAPPING_WORKLOAD, }; +enum smu_baco_seq { + BACO_SEQ_BACO = 0, + BACO_SEQ_MSR, + BACO_SEQ_BAMACO, + BACO_SEQ_ULPS, + BACO_SEQ_COUNT, +}; + #define MSG_MAP(msg, index, valid_in_vf) \ [SMU_MSG_##msg] = {1, (index), (valid_in_vf)} diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h 2023-01-18 18:27:39.000000000 +0000 @@ -25,7 +25,7 @@ #define SMU13_DRIVER_IF_V13_0_0_H //Increment this version if SkuTable_t or BoardTable_t change -#define PPTABLE_VERSION 0x24 +#define PPTABLE_VERSION 0x26 #define NUM_GFXCLK_DPM_LEVELS 16 #define NUM_SOCCLK_DPM_LEVELS 8 @@ -109,6 +109,22 @@ #define FEATURE_SPARE_63_BIT 63 #define NUM_FEATURES 64 +#define ALLOWED_FEATURE_CTRL_DEFAULT 0xFFFFFFFFFFFFFFFFULL +#define ALLOWED_FEATURE_CTRL_SCPM ((1 << FEATURE_DPM_GFXCLK_BIT) | \ + (1 << FEATURE_DPM_GFX_POWER_OPTIMIZER_BIT) | \ + (1 << FEATURE_DPM_UCLK_BIT) | \ + (1 << FEATURE_DPM_FCLK_BIT) | \ + (1 << FEATURE_DPM_SOCCLK_BIT) | \ + (1 << FEATURE_DPM_MP0CLK_BIT) | \ + (1 << FEATURE_DPM_LINK_BIT) | \ + (1 << FEATURE_DPM_DCN_BIT) | \ + (1 << FEATURE_DS_GFXCLK_BIT) | \ + (1 << FEATURE_DS_SOCCLK_BIT) | \ + (1 << FEATURE_DS_FCLK_BIT) | \ + (1 << FEATURE_DS_LCLK_BIT) | \ + (1 << FEATURE_DS_DCFCLK_BIT) | \ + (1 << FEATURE_DS_UCLK_BIT)) + //For use with feature control messages typedef enum { FEATURE_PWR_ALL, @@ -133,6 +149,7 @@ #define DEBUG_OVERRIDE_DISABLE_DFLL 0x00000200 #define DEBUG_OVERRIDE_ENABLE_RLC_VF_BRINGUP_MODE 0x00000400 #define DEBUG_OVERRIDE_DFLL_MASTER_MODE 0x00000800 +#define DEBUG_OVERRIDE_ENABLE_PROFILING_MODE 0x00001000 // VR Mapping Bit Defines #define VR_MAPPING_VR_SELECT_MASK 0x01 @@ -262,15 +279,15 @@ } I2cControllerPort_e; typedef enum { - I2C_CONTROLLER_NAME_VR_GFX = 0, - I2C_CONTROLLER_NAME_VR_SOC, - I2C_CONTROLLER_NAME_VR_VMEMP, - I2C_CONTROLLER_NAME_VR_VDDIO, - I2C_CONTROLLER_NAME_LIQUID0, - I2C_CONTROLLER_NAME_LIQUID1, - I2C_CONTROLLER_NAME_PLX, - I2C_CONTROLLER_NAME_OTHER, - I2C_CONTROLLER_NAME_COUNT, + I2C_CONTROLLER_NAME_VR_GFX = 0, + I2C_CONTROLLER_NAME_VR_SOC, + I2C_CONTROLLER_NAME_VR_VMEMP, + I2C_CONTROLLER_NAME_VR_VDDIO, + I2C_CONTROLLER_NAME_LIQUID0, + I2C_CONTROLLER_NAME_LIQUID1, + I2C_CONTROLLER_NAME_PLX, + I2C_CONTROLLER_NAME_FAN_INTAKE, + I2C_CONTROLLER_NAME_COUNT, } I2cControllerName_e; typedef enum { @@ -282,16 +299,17 @@ I2C_CONTROLLER_THROTTLER_LIQUID0, I2C_CONTROLLER_THROTTLER_LIQUID1, I2C_CONTROLLER_THROTTLER_PLX, + I2C_CONTROLLER_THROTTLER_FAN_INTAKE, I2C_CONTROLLER_THROTTLER_INA3221, I2C_CONTROLLER_THROTTLER_COUNT, } I2cControllerThrottler_e; typedef enum { - I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5, - I2C_CONTROLLER_PROTOCOL_VR_IR35217, - I2C_CONTROLLER_PROTOCOL_TMP_TMP102A, - I2C_CONTROLLER_PROTOCOL_INA3221, - I2C_CONTROLLER_PROTOCOL_COUNT, + I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5, + I2C_CONTROLLER_PROTOCOL_VR_IR35217, + I2C_CONTROLLER_PROTOCOL_TMP_MAX31875, + I2C_CONTROLLER_PROTOCOL_INA3221, + I2C_CONTROLLER_PROTOCOL_COUNT, } I2cControllerProtocol_e; typedef struct { @@ -658,13 +676,20 @@ #define PP_NUM_OD_VF_CURVE_POINTS PP_NUM_RTAVFS_PWL_ZONES + 1 +typedef enum { + FAN_MODE_AUTO = 0, + FAN_MODE_MANUAL_LINEAR, +} FanMode_e; typedef struct { uint32_t FeatureCtrlMask; //Voltage control int16_t VoltageOffsetPerZoneBoundary[PP_NUM_OD_VF_CURVE_POINTS]; - uint16_t reserved[2]; + uint16_t VddGfxVmax; // in mV + + uint8_t IdlePwrSavingFeaturesCtrl; + uint8_t RuntimePwrSavingFeaturesCtrl; //Frequency changes int16_t GfxclkFmin; // MHz @@ -674,7 +699,7 @@ //PPT int16_t Ppt; // % - int16_t reserved1; + int16_t Tdc; //Fan control uint8_t FanLinearPwmPoints[NUM_OD_FAN_MAX_POINTS]; @@ -701,16 +726,19 @@ uint32_t FeatureCtrlMask; int16_t VoltageOffsetPerZoneBoundary; - uint16_t reserved[2]; + uint16_t VddGfxVmax; // in mV - uint16_t GfxclkFmin; // MHz - uint16_t GfxclkFmax; // MHz + uint8_t IdlePwrSavingFeaturesCtrl; + uint8_t RuntimePwrSavingFeaturesCtrl; + + int16_t GfxclkFmin; // MHz + int16_t GfxclkFmax; // MHz uint16_t UclkFmin; // MHz uint16_t UclkFmax; // MHz //PPT int16_t Ppt; // % - int16_t reserved1; + int16_t Tdc; uint8_t FanLinearPwmPoints; uint8_t FanLinearTempPoints; @@ -857,7 +885,8 @@ uint16_t FanStartTempMin; uint16_t FanStartTempMax; - uint32_t Spare[12]; + uint16_t PowerMinPpt0[POWER_SOURCE_COUNT]; + uint32_t Spare[11]; } MsgLimits_t; @@ -1041,7 +1070,17 @@ uint32_t GfxoffSpare[15]; // GFX GPO - uint32_t GfxGpoSpare[16]; + uint32_t DfllBtcMasterScalerM; + int32_t DfllBtcMasterScalerB; + uint32_t DfllBtcSlaveScalerM; + int32_t DfllBtcSlaveScalerB; + + uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg + uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg + + uint32_t DfllL2FrequencyBoostM; //Unitless (float) + uint32_t DfllL2FrequencyBoostB; //In MHz (integer) + uint32_t GfxGpoSpare[8]; // GFX DCS @@ -1114,12 +1153,14 @@ uint16_t IntakeTempHighIntakeAcousticLimit; uint16_t IntakeTempAcouticLimitReleaseRate; - uint16_t FanStalledTempLimitOffset; + int16_t FanAbnormalTempLimitOffset; uint16_t FanStalledTriggerRpm; - uint16_t FanAbnormalTriggerRpm; - uint16_t FanPadding; + uint16_t FanAbnormalTriggerRpmCoeff; + uint16_t FanAbnormalDetectionEnable; - uint32_t FanSpare[14]; + uint8_t FanIntakeSensorSupport; + uint8_t FanIntakePadding[3]; + uint32_t FanSpare[13]; // SECTION: VDD_GFX AVFS @@ -1198,8 +1239,13 @@ int16_t TotalBoardPowerM; int16_t TotalBoardPowerB; + //PMFW-11158 + QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT]; + QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT]; + QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT]; + // SECTION: Sku Reserved - uint32_t Spare[61]; + uint32_t Spare[43]; // Padding for MMHUB - do not modify this uint32_t MmHubPadding[8]; @@ -1288,8 +1334,11 @@ uint32_t PostVoltageSetBacoDelay; // in microseconds. Amount of time FW will wait after power good is established or PSI0 command is issued uint32_t BacoEntryDelay; // in milliseconds. Amount of time FW will wait to trigger BACO entry after receiving entry notification from OS + uint8_t FuseWritePowerMuxPresent; + uint8_t FuseWritePadding[3]; + // SECTION: Board Reserved - uint32_t BoardSpare[64]; + uint32_t BoardSpare[63]; // SECTION: Structure Padding @@ -1381,7 +1430,7 @@ uint16_t AverageTotalBoardPower; uint16_t AvgTemperature[TEMP_COUNT]; - uint16_t TempPadding; + uint16_t AvgTemperatureFanIntake; uint8_t PcieRate ; uint8_t PcieWidth ; @@ -1550,5 +1599,7 @@ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5 #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6 #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7 +#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8 +#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9 #endif diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_7.h 2023-01-18 18:27:39.000000000 +0000 @@ -25,10 +25,10 @@ // *** IMPORTANT *** // PMFW TEAM: Always increment the interface version on any change to this file -#define SMU13_DRIVER_IF_VERSION 0x2C +#define SMU13_DRIVER_IF_VERSION 0x35 //Increment this version if SkuTable_t or BoardTable_t change -#define PPTABLE_VERSION 0x20 +#define PPTABLE_VERSION 0x27 #define NUM_GFXCLK_DPM_LEVELS 16 #define NUM_SOCCLK_DPM_LEVELS 8 @@ -96,7 +96,7 @@ #define FEATURE_MEM_TEMP_READ_BIT 47 #define FEATURE_ATHUB_MMHUB_PG_BIT 48 #define FEATURE_SOC_PCC_BIT 49 -#define FEATURE_SPARE_50_BIT 50 +#define FEATURE_EDC_PWRBRK_BIT 50 #define FEATURE_SPARE_51_BIT 51 #define FEATURE_SPARE_52_BIT 52 #define FEATURE_SPARE_53_BIT 53 @@ -282,15 +282,15 @@ } I2cControllerPort_e; typedef enum { - I2C_CONTROLLER_NAME_VR_GFX = 0, - I2C_CONTROLLER_NAME_VR_SOC, - I2C_CONTROLLER_NAME_VR_VMEMP, - I2C_CONTROLLER_NAME_VR_VDDIO, - I2C_CONTROLLER_NAME_LIQUID0, - I2C_CONTROLLER_NAME_LIQUID1, - I2C_CONTROLLER_NAME_PLX, - I2C_CONTROLLER_NAME_OTHER, - I2C_CONTROLLER_NAME_COUNT, + I2C_CONTROLLER_NAME_VR_GFX = 0, + I2C_CONTROLLER_NAME_VR_SOC, + I2C_CONTROLLER_NAME_VR_VMEMP, + I2C_CONTROLLER_NAME_VR_VDDIO, + I2C_CONTROLLER_NAME_LIQUID0, + I2C_CONTROLLER_NAME_LIQUID1, + I2C_CONTROLLER_NAME_PLX, + I2C_CONTROLLER_NAME_FAN_INTAKE, + I2C_CONTROLLER_NAME_COUNT, } I2cControllerName_e; typedef enum { @@ -302,6 +302,7 @@ I2C_CONTROLLER_THROTTLER_LIQUID0, I2C_CONTROLLER_THROTTLER_LIQUID1, I2C_CONTROLLER_THROTTLER_PLX, + I2C_CONTROLLER_THROTTLER_FAN_INTAKE, I2C_CONTROLLER_THROTTLER_INA3221, I2C_CONTROLLER_THROTTLER_COUNT, } I2cControllerThrottler_e; @@ -309,8 +310,9 @@ typedef enum { I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5, I2C_CONTROLLER_PROTOCOL_VR_IR35217, - I2C_CONTROLLER_PROTOCOL_TMP_TMP102A, + I2C_CONTROLLER_PROTOCOL_TMP_MAX31875, I2C_CONTROLLER_PROTOCOL_INA3221, + I2C_CONTROLLER_PROTOCOL_TMP_MAX6604, I2C_CONTROLLER_PROTOCOL_COUNT, } I2cControllerProtocol_e; @@ -690,6 +692,9 @@ #define PP_OD_FEATURE_UCLK_BIT 8 #define PP_OD_FEATURE_ZERO_FAN_BIT 9 #define PP_OD_FEATURE_TEMPERATURE_BIT 10 +#define PP_OD_FEATURE_POWER_FEATURE_CTRL_BIT 11 +#define PP_OD_FEATURE_ASIC_TDC_BIT 12 +#define PP_OD_FEATURE_COUNT 13 typedef enum { PP_OD_POWER_FEATURE_ALWAYS_ENABLED, @@ -697,6 +702,11 @@ PP_OD_POWER_FEATURE_ALWAYS_DISABLED, } PP_OD_POWER_FEATURE_e; +typedef enum { + FAN_MODE_AUTO = 0, + FAN_MODE_MANUAL_LINEAR, +} FanMode_e; + typedef struct { uint32_t FeatureCtrlMask; @@ -708,8 +718,8 @@ uint8_t RuntimePwrSavingFeaturesCtrl; //Frequency changes - int16_t GfxclkFmin; // MHz - int16_t GfxclkFmax; // MHz + int16_t GfxclkFmin; // MHz + int16_t GfxclkFmax; // MHz uint16_t UclkFmin; // MHz uint16_t UclkFmax; // MHz @@ -730,7 +740,12 @@ uint8_t MaxOpTemp; uint8_t Padding[4]; - uint32_t Spare[12]; + uint16_t GfxVoltageFullCtrlMode; + uint16_t GfxclkFullCtrlMode; + uint16_t UclkFullCtrlMode; + int16_t AsicTdc; + + uint32_t Spare[10]; uint32_t MmHubPadding[8]; // SMU internal use. Adding here instead of external as a workaround } OverDriveTable_t; @@ -748,8 +763,8 @@ uint8_t IdlePwrSavingFeaturesCtrl; uint8_t RuntimePwrSavingFeaturesCtrl; - uint16_t GfxclkFmin; // MHz - uint16_t GfxclkFmax; // MHz + int16_t GfxclkFmin; // MHz + int16_t GfxclkFmax; // MHz uint16_t UclkFmin; // MHz uint16_t UclkFmax; // MHz @@ -769,7 +784,12 @@ uint8_t MaxOpTemp; uint8_t Padding[4]; - uint32_t Spare[12]; + uint16_t GfxVoltageFullCtrlMode; + uint16_t GfxclkFullCtrlMode; + uint16_t UclkFullCtrlMode; + int16_t AsicTdc; + + uint32_t Spare[10]; } OverDriveLimits_t; @@ -903,7 +923,8 @@ uint16_t FanStartTempMin; uint16_t FanStartTempMax; - uint32_t Spare[12]; + uint16_t PowerMinPpt0[POWER_SOURCE_COUNT]; + uint32_t Spare[11]; } MsgLimits_t; @@ -1086,11 +1107,13 @@ uint32_t GfxoffSpare[15]; // GFX GPO - float DfllBtcMasterScalerM; + uint32_t DfllBtcMasterScalerM; int32_t DfllBtcMasterScalerB; - float DfllBtcSlaveScalerM; + uint32_t DfllBtcSlaveScalerM; int32_t DfllBtcSlaveScalerB; - uint32_t GfxGpoSpare[12]; + uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg + uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg + uint32_t GfxGpoSpare[10]; // GFX DCS @@ -1106,7 +1129,10 @@ uint16_t DcsTimeout; //This is the amount of time SMU FW waits for RLC to put GFX into GFXOFF before reverting to the fallback mechanism of throttling GFXCLK to Fmin. - uint32_t DcsSpare[16]; + uint32_t DcsSpare[14]; + + // UCLK section + uint16_t ShadowFreqTableUclk[NUM_UCLK_DPM_LEVELS]; // In MHz // UCLK section uint8_t UseStrobeModeOptimizations; //Set to indicate that FW should use strobe mode optimizations @@ -1163,13 +1189,14 @@ uint16_t IntakeTempHighIntakeAcousticLimit; uint16_t IntakeTempAcouticLimitReleaseRate; - uint16_t FanStalledTempLimitOffset; + int16_t FanAbnormalTempLimitOffset; uint16_t FanStalledTriggerRpm; - uint16_t FanAbnormalTriggerRpm; - uint16_t FanPadding; - - uint32_t FanSpare[14]; + uint16_t FanAbnormalTriggerRpmCoeff; + uint16_t FanAbnormalDetectionEnable; + uint8_t FanIntakeSensorSupport; + uint8_t FanIntakePadding[3]; + uint32_t FanSpare[13]; // SECTION: VDD_GFX AVFS uint8_t OverrideGfxAvfsFuses; @@ -1193,7 +1220,6 @@ uint32_t dGbV_dT_vmin; uint32_t dGbV_dT_vmax; - //Unused: PMFW-9370 uint32_t V2F_vmin_range_low; uint32_t V2F_vmin_range_high; uint32_t V2F_vmax_range_low; @@ -1238,8 +1264,21 @@ // SECTION: Advanced Options uint32_t DebugOverrides; + // Section: Total Board Power idle vs active coefficients + uint8_t TotalBoardPowerSupport; + uint8_t TotalBoardPowerPadding[3]; + + int16_t TotalIdleBoardPowerM; + int16_t TotalIdleBoardPowerB; + int16_t TotalBoardPowerM; + int16_t TotalBoardPowerB; + + QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT]; + QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT]; + QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT]; + // SECTION: Sku Reserved - uint32_t Spare[64]; + uint32_t Spare[43]; // Padding for MMHUB - do not modify this uint32_t MmHubPadding[8]; @@ -1304,7 +1343,8 @@ // SECTION: Clock Spread Spectrum // UCLK Spread Spectrum - uint16_t UclkSpreadPadding; + uint8_t UclkTrainingModeSpreadPercent; // Q4.4 + uint8_t UclkSpreadPadding; uint16_t UclkSpreadFreq; // kHz // UCLK Spread Spectrum @@ -1317,11 +1357,7 @@ // Section: Memory Config uint8_t DramWidth; // Width of interface to the channel for each DRAM module. See DRAM_BIT_WIDTH_TYPE_e - uint8_t PaddingMem1[3]; - - // Section: Total Board Power - uint16_t TotalBoardPower; //Only needed for TCP Estimated case, where TCP = TGP+Total Board Power - uint16_t BoardPowerPadding; + uint8_t PaddingMem1[7]; // SECTION: UMC feature flags uint8_t HsrEnabled; @@ -1423,8 +1459,11 @@ uint16_t Vcn1ActivityPercentage ; uint32_t EnergyAccumulator; - uint16_t AverageSocketPower ; + uint16_t AverageSocketPower; + uint16_t AverageTotalBoardPower; + uint16_t AvgTemperature[TEMP_COUNT]; + uint16_t AvgTemperatureFanIntake; uint8_t PcieRate ; uint8_t PcieWidth ; @@ -1592,5 +1631,7 @@ #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5 #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6 #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7 +#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8 +#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9 #endif diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h 2023-01-18 18:27:39.000000000 +0000 @@ -54,14 +54,14 @@ #define PPSMC_MSG_TestMessage 0x01 ///< To check if PMFW is alive and responding. Requirement specified by PMFW team #define PPSMC_MSG_GetPmfwVersion 0x02 ///< Get PMFW version #define PPSMC_MSG_GetDriverIfVersion 0x03 ///< Get PMFW_DRIVER_IF version -#define PPSMC_MSG_EnableGfxOff 0x04 ///< Enable GFXOFF -#define PPSMC_MSG_DisableGfxOff 0x05 ///< Disable GFXOFF +#define PPSMC_MSG_SPARE0 0x04 ///< SPARE +#define PPSMC_MSG_SPARE1 0x05 ///< SPARE #define PPSMC_MSG_PowerDownVcn 0x06 ///< Power down VCN #define PPSMC_MSG_PowerUpVcn 0x07 ///< Power up VCN; VCN is power gated by default #define PPSMC_MSG_SetHardMinVcn 0x08 ///< For wireless display #define PPSMC_MSG_SetSoftMinGfxclk 0x09 ///< Set SoftMin for GFXCLK, argument is frequency in MHz -#define PPSMC_MSG_ActiveProcessNotify 0x0A ///< Needs update -#define PPSMC_MSG_ForcePowerDownGfx 0x0B ///< Force power down GFX, i.e. enter GFXOFF +#define PPSMC_MSG_SPARE2 0x0A ///< SPARE +#define PPSMC_MSG_SPARE3 0x0B ///< SPARE #define PPSMC_MSG_PrepareMp1ForUnload 0x0C ///< Prepare PMFW for GFX driver unload #define PPSMC_MSG_SetDriverDramAddrHigh 0x0D ///< Set high 32 bits of DRAM address for Driver table transfer #define PPSMC_MSG_SetDriverDramAddrLow 0x0E ///< Set low 32 bits of DRAM address for Driver table transfer @@ -73,8 +73,7 @@ #define PPSMC_MSG_SetSoftMinFclk 0x14 ///< Set hard min for FCLK #define PPSMC_MSG_SetSoftMinVcn 0x15 ///< Set soft min for VCN clocks (VCLK and DCLK) - -#define PPSMC_MSG_EnableGfxImu 0x16 ///< Needs update +#define PPSMC_MSG_EnableGfxImu 0x16 ///< Enable GFX IMU #define PPSMC_MSG_GetGfxclkFrequency 0x17 ///< Get GFX clock frequency #define PPSMC_MSG_GetFclkFrequency 0x18 ///< Get FCLK frequency @@ -102,8 +101,8 @@ #define PPSMC_MSG_SetHardMinIspxclkByFreq 0x2C ///< Set HardMin by frequency for ISPXCLK #define PPSMC_MSG_PowerDownUmsch 0x2D ///< Power down VCN.UMSCH (aka VSCH) scheduler #define PPSMC_MSG_PowerUpUmsch 0x2E ///< Power up VCN.UMSCH (aka VSCH) scheduler -#define PPSMC_Message_IspStutterOn_MmhubPgDis 0x2F ///< ISP StutterOn mmHub PgDis -#define PPSMC_Message_IspStutterOff_MmhubPgEn 0x30 ///< ISP StufferOff mmHub PgEn +#define PPSMC_MSG_IspStutterOn_MmhubPgDis 0x2F ///< ISP StutterOn mmHub PgDis +#define PPSMC_MSG_IspStutterOff_MmhubPgEn 0x30 ///< ISP StufferOff mmHub PgEn #define PPSMC_Message_Count 0x31 ///< Total number of PPSMC messages /** @}*/ diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h 2023-01-18 18:27:39.000000000 +0000 @@ -147,14 +147,6 @@ uint32_t max_fast_ppt_limit; }; -enum smu_v11_0_baco_seq { - BACO_SEQ_BACO = 0, - BACO_SEQ_MSR, - BACO_SEQ_BAMACO, - BACO_SEQ_ULPS, - BACO_SEQ_COUNT, -}; - #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) int smu_v11_0_init_microcode(struct smu_context *smu); @@ -257,7 +249,7 @@ int smu_v11_0_baco_exit(struct smu_context *smu); int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu, - enum smu_v11_0_baco_seq baco_seq); + enum smu_baco_seq baco_seq); int smu_v11_0_mode1_reset(struct smu_context *smu); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h 2023-01-18 18:27:39.000000000 +0000 @@ -30,8 +30,9 @@ #define SMU13_DRIVER_IF_VERSION_ALDE 0x08 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04 -#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x30 -#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C +#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32 +#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x35 +#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D #define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms @@ -123,14 +124,6 @@ enum smu_13_0_power_state power_state; }; -enum smu_v13_0_baco_seq { - BACO_SEQ_BACO = 0, - BACO_SEQ_MSR, - BACO_SEQ_BAMACO, - BACO_SEQ_ULPS, - BACO_SEQ_COUNT, -}; - #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) int smu_v13_0_init_microcode(struct smu_context *smu); @@ -217,6 +210,9 @@ int smu_v13_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu, struct pp_smu_nv_clock_table *max_clocks); +int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu, + enum smu_baco_seq baco_seq); + bool smu_v13_0_baco_is_support(struct smu_context *smu); enum smu_baco_state smu_v13_0_baco_get_state(struct smu_context *smu); diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c 2023-01-18 18:27:39.000000000 +0000 @@ -376,7 +376,13 @@ if (((adev->pdev->device == 0x73A1) && (adev->pdev->revision == 0x00)) || ((adev->pdev->device == 0x73BF) && - (adev->pdev->revision == 0xCF))) + (adev->pdev->revision == 0xCF)) || + ((adev->pdev->device == 0x7422) && + (adev->pdev->revision == 0x00)) || + ((adev->pdev->device == 0x73A3) && + (adev->pdev->revision == 0x00)) || + ((adev->pdev->device == 0x73E3) && + (adev->pdev->revision == 0x00))) smu_baco->platform_support = false; } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c 2023-01-18 18:27:39.000000000 +0000 @@ -1576,7 +1576,7 @@ } int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu, - enum smu_v11_0_baco_seq baco_seq) + enum smu_baco_seq baco_seq) { return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq, NULL); } diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c 2023-01-18 18:27:39.000000000 +0000 @@ -120,6 +120,7 @@ MSG_MAP(Mode1Reset, PPSMC_MSG_Mode1Reset, 0), MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0), MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0), + MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0), }; static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = { @@ -1566,6 +1567,31 @@ NULL); } +static int smu_v13_0_0_baco_enter(struct smu_context *smu) +{ + struct smu_baco_context *smu_baco = &smu->smu_baco; + struct amdgpu_device *adev = smu->adev; + + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) + return smu_v13_0_baco_set_armd3_sequence(smu, + smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); + else + return smu_v13_0_baco_enter(smu); +} + +static int smu_v13_0_0_baco_exit(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) { + /* Wait for PMFW handling for the Dstate change */ + usleep_range(10000, 11000); + return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS); + } else { + return smu_v13_0_baco_exit(smu); + } +} + static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -1827,8 +1853,8 @@ .baco_is_support = smu_v13_0_baco_is_support, .baco_get_state = smu_v13_0_baco_get_state, .baco_set_state = smu_v13_0_baco_set_state, - .baco_enter = smu_v13_0_baco_enter, - .baco_exit = smu_v13_0_baco_exit, + .baco_enter = smu_v13_0_0_baco_enter, + .baco_exit = smu_v13_0_0_baco_exit, .mode1_reset_is_support = smu_v13_0_0_is_mode1_reset_supported, .mode1_reset = smu_v13_0_mode1_reset, .set_mp1_state = smu_v13_0_0_set_mp1_state, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c 2023-01-18 18:27:39.000000000 +0000 @@ -122,6 +122,7 @@ MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0), MSG_MAP(SetMGpuFanBoostLimitRpm, PPSMC_MSG_SetMGpuFanBoostLimitRpm, 0), MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0), + MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0), }; static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = { @@ -1578,6 +1579,31 @@ return ret; } +static int smu_v13_0_7_baco_enter(struct smu_context *smu) +{ + struct smu_baco_context *smu_baco = &smu->smu_baco; + struct amdgpu_device *adev = smu->adev; + + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) + return smu_v13_0_baco_set_armd3_sequence(smu, + smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); + else + return smu_v13_0_baco_enter(smu); +} + +static int smu_v13_0_7_baco_exit(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) { + /* Wait for PMFW handling for the Dstate change */ + usleep_range(10000, 11000); + return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS); + } else { + return smu_v13_0_baco_exit(smu); + } +} + static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -1655,8 +1681,8 @@ .baco_is_support = smu_v13_0_baco_is_support, .baco_get_state = smu_v13_0_baco_get_state, .baco_set_state = smu_v13_0_baco_set_state, - .baco_enter = smu_v13_0_baco_enter, - .baco_exit = smu_v13_0_baco_exit, + .baco_enter = smu_v13_0_7_baco_enter, + .baco_exit = smu_v13_0_7_baco_exit, .mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported, .mode1_reset = smu_v13_0_mode1_reset, .set_mp1_state = smu_v13_0_7_set_mp1_state, diff -Nru linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c --- linux-6.0.6/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c 2023-01-18 18:27:39.000000000 +0000 @@ -210,7 +210,8 @@ return 0; if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 7)) || - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0))) + (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)) || + (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10))) return 0; /* override pptable_id from driver parameter */ @@ -287,7 +288,8 @@ smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE; break; case IP_VERSION(13, 0, 0): - smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0; + case IP_VERSION(13, 0, 10): + smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10; break; case IP_VERSION(13, 0, 7): smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_7; @@ -2218,6 +2220,15 @@ return ret; } +int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu, + enum smu_baco_seq baco_seq) +{ + return smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_ArmD3, + baco_seq, + NULL); +} + bool smu_v13_0_baco_is_support(struct smu_context *smu) { struct smu_baco_context *smu_baco = &smu->smu_baco; diff -Nru linux-6.0.6/drivers/gpu/drm/bridge/parade-ps8640.c linux-6.0.12/drivers/gpu/drm/bridge/parade-ps8640.c --- linux-6.0.6/drivers/gpu/drm/bridge/parade-ps8640.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/bridge/parade-ps8640.c 2023-01-18 18:27:39.000000000 +0000 @@ -105,6 +105,7 @@ struct gpio_desc *gpio_powerdown; struct device_link *link; bool pre_enabled; + bool need_post_hpd_delay; }; static const struct regmap_config ps8640_regmap_config[] = { @@ -173,14 +174,31 @@ { struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL]; int status; + int ret; /* * Apparently something about the firmware in the chip signals that * HPD goes high by reporting GPIO9 as high (even though HPD isn't * actually connected to GPIO9). */ - return regmap_read_poll_timeout(map, PAGE2_GPIO_H, status, - status & PS_GPIO9, wait_us / 10, wait_us); + ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status, + status & PS_GPIO9, wait_us / 10, wait_us); + + /* + * The first time we see HPD go high after a reset we delay an extra + * 50 ms. The best guess is that the MCU is doing "stuff" during this + * time (maybe talking to the panel) and we don't want to interrupt it. + * + * No locking is done around "need_post_hpd_delay". If we're here we + * know we're holding a PM Runtime reference and the only other place + * that touches this is PM Runtime resume. + */ + if (!ret && ps_bridge->need_post_hpd_delay) { + ps_bridge->need_post_hpd_delay = false; + msleep(50); + } + + return ret; } static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us) @@ -376,6 +394,9 @@ usleep_range(2000, 2500); gpiod_set_value(ps_bridge->gpio_reset, 0); + /* We just reset things, so we need a delay after the first HPD */ + ps_bridge->need_post_hpd_delay = true; + /* * Mystery 200 ms delay for the "MCU to be ready". It's unclear if * this is truly necessary since the MCU will already signal that diff -Nru linux-6.0.6/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c linux-6.0.12/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c --- linux-6.0.6/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c 2023-01-18 18:27:39.000000000 +0000 @@ -63,23 +63,45 @@ ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter, u8 offset, void *buffer, size_t size) { + u8 zero = 0; + char *tmpbuf = NULL; + /* + * As sub-addressing is not supported by all adaptors, + * always explicitly read from the start and discard + * any bytes that come before the requested offset. + * This way, no matter whether the adaptor supports it + * or not, we'll end up reading the proper data. + */ struct i2c_msg msgs[] = { { .addr = DP_DUAL_MODE_SLAVE_ADDRESS, .flags = 0, .len = 1, - .buf = &offset, + .buf = &zero, }, { .addr = DP_DUAL_MODE_SLAVE_ADDRESS, .flags = I2C_M_RD, - .len = size, + .len = size + offset, .buf = buffer, }, }; int ret; + if (offset) { + tmpbuf = kmalloc(size + offset, GFP_KERNEL); + if (!tmpbuf) + return -ENOMEM; + + msgs[1].buf = tmpbuf; + } + ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); + if (tmpbuf) + memcpy(buffer, tmpbuf + offset, size); + + kfree(tmpbuf); + if (ret < 0) return ret; if (ret != ARRAY_SIZE(msgs)) @@ -208,18 +230,6 @@ if (ret) return DRM_DP_DUAL_MODE_UNKNOWN; - /* - * Sigh. Some (maybe all?) type 1 adaptors are broken and ack - * the offset but ignore it, and instead they just always return - * data from the start of the HDMI ID buffer. So for a broken - * type 1 HDMI adaptor a single byte read will always give us - * 0x44, and for a type 1 DVI adaptor it should give 0x00 - * (assuming it implements any registers). Fortunately neither - * of those values will match the type 2 signature of the - * DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with - * the type 2 adaptor detection safely even in the presence - * of broken type 1 adaptors. - */ ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID, &adaptor_id, sizeof(adaptor_id)); drm_dbg_kms(dev, "DP dual mode adaptor ID: %02x (err %zd)\n", adaptor_id, ret); @@ -233,11 +243,10 @@ return DRM_DP_DUAL_MODE_TYPE2_DVI; } /* - * If neither a proper type 1 ID nor a broken type 1 adaptor - * as described above, assume type 1, but let the user know - * that we may have misdetected the type. + * If not a proper type 1 ID, still assume type 1, but let + * the user know that we may have misdetected the type. */ - if (!is_type1_adaptor(adaptor_id) && adaptor_id != hdmi_id[0]) + if (!is_type1_adaptor(adaptor_id)) drm_err(dev, "Unexpected DP dual mode adaptor ID %02x\n", adaptor_id); } @@ -343,10 +352,8 @@ * @enable: enable (as opposed to disable) the TMDS output buffers * * Set the state of the TMDS output buffers in the adaptor. For - * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As - * some type 1 adaptors have problems with registers (see comments - * in drm_dp_dual_mode_detect()) we avoid touching the register, - * making this function a no-op on type 1 adaptors. + * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. + * Type1 adaptors do not support any register writes. * * Returns: * 0 on success, negative error code on failure diff -Nru linux-6.0.6/drivers/gpu/drm/display/drm_dp_mst_topology.c linux-6.0.12/drivers/gpu/drm/display/drm_dp_mst_topology.c --- linux-6.0.6/drivers/gpu/drm/display/drm_dp_mst_topology.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/display/drm_dp_mst_topology.c 2023-01-18 18:27:39.000000000 +0000 @@ -5293,7 +5293,7 @@ mst_state = drm_atomic_get_mst_topology_state(state, mgr); if (IS_ERR(mst_state)) - return -EINVAL; + return PTR_ERR(mst_state); list_for_each_entry(pos, &mst_state->vcpis, next) { diff -Nru linux-6.0.6/drivers/gpu/drm/drm_drv.c linux-6.0.12/drivers/gpu/drm/drm_drv.c --- linux-6.0.6/drivers/gpu/drm/drm_drv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/drm_drv.c 2023-01-18 18:27:39.000000000 +0000 @@ -615,7 +615,7 @@ mutex_init(&dev->clientlist_mutex); mutex_init(&dev->master_mutex); - ret = drmm_add_action(dev, drm_dev_init_release, NULL); + ret = drmm_add_action_or_reset(dev, drm_dev_init_release, NULL); if (ret) return ret; diff -Nru linux-6.0.6/drivers/gpu/drm/drm_internal.h linux-6.0.12/drivers/gpu/drm/drm_internal.h --- linux-6.0.6/drivers/gpu/drm/drm_internal.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/drm_internal.h 2023-01-18 18:27:39.000000000 +0000 @@ -104,7 +104,8 @@ static inline void drm_vblank_destroy_worker(struct drm_vblank_crtc *vblank) { - kthread_destroy_worker(vblank->worker); + if (vblank->worker) + kthread_destroy_worker(vblank->worker); } int drm_vblank_worker_init(struct drm_vblank_crtc *vblank); diff -Nru linux-6.0.6/drivers/gpu/drm/drm_panel_orientation_quirks.c linux-6.0.12/drivers/gpu/drm/drm_panel_orientation_quirks.c --- linux-6.0.6/drivers/gpu/drm/drm_panel_orientation_quirks.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-01-18 18:27:39.000000000 +0000 @@ -134,6 +134,12 @@ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Acer Switch V 10 (SW5-017) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* Anbernic Win600 */ .matches = { DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"), @@ -319,6 +325,12 @@ DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), }, .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* Nanote UMPC-01 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"), + DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, }, { /* OneGX1 Pro */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"), diff -Nru linux-6.0.6/drivers/gpu/drm/i915/display/intel_display_power.c linux-6.0.12/drivers/gpu/drm/i915/display/intel_display_power.c --- linux-6.0.6/drivers/gpu/drm/i915/display/intel_display_power.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/display/intel_display_power.c 2023-01-18 18:27:39.000000000 +0000 @@ -2427,7 +2427,7 @@ { const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port); - if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_io == POWER_DOMAIN_INVALID) + if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_io == POWER_DOMAIN_INVALID)) return POWER_DOMAIN_PORT_DDI_IO_A; return domains->ddi_io + (int)(port - domains->port_start); @@ -2438,7 +2438,7 @@ { const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port); - if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_lanes == POWER_DOMAIN_INVALID) + if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_lanes == POWER_DOMAIN_INVALID)) return POWER_DOMAIN_PORT_DDI_LANES_A; return domains->ddi_lanes + (int)(port - domains->port_start); @@ -2464,7 +2464,7 @@ { const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch); - if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID) + if (drm_WARN_ON(&i915->drm, !domains || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID)) return POWER_DOMAIN_AUX_A; return domains->aux_legacy_usbc + (int)(aux_ch - domains->aux_ch_start); @@ -2475,7 +2475,7 @@ { const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch); - if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_tbt == POWER_DOMAIN_INVALID) + if (drm_WARN_ON(&i915->drm, !domains || domains->aux_tbt == POWER_DOMAIN_INVALID)) return POWER_DOMAIN_AUX_TBT1; return domains->aux_tbt + (int)(aux_ch - domains->aux_ch_start); diff -Nru linux-6.0.6/drivers/gpu/drm/i915/display/intel_dp.c linux-6.0.12/drivers/gpu/drm/i915/display/intel_dp.c --- linux-6.0.6/drivers/gpu/drm/i915/display/intel_dp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/display/intel_dp.c 2023-01-18 18:27:39.000000000 +0000 @@ -3923,6 +3923,8 @@ drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base); + intel_dp->frl.is_trained = false; + /* Restart FRL training or fall back to TMDS mode */ intel_dp_check_frl_training(intel_dp); } @@ -5231,7 +5233,7 @@ encoder->devdata, IS_ERR(edid) ? NULL : edid); intel_panel_add_edid_fixed_modes(intel_connector, - intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE, + intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE || intel_vrr_is_capable(intel_connector)); /* MSO requires information from the EDID */ diff -Nru linux-6.0.6/drivers/gpu/drm/i915/display/intel_lvds.c linux-6.0.12/drivers/gpu/drm/i915/display/intel_lvds.c --- linux-6.0.6/drivers/gpu/drm/i915/display/intel_lvds.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/display/intel_lvds.c 2023-01-18 18:27:39.000000000 +0000 @@ -972,8 +972,7 @@ /* Try EDID first */ intel_panel_add_edid_fixed_modes(intel_connector, - intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE, - false); + intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE); /* Failed to get EDID, what about VBT? */ if (!intel_panel_preferred_fixed_mode(intel_connector)) diff -Nru linux-6.0.6/drivers/gpu/drm/i915/display/intel_panel.c linux-6.0.12/drivers/gpu/drm/i915/display/intel_panel.c --- linux-6.0.6/drivers/gpu/drm/i915/display/intel_panel.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/display/intel_panel.c 2023-01-18 18:27:39.000000000 +0000 @@ -81,15 +81,14 @@ mode->clock != preferred_mode->clock; } -static bool is_alt_vrr_mode(const struct drm_display_mode *mode, - const struct drm_display_mode *preferred_mode) +static bool is_alt_fixed_mode(const struct drm_display_mode *mode, + const struct drm_display_mode *preferred_mode) { return drm_mode_match(mode, preferred_mode, DRM_MODE_MATCH_FLAGS | DRM_MODE_MATCH_3D_FLAGS) && mode->hdisplay == preferred_mode->hdisplay && - mode->vdisplay == preferred_mode->vdisplay && - mode->clock != preferred_mode->clock; + mode->vdisplay == preferred_mode->vdisplay; } const struct drm_display_mode * @@ -172,19 +171,7 @@ return 0; } -static bool is_alt_fixed_mode(const struct drm_display_mode *mode, - const struct drm_display_mode *preferred_mode, - bool has_vrr) -{ - /* is_alt_drrs_mode() is a subset of is_alt_vrr_mode() */ - if (has_vrr) - return is_alt_vrr_mode(mode, preferred_mode); - else - return is_alt_drrs_mode(mode, preferred_mode); -} - -static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector, - bool has_vrr) +static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); const struct drm_display_mode *preferred_mode = @@ -192,7 +179,7 @@ struct drm_display_mode *mode, *next; list_for_each_entry_safe(mode, next, &connector->base.probed_modes, head) { - if (!is_alt_fixed_mode(mode, preferred_mode, has_vrr)) + if (!is_alt_fixed_mode(mode, preferred_mode)) continue; drm_dbg_kms(&dev_priv->drm, @@ -251,11 +238,11 @@ } void intel_panel_add_edid_fixed_modes(struct intel_connector *connector, - bool has_drrs, bool has_vrr) + bool use_alt_fixed_modes) { intel_panel_add_edid_preferred_mode(connector); - if (intel_panel_preferred_fixed_mode(connector) && (has_drrs || has_vrr)) - intel_panel_add_edid_alt_fixed_modes(connector, has_vrr); + if (intel_panel_preferred_fixed_mode(connector) && use_alt_fixed_modes) + intel_panel_add_edid_alt_fixed_modes(connector); intel_panel_destroy_probed_modes(connector); } diff -Nru linux-6.0.6/drivers/gpu/drm/i915/display/intel_panel.h linux-6.0.12/drivers/gpu/drm/i915/display/intel_panel.h --- linux-6.0.6/drivers/gpu/drm/i915/display/intel_panel.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/display/intel_panel.h 2023-01-18 18:27:39.000000000 +0000 @@ -41,7 +41,7 @@ int intel_panel_compute_config(struct intel_connector *connector, struct drm_display_mode *adjusted_mode); void intel_panel_add_edid_fixed_modes(struct intel_connector *connector, - bool has_drrs, bool has_vrr); + bool use_alt_fixed_modes); void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector); void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector); void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector, diff -Nru linux-6.0.6/drivers/gpu/drm/i915/display/intel_psr.c linux-6.0.12/drivers/gpu/drm/i915/display/intel_psr.c --- linux-6.0.6/drivers/gpu/drm/i915/display/intel_psr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/display/intel_psr.c 2023-01-18 18:27:39.000000000 +0000 @@ -2188,8 +2188,11 @@ if (intel_dp->psr.psr2_sel_fetch_enabled) { u32 val; - if (intel_dp->psr.psr2_sel_fetch_cff_enabled) + if (intel_dp->psr.psr2_sel_fetch_cff_enabled) { + /* Send one update otherwise lag is observed in screen */ + intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); return; + } val = man_trk_ctl_enable_bit_get(dev_priv) | man_trk_ctl_partial_frame_bit_get(dev_priv) | diff -Nru linux-6.0.6/drivers/gpu/drm/i915/display/intel_sdvo.c linux-6.0.12/drivers/gpu/drm/i915/display/intel_sdvo.c --- linux-6.0.6/drivers/gpu/drm/i915/display/intel_sdvo.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/display/intel_sdvo.c 2023-01-18 18:27:39.000000000 +0000 @@ -2747,13 +2747,10 @@ if (!intel_sdvo_connector) return false; - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; + if (device == 0) intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; + else if (device == 1) intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; - } intel_connector = &intel_sdvo_connector->base; connector = &intel_connector->base; @@ -2808,7 +2805,6 @@ encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; - intel_sdvo->controlled_output |= type; intel_sdvo_connector->output_flag = type; if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { @@ -2849,13 +2845,10 @@ encoder->encoder_type = DRM_MODE_ENCODER_DAC; connector->connector_type = DRM_MODE_CONNECTOR_VGA; - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; + if (device == 0) intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; + else if (device == 1) intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; - } if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { kfree(intel_sdvo_connector); @@ -2885,13 +2878,10 @@ encoder->encoder_type = DRM_MODE_ENCODER_LVDS; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; + if (device == 0) intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; + else if (device == 1) intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; - } if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { kfree(intel_sdvo_connector); @@ -2910,8 +2900,12 @@ intel_panel_add_vbt_sdvo_fixed_mode(intel_connector); if (!intel_panel_preferred_fixed_mode(intel_connector)) { + mutex_lock(&i915->drm.mode_config.mutex); + intel_ddc_get_modes(connector, &intel_sdvo->ddc); - intel_panel_add_edid_fixed_modes(intel_connector, false, false); + intel_panel_add_edid_fixed_modes(intel_connector, false); + + mutex_unlock(&i915->drm.mode_config.mutex); } intel_panel_init(intel_connector); @@ -2926,16 +2920,39 @@ return false; } +static u16 intel_sdvo_filter_output_flags(u16 flags) +{ + flags &= SDVO_OUTPUT_MASK; + + /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ + if (!(flags & SDVO_OUTPUT_TMDS0)) + flags &= ~SDVO_OUTPUT_TMDS1; + + if (!(flags & SDVO_OUTPUT_RGB0)) + flags &= ~SDVO_OUTPUT_RGB1; + + if (!(flags & SDVO_OUTPUT_LVDS0)) + flags &= ~SDVO_OUTPUT_LVDS1; + + return flags; +} + static bool intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags) { - /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ + struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + + flags = intel_sdvo_filter_output_flags(flags); + + intel_sdvo->controlled_output = flags; + + intel_sdvo_select_ddc_bus(i915, intel_sdvo); if (flags & SDVO_OUTPUT_TMDS0) if (!intel_sdvo_dvi_init(intel_sdvo, 0)) return false; - if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) + if (flags & SDVO_OUTPUT_TMDS1) if (!intel_sdvo_dvi_init(intel_sdvo, 1)) return false; @@ -2956,7 +2973,7 @@ if (!intel_sdvo_analog_init(intel_sdvo, 0)) return false; - if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) + if (flags & SDVO_OUTPUT_RGB1) if (!intel_sdvo_analog_init(intel_sdvo, 1)) return false; @@ -2964,14 +2981,13 @@ if (!intel_sdvo_lvds_init(intel_sdvo, 0)) return false; - if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) + if (flags & SDVO_OUTPUT_LVDS1) if (!intel_sdvo_lvds_init(intel_sdvo, 1)) return false; - if ((flags & SDVO_OUTPUT_MASK) == 0) { + if (flags == 0) { unsigned char bytes[2]; - intel_sdvo->controlled_output = 0; memcpy(bytes, &intel_sdvo->caps.output_flags, 2); DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", SDVO_NAME(intel_sdvo), @@ -3383,8 +3399,6 @@ */ intel_sdvo->base.cloneable = 0; - intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo); - /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(intel_sdvo)) goto err_output; diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c --- linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 2023-01-18 18:27:39.000000000 +0000 @@ -40,13 +40,13 @@ goto err; } - ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL); + ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL); if (ret) goto err_free; src = obj->mm.pages->sgl; dst = st->sgl; - for (i = 0; i < obj->mm.pages->nents; i++) { + for (i = 0; i < obj->mm.pages->orig_nents; i++) { sg_set_page(dst, sg_page(src), src->length, 0); dst = sg_next(dst); src = sg_next(src); diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_internal.c linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_internal.c --- linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_internal.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_internal.c 2023-01-18 18:27:39.000000000 +0000 @@ -6,7 +6,6 @@ #include #include -#include #include "i915_drv.h" #include "i915_gem.h" @@ -38,22 +37,12 @@ struct scatterlist *sg; unsigned int sg_page_sizes; unsigned int npages; - int max_order; + int max_order = MAX_ORDER; + unsigned int max_segment; gfp_t gfp; - max_order = MAX_ORDER; -#ifdef CONFIG_SWIOTLB - if (is_swiotlb_active(obj->base.dev->dev)) { - unsigned int max_segment; - - max_segment = swiotlb_max_segment(); - if (max_segment) { - max_segment = max_t(unsigned int, max_segment, - PAGE_SIZE) >> PAGE_SHIFT; - max_order = min(max_order, ilog2(max_segment)); - } - } -#endif + max_segment = i915_sg_segment_size(i915->drm.dev) >> PAGE_SHIFT; + max_order = min(max_order, get_order(max_segment)); gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE; if (IS_I965GM(i915) || IS_I965G(i915)) { diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_shmem.c linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_shmem.c --- linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 2023-01-18 18:27:39.000000000 +0000 @@ -194,7 +194,7 @@ struct intel_memory_region *mem = obj->mm.region; struct address_space *mapping = obj->base.filp->f_mapping; const unsigned long page_count = obj->base.size / PAGE_SIZE; - unsigned int max_segment = i915_sg_segment_size(); + unsigned int max_segment = i915_sg_segment_size(i915->drm.dev); struct sg_table *st; struct sgt_iter sgt_iter; struct page *page; @@ -369,14 +369,14 @@ __start_cpu_write(obj); /* - * On non-LLC platforms, force the flush-on-acquire if this is ever + * On non-LLC igfx platforms, force the flush-on-acquire if this is ever * swapped-in. Our async flush path is not trust worthy enough yet(and * happens in the wrong order), and with some tricks it's conceivable * for userspace to change the cache-level to I915_CACHE_NONE after the * pages are swapped-in, and since execbuf binds the object before doing * the async flush, we have a race window. */ - if (!HAS_LLC(i915)) + if (!HAS_LLC(i915) && !IS_DGFX(i915)) obj->cache_dirty = true; } diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_ttm.c linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_ttm.c --- linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 2023-01-18 18:27:39.000000000 +0000 @@ -189,7 +189,7 @@ struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev); struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM]; struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm); - const unsigned int max_segment = i915_sg_segment_size(); + const unsigned int max_segment = i915_sg_segment_size(i915->drm.dev); const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT; struct file *filp = i915_tt->filp; struct sgt_iter sgt_iter; @@ -568,7 +568,7 @@ ret = sg_alloc_table_from_pages_segment(st, ttm->pages, ttm->num_pages, 0, (unsigned long)ttm->num_pages << PAGE_SHIFT, - i915_sg_segment_size(), GFP_KERNEL); + i915_sg_segment_size(i915_tt->dev), GFP_KERNEL); if (ret) { st->sgl = NULL; return ERR_PTR(ret); @@ -642,6 +642,10 @@ WARN_ON_ONCE(obj->mm.madv == I915_MADV_WILLNEED); + err = ttm_bo_wait(bo, true, false); + if (err) + return err; + err = i915_ttm_move_notify(bo); if (err) return err; diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_userptr.c linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_userptr.c --- linux-6.0.6/drivers/gpu/drm/i915/gem/i915_gem_userptr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gem/i915_gem_userptr.c 2023-01-18 18:27:39.000000000 +0000 @@ -129,7 +129,7 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) { const unsigned long num_pages = obj->base.size >> PAGE_SHIFT; - unsigned int max_segment = i915_sg_segment_size(); + unsigned int max_segment = i915_sg_segment_size(obj->base.dev->dev); struct sg_table *st; unsigned int sg_page_sizes; struct page **pvec; diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gt/intel_gt.c linux-6.0.12/drivers/gpu/drm/i915/gt/intel_gt.c --- linux-6.0.6/drivers/gpu/drm/i915/gt/intel_gt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gt/intel_gt.c 2023-01-18 18:27:39.000000000 +0000 @@ -616,8 +616,13 @@ return -EINTR; } - return timeout ? timeout : intel_uc_wait_for_idle(>->uc, - remaining_timeout); + if (timeout) + return timeout; + + if (remaining_timeout < 0) + remaining_timeout = 0; + + return intel_uc_wait_for_idle(>->uc, remaining_timeout); } int intel_gt_init(struct intel_gt *gt) @@ -961,6 +966,11 @@ if (!i915_mmio_reg_offset(rb.reg)) continue; + if (GRAPHICS_VER(i915) == 12 && (engine->class == VIDEO_DECODE_CLASS || + engine->class == VIDEO_ENHANCEMENT_CLASS || + engine->class == COMPUTE_CLASS)) + rb.bit = _MASKED_BIT_ENABLE(rb.bit); + intel_uncore_write_fw(uncore, rb.reg, rb.bit); awake |= engine->mask; } diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gt/intel_gt_requests.c linux-6.0.12/drivers/gpu/drm/i915/gt/intel_gt_requests.c --- linux-6.0.6/drivers/gpu/drm/i915/gt/intel_gt_requests.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gt/intel_gt_requests.c 2023-01-18 18:27:39.000000000 +0000 @@ -199,7 +199,7 @@ if (remaining_timeout) *remaining_timeout = timeout; - return active_count ? timeout : 0; + return active_count ? timeout ?: -ETIME : 0; } static void retire_work_handler(struct work_struct *work) diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gt/intel_workarounds.c linux-6.0.12/drivers/gpu/drm/i915/gt/intel_workarounds.c --- linux-6.0.6/drivers/gpu/drm/i915/gt/intel_workarounds.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gt/intel_workarounds.c 2023-01-18 18:27:39.000000000 +0000 @@ -2301,11 +2301,11 @@ } if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) || - IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) { + IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) { /* * Wa_1607030317:tgl * Wa_1607186500:tgl - * Wa_1607297627:tgl,rkl,dg1[a0] + * Wa_1607297627:tgl,rkl,dg1[a0],adlp * * On TGL and RKL there are multiple entries for this WA in the * BSpec; some indicate this is an A0-only WA, others indicate diff -Nru linux-6.0.6/drivers/gpu/drm/i915/gvt/kvmgt.c linux-6.0.12/drivers/gpu/drm/i915/gvt/kvmgt.c --- linux-6.0.6/drivers/gpu/drm/i915/gvt/kvmgt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/gvt/kvmgt.c 2023-01-18 18:27:39.000000000 +0000 @@ -765,8 +765,6 @@ return -ESRCH; } - kvm_get_kvm(vgpu->vfio_device.kvm); - if (__kvmgt_vgpu_exist(vgpu)) return -EEXIST; @@ -777,6 +775,7 @@ vgpu->track_node.track_write = kvmgt_page_track_write; vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot; + kvm_get_kvm(vgpu->vfio_device.kvm); kvm_page_track_register_notifier(vgpu->vfio_device.kvm, &vgpu->track_node); @@ -1595,6 +1594,9 @@ if (WARN_ON_ONCE(vgpu->attached)) return; + + vfio_unregister_group_dev(&vgpu->vfio_device); + vfio_uninit_group_dev(&vgpu->vfio_device); intel_gvt_destroy_vgpu(vgpu); } diff -Nru linux-6.0.6/drivers/gpu/drm/i915/i915_scatterlist.h linux-6.0.12/drivers/gpu/drm/i915/i915_scatterlist.h --- linux-6.0.6/drivers/gpu/drm/i915/i915_scatterlist.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/i915_scatterlist.h 2023-01-18 18:27:39.000000000 +0000 @@ -9,7 +9,8 @@ #include #include -#include +#include +#include #include "i915_gem.h" @@ -127,19 +128,26 @@ return page_sizes; } -static inline unsigned int i915_sg_segment_size(void) +static inline unsigned int i915_sg_segment_size(struct device *dev) { - unsigned int size = swiotlb_max_segment(); + size_t max = min_t(size_t, UINT_MAX, dma_max_mapping_size(dev)); - if (size == 0) - size = UINT_MAX; - - size = rounddown(size, PAGE_SIZE); - /* swiotlb_max_segment_size can return 1 byte when it means one page. */ - if (size < PAGE_SIZE) - size = PAGE_SIZE; - - return size; + /* + * For Xen PV guests pages aren't contiguous in DMA (machine) address + * space. The DMA API takes care of that both in dma_alloc_* (by + * calling into the hypervisor to make the pages contiguous) and in + * dma_map_* (by bounce buffering). But i915 abuses ignores the + * coherency aspects of the DMA API and thus can't cope with bounce + * buffering actually happening, so add a hack here to force small + * allocations and mappings when running in PV mode on Xen. + * + * Note this will still break if bounce buffering is required for other + * reasons, like confidential computing hypervisors or PCIe root ports + * with addressing limitations. + */ + if (xen_pv_domain()) + max = PAGE_SIZE; + return round_down(max, PAGE_SIZE); } bool i915_sg_trim(struct sg_table *orig_st); diff -Nru linux-6.0.6/drivers/gpu/drm/i915/intel_runtime_pm.c linux-6.0.12/drivers/gpu/drm/i915/intel_runtime_pm.c --- linux-6.0.6/drivers/gpu/drm/i915/intel_runtime_pm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/i915/intel_runtime_pm.c 2023-01-18 18:27:39.000000000 +0000 @@ -591,8 +591,15 @@ pm_runtime_use_autosuspend(kdev); } - /* Enable by default */ - pm_runtime_allow(kdev); + /* + * FIXME: Temp hammer to keep autosupend disable on lmem supported platforms. + * As per PCIe specs 5.3.1.4.1, all iomem read write request over a PCIe + * function will be unsupported in case PCIe endpoint function is in D3. + * Let's keep i915 autosuspend control 'on' till we fix all known issue + * with lmem access in D3. + */ + if (!IS_DGFX(i915)) + pm_runtime_allow(kdev); /* * The core calls the driver load handler with an RPM reference held. diff -Nru linux-6.0.6/drivers/gpu/drm/imx/imx-tve.c linux-6.0.12/drivers/gpu/drm/imx/imx-tve.c --- linux-6.0.6/drivers/gpu/drm/imx/imx-tve.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/imx/imx-tve.c 2023-01-18 18:27:39.000000000 +0000 @@ -218,8 +218,9 @@ return ret; } -static int imx_tve_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +imx_tve_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { struct imx_tve *tve = con_to_tve(connector); unsigned long rate; diff -Nru linux-6.0.6/drivers/gpu/drm/lima/lima_devfreq.c linux-6.0.12/drivers/gpu/drm/lima/lima_devfreq.c --- linux-6.0.6/drivers/gpu/drm/lima/lima_devfreq.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/lima/lima_devfreq.c 2023-01-18 18:27:39.000000000 +0000 @@ -112,11 +112,6 @@ unsigned long cur_freq; int ret; const char *regulator_names[] = { "mali", NULL }; - const char *clk_names[] = { "core", NULL }; - struct dev_pm_opp_config config = { - .regulator_names = regulator_names, - .clk_names = clk_names, - }; if (!device_property_present(dev, "operating-points-v2")) /* Optional, continue without devfreq */ @@ -124,7 +119,15 @@ spin_lock_init(&ldevfreq->lock); - ret = devm_pm_opp_set_config(dev, &config); + /* + * clkname is set separately so it is not affected by the optional + * regulator setting which may return error. + */ + ret = devm_pm_opp_set_clkname(dev, "core"); + if (ret) + return ret; + + ret = devm_pm_opp_set_regulators(dev, regulator_names); if (ret) { /* Continue if the optional regulator is missing */ if (ret != -ENODEV) diff -Nru linux-6.0.6/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c linux-6.0.12/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c --- linux-6.0.6/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c 2023-01-18 18:27:39.000000000 +0000 @@ -91,7 +91,7 @@ static void *state_kcalloc(struct a6xx_gpu_state *a6xx_state, int nr, size_t objsize) { struct a6xx_state_memobj *obj = - kzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL); + kvzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL); if (!obj) return NULL; @@ -1040,8 +1040,11 @@ if (a6xx_state->gmu_hfi) kvfree(a6xx_state->gmu_hfi->data); + if (a6xx_state->gmu_debug) + kvfree(a6xx_state->gmu_debug->data); + list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) - kfree(obj); + kvfree(obj); adreno_gpu_state_destroy(state); kfree(a6xx_state); diff -Nru linux-6.0.6/drivers/gpu/drm/msm/adreno/adreno_device.c linux-6.0.12/drivers/gpu/drm/msm/adreno/adreno_device.c --- linux-6.0.6/drivers/gpu/drm/msm/adreno/adreno_device.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/adreno/adreno_device.c 2023-01-18 18:27:39.000000000 +0000 @@ -679,6 +679,9 @@ struct msm_gpu *gpu = dev_to_gpu(dev); int remaining, ret; + if (!gpu) + return 0; + suspend_scheduler(gpu); remaining = wait_event_timeout(gpu->retire_event, @@ -700,7 +703,12 @@ static int adreno_system_resume(struct device *dev) { - resume_scheduler(dev_to_gpu(dev)); + struct msm_gpu *gpu = dev_to_gpu(dev); + + if (!gpu) + return 0; + + resume_scheduler(gpu); return pm_runtime_force_resume(dev); } diff -Nru linux-6.0.6/drivers/gpu/drm/msm/adreno/adreno_gpu.c linux-6.0.12/drivers/gpu/drm/msm/adreno/adreno_gpu.c --- linux-6.0.6/drivers/gpu/drm/msm/adreno/adreno_gpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/adreno/adreno_gpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -729,7 +729,12 @@ return buf; } -/* len is expected to be in bytes */ +/* len is expected to be in bytes + * + * WARNING: *ptr should be allocated with kvmalloc or friends. It can be free'd + * with kvfree() and replaced with a newly kvmalloc'd buffer on the first call + * when the unencoded raw data is encoded + */ void adreno_show_object(struct drm_printer *p, void **ptr, int len, bool *encoded) { diff -Nru linux-6.0.6/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c linux-6.0.12/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c --- linux-6.0.6/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c 2023-01-18 18:27:39.000000000 +0000 @@ -56,8 +56,9 @@ return ret; } -static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +mdp4_lvds_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { struct mdp4_lvds_connector *mdp4_lvds_connector = to_mdp4_lvds_connector(connector); diff -Nru linux-6.0.6/drivers/gpu/drm/msm/dp/dp_ctrl.c linux-6.0.12/drivers/gpu/drm/msm/dp/dp_ctrl.c --- linux-6.0.6/drivers/gpu/drm/msm/dp/dp_ctrl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/dp/dp_ctrl.c 2023-01-18 18:27:39.000000000 +0000 @@ -1245,8 +1245,7 @@ { int ret = 0; const u8 *dpcd = ctrl->panel->dpcd; - u8 encoding = DP_SET_ANSI_8B10B; - u8 ssc; + u8 encoding[] = { 0, DP_SET_ANSI_8B10B }; u8 assr; struct dp_link_info link_info = {0}; @@ -1258,13 +1257,11 @@ dp_aux_link_configure(ctrl->aux, &link_info); - if (drm_dp_max_downspread(dpcd)) { - ssc = DP_SPREAD_AMP_0_5; - drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, &ssc, 1); - } + if (drm_dp_max_downspread(dpcd)) + encoding[0] |= DP_SPREAD_AMP_0_5; - drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, - &encoding, 1); + /* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */ + drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2); if (drm_dp_alternate_scrambler_reset_cap(dpcd)) { assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE; diff -Nru linux-6.0.6/drivers/gpu/drm/msm/dp/dp_display.c linux-6.0.12/drivers/gpu/drm/msm/dp/dp_display.c --- linux-6.0.6/drivers/gpu/drm/msm/dp/dp_display.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/dp/dp_display.c 2023-01-18 18:27:39.000000000 +0000 @@ -1249,7 +1249,7 @@ return -EINVAL; } - rc = devm_request_irq(&dp->pdev->dev, dp->irq, + rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq, dp_display_irq_handler, IRQF_TRIGGER_HIGH, "dp_display_isr", dp); if (rc < 0) { @@ -1528,6 +1528,11 @@ } } +static void of_dp_aux_depopulate_bus_void(void *data) +{ + of_dp_aux_depopulate_bus(data); +} + static int dp_display_get_next_bridge(struct msm_dp *dp) { int rc; @@ -1552,10 +1557,16 @@ * panel driver is probed asynchronously but is the best we * can do without a bigger driver reorganization. */ - rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux); + rc = of_dp_aux_populate_bus(dp_priv->aux, NULL); of_node_put(aux_bus); if (rc) goto error; + + rc = devm_add_action_or_reset(dp->drm_dev->dev, + of_dp_aux_depopulate_bus_void, + dp_priv->aux); + if (rc) + goto error; } else if (dp->is_edp) { DRM_ERROR("eDP aux_bus not found\n"); return -ENODEV; @@ -1568,7 +1579,7 @@ * For DisplayPort interfaces external bridges are optional, so * silently ignore an error if one is not present (-ENODEV). */ - rc = dp_parser_find_next_bridge(dp_priv->parser); + rc = devm_dp_parser_find_next_bridge(dp->drm_dev->dev, dp_priv->parser); if (!dp->is_edp && rc == -ENODEV) return 0; @@ -1597,6 +1608,12 @@ return -EINVAL; priv = dev->dev_private; + + if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) { + DRM_DEV_ERROR(dev->dev, "too many bridges\n"); + return -ENOSPC; + } + dp_display->drm_dev = dev; dp_priv = container_of(dp_display, struct dp_display_private, dp_display); diff -Nru linux-6.0.6/drivers/gpu/drm/msm/dp/dp_drm.c linux-6.0.12/drivers/gpu/drm/msm/dp/dp_drm.c --- linux-6.0.6/drivers/gpu/drm/msm/dp/dp_drm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/dp/dp_drm.c 2023-01-18 18:27:39.000000000 +0000 @@ -31,6 +31,36 @@ connector_status_disconnected; } +static int dp_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct msm_dp *dp; + + dp = to_dp_bridge(bridge)->dp_display; + + drm_dbg_dp(dp->drm_dev, "is_connected = %s\n", + (dp->is_connected) ? "true" : "false"); + + /* + * There is no protection in the DRM framework to check if the display + * pipeline has been already disabled before trying to disable it again. + * Hence if the sink is unplugged, the pipeline gets disabled, but the + * crtc->active is still true. Any attempt to set the mode or manually + * disable this encoder will result in the crash. + * + * TODO: add support for telling the DRM subsystem that the pipeline is + * disabled by the hardware and thus all access to it should be forbidden. + * After that this piece of code can be removed. + */ + if (bridge->ops & DRM_BRIDGE_OP_HPD) + return (dp->is_connected) ? 0 : -ENOTCONN; + + return 0; +} + + /** * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add() * @bridge: Poiner to drm bridge @@ -61,6 +91,9 @@ } static const struct drm_bridge_funcs dp_bridge_ops = { + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, .enable = dp_bridge_enable, .disable = dp_bridge_disable, .post_disable = dp_bridge_post_disable, @@ -68,6 +101,7 @@ .mode_valid = dp_bridge_mode_valid, .get_modes = dp_bridge_get_modes, .detect = dp_bridge_detect, + .atomic_check = dp_bridge_atomic_check, }; struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, diff -Nru linux-6.0.6/drivers/gpu/drm/msm/dp/dp_parser.c linux-6.0.12/drivers/gpu/drm/msm/dp/dp_parser.c --- linux-6.0.6/drivers/gpu/drm/msm/dp/dp_parser.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/dp/dp_parser.c 2023-01-18 18:27:39.000000000 +0000 @@ -240,12 +240,12 @@ return 0; } -int dp_parser_find_next_bridge(struct dp_parser *parser) +int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser) { - struct device *dev = &parser->pdev->dev; + struct platform_device *pdev = parser->pdev; struct drm_bridge *bridge; - bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); + bridge = devm_drm_of_get_bridge(dev, pdev->dev.of_node, 1, 0); if (IS_ERR(bridge)) return PTR_ERR(bridge); diff -Nru linux-6.0.6/drivers/gpu/drm/msm/dp/dp_parser.h linux-6.0.12/drivers/gpu/drm/msm/dp/dp_parser.h --- linux-6.0.6/drivers/gpu/drm/msm/dp/dp_parser.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/dp/dp_parser.h 2023-01-18 18:27:39.000000000 +0000 @@ -138,8 +138,9 @@ struct dp_parser *dp_parser_get(struct platform_device *pdev); /** - * dp_parser_find_next_bridge() - find an additional bridge to DP + * devm_dp_parser_find_next_bridge() - find an additional bridge to DP * + * @dev: device to tie bridge lifetime to * @parser: dp_parser data from client * * This function is used to find any additional bridge attached to @@ -147,6 +148,6 @@ * * Return: 0 if able to get the bridge, otherwise negative errno for failure. */ -int dp_parser_find_next_bridge(struct dp_parser *parser); +int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser); #endif diff -Nru linux-6.0.6/drivers/gpu/drm/msm/dsi/dsi.c linux-6.0.12/drivers/gpu/drm/msm/dsi/dsi.c --- linux-6.0.6/drivers/gpu/drm/msm/dsi/dsi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/dsi/dsi.c 2023-01-18 18:27:39.000000000 +0000 @@ -227,6 +227,12 @@ return -EINVAL; priv = dev->dev_private; + + if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) { + DRM_DEV_ERROR(dev->dev, "too many bridges\n"); + return -ENOSPC; + } + msm_dsi->dev = dev; ret = msm_dsi_host_modeset_init(msm_dsi->host, dev); diff -Nru linux-6.0.6/drivers/gpu/drm/msm/hdmi/hdmi.c linux-6.0.12/drivers/gpu/drm/msm/hdmi/hdmi.c --- linux-6.0.6/drivers/gpu/drm/msm/hdmi/hdmi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/hdmi/hdmi.c 2023-01-18 18:27:39.000000000 +0000 @@ -300,6 +300,11 @@ struct platform_device *pdev = hdmi->pdev; int ret; + if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) { + DRM_DEV_ERROR(dev->dev, "too many bridges\n"); + return -ENOSPC; + } + hdmi->dev = dev; hdmi->encoder = encoder; @@ -339,7 +344,7 @@ goto fail; } - ret = devm_request_irq(&pdev->dev, hdmi->irq, + ret = devm_request_irq(dev->dev, hdmi->irq, msm_hdmi_irq, IRQF_TRIGGER_HIGH, "hdmi_isr", hdmi); if (ret < 0) { diff -Nru linux-6.0.6/drivers/gpu/drm/msm/msm_drv.c linux-6.0.12/drivers/gpu/drm/msm/msm_drv.c --- linux-6.0.6/drivers/gpu/drm/msm/msm_drv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/msm_drv.c 2023-01-18 18:27:39.000000000 +0000 @@ -241,6 +241,7 @@ for (i = 0; i < priv->num_bridges; i++) drm_bridge_remove(priv->bridges[i]); + priv->num_bridges = 0; pm_runtime_get_sync(dev); msm_irq_uninstall(ddev); diff -Nru linux-6.0.6/drivers/gpu/drm/msm/msm_gpu.c linux-6.0.12/drivers/gpu/drm/msm/msm_gpu.c --- linux-6.0.6/drivers/gpu/drm/msm/msm_gpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/msm_gpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -993,4 +993,6 @@ } msm_devfreq_cleanup(gpu); + + platform_set_drvdata(gpu->pdev, NULL); } diff -Nru linux-6.0.6/drivers/gpu/drm/msm/msm_gpu.h linux-6.0.12/drivers/gpu/drm/msm/msm_gpu.h --- linux-6.0.6/drivers/gpu/drm/msm/msm_gpu.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/msm/msm_gpu.h 2023-01-18 18:27:39.000000000 +0000 @@ -282,6 +282,10 @@ static inline struct msm_gpu *dev_to_gpu(struct device *dev) { struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev); + + if (!adreno_smmu) + return NULL; + return container_of(adreno_smmu, struct msm_gpu, adreno_smmu); } diff -Nru linux-6.0.6/drivers/gpu/drm/panel/panel-simple.c linux-6.0.12/drivers/gpu/drm/panel/panel-simple.c --- linux-6.0.6/drivers/gpu/drm/panel/panel-simple.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/panel/panel-simple.c 2023-01-18 18:27:39.000000000 +0000 @@ -2505,6 +2505,7 @@ static const struct panel_desc logictechno_lt161010_2nh = { .timings = &logictechno_lt161010_2nh_timing, .num_timings = 1, + .bpc = 6, .size = { .width = 154, .height = 86, @@ -2534,6 +2535,7 @@ static const struct panel_desc logictechno_lt170410_2whc = { .timings = &logictechno_lt170410_2whc_timing, .num_timings = 1, + .bpc = 8, .size = { .width = 217, .height = 136, diff -Nru linux-6.0.6/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c linux-6.0.12/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c --- linux-6.0.6/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 2023-01-18 18:27:39.000000000 +0000 @@ -565,7 +565,8 @@ ret = rockchip_hdmi_parse_dt(hdmi); if (ret) { - DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n"); + if (ret != -EPROBE_DEFER) + DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n"); return ret; } diff -Nru linux-6.0.6/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c linux-6.0.12/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c --- linux-6.0.6/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 2023-01-18 18:27:39.000000000 +0000 @@ -1031,23 +1031,31 @@ if (ret) { DRM_DEV_ERROR(dsi->dev, "Failed to register component: %d\n", ret); - return ret; + goto out; } second = dw_mipi_dsi_rockchip_find_second(dsi); - if (IS_ERR(second)) - return PTR_ERR(second); + if (IS_ERR(second)) { + ret = PTR_ERR(second); + goto out; + } if (second) { ret = component_add(second, &dw_mipi_dsi_rockchip_ops); if (ret) { DRM_DEV_ERROR(second, "Failed to register component: %d\n", ret); - return ret; + goto out; } } return 0; + +out: + mutex_lock(&dsi->usage_mutex); + dsi->usage_mode = DW_DSI_USAGE_IDLE; + mutex_unlock(&dsi->usage_mutex); + return ret; } static int dw_mipi_dsi_rockchip_host_detach(void *priv_data, @@ -1634,5 +1642,11 @@ .of_match_table = dw_mipi_dsi_rockchip_dt_ids, .pm = &dw_mipi_dsi_rockchip_pm_ops, .name = "dw-mipi-dsi-rockchip", + /* + * For dual-DSI display, one DSI pokes at the other DSI's + * drvdata in dw_mipi_dsi_rockchip_find_second(). This is not + * safe for asynchronous probe. + */ + .probe_type = PROBE_FORCE_SYNCHRONOUS, }, }; diff -Nru linux-6.0.6/drivers/gpu/drm/rockchip/rockchip_drm_gem.c linux-6.0.12/drivers/gpu/drm/rockchip/rockchip_drm_gem.c --- linux-6.0.6/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 2023-01-18 18:27:39.000000000 +0000 @@ -364,9 +364,12 @@ { struct rockchip_gem_object *rk_obj; struct drm_gem_object *obj; + bool is_framebuffer; int ret; - rk_obj = rockchip_gem_create_object(drm, size, false); + is_framebuffer = drm->fb_helper && file_priv == drm->fb_helper->client.file; + + rk_obj = rockchip_gem_create_object(drm, size, is_framebuffer); if (IS_ERR(rk_obj)) return ERR_CAST(rk_obj); diff -Nru linux-6.0.6/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c linux-6.0.12/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c --- linux-6.0.6/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 2023-01-18 18:27:39.000000000 +0000 @@ -878,10 +878,14 @@ { struct vop2_video_port *vp = to_vop2_video_port(crtc); struct vop2 *vop2 = vp->vop2; + struct drm_crtc_state *old_crtc_state; int ret; vop2_lock(vop2); + old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); + drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); + drm_crtc_vblank_off(crtc); /* @@ -997,13 +1001,15 @@ static void vop2_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) { - struct drm_plane_state *old_pstate = drm_atomic_get_old_plane_state(state, plane); + struct drm_plane_state *old_pstate = NULL; struct vop2_win *win = to_vop2_win(plane); struct vop2 *vop2 = win->vop2; drm_dbg(vop2->drm, "%s disable\n", win->data->name); - if (!old_pstate->crtc) + if (state) + old_pstate = drm_atomic_get_old_plane_state(state, plane); + if (old_pstate && !old_pstate->crtc) return; vop2_win_disable(win); diff -Nru linux-6.0.6/drivers/gpu/drm/scheduler/sched_entity.c linux-6.0.12/drivers/gpu/drm/scheduler/sched_entity.c --- linux-6.0.6/drivers/gpu/drm/scheduler/sched_entity.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/scheduler/sched_entity.c 2023-01-18 18:27:39.000000000 +0000 @@ -207,6 +207,7 @@ struct drm_sched_job *job = container_of(cb, struct drm_sched_job, finish_cb); + dma_fence_put(f); INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work); schedule_work(&job->work); } @@ -234,8 +235,10 @@ struct drm_sched_fence *s_fence = job->s_fence; /* Wait for all dependencies to avoid data corruptions */ - while ((f = drm_sched_job_dependency(job, entity))) + while ((f = drm_sched_job_dependency(job, entity))) { dma_fence_wait(f, false); + dma_fence_put(f); + } drm_sched_fence_scheduled(s_fence); dma_fence_set_error(&s_fence->finished, -ESRCH); @@ -250,6 +253,7 @@ continue; } + dma_fence_get(entity->last_scheduled); r = dma_fence_add_callback(entity->last_scheduled, &job->finish_cb, drm_sched_entity_kill_jobs_cb); diff -Nru linux-6.0.6/drivers/gpu/drm/tegra/drm.c linux-6.0.12/drivers/gpu/drm/tegra/drm.c --- linux-6.0.6/drivers/gpu/drm/tegra/drm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/tegra/drm.c 2023-01-18 18:27:39.000000000 +0000 @@ -1093,6 +1093,10 @@ struct host1x *host1x = dev_get_drvdata(dev->dev.parent); struct iommu_domain *domain; + /* Our IOMMU usage policy doesn't currently play well with GART */ + if (of_machine_is_compatible("nvidia,tegra20")) + return false; + /* * If the Tegra DRM clients are backed by an IOMMU, push buffers are * likely to be allocated beyond the 32-bit boundary if sufficient diff -Nru linux-6.0.6/drivers/gpu/drm/vc4/vc4_drv.c linux-6.0.12/drivers/gpu/drm/vc4/vc4_drv.c --- linux-6.0.6/drivers/gpu/drm/vc4/vc4_drv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/vc4/vc4_drv.c 2023-01-18 18:27:39.000000000 +0000 @@ -476,7 +476,12 @@ if (ret) return ret; - return platform_driver_register(&vc4_platform_driver); + ret = platform_driver_register(&vc4_platform_driver); + if (ret) + platform_unregister_drivers(component_drivers, + ARRAY_SIZE(component_drivers)); + + return ret; } static void __exit vc4_drm_unregister(void) diff -Nru linux-6.0.6/drivers/gpu/drm/vc4/vc4_hdmi.c linux-6.0.12/drivers/gpu/drm/vc4/vc4_hdmi.c --- linux-6.0.6/drivers/gpu/drm/vc4/vc4_hdmi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/vc4/vc4_hdmi.c 2023-01-18 18:27:39.000000000 +0000 @@ -2712,9 +2712,16 @@ DRM_ERROR("Failed to get HDMI state machine clock\n"); return PTR_ERR(vc4_hdmi->hsm_clock); } + vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock; vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock; + vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi"); + if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) { + DRM_ERROR("Failed to get HDMI state machine clock\n"); + return PTR_ERR(vc4_hdmi->hsm_rpm_clock); + } + return 0; } @@ -2796,6 +2803,12 @@ return PTR_ERR(vc4_hdmi->hsm_clock); } + vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi"); + if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) { + DRM_ERROR("Failed to get HDMI state machine clock\n"); + return PTR_ERR(vc4_hdmi->hsm_rpm_clock); + } + vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb"); if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) { DRM_ERROR("Failed to get pixel bvb clock\n"); @@ -2859,7 +2872,7 @@ { struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); - clk_disable_unprepare(vc4_hdmi->hsm_clock); + clk_disable_unprepare(vc4_hdmi->hsm_rpm_clock); return 0; } @@ -2869,6 +2882,7 @@ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); unsigned long __maybe_unused flags; u32 __maybe_unused value; + unsigned long rate; int ret; /* @@ -2876,14 +2890,29 @@ * its frequency while the power domain is active so that it * keeps its rate. */ - ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ); + ret = clk_set_min_rate(vc4_hdmi->hsm_rpm_clock, HSM_MIN_CLOCK_FREQ); if (ret) return ret; - ret = clk_prepare_enable(vc4_hdmi->hsm_clock); + ret = clk_prepare_enable(vc4_hdmi->hsm_rpm_clock); if (ret) return ret; + /* + * Whenever the RaspberryPi boots without an HDMI monitor + * plugged in, the firmware won't have initialized the HSM clock + * rate and it will be reported as 0. + * + * If we try to access a register of the controller in such a + * case, it will lead to a silent CPU stall. Let's make sure we + * prevent such a case. + */ + rate = clk_get_rate(vc4_hdmi->hsm_rpm_clock); + if (!rate) { + ret = -EINVAL; + goto err_disable_clk; + } + if (vc4_hdmi->variant->reset) vc4_hdmi->variant->reset(vc4_hdmi); @@ -2905,6 +2934,10 @@ #endif return 0; + +err_disable_clk: + clk_disable_unprepare(vc4_hdmi->hsm_clock); + return ret; } static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) diff -Nru linux-6.0.6/drivers/gpu/drm/vc4/vc4_hdmi.h linux-6.0.12/drivers/gpu/drm/vc4/vc4_hdmi.h --- linux-6.0.6/drivers/gpu/drm/vc4/vc4_hdmi.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/vc4/vc4_hdmi.h 2023-01-18 18:27:39.000000000 +0000 @@ -171,6 +171,7 @@ struct clk *cec_clock; struct clk *pixel_clock; struct clk *hsm_clock; + struct clk *hsm_rpm_clock; struct clk *audio_clock; struct clk *pixel_bvb_clock; diff -Nru linux-6.0.6/drivers/gpu/drm/vc4/vc4_kms.c linux-6.0.12/drivers/gpu/drm/vc4/vc4_kms.c --- linux-6.0.6/drivers/gpu/drm/vc4/vc4_kms.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/drm/vc4/vc4_kms.c 2023-01-18 18:27:39.000000000 +0000 @@ -198,8 +198,8 @@ struct drm_private_state *priv_state; priv_state = drm_atomic_get_new_private_obj_state(state, &vc4->hvs_channels); - if (IS_ERR(priv_state)) - return ERR_CAST(priv_state); + if (!priv_state) + return ERR_PTR(-EINVAL); return to_vc4_hvs_state(priv_state); } @@ -211,8 +211,8 @@ struct drm_private_state *priv_state; priv_state = drm_atomic_get_old_private_obj_state(state, &vc4->hvs_channels); - if (IS_ERR(priv_state)) - return ERR_CAST(priv_state); + if (!priv_state) + return ERR_PTR(-EINVAL); return to_vc4_hvs_state(priv_state); } diff -Nru linux-6.0.6/drivers/gpu/host1x/dev.c linux-6.0.12/drivers/gpu/host1x/dev.c --- linux-6.0.6/drivers/gpu/host1x/dev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/gpu/host1x/dev.c 2023-01-18 18:27:39.000000000 +0000 @@ -292,6 +292,10 @@ static bool host1x_wants_iommu(struct host1x *host1x) { + /* Our IOMMU usage policy doesn't currently play well with GART */ + if (of_machine_is_compatible("nvidia,tegra20")) + return false; + /* * If we support addressing a maximum of 32 bits of physical memory * and if the host1x firewall is enabled, there's no need to enable diff -Nru linux-6.0.6/drivers/hid/hid-hyperv.c linux-6.0.12/drivers/hid/hid-hyperv.c --- linux-6.0.6/drivers/hid/hid-hyperv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hid/hid-hyperv.c 2023-01-18 18:27:39.000000000 +0000 @@ -499,7 +499,7 @@ ret = hid_add_device(hid_dev); if (ret) - goto probe_err1; + goto probe_err2; ret = hid_parse(hid_dev); diff -Nru linux-6.0.6/drivers/hid/hid-ids.h linux-6.0.12/drivers/hid/hid-ids.h --- linux-6.0.6/drivers/hid/hid-ids.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hid/hid-ids.h 2023-01-18 18:27:39.000000000 +0000 @@ -867,6 +867,7 @@ #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 #define USB_DEVICE_ID_MADCATZ_RAT5 0x1705 #define USB_DEVICE_ID_MADCATZ_RAT9 0x1709 +#define USB_DEVICE_ID_MADCATZ_MMO7 0x1713 #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 diff -Nru linux-6.0.6/drivers/hid/hid-quirks.c linux-6.0.12/drivers/hid/hid-quirks.c --- linux-6.0.6/drivers/hid/hid-quirks.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hid/hid-quirks.c 2023-01-18 18:27:39.000000000 +0000 @@ -620,6 +620,7 @@ { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) }, { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) }, { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7) }, #endif #if IS_ENABLED(CONFIG_HID_SAMSUNG) { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, diff -Nru linux-6.0.6/drivers/hid/hid-saitek.c linux-6.0.12/drivers/hid/hid-saitek.c --- linux-6.0.6/drivers/hid/hid-saitek.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hid/hid-saitek.c 2023-01-18 18:27:39.000000000 +0000 @@ -187,6 +187,8 @@ .driver_data = SAITEK_RELEASE_MODE_RAT7 }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7), .driver_data = SAITEK_RELEASE_MODE_MMO7 }, + { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7), + .driver_data = SAITEK_RELEASE_MODE_MMO7 }, { } }; diff -Nru linux-6.0.6/drivers/hid/wacom_wac.c linux-6.0.12/drivers/hid/wacom_wac.c --- linux-6.0.6/drivers/hid/wacom_wac.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hid/wacom_wac.c 2023-01-18 18:27:39.000000000 +0000 @@ -2522,11 +2522,12 @@ if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) { int id = wacom_wac->id[0]; - if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3 && - wacom_wac->hid_data.barrelswitch & wacom_wac->hid_data.barrelswitch2) { - wacom_wac->hid_data.barrelswitch = 0; - wacom_wac->hid_data.barrelswitch2 = 0; - wacom_wac->hid_data.barrelswitch3 = 1; + if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3) { + int sw_state = wacom_wac->hid_data.barrelswitch | + (wacom_wac->hid_data.barrelswitch2 << 1); + wacom_wac->hid_data.barrelswitch = sw_state == 1; + wacom_wac->hid_data.barrelswitch2 = sw_state == 2; + wacom_wac->hid_data.barrelswitch3 = sw_state == 3; } input_report_key(input, BTN_STYLUS, wacom_wac->hid_data.barrelswitch); input_report_key(input, BTN_STYLUS2, wacom_wac->hid_data.barrelswitch2); diff -Nru linux-6.0.6/drivers/hv/channel_mgmt.c linux-6.0.12/drivers/hv/channel_mgmt.c --- linux-6.0.6/drivers/hv/channel_mgmt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hv/channel_mgmt.c 2023-01-18 18:27:39.000000000 +0000 @@ -533,13 +533,17 @@ * Add the new device to the bus. This will kick off device-driver * binding which eventually invokes the device driver's AddDevice() * method. + * + * If vmbus_device_register() fails, the 'device_obj' is freed in + * vmbus_device_release() as called by device_unregister() in the + * error path of vmbus_device_register(). In the outside error + * path, there's no need to free it. */ ret = vmbus_device_register(newchannel->device_obj); if (ret != 0) { pr_err("unable to add child device object (relid %d)\n", newchannel->offermsg.child_relid); - kfree(newchannel->device_obj); goto err_deq_chan; } diff -Nru linux-6.0.6/drivers/hv/vmbus_drv.c linux-6.0.12/drivers/hv/vmbus_drv.c --- linux-6.0.6/drivers/hv/vmbus_drv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hv/vmbus_drv.c 2023-01-18 18:27:39.000000000 +0000 @@ -2083,6 +2083,7 @@ ret = device_register(&child_device_obj->device); if (ret) { pr_err("Unable to register child device\n"); + put_device(&child_device_obj->device); return ret; } diff -Nru linux-6.0.6/drivers/hwmon/asus-ec-sensors.c linux-6.0.12/drivers/hwmon/asus-ec-sensors.c --- linux-6.0.6/drivers/hwmon/asus-ec-sensors.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hwmon/asus-ec-sensors.c 2023-01-18 18:27:39.000000000 +0000 @@ -938,6 +938,8 @@ ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors); ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors, sizeof(struct ec_sensor), GFP_KERNEL); + if (!ec_data->sensors) + return -ENOMEM; status = setup_lock_data(dev); if (status) { diff -Nru linux-6.0.6/drivers/hwmon/coretemp.c linux-6.0.12/drivers/hwmon/coretemp.c --- linux-6.0.6/drivers/hwmon/coretemp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hwmon/coretemp.c 2023-01-18 18:27:39.000000000 +0000 @@ -242,10 +242,13 @@ */ if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL) { for (i = 0; i < ARRAY_SIZE(tjmax_pci_table); i++) { - if (host_bridge->device == tjmax_pci_table[i].device) + if (host_bridge->device == tjmax_pci_table[i].device) { + pci_dev_put(host_bridge); return tjmax_pci_table[i].tjmax; + } } } + pci_dev_put(host_bridge); for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { if (strstr(c->x86_model_id, tjmax_table[i].id)) @@ -533,6 +536,10 @@ { struct temp_data *tdata = pdata->core_data[indx]; + /* if we errored on add then this is already gone */ + if (!tdata) + return; + /* Remove the sysfs attributes */ sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group); diff -Nru linux-6.0.6/drivers/hwmon/i5500_temp.c linux-6.0.12/drivers/hwmon/i5500_temp.c --- linux-6.0.6/drivers/hwmon/i5500_temp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hwmon/i5500_temp.c 2023-01-18 18:27:39.000000000 +0000 @@ -117,7 +117,7 @@ u32 tstimer; s8 tsfsc; - err = pci_enable_device(pdev); + err = pcim_enable_device(pdev); if (err) { dev_err(&pdev->dev, "Failed to enable device\n"); return err; diff -Nru linux-6.0.6/drivers/hwmon/ibmpex.c linux-6.0.12/drivers/hwmon/ibmpex.c --- linux-6.0.6/drivers/hwmon/ibmpex.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hwmon/ibmpex.c 2023-01-18 18:27:39.000000000 +0000 @@ -502,6 +502,7 @@ return; out_register: + list_del(&data->list); hwmon_device_unregister(data->hwmon_dev); out_user: ipmi_destroy_user(data->user); diff -Nru linux-6.0.6/drivers/hwmon/ina3221.c linux-6.0.12/drivers/hwmon/ina3221.c --- linux-6.0.6/drivers/hwmon/ina3221.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hwmon/ina3221.c 2023-01-18 18:27:39.000000000 +0000 @@ -228,7 +228,7 @@ * Shunt Voltage Sum register has 14-bit value with 1-bit shift * Other Shunt Voltage registers have 12 bits with 3-bit shift */ - if (reg == INA3221_SHUNT_SUM) + if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM) *val = sign_extend32(regval >> 1, 14); else *val = sign_extend32(regval >> 3, 12); @@ -465,7 +465,7 @@ * SHUNT_SUM: (1 / 40uV) << 1 = 1 / 20uV * SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV */ - if (reg == INA3221_SHUNT_SUM) + if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM) regval = DIV_ROUND_CLOSEST(voltage_uv, 20) & 0xfffe; else regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8; diff -Nru linux-6.0.6/drivers/hwmon/ltc2947-core.c linux-6.0.12/drivers/hwmon/ltc2947-core.c --- linux-6.0.6/drivers/hwmon/ltc2947-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hwmon/ltc2947-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -396,7 +396,7 @@ return ret; /* in milidegrees celcius, temp is given by: */ - *val = (__val * 204) + 550; + *val = (__val * 204) + 5500; return 0; } diff -Nru linux-6.0.6/drivers/hwspinlock/qcom_hwspinlock.c linux-6.0.12/drivers/hwspinlock/qcom_hwspinlock.c --- linux-6.0.6/drivers/hwspinlock/qcom_hwspinlock.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hwspinlock/qcom_hwspinlock.c 2023-01-18 18:27:39.000000000 +0000 @@ -121,7 +121,7 @@ .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x40000, + .max_register = 0x20000, .fast_io = true, }; diff -Nru linux-6.0.6/drivers/hwtracing/coresight/coresight-cti-core.c linux-6.0.12/drivers/hwtracing/coresight/coresight-cti-core.c --- linux-6.0.6/drivers/hwtracing/coresight/coresight-cti-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/hwtracing/coresight/coresight-cti-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -90,11 +90,9 @@ static int cti_enable_hw(struct cti_drvdata *drvdata) { struct cti_config *config = &drvdata->config; - struct device *dev = &drvdata->csdev->dev; unsigned long flags; int rc = 0; - pm_runtime_get_sync(dev->parent); spin_lock_irqsave(&drvdata->spinlock, flags); /* no need to do anything if enabled or unpowered*/ @@ -119,7 +117,6 @@ /* cannot enable due to error */ cti_err_not_enabled: spin_unlock_irqrestore(&drvdata->spinlock, flags); - pm_runtime_put(dev->parent); return rc; } @@ -153,7 +150,6 @@ static int cti_disable_hw(struct cti_drvdata *drvdata) { struct cti_config *config = &drvdata->config; - struct device *dev = &drvdata->csdev->dev; struct coresight_device *csdev = drvdata->csdev; spin_lock(&drvdata->spinlock); @@ -175,7 +171,6 @@ coresight_disclaim_device_unlocked(csdev); CS_LOCK(drvdata->base); spin_unlock(&drvdata->spinlock); - pm_runtime_put(dev->parent); return 0; /* not disabled this call */ diff -Nru linux-6.0.6/drivers/i2c/busses/i2c-i801.c linux-6.0.12/drivers/i2c/busses/i2c-i801.c --- linux-6.0.6/drivers/i2c/busses/i2c-i801.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/i2c/busses/i2c-i801.c 2023-01-18 18:27:39.000000000 +0000 @@ -1243,6 +1243,7 @@ */ { "Latitude 5480", 0x29 }, { "Vostro V131", 0x1d }, + { "Vostro 5568", 0x29 }, }; static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv) diff -Nru linux-6.0.6/drivers/i2c/busses/i2c-imx.c linux-6.0.12/drivers/i2c/busses/i2c-imx.c --- linux-6.0.6/drivers/i2c/busses/i2c-imx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/i2c/busses/i2c-imx.c 2023-01-18 18:27:39.000000000 +0000 @@ -1132,7 +1132,8 @@ int i, result; unsigned int temp; int block_data = msgs->flags & I2C_M_RECV_LEN; - int use_dma = i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data; + int use_dma = i2c_imx->dma && msgs->flags & I2C_M_DMA_SAFE && + msgs->len >= DMA_THRESHOLD && !block_data; dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n", @@ -1298,7 +1299,8 @@ result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg, atomic); } else { if (!atomic && - i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD) + i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD && + msgs[i].flags & I2C_M_DMA_SAFE) result = i2c_imx_dma_write(i2c_imx, &msgs[i]); else result = i2c_imx_write(i2c_imx, &msgs[i], atomic); diff -Nru linux-6.0.6/drivers/i2c/busses/i2c-npcm7xx.c linux-6.0.12/drivers/i2c/busses/i2c-npcm7xx.c --- linux-6.0.6/drivers/i2c/busses/i2c-npcm7xx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/i2c/busses/i2c-npcm7xx.c 2023-01-18 18:27:39.000000000 +0000 @@ -2393,8 +2393,17 @@ static int __init npcm_i2c_init(void) { + int ret; + npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL); - return platform_driver_register(&npcm_i2c_bus_driver); + + ret = platform_driver_register(&npcm_i2c_bus_driver); + if (ret) { + debugfs_remove_recursive(npcm_i2c_debugfs_dir); + return ret; + } + + return 0; } module_init(npcm_i2c_init); diff -Nru linux-6.0.6/drivers/i2c/busses/i2c-piix4.c linux-6.0.12/drivers/i2c/busses/i2c-piix4.c --- linux-6.0.6/drivers/i2c/busses/i2c-piix4.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/i2c/busses/i2c-piix4.c 2023-01-18 18:27:39.000000000 +0000 @@ -1080,6 +1080,7 @@ "", &piix4_main_adapters[0]); if (retval < 0) return retval; + piix4_adapter_count = 1; } /* Check for auxiliary SMBus on some AMD chipsets */ diff -Nru linux-6.0.6/drivers/i2c/busses/i2c-qcom-geni.c linux-6.0.12/drivers/i2c/busses/i2c-qcom-geni.c --- linux-6.0.6/drivers/i2c/busses/i2c-qcom-geni.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/i2c/busses/i2c-qcom-geni.c 2023-01-18 18:27:39.000000000 +0000 @@ -626,7 +626,6 @@ dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n", gi2c->cur->flags, gi2c->cur->addr); gi2c->err = -ETIMEDOUT; - goto err; } if (gi2c->err) { diff -Nru linux-6.0.6/drivers/i2c/busses/i2c-tegra.c linux-6.0.12/drivers/i2c/busses/i2c-tegra.c --- linux-6.0.6/drivers/i2c/busses/i2c-tegra.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/i2c/busses/i2c-tegra.c 2023-01-18 18:27:39.000000000 +0000 @@ -284,6 +284,7 @@ struct dma_chan *tx_dma_chan; struct dma_chan *rx_dma_chan; unsigned int dma_buf_size; + struct device *dma_dev; dma_addr_t dma_phys; void *dma_buf; @@ -420,7 +421,7 @@ static void tegra_i2c_release_dma(struct tegra_i2c_dev *i2c_dev) { if (i2c_dev->dma_buf) { - dma_free_coherent(i2c_dev->dev, i2c_dev->dma_buf_size, + dma_free_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size, i2c_dev->dma_buf, i2c_dev->dma_phys); i2c_dev->dma_buf = NULL; } @@ -467,10 +468,13 @@ i2c_dev->tx_dma_chan = chan; + WARN_ON(i2c_dev->tx_dma_chan->device != i2c_dev->rx_dma_chan->device); + i2c_dev->dma_dev = chan->device->dev; + i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len + I2C_PACKET_HEADER_SIZE; - dma_buf = dma_alloc_coherent(i2c_dev->dev, i2c_dev->dma_buf_size, + dma_buf = dma_alloc_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size, &dma_phys, GFP_KERNEL | __GFP_NOWARN); if (!dma_buf) { dev_err(i2c_dev->dev, "failed to allocate DMA buffer\n"); @@ -1267,7 +1271,7 @@ if (i2c_dev->dma_mode) { if (i2c_dev->msg_read) { - dma_sync_single_for_device(i2c_dev->dev, + dma_sync_single_for_device(i2c_dev->dma_dev, i2c_dev->dma_phys, xfer_size, DMA_FROM_DEVICE); @@ -1275,7 +1279,7 @@ if (err) return err; } else { - dma_sync_single_for_cpu(i2c_dev->dev, + dma_sync_single_for_cpu(i2c_dev->dma_dev, i2c_dev->dma_phys, xfer_size, DMA_TO_DEVICE); } @@ -1288,7 +1292,7 @@ memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE, msg->buf, msg->len); - dma_sync_single_for_device(i2c_dev->dev, + dma_sync_single_for_device(i2c_dev->dma_dev, i2c_dev->dma_phys, xfer_size, DMA_TO_DEVICE); @@ -1339,7 +1343,7 @@ } if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) { - dma_sync_single_for_cpu(i2c_dev->dev, + dma_sync_single_for_cpu(i2c_dev->dma_dev, i2c_dev->dma_phys, xfer_size, DMA_FROM_DEVICE); diff -Nru linux-6.0.6/drivers/i2c/busses/i2c-xiic.c linux-6.0.12/drivers/i2c/busses/i2c-xiic.c --- linux-6.0.6/drivers/i2c/busses/i2c-xiic.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/i2c/busses/i2c-xiic.c 2023-01-18 18:27:39.000000000 +0000 @@ -920,6 +920,7 @@ module_platform_driver(xiic_i2c_driver); +MODULE_ALIAS("platform:" DRIVER_NAME); MODULE_AUTHOR("info@mocean-labs.com"); MODULE_DESCRIPTION("Xilinx I2C bus driver"); MODULE_LICENSE("GPL v2"); diff -Nru linux-6.0.6/drivers/i2c/i2c-core-base.c linux-6.0.12/drivers/i2c/i2c-core-base.c --- linux-6.0.6/drivers/i2c/i2c-core-base.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/i2c/i2c-core-base.c 2023-01-18 18:27:39.000000000 +0000 @@ -467,6 +467,7 @@ { struct i2c_client *client = i2c_verify_client(dev); struct i2c_driver *driver; + bool do_power_on; int status; if (!client) @@ -541,8 +542,8 @@ if (status < 0) goto err_clear_wakeup_irq; - status = dev_pm_domain_attach(&client->dev, - !i2c_acpi_waive_d0_probe(dev)); + do_power_on = !i2c_acpi_waive_d0_probe(dev); + status = dev_pm_domain_attach(&client->dev, do_power_on); if (status) goto err_clear_wakeup_irq; @@ -581,7 +582,7 @@ err_release_driver_resources: devres_release_group(&client->dev, client->devres_group_id); err_detach_pm_domain: - dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); + dev_pm_domain_detach(&client->dev, do_power_on); err_clear_wakeup_irq: dev_pm_clear_wake_irq(&client->dev); device_init_wakeup(&client->dev, false); @@ -610,7 +611,7 @@ devres_release_group(&client->dev, client->devres_group_id); - dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); + dev_pm_domain_detach(&client->dev, true); dev_pm_clear_wake_irq(&client->dev); device_init_wakeup(&client->dev, false); diff -Nru linux-6.0.6/drivers/iio/accel/adxl367.c linux-6.0.12/drivers/iio/accel/adxl367.c --- linux-6.0.6/drivers/iio/accel/adxl367.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/accel/adxl367.c 2023-01-18 18:27:39.000000000 +0000 @@ -1185,17 +1185,30 @@ return sysfs_emit(buf, "%d\n", fifo_watermark); } -static IIO_CONST_ATTR(hwfifo_watermark_min, "1"); -static IIO_CONST_ATTR(hwfifo_watermark_max, - __stringify(ADXL367_FIFO_MAX_WATERMARK)); +static ssize_t hwfifo_watermark_min_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", "1"); +} + +static ssize_t hwfifo_watermark_max_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", __stringify(ADXL367_FIFO_MAX_WATERMARK)); +} + +static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, adxl367_get_fifo_watermark, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, adxl367_get_fifo_enabled, NULL, 0); static const struct attribute *adxl367_fifo_attributes[] = { - &iio_const_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_const_attr_hwfifo_watermark_max.dev_attr.attr, + &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, + &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, &iio_dev_attr_hwfifo_watermark.dev_attr.attr, &iio_dev_attr_hwfifo_enabled.dev_attr.attr, NULL, diff -Nru linux-6.0.6/drivers/iio/accel/adxl372.c linux-6.0.12/drivers/iio/accel/adxl372.c --- linux-6.0.6/drivers/iio/accel/adxl372.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/accel/adxl372.c 2023-01-18 18:27:39.000000000 +0000 @@ -998,17 +998,30 @@ return sprintf(buf, "%d\n", st->watermark); } -static IIO_CONST_ATTR(hwfifo_watermark_min, "1"); -static IIO_CONST_ATTR(hwfifo_watermark_max, - __stringify(ADXL372_FIFO_SIZE)); +static ssize_t hwfifo_watermark_min_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", "1"); +} + +static ssize_t hwfifo_watermark_max_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", __stringify(ADXL372_FIFO_SIZE)); +} + +static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0); +static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0); static IIO_DEVICE_ATTR(hwfifo_watermark, 0444, adxl372_get_fifo_watermark, NULL, 0); static IIO_DEVICE_ATTR(hwfifo_enabled, 0444, adxl372_get_fifo_enabled, NULL, 0); static const struct attribute *adxl372_fifo_attributes[] = { - &iio_const_attr_hwfifo_watermark_min.dev_attr.attr, - &iio_const_attr_hwfifo_watermark_max.dev_attr.attr, + &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr, + &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr, &iio_dev_attr_hwfifo_watermark.dev_attr.attr, &iio_dev_attr_hwfifo_enabled.dev_attr.attr, NULL, diff -Nru linux-6.0.6/drivers/iio/accel/bma400_core.c linux-6.0.12/drivers/iio/accel/bma400_core.c --- linux-6.0.6/drivers/iio/accel/bma400_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/accel/bma400_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -673,8 +673,10 @@ ret = regmap_bulk_read(data->regmap, BMA400_STEP_CNT0_REG, steps_raw, BMA400_STEP_RAW_LEN); - if (ret) + if (ret) { + kfree(steps_raw); return ret; + } *val = get_unaligned_le24(steps_raw); kfree(steps_raw); return IIO_VAL_INT; @@ -737,18 +739,6 @@ unsigned int val; int ret; - /* Try to read chip_id register. It must return 0x90. */ - ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val); - if (ret) { - dev_err(data->dev, "Failed to read chip id register\n"); - return ret; - } - - if (val != BMA400_ID_REG_VAL) { - dev_err(data->dev, "Chip ID mismatch\n"); - return -ENODEV; - } - data->regulators[BMA400_VDD_REGULATOR].supply = "vdd"; data->regulators[BMA400_VDDIO_REGULATOR].supply = "vddio"; ret = devm_regulator_bulk_get(data->dev, @@ -774,6 +764,18 @@ if (ret) return ret; + /* Try to read chip_id register. It must return 0x90. */ + ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val); + if (ret) { + dev_err(data->dev, "Failed to read chip id register\n"); + return ret; + } + + if (val != BMA400_ID_REG_VAL) { + dev_err(data->dev, "Chip ID mismatch\n"); + return -ENODEV; + } + ret = bma400_get_power_mode(data); if (ret) { dev_err(data->dev, "Failed to get the initial power-mode\n"); diff -Nru linux-6.0.6/drivers/iio/adc/aspeed_adc.c linux-6.0.12/drivers/iio/adc/aspeed_adc.c --- linux-6.0.6/drivers/iio/adc/aspeed_adc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/adc/aspeed_adc.c 2023-01-18 18:27:39.000000000 +0000 @@ -202,6 +202,8 @@ ((scu_otp) & (data->model_data->trim_locate->field)) >> __ffs(data->model_data->trim_locate->field); + if (!trimming_val) + trimming_val = 0x8; } dev_dbg(data->dev, "trimming val = %d, offset = %08x, fields = %08x\n", @@ -563,12 +565,9 @@ if (ret) return ret; - if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid", - NULL)) { - ret = aspeed_adc_set_trim_data(indio_dev); - if (ret) - return ret; - } + ret = aspeed_adc_set_trim_data(indio_dev); + if (ret) + return ret; if (of_find_property(data->dev->of_node, "aspeed,battery-sensing", NULL)) { diff -Nru linux-6.0.6/drivers/iio/adc/at91_adc.c linux-6.0.12/drivers/iio/adc/at91_adc.c --- linux-6.0.6/drivers/iio/adc/at91_adc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/adc/at91_adc.c 2023-01-18 18:27:39.000000000 +0000 @@ -634,8 +634,10 @@ trig->ops = &at91_adc_trigger_ops; ret = iio_trigger_register(trig); - if (ret) + if (ret) { + iio_trigger_free(trig); return NULL; + } return trig; } diff -Nru linux-6.0.6/drivers/iio/adc/mp2629_adc.c linux-6.0.12/drivers/iio/adc/mp2629_adc.c --- linux-6.0.6/drivers/iio/adc/mp2629_adc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/adc/mp2629_adc.c 2023-01-18 18:27:39.000000000 +0000 @@ -57,7 +57,8 @@ MP2629_MAP(SYSTEM_VOLT, "system-volt"), MP2629_MAP(INPUT_VOLT, "input-volt"), MP2629_MAP(BATT_CURRENT, "batt-current"), - MP2629_MAP(INPUT_CURRENT, "input-current") + MP2629_MAP(INPUT_CURRENT, "input-current"), + { } }; static int mp2629_read_raw(struct iio_dev *indio_dev, @@ -74,7 +75,7 @@ if (ret) return ret; - if (chan->address == MP2629_INPUT_VOLT) + if (chan->channel == MP2629_INPUT_VOLT) rval &= GENMASK(6, 0); *val = rval; return IIO_VAL_INT; diff -Nru linux-6.0.6/drivers/iio/adc/stm32-adc.c linux-6.0.12/drivers/iio/adc/stm32-adc.c --- linux-6.0.6/drivers/iio/adc/stm32-adc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/adc/stm32-adc.c 2023-01-18 18:27:39.000000000 +0000 @@ -2064,18 +2064,19 @@ stm32_adc_chan_init_one(indio_dev, &channels[scan_index], val, vin[1], scan_index, differential); + val = 0; ret = of_property_read_u32(child, "st,min-sample-time-ns", &val); /* st,min-sample-time-ns is optional */ - if (!ret) { - stm32_adc_smpr_init(adc, channels[scan_index].channel, val); - if (differential) - stm32_adc_smpr_init(adc, vin[1], val); - } else if (ret != -EINVAL) { + if (ret && ret != -EINVAL) { dev_err(&indio_dev->dev, "Invalid st,min-sample-time-ns property %d\n", ret); goto err; } + stm32_adc_smpr_init(adc, channels[scan_index].channel, val); + if (differential) + stm32_adc_smpr_init(adc, vin[1], val); + scan_index++; } diff -Nru linux-6.0.6/drivers/iio/health/afe4403.c linux-6.0.12/drivers/iio/health/afe4403.c --- linux-6.0.6/drivers/iio/health/afe4403.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/health/afe4403.c 2023-01-18 18:27:39.000000000 +0000 @@ -245,14 +245,14 @@ int *val, int *val2, long mask) { struct afe4403_data *afe = iio_priv(indio_dev); - unsigned int reg = afe4403_channel_values[chan->address]; - unsigned int field = afe4403_channel_leds[chan->address]; + unsigned int reg, field; int ret; switch (chan->type) { case IIO_INTENSITY: switch (mask) { case IIO_CHAN_INFO_RAW: + reg = afe4403_channel_values[chan->address]; ret = afe4403_read(afe, reg, val); if (ret) return ret; @@ -262,6 +262,7 @@ case IIO_CURRENT: switch (mask) { case IIO_CHAN_INFO_RAW: + field = afe4403_channel_leds[chan->address]; ret = regmap_field_read(afe->fields[field], val); if (ret) return ret; diff -Nru linux-6.0.6/drivers/iio/health/afe4404.c linux-6.0.12/drivers/iio/health/afe4404.c --- linux-6.0.6/drivers/iio/health/afe4404.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/health/afe4404.c 2023-01-18 18:27:39.000000000 +0000 @@ -250,20 +250,20 @@ int *val, int *val2, long mask) { struct afe4404_data *afe = iio_priv(indio_dev); - unsigned int value_reg = afe4404_channel_values[chan->address]; - unsigned int led_field = afe4404_channel_leds[chan->address]; - unsigned int offdac_field = afe4404_channel_offdacs[chan->address]; + unsigned int value_reg, led_field, offdac_field; int ret; switch (chan->type) { case IIO_INTENSITY: switch (mask) { case IIO_CHAN_INFO_RAW: + value_reg = afe4404_channel_values[chan->address]; ret = regmap_read(afe->regmap, value_reg, val); if (ret) return ret; return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: + offdac_field = afe4404_channel_offdacs[chan->address]; ret = regmap_field_read(afe->fields[offdac_field], val); if (ret) return ret; @@ -273,6 +273,7 @@ case IIO_CURRENT: switch (mask) { case IIO_CHAN_INFO_RAW: + led_field = afe4404_channel_leds[chan->address]; ret = regmap_field_read(afe->fields[led_field], val); if (ret) return ret; @@ -295,19 +296,20 @@ int val, int val2, long mask) { struct afe4404_data *afe = iio_priv(indio_dev); - unsigned int led_field = afe4404_channel_leds[chan->address]; - unsigned int offdac_field = afe4404_channel_offdacs[chan->address]; + unsigned int led_field, offdac_field; switch (chan->type) { case IIO_INTENSITY: switch (mask) { case IIO_CHAN_INFO_OFFSET: + offdac_field = afe4404_channel_offdacs[chan->address]; return regmap_field_write(afe->fields[offdac_field], val); } break; case IIO_CURRENT: switch (mask) { case IIO_CHAN_INFO_RAW: + led_field = afe4404_channel_leds[chan->address]; return regmap_field_write(afe->fields[led_field], val); } break; diff -Nru linux-6.0.6/drivers/iio/industrialio-sw-trigger.c linux-6.0.12/drivers/iio/industrialio-sw-trigger.c --- linux-6.0.6/drivers/iio/industrialio-sw-trigger.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/industrialio-sw-trigger.c 2023-01-18 18:27:39.000000000 +0000 @@ -58,8 +58,12 @@ t->group = configfs_register_default_group(iio_triggers_group, t->name, &iio_trigger_type_group_type); - if (IS_ERR(t->group)) + if (IS_ERR(t->group)) { + mutex_lock(&iio_trigger_types_lock); + list_del(&t->list); + mutex_unlock(&iio_trigger_types_lock); ret = PTR_ERR(t->group); + } return ret; } diff -Nru linux-6.0.6/drivers/iio/light/apds9960.c linux-6.0.12/drivers/iio/light/apds9960.c --- linux-6.0.6/drivers/iio/light/apds9960.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/light/apds9960.c 2023-01-18 18:27:39.000000000 +0000 @@ -54,9 +54,6 @@ #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT 2 #define APDS9960_REG_CONFIG_2 0x90 -#define APDS9960_REG_CONFIG_2_GGAIN_MASK 0x60 -#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT 5 - #define APDS9960_REG_ID 0x92 #define APDS9960_REG_STATUS 0x93 @@ -77,6 +74,9 @@ #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT 6 #define APDS9960_REG_GCONF_2 0xa3 +#define APDS9960_REG_GCONF_2_GGAIN_MASK 0x60 +#define APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT 5 + #define APDS9960_REG_GOFFSET_U 0xa4 #define APDS9960_REG_GOFFSET_D 0xa5 #define APDS9960_REG_GPULSE 0xa6 @@ -396,9 +396,9 @@ } ret = regmap_update_bits(data->regmap, - APDS9960_REG_CONFIG_2, - APDS9960_REG_CONFIG_2_GGAIN_MASK, - idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT); + APDS9960_REG_GCONF_2, + APDS9960_REG_GCONF_2_GGAIN_MASK, + idx << APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT); if (!ret) data->pxs_gain = idx; mutex_unlock(&data->lock); diff -Nru linux-6.0.6/drivers/iio/light/Kconfig linux-6.0.12/drivers/iio/light/Kconfig --- linux-6.0.6/drivers/iio/light/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/light/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -293,6 +293,8 @@ tristate "ROHM RPR0521 ALS and proximity sensor driver" depends on I2C select REGMAP_I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say Y here if you want to build support for ROHM's RPR0521 ambient light and proximity sensor device. diff -Nru linux-6.0.6/drivers/iio/light/tsl2583.c linux-6.0.12/drivers/iio/light/tsl2583.c --- linux-6.0.6/drivers/iio/light/tsl2583.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/light/tsl2583.c 2023-01-18 18:27:39.000000000 +0000 @@ -858,7 +858,7 @@ TSL2583_POWER_OFF_DELAY_MS); pm_runtime_use_autosuspend(&clientp->dev); - ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); + ret = iio_device_register(indio_dev); if (ret) { dev_err(&clientp->dev, "%s: iio registration failed\n", __func__); diff -Nru linux-6.0.6/drivers/iio/pressure/ms5611_core.c linux-6.0.12/drivers/iio/pressure/ms5611_core.c --- linux-6.0.6/drivers/iio/pressure/ms5611_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/pressure/ms5611_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -85,7 +85,7 @@ struct ms5611_state *st = iio_priv(indio_dev); for (i = 0; i < MS5611_PROM_WORDS_NB; i++) { - ret = st->read_prom_word(st, i, &st->chip_info->prom[i]); + ret = st->read_prom_word(st, i, &st->prom[i]); if (ret < 0) { dev_err(&indio_dev->dev, "failed to read prom at %d\n", i); @@ -93,7 +93,7 @@ } } - if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) { + if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) { dev_err(&indio_dev->dev, "PROM integrity check failed\n"); return -ENODEV; } @@ -114,21 +114,20 @@ return ret; } - return st->chip_info->temp_and_pressure_compensate(st->chip_info, - temp, pressure); + return st->compensate_temp_and_pressure(st, temp, pressure); } -static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, +static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st, s32 *temp, s32 *pressure) { s32 t = *temp, p = *pressure; s64 off, sens, dt; - dt = t - (chip_info->prom[5] << 8); - off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7); - sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8); + dt = t - (st->prom[5] << 8); + off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7); + sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8); - t = 2000 + ((chip_info->prom[6] * dt) >> 23); + t = 2000 + ((st->prom[6] * dt) >> 23); if (t < 2000) { s64 off2, sens2, t2; @@ -154,17 +153,17 @@ return 0; } -static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, +static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st, s32 *temp, s32 *pressure) { s32 t = *temp, p = *pressure; s64 off, sens, dt; - dt = t - (chip_info->prom[5] << 8); - off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6); - sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7); + dt = t - (st->prom[5] << 8); + off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6); + sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7); - t = 2000 + ((chip_info->prom[6] * dt) >> 23); + t = 2000 + ((st->prom[6] * dt) >> 23); if (t < 2000) { s64 off2, sens2, t2, tmp; @@ -342,15 +341,6 @@ static const unsigned long ms5611_scan_masks[] = {0x3, 0}; -static struct ms5611_chip_info chip_info_tbl[] = { - [MS5611] = { - .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate, - }, - [MS5607] = { - .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate, - } -}; - static const struct iio_chan_spec ms5611_channels[] = { { .type = IIO_PRESSURE, @@ -433,7 +423,20 @@ struct ms5611_state *st = iio_priv(indio_dev); mutex_init(&st->lock); - st->chip_info = &chip_info_tbl[type]; + + switch (type) { + case MS5611: + st->compensate_temp_and_pressure = + ms5611_temp_and_pressure_compensate; + break; + case MS5607: + st->compensate_temp_and_pressure = + ms5607_temp_and_pressure_compensate; + break; + default: + return -EINVAL; + } + st->temp_osr = &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1]; st->pressure_osr = diff -Nru linux-6.0.6/drivers/iio/pressure/ms5611.h linux-6.0.12/drivers/iio/pressure/ms5611.h --- linux-6.0.6/drivers/iio/pressure/ms5611.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/pressure/ms5611.h 2023-01-18 18:27:39.000000000 +0000 @@ -25,13 +25,6 @@ MS5607, }; -struct ms5611_chip_info { - u16 prom[MS5611_PROM_WORDS_NB]; - - int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info, - s32 *temp, s32 *pressure); -}; - /* * OverSampling Rate descriptor. * Warning: cmd MUST be kept aligned on a word boundary (see @@ -50,12 +43,15 @@ const struct ms5611_osr *pressure_osr; const struct ms5611_osr *temp_osr; + u16 prom[MS5611_PROM_WORDS_NB]; + int (*reset)(struct ms5611_state *st); int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word); int (*read_adc_temp_and_pressure)(struct ms5611_state *st, s32 *temp, s32 *pressure); - struct ms5611_chip_info *chip_info; + int (*compensate_temp_and_pressure)(struct ms5611_state *st, s32 *temp, + s32 *pressure); struct regulator *vdd; }; diff -Nru linux-6.0.6/drivers/iio/pressure/ms5611_spi.c linux-6.0.12/drivers/iio/pressure/ms5611_spi.c --- linux-6.0.6/drivers/iio/pressure/ms5611_spi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/pressure/ms5611_spi.c 2023-01-18 18:27:39.000000000 +0000 @@ -91,7 +91,7 @@ spi_set_drvdata(spi, indio_dev); spi->mode = SPI_MODE_0; - spi->max_speed_hz = 20000000; + spi->max_speed_hz = min(spi->max_speed_hz, 20000000U); spi->bits_per_word = 8; ret = spi_setup(spi); if (ret < 0) diff -Nru linux-6.0.6/drivers/iio/temperature/ltc2983.c linux-6.0.12/drivers/iio/temperature/ltc2983.c --- linux-6.0.6/drivers/iio/temperature/ltc2983.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/temperature/ltc2983.c 2023-01-18 18:27:39.000000000 +0000 @@ -1385,13 +1385,6 @@ return ret; } - st->iio_chan = devm_kzalloc(&st->spi->dev, - st->iio_channels * sizeof(*st->iio_chan), - GFP_KERNEL); - - if (!st->iio_chan) - return -ENOMEM; - ret = regmap_update_bits(st->regmap, LTC2983_GLOBAL_CONFIG_REG, LTC2983_NOTCH_FREQ_MASK, LTC2983_NOTCH_FREQ(st->filter_notch_freq)); @@ -1514,6 +1507,12 @@ gpiod_set_value_cansleep(gpio, 0); } + st->iio_chan = devm_kzalloc(&spi->dev, + st->iio_channels * sizeof(*st->iio_chan), + GFP_KERNEL); + if (!st->iio_chan) + return -ENOMEM; + ret = ltc2983_setup(st, true); if (ret) return ret; diff -Nru linux-6.0.6/drivers/iio/trigger/iio-trig-sysfs.c linux-6.0.12/drivers/iio/trigger/iio-trig-sysfs.c --- linux-6.0.6/drivers/iio/trigger/iio-trig-sysfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iio/trigger/iio-trig-sysfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -203,9 +203,13 @@ static int __init iio_sysfs_trig_init(void) { + int ret; device_initialize(&iio_sysfs_trig_dev); dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger"); - return device_add(&iio_sysfs_trig_dev); + ret = device_add(&iio_sysfs_trig_dev); + if (ret) + put_device(&iio_sysfs_trig_dev); + return ret; } module_init(iio_sysfs_trig_init); diff -Nru linux-6.0.6/drivers/infiniband/core/cma.c linux-6.0.12/drivers/infiniband/core/cma.c --- linux-6.0.6/drivers/infiniband/core/cma.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/core/cma.c 2023-01-18 18:27:39.000000000 +0000 @@ -1556,7 +1556,7 @@ return false; memset(&fl4, 0, sizeof(fl4)); - fl4.flowi4_iif = net_dev->ifindex; + fl4.flowi4_oif = net_dev->ifindex; fl4.daddr = daddr; fl4.saddr = saddr; diff -Nru linux-6.0.6/drivers/infiniband/core/device.c linux-6.0.12/drivers/infiniband/core/device.c --- linux-6.0.6/drivers/infiniband/core/device.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/core/device.c 2023-01-18 18:27:39.000000000 +0000 @@ -2815,10 +2815,18 @@ nldev_init(); rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table); - roce_gid_mgmt_init(); + ret = roce_gid_mgmt_init(); + if (ret) { + pr_warn("Couldn't init RoCE GID management\n"); + goto err_parent; + } return 0; +err_parent: + rdma_nl_unregister(RDMA_NL_LS); + nldev_exit(); + unregister_pernet_device(&rdma_dev_net_ops); err_compat: unregister_blocking_lsm_notifier(&ibdev_lsm_nb); err_sa: diff -Nru linux-6.0.6/drivers/infiniband/core/nldev.c linux-6.0.12/drivers/infiniband/core/nldev.c --- linux-6.0.6/drivers/infiniband/core/nldev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/core/nldev.c 2023-01-18 18:27:39.000000000 +0000 @@ -2537,7 +2537,7 @@ rdma_nl_register(RDMA_NL_NLDEV, nldev_cb_table); } -void __exit nldev_exit(void) +void nldev_exit(void) { rdma_nl_unregister(RDMA_NL_NLDEV); } diff -Nru linux-6.0.6/drivers/infiniband/hw/efa/efa_main.c linux-6.0.12/drivers/infiniband/hw/efa/efa_main.c --- linux-6.0.6/drivers/infiniband/hw/efa/efa_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/hw/efa/efa_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause /* - * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright 2018-2022 Amazon.com, Inc. or its affiliates. All rights reserved. */ #include @@ -14,10 +14,12 @@ #define PCI_DEV_ID_EFA0_VF 0xefa0 #define PCI_DEV_ID_EFA1_VF 0xefa1 +#define PCI_DEV_ID_EFA2_VF 0xefa2 static const struct pci_device_id efa_pci_tbl[] = { { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) }, { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) }, + { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA2_VF) }, { } }; diff -Nru linux-6.0.6/drivers/infiniband/hw/hfi1/pio.c linux-6.0.12/drivers/infiniband/hw/hfi1/pio.c --- linux-6.0.6/drivers/infiniband/hw/hfi1/pio.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/hw/hfi1/pio.c 2023-01-18 18:27:39.000000000 +0000 @@ -913,8 +913,7 @@ spin_unlock(&sc->release_lock); write_seqlock(&sc->waitlock); - if (!list_empty(&sc->piowait)) - list_move(&sc->piowait, &wake_list); + list_splice_init(&sc->piowait, &wake_list); write_sequnlock(&sc->waitlock); while (!list_empty(&wake_list)) { struct iowait *wait; diff -Nru linux-6.0.6/drivers/infiniband/hw/hns/hns_roce_hw_v2.c linux-6.0.12/drivers/infiniband/hw/hns/hns_roce_hw_v2.c --- linux-6.0.6/drivers/infiniband/hw/hns/hns_roce_hw_v2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/hw/hns/hns_roce_hw_v2.c 2023-01-18 18:27:39.000000000 +0000 @@ -118,7 +118,6 @@ HR_OPC_MAP(ATOMIC_CMP_AND_SWP, ATOM_CMP_AND_SWAP), HR_OPC_MAP(ATOMIC_FETCH_AND_ADD, ATOM_FETCH_AND_ADD), HR_OPC_MAP(SEND_WITH_INV, SEND_WITH_INV), - HR_OPC_MAP(LOCAL_INV, LOCAL_INV), HR_OPC_MAP(MASKED_ATOMIC_CMP_AND_SWP, ATOM_MSK_CMP_AND_SWAP), HR_OPC_MAP(MASKED_ATOMIC_FETCH_AND_ADD, ATOM_MSK_FETCH_AND_ADD), HR_OPC_MAP(REG_MR, FAST_REG_PMR), @@ -560,9 +559,6 @@ else ret = -EOPNOTSUPP; break; - case IB_WR_LOCAL_INV: - hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_SO); - fallthrough; case IB_WR_SEND_WITH_INV: rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey); break; @@ -2809,8 +2805,12 @@ static int free_mr_init(struct hns_roce_dev *hr_dev) { + struct hns_roce_v2_priv *priv = hr_dev->priv; + struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; int ret; + mutex_init(&free_mr->mutex); + ret = free_mr_alloc_res(hr_dev); if (ret) return ret; @@ -3226,7 +3226,6 @@ hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_VALID); hr_reg_write(mpt_entry, MPT_PD, mr->pd); - hr_reg_enable(mpt_entry, MPT_L_INV_EN); hr_reg_write_bool(mpt_entry, MPT_BIND_EN, mr->access & IB_ACCESS_MW_BIND); @@ -3317,7 +3316,6 @@ hr_reg_enable(mpt_entry, MPT_RA_EN); hr_reg_enable(mpt_entry, MPT_R_INV_EN); - hr_reg_enable(mpt_entry, MPT_L_INV_EN); hr_reg_enable(mpt_entry, MPT_FRE); hr_reg_clear(mpt_entry, MPT_MR_MW); @@ -3349,7 +3347,6 @@ hr_reg_write(mpt_entry, MPT_PD, mw->pdn); hr_reg_enable(mpt_entry, MPT_R_INV_EN); - hr_reg_enable(mpt_entry, MPT_L_INV_EN); hr_reg_enable(mpt_entry, MPT_LW_EN); hr_reg_enable(mpt_entry, MPT_MR_MW); @@ -3798,7 +3795,6 @@ HR_WC_OP_MAP(RDMA_READ, RDMA_READ), HR_WC_OP_MAP(RDMA_WRITE, RDMA_WRITE), HR_WC_OP_MAP(RDMA_WRITE_WITH_IMM, RDMA_WRITE), - HR_WC_OP_MAP(LOCAL_INV, LOCAL_INV), HR_WC_OP_MAP(ATOM_CMP_AND_SWAP, COMP_SWAP), HR_WC_OP_MAP(ATOM_FETCH_AND_ADD, FETCH_ADD), HR_WC_OP_MAP(ATOM_MSK_CMP_AND_SWAP, MASKED_COMP_SWAP), @@ -3848,9 +3844,6 @@ case HNS_ROCE_V2_WQE_OP_RDMA_WRITE_WITH_IMM: wc->wc_flags |= IB_WC_WITH_IMM; break; - case HNS_ROCE_V2_WQE_OP_LOCAL_INV: - wc->wc_flags |= IB_WC_WITH_INVALIDATE; - break; case HNS_ROCE_V2_WQE_OP_ATOM_CMP_AND_SWAP: case HNS_ROCE_V2_WQE_OP_ATOM_FETCH_AND_ADD: case HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP: diff -Nru linux-6.0.6/drivers/infiniband/hw/hns/hns_roce_hw_v2.h linux-6.0.12/drivers/infiniband/hw/hns/hns_roce_hw_v2.h --- linux-6.0.6/drivers/infiniband/hw/hns/hns_roce_hw_v2.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/hw/hns/hns_roce_hw_v2.h 2023-01-18 18:27:39.000000000 +0000 @@ -182,7 +182,6 @@ HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP = 0x8, HNS_ROCE_V2_WQE_OP_ATOM_MSK_FETCH_AND_ADD = 0x9, HNS_ROCE_V2_WQE_OP_FAST_REG_PMR = 0xa, - HNS_ROCE_V2_WQE_OP_LOCAL_INV = 0xb, HNS_ROCE_V2_WQE_OP_BIND_MW = 0xc, HNS_ROCE_V2_WQE_OP_MASK = 0x1f, }; @@ -916,7 +915,6 @@ #define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7) #define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8) #define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9) -#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10) #define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11) #define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12) #define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15) diff -Nru linux-6.0.6/drivers/infiniband/hw/qedr/main.c linux-6.0.12/drivers/infiniband/hw/qedr/main.c --- linux-6.0.6/drivers/infiniband/hw/qedr/main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/hw/qedr/main.c 2023-01-18 18:27:39.000000000 +0000 @@ -344,6 +344,10 @@ if (IS_IWARP(dev)) { xa_init(&dev->qps); dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq"); + if (!dev->iwarp_wq) { + rc = -ENOMEM; + goto err1; + } } /* Allocate Status blocks for CNQ */ @@ -351,7 +355,7 @@ GFP_KERNEL); if (!dev->sb_array) { rc = -ENOMEM; - goto err1; + goto err_destroy_wq; } dev->cnq_array = kcalloc(dev->num_cnq, @@ -402,6 +406,9 @@ kfree(dev->cnq_array); err2: kfree(dev->sb_array); +err_destroy_wq: + if (IS_IWARP(dev)) + destroy_workqueue(dev->iwarp_wq); err1: kfree(dev->sgid_tbl); return rc; diff -Nru linux-6.0.6/drivers/infiniband/sw/rxe/rxe_resp.c linux-6.0.12/drivers/infiniband/sw/rxe/rxe_resp.c --- linux-6.0.6/drivers/infiniband/sw/rxe/rxe_resp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/infiniband/sw/rxe/rxe_resp.c 2023-01-18 18:27:39.000000000 +0000 @@ -806,8 +806,10 @@ skb = prepare_ack_packet(qp, &ack_pkt, opcode, payload, res->cur_psn, AETH_ACK_UNLIMITED); - if (!skb) + if (!skb) { + rxe_put(mr); return RESPST_ERR_RNR; + } rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt), payload, RXE_FROM_MR_OBJ); diff -Nru linux-6.0.6/drivers/input/joystick/iforce/iforce-main.c linux-6.0.12/drivers/input/joystick/iforce/iforce-main.c --- linux-6.0.6/drivers/input/joystick/iforce/iforce-main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/input/joystick/iforce/iforce-main.c 2023-01-18 18:27:39.000000000 +0000 @@ -273,22 +273,22 @@ * Get device info. */ - if (!iforce_get_id_packet(iforce, 'M', buf, &len) || len < 3) + if (!iforce_get_id_packet(iforce, 'M', buf, &len) && len >= 3) input_dev->id.vendor = get_unaligned_le16(buf + 1); else dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n"); - if (!iforce_get_id_packet(iforce, 'P', buf, &len) || len < 3) + if (!iforce_get_id_packet(iforce, 'P', buf, &len) && len >= 3) input_dev->id.product = get_unaligned_le16(buf + 1); else dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n"); - if (!iforce_get_id_packet(iforce, 'B', buf, &len) || len < 3) + if (!iforce_get_id_packet(iforce, 'B', buf, &len) && len >= 3) iforce->device_memory.end = get_unaligned_le16(buf + 1); else dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n"); - if (!iforce_get_id_packet(iforce, 'N', buf, &len) || len < 2) + if (!iforce_get_id_packet(iforce, 'N', buf, &len) && len >= 2) ff_effects = buf[1]; else dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n"); diff -Nru linux-6.0.6/drivers/input/misc/soc_button_array.c linux-6.0.12/drivers/input/misc/soc_button_array.c --- linux-6.0.6/drivers/input/misc/soc_button_array.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/input/misc/soc_button_array.c 2023-01-18 18:27:39.000000000 +0000 @@ -18,6 +18,10 @@ #include #include +static bool use_low_level_irq; +module_param(use_low_level_irq, bool, 0444); +MODULE_PARM_DESC(use_low_level_irq, "Use low-level triggered IRQ instead of edge triggered"); + struct soc_button_info { const char *name; int acpi_index; @@ -74,6 +78,13 @@ }, }, { + /* Acer Switch V 10 SW5-017, same issue as Acer Switch 10 SW5-012. */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "SW5-017"), + }, + }, + { /* * Acer One S1003. _LID method messes with power-button GPIO * IRQ settings, leading to a non working power-button. @@ -164,7 +175,8 @@ } /* See dmi_use_low_level_irq[] comment */ - if (!autorepeat && dmi_check_system(dmi_use_low_level_irq)) { + if (!autorepeat && (use_low_level_irq || + dmi_check_system(dmi_use_low_level_irq))) { irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); gpio_keys[n_buttons].irq = irq; gpio_keys[n_buttons].gpio = -ENOENT; diff -Nru linux-6.0.6/drivers/input/mouse/synaptics.c linux-6.0.12/drivers/input/mouse/synaptics.c --- linux-6.0.6/drivers/input/mouse/synaptics.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/input/mouse/synaptics.c 2023-01-18 18:27:39.000000000 +0000 @@ -191,6 +191,7 @@ "SYN3221", /* HP 15-ay000 */ "SYN323d", /* HP Spectre X360 13-w013dx */ "SYN3257", /* HP Envy 13-ad105ng */ + "SYN3286", /* HP Laptop 15-da3001TU */ NULL }; diff -Nru linux-6.0.6/drivers/input/serio/i8042.c linux-6.0.12/drivers/input/serio/i8042.c --- linux-6.0.6/drivers/input/serio/i8042.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/input/serio/i8042.c 2023-01-18 18:27:39.000000000 +0000 @@ -1543,8 +1543,6 @@ { int error; - i8042_platform_device = dev; - if (i8042_reset == I8042_RESET_ALWAYS) { error = i8042_controller_selftest(); if (error) @@ -1582,7 +1580,6 @@ i8042_free_aux_ports(); /* in case KBD failed but AUX not */ i8042_free_irqs(); i8042_controller_reset(false); - i8042_platform_device = NULL; return error; } @@ -1592,7 +1589,6 @@ i8042_unregister_ports(); i8042_free_irqs(); i8042_controller_reset(false); - i8042_platform_device = NULL; return 0; } diff -Nru linux-6.0.6/drivers/input/serio/i8042-x86ia64io.h linux-6.0.12/drivers/input/serio/i8042-x86ia64io.h --- linux-6.0.6/drivers/input/serio/i8042-x86ia64io.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/input/serio/i8042-x86ia64io.h 2023-01-18 18:27:39.000000000 +0000 @@ -114,18 +114,18 @@ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER) }, { - /* ASUS ZenBook UX425UA */ + /* ASUS ZenBook UX425UA/QA */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425"), }, .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) }, { - /* ASUS ZenBook UM325UA */ + /* ASUS ZenBook UM325UA/QA */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325"), }, .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) }, diff -Nru linux-6.0.6/drivers/input/touchscreen/goodix.c linux-6.0.12/drivers/input/touchscreen/goodix.c --- linux-6.0.6/drivers/input/touchscreen/goodix.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/input/touchscreen/goodix.c 2023-01-18 18:27:39.000000000 +0000 @@ -1158,6 +1158,7 @@ input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); +retry_read_config: /* Read configuration and apply touchscreen parameters */ goodix_read_config(ts); @@ -1165,6 +1166,16 @@ touchscreen_parse_properties(ts->input_dev, true, &ts->prop); if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) { + if (!ts->reset_controller_at_probe && + ts->irq_pin_access_method != IRQ_PIN_ACCESS_NONE) { + dev_info(&ts->client->dev, "Config not set, resetting controller\n"); + /* Retry after a controller reset */ + ts->reset_controller_at_probe = true; + error = goodix_reset(ts); + if (error) + return error; + goto retry_read_config; + } dev_err(&ts->client->dev, "Invalid config (%d, %d, %d), using defaults\n", ts->prop.max_x, ts->prop.max_y, ts->max_touch_num); diff -Nru linux-6.0.6/drivers/input/touchscreen/raydium_i2c_ts.c linux-6.0.12/drivers/input/touchscreen/raydium_i2c_ts.c --- linux-6.0.6/drivers/input/touchscreen/raydium_i2c_ts.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/input/touchscreen/raydium_i2c_ts.c 2023-01-18 18:27:39.000000000 +0000 @@ -211,12 +211,14 @@ error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer)); if (likely(!error)) - return 0; + goto out; msleep(RM_RETRY_DELAY_MS); } while (++tries < RM_MAX_RETRIES); dev_err(&client->dev, "%s failed: %d\n", __func__, error); +out: + kfree(tx_buf); return error; } diff -Nru linux-6.0.6/drivers/iommu/intel/dmar.c linux-6.0.12/drivers/iommu/intel/dmar.c --- linux-6.0.6/drivers/iommu/intel/dmar.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iommu/intel/dmar.c 2023-01-18 18:27:39.000000000 +0000 @@ -820,6 +820,7 @@ info = dmar_alloc_pci_notify_info(dev, BUS_NOTIFY_ADD_DEVICE); if (!info) { + pci_dev_put(dev); return dmar_dev_scope_status; } else { dmar_pci_bus_add_dev(info); diff -Nru linux-6.0.6/drivers/iommu/intel/iommu.c linux-6.0.12/drivers/iommu/intel/iommu.c --- linux-6.0.6/drivers/iommu/intel/iommu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iommu/intel/iommu.c 2023-01-18 18:27:39.000000000 +0000 @@ -954,11 +954,9 @@ domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE); pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE; - if (domain_use_first_level(domain)) { - pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US; - if (iommu_is_dma_domain(&domain->domain)) - pteval |= DMA_FL_PTE_ACCESS; - } + if (domain_use_first_level(domain)) + pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US | DMA_FL_PTE_ACCESS; + if (cmpxchg64(&pte->val, 0ULL, pteval)) /* Someone else set it while we were thinking; use theirs. */ free_pgtable_page(tmp_page); @@ -3846,8 +3844,10 @@ struct pci_dev *pdev = NULL; for_each_pci_dev(pdev) - if (pdev->external_facing) + if (pdev->external_facing) { + pci_dev_put(pdev); return true; + } return false; } diff -Nru linux-6.0.6/drivers/iommu/intel/pasid.c linux-6.0.12/drivers/iommu/intel/pasid.c --- linux-6.0.6/drivers/iommu/intel/pasid.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/iommu/intel/pasid.c 2023-01-18 18:27:39.000000000 +0000 @@ -652,7 +652,7 @@ * Since it is a second level only translation setup, we should * set SRE bit as well (addresses are expected to be GPAs). */ - if (pasid != PASID_RID2PASID) + if (pasid != PASID_RID2PASID && ecap_srs(iommu->ecap)) pasid_set_sre(pte); pasid_set_present(pte); spin_unlock(&iommu->lock); @@ -695,7 +695,8 @@ * We should set SRE bit as well since the addresses are expected * to be GPAs. */ - pasid_set_sre(pte); + if (ecap_srs(iommu->ecap)) + pasid_set_sre(pte); pasid_set_present(pte); spin_unlock(&iommu->lock); diff -Nru linux-6.0.6/drivers/isdn/hardware/mISDN/netjet.c linux-6.0.12/drivers/isdn/hardware/mISDN/netjet.c --- linux-6.0.6/drivers/isdn/hardware/mISDN/netjet.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/isdn/hardware/mISDN/netjet.c 2023-01-18 18:27:39.000000000 +0000 @@ -956,7 +956,7 @@ } if (card->irq > 0) free_irq(card->irq, card); - if (card->isac.dch.dev.dev.class) + if (device_is_registered(&card->isac.dch.dev.dev)) mISDN_unregister_device(&card->isac.dch.dev); for (i = 0; i < 2; i++) { diff -Nru linux-6.0.6/drivers/isdn/mISDN/core.c linux-6.0.12/drivers/isdn/mISDN/core.c --- linux-6.0.6/drivers/isdn/mISDN/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/isdn/mISDN/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -222,7 +222,7 @@ err = get_free_devid(); if (err < 0) - goto error1; + return err; dev->id = err; device_initialize(&dev->dev); @@ -233,11 +233,12 @@ if (debug & DEBUG_CORE) printk(KERN_DEBUG "mISDN_register %s %d\n", dev_name(&dev->dev), dev->id); + dev->dev.class = &mISDN_class; + err = create_stack(dev); if (err) goto error1; - dev->dev.class = &mISDN_class; dev->dev.platform_data = dev; dev->dev.parent = parent; dev_set_drvdata(&dev->dev, dev); @@ -249,8 +250,8 @@ error3: delete_stack(dev); - return err; error1: + put_device(&dev->dev); return err; } diff -Nru linux-6.0.6/drivers/isdn/mISDN/dsp_pipeline.c linux-6.0.12/drivers/isdn/mISDN/dsp_pipeline.c --- linux-6.0.6/drivers/isdn/mISDN/dsp_pipeline.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/isdn/mISDN/dsp_pipeline.c 2023-01-18 18:27:39.000000000 +0000 @@ -77,6 +77,7 @@ if (!entry) return -ENOMEM; + INIT_LIST_HEAD(&entry->list); entry->elem = elem; entry->dev.class = elements_class; @@ -107,7 +108,7 @@ device_unregister(&entry->dev); return ret; err1: - kfree(entry); + put_device(&entry->dev); return ret; } EXPORT_SYMBOL(mISDN_dsp_element_register); diff -Nru linux-6.0.6/drivers/md/dm-bufio.c linux-6.0.12/drivers/md/dm-bufio.c --- linux-6.0.6/drivers/md/dm-bufio.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/md/dm-bufio.c 2023-01-18 18:27:39.000000000 +0000 @@ -1858,6 +1858,8 @@ dm_io_client_destroy(c->dm_io); bad_dm_io: mutex_destroy(&c->lock); + if (c->no_sleep) + static_branch_dec(&no_sleep_enabled); kfree(c); bad_client: return ERR_PTR(r); diff -Nru linux-6.0.6/drivers/md/dm-crypt.c linux-6.0.12/drivers/md/dm-crypt.c --- linux-6.0.6/drivers/md/dm-crypt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/md/dm-crypt.c 2023-01-18 18:27:39.000000000 +0000 @@ -3630,6 +3630,7 @@ limits->physical_block_size = max_t(unsigned, limits->physical_block_size, cc->sector_size); limits->io_min = max_t(unsigned, limits->io_min, cc->sector_size); + limits->dma_alignment = limits->logical_block_size - 1; } static struct target_type crypt_target = { diff -Nru linux-6.0.6/drivers/md/dm-integrity.c linux-6.0.12/drivers/md/dm-integrity.c --- linux-6.0.6/drivers/md/dm-integrity.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/md/dm-integrity.c 2023-01-18 18:27:39.000000000 +0000 @@ -263,6 +263,7 @@ struct completion crypto_backoff; + bool wrote_to_journal; bool journal_uptodate; bool just_formatted; bool recalculate_flag; @@ -2375,6 +2376,8 @@ if (!commit_sections) goto release_flush_bios; + ic->wrote_to_journal = true; + i = commit_start; for (n = 0; n < commit_sections; n++) { for (j = 0; j < ic->journal_section_entries; j++) { @@ -2591,10 +2594,6 @@ unsigned prev_free_sectors; - /* the following test is not needed, but it tests the replay code */ - if (unlikely(dm_post_suspending(ic->ti)) && !ic->meta_dev) - return; - spin_lock_irq(&ic->endio_wait.lock); write_start = ic->committed_section; write_sections = ic->n_committed_sections; @@ -3101,10 +3100,17 @@ drain_workqueue(ic->commit_wq); if (ic->mode == 'J') { - if (ic->meta_dev) - queue_work(ic->writer_wq, &ic->writer_work); + queue_work(ic->writer_wq, &ic->writer_work); drain_workqueue(ic->writer_wq); dm_integrity_flush_buffers(ic, true); + if (ic->wrote_to_journal) { + init_journal(ic, ic->free_section, + ic->journal_sections - ic->free_section, ic->commit_seq); + if (ic->free_section) { + init_journal(ic, 0, ic->free_section, + next_commit_seq(ic->commit_seq)); + } + } } if (ic->mode == 'B') { @@ -3132,6 +3138,8 @@ DEBUG_print("resume\n"); + ic->wrote_to_journal = false; + if (ic->provided_data_sectors != old_provided_data_sectors) { if (ic->provided_data_sectors > old_provided_data_sectors && ic->mode == 'B' && @@ -3370,6 +3378,7 @@ limits->logical_block_size = ic->sectors_per_block << SECTOR_SHIFT; limits->physical_block_size = ic->sectors_per_block << SECTOR_SHIFT; blk_limits_io_min(limits, ic->sectors_per_block << SECTOR_SHIFT); + limits->dma_alignment = limits->logical_block_size - 1; } } diff -Nru linux-6.0.6/drivers/md/dm-ioctl.c linux-6.0.12/drivers/md/dm-ioctl.c --- linux-6.0.6/drivers/md/dm-ioctl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/md/dm-ioctl.c 2023-01-18 18:27:39.000000000 +0000 @@ -655,7 +655,7 @@ size_t *needed = needed_param; *needed += sizeof(struct dm_target_versions); - *needed += strlen(tt->name); + *needed += strlen(tt->name) + 1; *needed += ALIGN_MASK; } @@ -720,7 +720,7 @@ iter_info.old_vers = NULL; iter_info.vers = vers; iter_info.flags = 0; - iter_info.end = (char *)vers+len; + iter_info.end = (char *)vers + needed; /* * Now loop through filling out the names & versions. diff -Nru linux-6.0.6/drivers/md/dm-log-writes.c linux-6.0.12/drivers/md/dm-log-writes.c --- linux-6.0.6/drivers/md/dm-log-writes.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/md/dm-log-writes.c 2023-01-18 18:27:39.000000000 +0000 @@ -875,6 +875,7 @@ limits->logical_block_size = bdev_logical_block_size(lc->dev->bdev); limits->physical_block_size = bdev_physical_block_size(lc->dev->bdev); limits->io_min = limits->physical_block_size; + limits->dma_alignment = limits->logical_block_size - 1; } #if IS_ENABLED(CONFIG_FS_DAX) diff -Nru linux-6.0.6/drivers/media/cec/platform/cros-ec/cros-ec-cec.c linux-6.0.12/drivers/media/cec/platform/cros-ec/cros-ec-cec.c --- linux-6.0.6/drivers/media/cec/platform/cros-ec/cros-ec-cec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/cec/platform/cros-ec/cros-ec-cec.c 2023-01-18 18:27:39.000000000 +0000 @@ -44,6 +44,8 @@ uint8_t *cec_message = cros_ec->event_data.data.cec_message; unsigned int len = cros_ec->event_size; + if (len > CEC_MAX_MSG_SIZE) + len = CEC_MAX_MSG_SIZE; cros_ec_cec->rx_msg.len = len; memcpy(cros_ec_cec->rx_msg.msg, cec_message, len); @@ -221,6 +223,8 @@ { "Google", "Moli", "0000:00:02.0", "Port B" }, /* Google Kinox */ { "Google", "Kinox", "0000:00:02.0", "Port B" }, + /* Google Kuldax */ + { "Google", "Kuldax", "0000:00:02.0", "Port B" }, }; static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev, diff -Nru linux-6.0.6/drivers/media/cec/platform/s5p/s5p_cec.c linux-6.0.12/drivers/media/cec/platform/s5p/s5p_cec.c --- linux-6.0.6/drivers/media/cec/platform/s5p/s5p_cec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/cec/platform/s5p/s5p_cec.c 2023-01-18 18:27:39.000000000 +0000 @@ -115,6 +115,8 @@ dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n"); cec->rx = STATE_BUSY; cec->msg.len = status >> 24; + if (cec->msg.len > CEC_MAX_MSG_SIZE) + cec->msg.len = CEC_MAX_MSG_SIZE; cec->msg.rx_status = CEC_RX_STATUS_OK; s5p_cec_get_rx_buf(cec, cec->msg.len, cec->msg.msg); diff -Nru linux-6.0.6/drivers/media/common/videobuf2/frame_vector.c linux-6.0.12/drivers/media/common/videobuf2/frame_vector.c --- linux-6.0.6/drivers/media/common/videobuf2/frame_vector.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/common/videobuf2/frame_vector.c 2023-01-18 18:27:39.000000000 +0000 @@ -35,11 +35,7 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, struct frame_vector *vec) { - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - int ret_pin_user_pages_fast = 0; - int ret = 0; - int err; + int ret; if (nr_frames == 0) return 0; @@ -52,57 +48,17 @@ ret = pin_user_pages_fast(start, nr_frames, FOLL_FORCE | FOLL_WRITE | FOLL_LONGTERM, (struct page **)(vec->ptrs)); - if (ret > 0) { - vec->got_ref = true; - vec->is_pfns = false; - goto out_unlocked; - } - ret_pin_user_pages_fast = ret; - - mmap_read_lock(mm); - vec->got_ref = false; - vec->is_pfns = true; - ret = 0; - do { - unsigned long *nums = frame_vector_pfns(vec); - - vma = vma_lookup(mm, start); - if (!vma) - break; - - while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) { - err = follow_pfn(vma, start, &nums[ret]); - if (err) { - if (ret) - goto out; - // If follow_pfn() returns -EINVAL, then this - // is not an IO mapping or a raw PFN mapping. - // In that case, return the original error from - // pin_user_pages_fast(). Otherwise this - // function would return -EINVAL when - // pin_user_pages_fast() returned -ENOMEM, - // which makes debugging hard. - if (err == -EINVAL && ret_pin_user_pages_fast) - ret = ret_pin_user_pages_fast; - else - ret = err; - goto out; - } - start += PAGE_SIZE; - ret++; - } - /* Bail out if VMA doesn't completely cover the tail page. */ - if (start < vma->vm_end) - break; - } while (ret < nr_frames); -out: - mmap_read_unlock(mm); -out_unlocked: - if (!ret) - ret = -EFAULT; - if (ret > 0) - vec->nr_frames = ret; - return ret; + vec->got_ref = true; + vec->is_pfns = false; + vec->nr_frames = ret; + + if (likely(ret > 0)) + return ret; + + /* This used to (racily) return non-refcounted pfns. Let people know */ + WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping"); + vec->nr_frames = 0; + return ret ? ret : -EFAULT; } EXPORT_SYMBOL(get_vaddr_frames); diff -Nru linux-6.0.6/drivers/media/dvb-frontends/drxk_hard.c linux-6.0.12/drivers/media/dvb-frontends/drxk_hard.c --- linux-6.0.6/drivers/media/dvb-frontends/drxk_hard.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/dvb-frontends/drxk_hard.c 2023-01-18 18:27:39.000000000 +0000 @@ -6660,7 +6660,7 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct drxk_state *state = fe->demodulator_priv; - u16 err; + u16 err = 0; dprintk(1, "\n"); diff -Nru linux-6.0.6/drivers/media/i2c/ar0521.c linux-6.0.12/drivers/media/i2c/ar0521.c --- linux-6.0.6/drivers/media/i2c/ar0521.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/i2c/ar0521.c 2023-01-18 18:27:39.000000000 +0000 @@ -756,10 +756,12 @@ gpiod_set_value(sensor->reset_gpio, 0); usleep_range(4500, 5000); /* min 45000 clocks */ - for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) - if (ar0521_write_regs(sensor, initial_regs[cnt].data, - initial_regs[cnt].count)) + for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) { + ret = ar0521_write_regs(sensor, initial_regs[cnt].data, + initial_regs[cnt].count); + if (ret) goto off; + } ret = ar0521_write_reg(sensor, AR0521_REG_SERIAL_FORMAT, AR0521_REG_SERIAL_FORMAT_MIPI | diff -Nru linux-6.0.6/drivers/media/i2c/ov8865.c linux-6.0.12/drivers/media/i2c/ov8865.c --- linux-6.0.6/drivers/media/i2c/ov8865.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/i2c/ov8865.c 2023-01-18 18:27:39.000000000 +0000 @@ -3034,11 +3034,13 @@ &rate); if (!ret && sensor->extclk) { ret = clk_set_rate(sensor->extclk, rate); - if (ret) - return dev_err_probe(dev, ret, - "failed to set clock rate\n"); + if (ret) { + dev_err_probe(dev, ret, "failed to set clock rate\n"); + goto error_endpoint; + } } else if (ret && !sensor->extclk) { - return dev_err_probe(dev, ret, "invalid clock config\n"); + dev_err_probe(dev, ret, "invalid clock config\n"); + goto error_endpoint; } sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk); diff -Nru linux-6.0.6/drivers/media/platform/amphion/vpu_v4l2.c linux-6.0.12/drivers/media/platform/amphion/vpu_v4l2.c --- linux-6.0.6/drivers/media/platform/amphion/vpu_v4l2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/amphion/vpu_v4l2.c 2023-01-18 18:27:39.000000000 +0000 @@ -603,6 +603,10 @@ inst->workqueue = NULL; } + if (inst->fh.m2m_ctx) { + v4l2_m2m_ctx_release(inst->fh.m2m_ctx); + inst->fh.m2m_ctx = NULL; + } v4l2_ctrl_handler_free(&inst->ctrl_handler); mutex_destroy(&inst->lock); v4l2_fh_del(&inst->fh); @@ -685,13 +689,6 @@ vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n", inst->tgid, inst->pid, inst); - vpu_inst_lock(inst); - if (inst->fh.m2m_ctx) { - v4l2_m2m_ctx_release(inst->fh.m2m_ctx); - inst->fh.m2m_ctx = NULL; - } - vpu_inst_unlock(inst); - call_void_vop(inst, release); vpu_inst_unregister(inst); vpu_inst_put(inst); diff -Nru linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c --- linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c 2023-01-18 18:27:39.000000000 +0000 @@ -1273,11 +1273,12 @@ struct rkisp1_capture *cap = video_get_drvdata(vdev); const struct rkisp1_capture_fmt_cfg *fmt = rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat); - struct v4l2_subdev_format sd_fmt; + struct v4l2_subdev_format sd_fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = link->source->index, + }; int ret; - sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; - sd_fmt.pad = link->source->index; ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt); if (ret) return ret; diff -Nru linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c --- linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c 2023-01-18 18:27:39.000000000 +0000 @@ -472,23 +472,43 @@ struct v4l2_mbus_framefmt *format, unsigned int which) { - const struct rkisp1_mbus_info *mbus_info; + const struct rkisp1_mbus_info *sink_info; + const struct rkisp1_mbus_info *src_info; + struct v4l2_mbus_framefmt *sink_fmt; struct v4l2_mbus_framefmt *src_fmt; const struct v4l2_rect *src_crop; + sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, + RKISP1_ISP_PAD_SINK_VIDEO, which); src_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO, which); src_crop = rkisp1_isp_get_pad_crop(isp, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO, which); + /* + * Media bus code. The ISP can operate in pass-through mode (Bayer in, + * Bayer out or YUV in, YUV out) or process Bayer data to YUV, but + * can't convert from YUV to Bayer. + */ + sink_info = rkisp1_mbus_info_get_by_code(sink_fmt->code); + src_fmt->code = format->code; - mbus_info = rkisp1_mbus_info_get_by_code(src_fmt->code); - if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) { + src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); + if (!src_info || !(src_info->direction & RKISP1_ISP_SD_SRC)) { src_fmt->code = RKISP1_DEF_SRC_PAD_FMT; - mbus_info = rkisp1_mbus_info_get_by_code(src_fmt->code); + src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); } - if (which == V4L2_SUBDEV_FORMAT_ACTIVE) - isp->src_fmt = mbus_info; + + if (sink_info->pixel_enc == V4L2_PIXEL_ENC_YUV && + src_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) { + src_fmt->code = sink_fmt->code; + src_info = sink_info; + } + + /* + * The source width and height must be identical to the source crop + * size. + */ src_fmt->width = src_crop->width; src_fmt->height = src_crop->height; @@ -498,14 +518,18 @@ */ if (format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC && format->quantization == V4L2_QUANTIZATION_FULL_RANGE && - mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV) + src_info->pixel_enc == V4L2_PIXEL_ENC_YUV) src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; - else if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV) + else if (src_info->pixel_enc == V4L2_PIXEL_ENC_YUV) src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE; else src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; *format = *src_fmt; + + /* Store the source format info when setting the active format. */ + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) + isp->src_fmt = src_info; } static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp, diff -Nru linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c --- linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c 2023-01-18 18:27:39.000000000 +0000 @@ -343,7 +343,7 @@ RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4, data); /* program x grad tables */ - data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2], + data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->x_grad_tbl[i * 2], arg->x_grad_tbl[i * 2 + 1]); rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4, data); @@ -355,7 +355,7 @@ RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4, data); /* program y grad tables */ - data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2], + data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->y_grad_tbl[i * 2], arg->y_grad_tbl[i * 2 + 1]); rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4, data); @@ -1066,7 +1066,7 @@ } } -static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range) +static void rkisp1_csm_config(struct rkisp1_params *params) { static const u16 full_range_coeff[] = { 0x0026, 0x004b, 0x000f, @@ -1080,7 +1080,7 @@ }; unsigned int i; - if (full_range) { + if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) { for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++) rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CC_COEFF_0 + i * 4, @@ -1552,11 +1552,7 @@ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10, rkisp1_hst_params_default_config.mode); - /* set the range */ - if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) - rkisp1_csm_config(params, true); - else - rkisp1_csm_config(params, false); + rkisp1_csm_config(params); spin_lock_irq(¶ms->config_lock); diff -Nru linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h --- linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h 2023-01-18 18:27:39.000000000 +0000 @@ -576,7 +576,7 @@ (((v0) & 0x1FFF) | (((v1) & 0x1FFF) << 13)) #define RKISP1_CIF_ISP_LSC_SECT_SIZE(v0, v1) \ (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16)) -#define RKISP1_CIF_ISP_LSC_GRAD_SIZE(v0, v1) \ +#define RKISP1_CIF_ISP_LSC_SECT_GRAD(v0, v1) \ (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16)) /* LSC: ISP_LSC_TABLE_SEL */ diff -Nru linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c --- linux-6.0.6/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c 2023-01-18 18:27:39.000000000 +0000 @@ -411,6 +411,10 @@ sink_fmt->height = RKISP1_DEFAULT_HEIGHT; sink_fmt->field = V4L2_FIELD_NONE; sink_fmt->code = RKISP1_DEF_FMT; + sink_fmt->colorspace = V4L2_COLORSPACE_SRGB; + sink_fmt->xfer_func = V4L2_XFER_FUNC_SRGB; + sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601; + sink_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE; sink_crop = v4l2_subdev_get_try_crop(sd, sd_state, RKISP1_RSZ_PAD_SINK); diff -Nru linux-6.0.6/drivers/media/platform/sunxi/sun4i-csi/Kconfig linux-6.0.12/drivers/media/platform/sunxi/sun4i-csi/Kconfig --- linux-6.0.6/drivers/media/platform/sunxi/sun4i-csi/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/sunxi/sun4i-csi/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -3,7 +3,7 @@ config VIDEO_SUN4I_CSI tristate "Allwinner A10 CMOS Sensor Interface Support" depends on V4L_PLATFORM_DRIVERS - depends on VIDEO_DEV && COMMON_CLK && HAS_DMA + depends on VIDEO_DEV && COMMON_CLK && RESET_CONTROLLER && HAS_DMA depends on ARCH_SUNXI || COMPILE_TEST select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API diff -Nru linux-6.0.6/drivers/media/platform/sunxi/sun6i-csi/Kconfig linux-6.0.12/drivers/media/platform/sunxi/sun6i-csi/Kconfig --- linux-6.0.6/drivers/media/platform/sunxi/sun6i-csi/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/sunxi/sun6i-csi/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -2,7 +2,7 @@ config VIDEO_SUN6I_CSI tristate "Allwinner V3s Camera Sensor Interface driver" depends on V4L_PLATFORM_DRIVERS - depends on VIDEO_DEV && COMMON_CLK && HAS_DMA + depends on VIDEO_DEV && COMMON_CLK && RESET_CONTROLLER && HAS_DMA depends on ARCH_SUNXI || COMPILE_TEST select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API diff -Nru linux-6.0.6/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig linux-6.0.12/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig --- linux-6.0.6/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -3,11 +3,11 @@ tristate "Allwinner A31 MIPI CSI-2 Controller Driver" depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV depends on ARCH_SUNXI || COMPILE_TEST - depends on PM && COMMON_CLK + depends on PM && COMMON_CLK && RESET_CONTROLLER + depends on PHY_SUN6I_MIPI_DPHY select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API select V4L2_FWNODE - select PHY_SUN6I_MIPI_DPHY select GENERIC_PHY_MIPI_DPHY select REGMAP_MMIO help diff -Nru linux-6.0.6/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c linux-6.0.12/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c --- linux-6.0.6/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c 2023-01-18 18:27:39.000000000 +0000 @@ -661,7 +661,8 @@ csi2_dev->reset = devm_reset_control_get_shared(dev, NULL); if (IS_ERR(csi2_dev->reset)) { dev_err(dev, "failed to get reset controller\n"); - return PTR_ERR(csi2_dev->reset); + ret = PTR_ERR(csi2_dev->reset); + goto error_clock_rate_exclusive; } /* D-PHY */ @@ -669,13 +670,14 @@ csi2_dev->dphy = devm_phy_get(dev, "dphy"); if (IS_ERR(csi2_dev->dphy)) { dev_err(dev, "failed to get MIPI D-PHY\n"); - return PTR_ERR(csi2_dev->dphy); + ret = PTR_ERR(csi2_dev->dphy); + goto error_clock_rate_exclusive; } ret = phy_init(csi2_dev->dphy); if (ret) { dev_err(dev, "failed to initialize MIPI D-PHY\n"); - return ret; + goto error_clock_rate_exclusive; } /* Runtime PM */ @@ -683,6 +685,11 @@ pm_runtime_enable(dev); return 0; + +error_clock_rate_exclusive: + clk_rate_exclusive_put(csi2_dev->clock_mod); + + return ret; } static void @@ -712,9 +719,14 @@ ret = sun6i_mipi_csi2_bridge_setup(csi2_dev); if (ret) - return ret; + goto error_resources; return 0; + +error_resources: + sun6i_mipi_csi2_resources_cleanup(csi2_dev); + + return ret; } static int sun6i_mipi_csi2_remove(struct platform_device *platform_dev) diff -Nru linux-6.0.6/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig linux-6.0.12/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig --- linux-6.0.6/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -3,7 +3,7 @@ tristate "Allwinner A83T MIPI CSI-2 Controller and D-PHY Driver" depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV depends on ARCH_SUNXI || COMPILE_TEST - depends on PM && COMMON_CLK + depends on PM && COMMON_CLK && RESET_CONTROLLER select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API select V4L2_FWNODE diff -Nru linux-6.0.6/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c linux-6.0.12/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c --- linux-6.0.6/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c 2023-01-18 18:27:39.000000000 +0000 @@ -719,13 +719,15 @@ csi2_dev->clock_mipi = devm_clk_get(dev, "mipi"); if (IS_ERR(csi2_dev->clock_mipi)) { dev_err(dev, "failed to acquire mipi clock\n"); - return PTR_ERR(csi2_dev->clock_mipi); + ret = PTR_ERR(csi2_dev->clock_mipi); + goto error_clock_rate_exclusive; } csi2_dev->clock_misc = devm_clk_get(dev, "misc"); if (IS_ERR(csi2_dev->clock_misc)) { dev_err(dev, "failed to acquire misc clock\n"); - return PTR_ERR(csi2_dev->clock_misc); + ret = PTR_ERR(csi2_dev->clock_misc); + goto error_clock_rate_exclusive; } /* Reset */ @@ -733,7 +735,8 @@ csi2_dev->reset = devm_reset_control_get_shared(dev, NULL); if (IS_ERR(csi2_dev->reset)) { dev_err(dev, "failed to get reset controller\n"); - return PTR_ERR(csi2_dev->reset); + ret = PTR_ERR(csi2_dev->reset); + goto error_clock_rate_exclusive; } /* D-PHY */ @@ -741,7 +744,7 @@ ret = sun8i_a83t_dphy_register(csi2_dev); if (ret) { dev_err(dev, "failed to initialize MIPI D-PHY\n"); - return ret; + goto error_clock_rate_exclusive; } /* Runtime PM */ @@ -749,6 +752,11 @@ pm_runtime_enable(dev); return 0; + +error_clock_rate_exclusive: + clk_rate_exclusive_put(csi2_dev->clock_mod); + + return ret; } static void @@ -778,9 +786,14 @@ ret = sun8i_a83t_mipi_csi2_bridge_setup(csi2_dev); if (ret) - return ret; + goto error_resources; return 0; + +error_resources: + sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev); + + return ret; } static int sun8i_a83t_mipi_csi2_remove(struct platform_device *platform_dev) diff -Nru linux-6.0.6/drivers/media/platform/sunxi/sun8i-di/Kconfig linux-6.0.12/drivers/media/platform/sunxi/sun8i-di/Kconfig --- linux-6.0.6/drivers/media/platform/sunxi/sun8i-di/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/sunxi/sun8i-di/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -4,7 +4,7 @@ depends on V4L_MEM2MEM_DRIVERS depends on VIDEO_DEV depends on ARCH_SUNXI || COMPILE_TEST - depends on COMMON_CLK && OF + depends on COMMON_CLK && RESET_CONTROLLER && OF depends on PM select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV diff -Nru linux-6.0.6/drivers/media/platform/sunxi/sun8i-rotate/Kconfig linux-6.0.12/drivers/media/platform/sunxi/sun8i-rotate/Kconfig --- linux-6.0.6/drivers/media/platform/sunxi/sun8i-rotate/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/platform/sunxi/sun8i-rotate/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -5,7 +5,7 @@ depends on V4L_MEM2MEM_DRIVERS depends on VIDEO_DEV depends on ARCH_SUNXI || COMPILE_TEST - depends on COMMON_CLK && OF + depends on COMMON_CLK && RESET_CONTROLLER && OF depends on PM select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV diff -Nru linux-6.0.6/drivers/media/test-drivers/vivid/vivid-core.c linux-6.0.12/drivers/media/test-drivers/vivid/vivid-core.c --- linux-6.0.6/drivers/media/test-drivers/vivid/vivid-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/test-drivers/vivid/vivid-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -339,6 +339,28 @@ return vivid_vid_out_g_fbuf(file, fh, a); } +/* + * Only support the framebuffer of one of the vivid instances. + * Anything else is rejected. + */ +bool vivid_validate_fb(const struct v4l2_framebuffer *a) +{ + struct vivid_dev *dev; + int i; + + for (i = 0; i < n_devs; i++) { + dev = vivid_devs[i]; + if (!dev || !dev->video_pbase) + continue; + if ((unsigned long)a->base == dev->video_pbase && + a->fmt.width <= dev->display_width && + a->fmt.height <= dev->display_height && + a->fmt.bytesperline <= dev->display_byte_stride) + return true; + } + return false; +} + static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a) { struct video_device *vdev = video_devdata(file); @@ -920,8 +942,12 @@ /* how many inputs do we have and of what type? */ dev->num_inputs = num_inputs[inst]; - if (dev->num_inputs < 1) - dev->num_inputs = 1; + if (node_type & 0x20007) { + if (dev->num_inputs < 1) + dev->num_inputs = 1; + } else { + dev->num_inputs = 0; + } if (dev->num_inputs >= MAX_INPUTS) dev->num_inputs = MAX_INPUTS; for (i = 0; i < dev->num_inputs; i++) { @@ -938,8 +964,12 @@ /* how many outputs do we have and of what type? */ dev->num_outputs = num_outputs[inst]; - if (dev->num_outputs < 1) - dev->num_outputs = 1; + if (node_type & 0x40300) { + if (dev->num_outputs < 1) + dev->num_outputs = 1; + } else { + dev->num_outputs = 0; + } if (dev->num_outputs >= MAX_OUTPUTS) dev->num_outputs = MAX_OUTPUTS; for (i = 0; i < dev->num_outputs; i++) { diff -Nru linux-6.0.6/drivers/media/test-drivers/vivid/vivid-core.h linux-6.0.12/drivers/media/test-drivers/vivid/vivid-core.h --- linux-6.0.6/drivers/media/test-drivers/vivid/vivid-core.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/test-drivers/vivid/vivid-core.h 2023-01-18 18:27:39.000000000 +0000 @@ -610,4 +610,6 @@ return dev->output_type[dev->output] == HDMI; } +bool vivid_validate_fb(const struct v4l2_framebuffer *a); + #endif diff -Nru linux-6.0.6/drivers/media/test-drivers/vivid/vivid-vid-cap.c linux-6.0.12/drivers/media/test-drivers/vivid/vivid-vid-cap.c --- linux-6.0.6/drivers/media/test-drivers/vivid/vivid-vid-cap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/test-drivers/vivid/vivid-vid-cap.c 2023-01-18 18:27:39.000000000 +0000 @@ -452,6 +452,12 @@ tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap); dev->crop_cap = dev->src_rect; dev->crop_bounds_cap = dev->src_rect; + if (dev->bitmap_cap && + (dev->compose_cap.width != dev->crop_cap.width || + dev->compose_cap.height != dev->crop_cap.height)) { + vfree(dev->bitmap_cap); + dev->bitmap_cap = NULL; + } dev->compose_cap = dev->crop_cap; if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap)) dev->compose_cap.height /= 2; @@ -909,6 +915,8 @@ struct vivid_dev *dev = video_drvdata(file); struct v4l2_rect *crop = &dev->crop_cap; struct v4l2_rect *compose = &dev->compose_cap; + unsigned orig_compose_w = compose->width; + unsigned orig_compose_h = compose->height; unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; int ret; @@ -1025,17 +1033,17 @@ s->r.height /= factor; } v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect); - if (dev->bitmap_cap && (compose->width != s->r.width || - compose->height != s->r.height)) { - vfree(dev->bitmap_cap); - dev->bitmap_cap = NULL; - } *compose = s->r; break; default: return -EINVAL; } + if (dev->bitmap_cap && (compose->width != orig_compose_w || + compose->height != orig_compose_h)) { + vfree(dev->bitmap_cap); + dev->bitmap_cap = NULL; + } tpg_s_crop_compose(&dev->tpg, crop, compose); return 0; } @@ -1272,7 +1280,14 @@ return -EINVAL; if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8) return -EINVAL; - if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage) + if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height) + return -EINVAL; + + /* + * Only support the framebuffer of one of the vivid instances. + * Anything else is rejected. + */ + if (!vivid_validate_fb(a)) return -EINVAL; dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base); diff -Nru linux-6.0.6/drivers/media/v4l2-core/v4l2-dv-timings.c linux-6.0.12/drivers/media/v4l2-core/v4l2-dv-timings.c --- linux-6.0.6/drivers/media/v4l2-core/v4l2-dv-timings.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/media/v4l2-core/v4l2-dv-timings.c 2023-01-18 18:27:39.000000000 +0000 @@ -161,6 +161,20 @@ (bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) || (!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE))) return false; + + /* sanity checks for the blanking timings */ + if (!bt->interlaced && + (bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch)) + return false; + if (bt->hfrontporch > 2 * bt->width || + bt->hsync > 1024 || bt->hbackporch > 1024) + return false; + if (bt->vfrontporch > 4096 || + bt->vsync > 128 || bt->vbackporch > 4096) + return false; + if (bt->interlaced && (bt->il_vfrontporch > 4096 || + bt->il_vsync > 128 || bt->il_vbackporch > 4096)) + return false; return fnc == NULL || fnc(t, fnc_handle); } EXPORT_SYMBOL_GPL(v4l2_valid_dv_timings); diff -Nru linux-6.0.6/drivers/misc/vmw_vmci/vmci_queue_pair.c linux-6.0.12/drivers/misc/vmw_vmci/vmci_queue_pair.c --- linux-6.0.6/drivers/misc/vmw_vmci/vmci_queue_pair.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/misc/vmw_vmci/vmci_queue_pair.c 2023-01-18 18:27:39.000000000 +0000 @@ -854,6 +854,7 @@ u32 context_id = vmci_get_context_id(); struct vmci_event_qp ev; + memset(&ev, 0, sizeof(ev)); ev.msg.hdr.dst = vmci_make_handle(context_id, VMCI_EVENT_HANDLER); ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); @@ -1467,6 +1468,7 @@ * kernel. */ + memset(&ev, 0, sizeof(ev)); ev.msg.hdr.dst = vmci_make_handle(peer_id, VMCI_EVENT_HANDLER); ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); diff -Nru linux-6.0.6/drivers/mmc/core/block.c linux-6.0.12/drivers/mmc/core/block.c --- linux-6.0.6/drivers/mmc/core/block.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/core/block.c 2023-01-18 18:27:39.000000000 +0000 @@ -134,6 +134,7 @@ * track of the current selected device partition. */ unsigned int part_curr; +#define MMC_BLK_PART_INVALID UINT_MAX /* Unknown partition active */ int area_type; /* debugfs files (only in main mmc_blk_data) */ @@ -987,33 +988,39 @@ return ms; } +/* + * Attempts to reset the card and get back to the requested partition. + * Therefore any error here must result in cancelling the block layer + * request, it must not be reattempted without going through the mmc_blk + * partition sanity checks. + */ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host, int type) { int err; + struct mmc_blk_data *main_md = dev_get_drvdata(&host->card->dev); if (md->reset_done & type) return -EEXIST; md->reset_done |= type; err = mmc_hw_reset(host->card); + /* + * A successful reset will leave the card in the main partition, but + * upon failure it might not be, so set it to MMC_BLK_PART_INVALID + * in that case. + */ + main_md->part_curr = err ? MMC_BLK_PART_INVALID : main_md->part_type; + if (err) + return err; /* Ensure we switch back to the correct partition */ - if (err) { - struct mmc_blk_data *main_md = - dev_get_drvdata(&host->card->dev); - int part_err; - - main_md->part_curr = main_md->part_type; - part_err = mmc_blk_part_switch(host->card, md->part_type); - if (part_err) { - /* - * We have failed to get back into the correct - * partition, so we need to abort the whole request. - */ - return -ENODEV; - } - } - return err; + if (mmc_blk_part_switch(host->card, md->part_type)) + /* + * We have failed to get back into the correct + * partition, so we need to abort the whole request. + */ + return -ENODEV; + return 0; } static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type) @@ -1871,8 +1878,9 @@ return; /* Reset before last retry */ - if (mqrq->retries + 1 == MMC_MAX_RETRIES) - mmc_blk_reset(md, card->host, type); + if (mqrq->retries + 1 == MMC_MAX_RETRIES && + mmc_blk_reset(md, card->host, type)) + return; /* Command errors fail fast, so use all MMC_MAX_RETRIES */ if (brq->sbc.error || brq->cmd.error) diff -Nru linux-6.0.6/drivers/mmc/core/core.c linux-6.0.12/drivers/mmc/core/core.c --- linux-6.0.6/drivers/mmc/core/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/core/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -1134,7 +1134,13 @@ mmc_power_cycle(host, ocr); } else { bit = fls(ocr) - 1; - ocr &= 3 << bit; + /* + * The bit variable represents the highest voltage bit set in + * the OCR register. + * To keep a range of 2 values (e.g. 3.2V/3.3V and 3.3V/3.4V), + * we must shift the mask '3' with (bit - 1). + */ + ocr &= 3 << (bit - 1); if (bit != host->ios.vdd) dev_warn(mmc_dev(host), "exceeding card's volts\n"); } @@ -1478,6 +1484,11 @@ card->pref_erase = 0; } +static bool is_trim_arg(unsigned int arg) +{ + return (arg & MMC_TRIM_OR_DISCARD_ARGS) && arg != MMC_DISCARD_ARG; +} + static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, unsigned int arg, unsigned int qty) { @@ -1760,7 +1771,7 @@ !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) return -EOPNOTSUPP; - if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) && + if (mmc_card_mmc(card) && is_trim_arg(arg) && !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) return -EOPNOTSUPP; @@ -1790,7 +1801,7 @@ * identified by the card->eg_boundary flag. */ rem = card->erase_size - (from % card->erase_size); - if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && (nr > rem)) { + if ((arg & MMC_TRIM_OR_DISCARD_ARGS) && card->eg_boundary && nr > rem) { err = mmc_do_erase(card, from, from + rem - 1, arg); from += rem; if ((err) || (to <= from)) diff -Nru linux-6.0.6/drivers/mmc/core/mmc_test.c linux-6.0.12/drivers/mmc/core/mmc_test.c --- linux-6.0.6/drivers/mmc/core/mmc_test.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/core/mmc_test.c 2023-01-18 18:27:39.000000000 +0000 @@ -3179,7 +3179,8 @@ struct mmc_test_dbgfs_file *df; if (card->debugfs_root) - debugfs_create_file(name, mode, card->debugfs_root, card, fops); + file = debugfs_create_file(name, mode, card->debugfs_root, + card, fops); df = kmalloc(sizeof(*df), GFP_KERNEL); if (!df) { diff -Nru linux-6.0.6/drivers/mmc/core/queue.c linux-6.0.12/drivers/mmc/core/queue.c --- linux-6.0.6/drivers/mmc/core/queue.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/core/queue.c 2023-01-18 18:27:39.000000000 +0000 @@ -48,6 +48,7 @@ case REQ_OP_DRV_OUT: case REQ_OP_DISCARD: case REQ_OP_SECURE_ERASE: + case REQ_OP_WRITE_ZEROES: return MMC_ISSUE_SYNC; case REQ_OP_FLUSH: return mmc_cqe_can_dcmd(host) ? MMC_ISSUE_DCMD : MMC_ISSUE_SYNC; @@ -493,6 +494,13 @@ if (blk_queue_quiesced(q)) blk_mq_unquiesce_queue(q); + /* + * If the recovery completes the last (and only remaining) request in + * the queue, and the card has been removed, we could end up here with + * the recovery not quite finished yet, so cancel it. + */ + cancel_work_sync(&mq->recovery_work); + blk_mq_free_tag_set(&mq->tag_set); /* diff -Nru linux-6.0.6/drivers/mmc/core/sdio_bus.c linux-6.0.12/drivers/mmc/core/sdio_bus.c --- linux-6.0.6/drivers/mmc/core/sdio_bus.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/core/sdio_bus.c 2023-01-18 18:27:39.000000000 +0000 @@ -291,7 +291,8 @@ { struct sdio_func *func = dev_to_sdio_func(dev); - sdio_free_func_cis(func); + if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO)) + sdio_free_func_cis(func); kfree(func->info); kfree(func->tmpbuf); diff -Nru linux-6.0.6/drivers/mmc/host/Kconfig linux-6.0.12/drivers/mmc/host/Kconfig --- linux-6.0.6/drivers/mmc/host/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -1074,9 +1074,10 @@ config MMC_SDHCI_AM654 tristate "Support for the SDHCI Controller in TI's AM654 SOCs" - depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO + depends on MMC_SDHCI_PLTFM && OF select MMC_SDHCI_IO_ACCESSORS select MMC_CQHCI + select REGMAP_MMIO help This selects the Secure Digital Host Controller Interface (SDHCI) support present in TI's AM654 SOCs. The controller supports diff -Nru linux-6.0.6/drivers/mmc/host/mtk-sd.c linux-6.0.12/drivers/mmc/host/mtk-sd.c --- linux-6.0.6/drivers/mmc/host/mtk-sd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/mtk-sd.c 2023-01-18 18:27:39.000000000 +0000 @@ -2573,13 +2573,11 @@ return PTR_ERR(host->src_clk_cg); } - host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg"); + /* If present, always enable for this clock gate */ + host->sys_clk_cg = devm_clk_get_optional_enabled(&pdev->dev, "sys_cg"); if (IS_ERR(host->sys_clk_cg)) host->sys_clk_cg = NULL; - /* If present, always enable for this clock gate */ - clk_prepare_enable(host->sys_clk_cg); - host->bulk_clks[0].id = "pclk_cg"; host->bulk_clks[1].id = "axi_cg"; host->bulk_clks[2].id = "ahb_cg"; diff -Nru linux-6.0.6/drivers/mmc/host/sdhci_am654.c linux-6.0.12/drivers/mmc/host/sdhci_am654.c --- linux-6.0.6/drivers/mmc/host/sdhci_am654.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci_am654.c 2023-01-18 18:27:39.000000000 +0000 @@ -15,6 +15,7 @@ #include #include "cqhci.h" +#include "sdhci-cqhci.h" #include "sdhci-pltfm.h" /* CTL_CFG Registers */ @@ -378,7 +379,7 @@ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); - sdhci_reset(host, mask); + sdhci_and_cqhci_reset(host, mask); if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) { ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); @@ -464,7 +465,7 @@ .set_clock = sdhci_am654_set_clock, .write_b = sdhci_am654_write_b, .irq = sdhci_am654_cqhci_irq, - .reset = sdhci_reset, + .reset = sdhci_and_cqhci_reset, }; static const struct sdhci_pltfm_data sdhci_am654_pdata = { @@ -494,7 +495,7 @@ .set_clock = sdhci_am654_set_clock, .write_b = sdhci_am654_write_b, .irq = sdhci_am654_cqhci_irq, - .reset = sdhci_reset, + .reset = sdhci_and_cqhci_reset, }; static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = { diff -Nru linux-6.0.6/drivers/mmc/host/sdhci-brcmstb.c linux-6.0.12/drivers/mmc/host/sdhci-brcmstb.c --- linux-6.0.6/drivers/mmc/host/sdhci-brcmstb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci-brcmstb.c 2023-01-18 18:27:39.000000000 +0000 @@ -12,6 +12,7 @@ #include #include +#include "sdhci-cqhci.h" #include "sdhci-pltfm.h" #include "cqhci.h" @@ -55,7 +56,7 @@ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host); - sdhci_reset(host, mask); + sdhci_and_cqhci_reset(host, mask); /* Reset will clear this, so re-enable it */ if (priv->flags & BRCMSTB_PRIV_FLAGS_GATE_CLOCK) diff -Nru linux-6.0.6/drivers/mmc/host/sdhci.c linux-6.0.12/drivers/mmc/host/sdhci.c --- linux-6.0.6/drivers/mmc/host/sdhci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci.c 2023-01-18 18:27:39.000000000 +0000 @@ -339,6 +339,7 @@ if (soft) { /* force clock reconfiguration */ host->clock = 0; + host->reinit_uhs = true; mmc->ops->set_ios(mmc, &mmc->ios); } } @@ -2258,11 +2259,46 @@ } EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling); +static bool sdhci_timing_has_preset(unsigned char timing) +{ + switch (timing) { + case MMC_TIMING_UHS_SDR12: + case MMC_TIMING_UHS_SDR25: + case MMC_TIMING_UHS_SDR50: + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_UHS_DDR50: + case MMC_TIMING_MMC_DDR52: + return true; + }; + return false; +} + +static bool sdhci_preset_needed(struct sdhci_host *host, unsigned char timing) +{ + return !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && + sdhci_timing_has_preset(timing); +} + +static bool sdhci_presetable_values_change(struct sdhci_host *host, struct mmc_ios *ios) +{ + /* + * Preset Values are: Driver Strength, Clock Generator and SDCLK/RCLK + * Frequency. Check if preset values need to be enabled, or the Driver + * Strength needs updating. Note, clock changes are handled separately. + */ + return !host->preset_enabled && + (sdhci_preset_needed(host, ios->timing) || host->drv_type != ios->drv_type); +} + void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct sdhci_host *host = mmc_priv(mmc); + bool reinit_uhs = host->reinit_uhs; + bool turning_on_clk = false; u8 ctrl; + host->reinit_uhs = false; + if (ios->power_mode == MMC_POWER_UNDEFINED) return; @@ -2288,6 +2324,8 @@ sdhci_enable_preset_value(host, false); if (!ios->clock || ios->clock != host->clock) { + turning_on_clk = ios->clock && !host->clock; + host->ops->set_clock(host, ios->clock); host->clock = ios->clock; @@ -2314,6 +2352,17 @@ host->ops->set_bus_width(host, ios->bus_width); + /* + * Special case to avoid multiple clock changes during voltage + * switching. + */ + if (!reinit_uhs && + turning_on_clk && + host->timing == ios->timing && + host->version >= SDHCI_SPEC_300 && + !sdhci_presetable_values_change(host, ios)) + return; + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) { @@ -2357,6 +2406,7 @@ } sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); + host->drv_type = ios->drv_type; } else { /* * According to SDHC Spec v3.00, if the Preset Value @@ -2384,19 +2434,14 @@ host->ops->set_uhs_signaling(host, ios->timing); host->timing = ios->timing; - if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && - ((ios->timing == MMC_TIMING_UHS_SDR12) || - (ios->timing == MMC_TIMING_UHS_SDR25) || - (ios->timing == MMC_TIMING_UHS_SDR50) || - (ios->timing == MMC_TIMING_UHS_SDR104) || - (ios->timing == MMC_TIMING_UHS_DDR50) || - (ios->timing == MMC_TIMING_MMC_DDR52))) { + if (sdhci_preset_needed(host, ios->timing)) { u16 preset; sdhci_enable_preset_value(host, true); preset = sdhci_get_preset_value(host); ios->drv_type = FIELD_GET(SDHCI_PRESET_DRV_MASK, preset); + host->drv_type = ios->drv_type; } /* Re-enable SD Clock */ @@ -3748,6 +3793,7 @@ sdhci_init(host, 0); host->pwr = 0; host->clock = 0; + host->reinit_uhs = true; mmc->ops->set_ios(mmc, &mmc->ios); } else { sdhci_init(host, (mmc->pm_flags & MMC_PM_KEEP_POWER)); @@ -3810,6 +3856,7 @@ /* Force clock and power re-program */ host->pwr = 0; host->clock = 0; + host->reinit_uhs = true; mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios); mmc->ops->set_ios(mmc, &mmc->ios); diff -Nru linux-6.0.6/drivers/mmc/host/sdhci-cqhci.h linux-6.0.12/drivers/mmc/host/sdhci-cqhci.h --- linux-6.0.6/drivers/mmc/host/sdhci-cqhci.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci-cqhci.h 2023-01-18 18:27:39.000000000 +0000 @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2022 The Chromium OS Authors + * + * Support that applies to the combination of SDHCI and CQHCI, while not + * expressing a dependency between the two modules. + */ + +#ifndef __MMC_HOST_SDHCI_CQHCI_H__ +#define __MMC_HOST_SDHCI_CQHCI_H__ + +#include "cqhci.h" +#include "sdhci.h" + +static inline void sdhci_and_cqhci_reset(struct sdhci_host *host, u8 mask) +{ + if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) && + host->mmc->cqe_private) + cqhci_deactivate(host->mmc); + + sdhci_reset(host, mask); +} + +#endif /* __MMC_HOST_SDHCI_CQHCI_H__ */ diff -Nru linux-6.0.6/drivers/mmc/host/sdhci-esdhc-imx.c linux-6.0.12/drivers/mmc/host/sdhci-esdhc-imx.c --- linux-6.0.6/drivers/mmc/host/sdhci-esdhc-imx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci-esdhc-imx.c 2023-01-18 18:27:39.000000000 +0000 @@ -25,6 +25,7 @@ #include #include #include +#include "sdhci-cqhci.h" #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" #include "cqhci.h" @@ -1288,7 +1289,7 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask) { - sdhci_reset(host, mask); + sdhci_and_cqhci_reset(host, mask); sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); @@ -1511,7 +1512,7 @@ * system resume back. */ cqhci_writel(cq_host, 0, CQHCI_CTL); - if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT) + if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) dev_err(mmc_dev(host->mmc), "failed to exit halt state when enable CQE\n"); @@ -1660,6 +1661,10 @@ host->mmc_host_ops.execute_tuning = usdhc_execute_tuning; } + err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data); + if (err) + goto disable_ahb_clk; + if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) sdhci_esdhc_ops.platform_execute_tuning = esdhc_executing_tuning; @@ -1667,13 +1672,15 @@ if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; - if (imx_data->socdata->flags & ESDHC_FLAG_HS400) + if (host->mmc->caps & MMC_CAP_8_BIT_DATA && + imx_data->socdata->flags & ESDHC_FLAG_HS400) host->mmc->caps2 |= MMC_CAP2_HS400; if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23) host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN; - if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) { + if (host->mmc->caps & MMC_CAP_8_BIT_DATA && + imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) { host->mmc->caps2 |= MMC_CAP2_HS400_ES; host->mmc_host_ops.hs400_enhanced_strobe = esdhc_hs400_enhanced_strobe; @@ -1695,10 +1702,6 @@ goto disable_ahb_clk; } - err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data); - if (err) - goto disable_ahb_clk; - sdhci_esdhc_imx_hwinit(host); err = sdhci_add_host(host); diff -Nru linux-6.0.6/drivers/mmc/host/sdhci.h linux-6.0.12/drivers/mmc/host/sdhci.h --- linux-6.0.6/drivers/mmc/host/sdhci.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci.h 2023-01-18 18:27:39.000000000 +0000 @@ -526,6 +526,8 @@ unsigned int clock; /* Current clock (MHz) */ u8 pwr; /* Current voltage */ + u8 drv_type; /* Current UHS-I driver type */ + bool reinit_uhs; /* Force UHS-related re-initialization */ bool runtime_suspended; /* Host is runtime suspended */ bool bus_on; /* Bus power prevents runtime suspend */ diff -Nru linux-6.0.6/drivers/mmc/host/sdhci-of-arasan.c linux-6.0.12/drivers/mmc/host/sdhci-of-arasan.c --- linux-6.0.6/drivers/mmc/host/sdhci-of-arasan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci-of-arasan.c 2023-01-18 18:27:39.000000000 +0000 @@ -25,6 +25,7 @@ #include #include "cqhci.h" +#include "sdhci-cqhci.h" #include "sdhci-pltfm.h" #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 @@ -366,7 +367,7 @@ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); - sdhci_reset(host, mask); + sdhci_and_cqhci_reset(host, mask); if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) { ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); diff -Nru linux-6.0.6/drivers/mmc/host/sdhci-pci-core.c linux-6.0.12/drivers/mmc/host/sdhci-pci-core.c --- linux-6.0.6/drivers/mmc/host/sdhci-pci-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci-pci-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -893,6 +893,12 @@ dmi_match(DMI_SYS_VENDOR, "IRBIS")); } +static bool jsl_broken_hs400es(struct sdhci_pci_slot *slot) +{ + return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_JSL_EMMC && + dmi_match(DMI_BIOS_VENDOR, "ASUSTeK COMPUTER INC."); +} + static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot) { int ret = byt_emmc_probe_slot(slot); @@ -901,9 +907,11 @@ slot->host->mmc->caps2 |= MMC_CAP2_CQE; if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) { - slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES; - slot->host->mmc_host_ops.hs400_enhanced_strobe = - intel_hs400_enhanced_strobe; + if (!jsl_broken_hs400es(slot)) { + slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES; + slot->host->mmc_host_ops.hs400_enhanced_strobe = + intel_hs400_enhanced_strobe; + } slot->host->mmc->caps2 |= MMC_CAP2_CQE_DCMD; } @@ -1720,6 +1728,8 @@ } } + pci_dev_put(smbus_dev); + if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ) chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD; diff -Nru linux-6.0.6/drivers/mmc/host/sdhci-pci-o2micro.c linux-6.0.12/drivers/mmc/host/sdhci-pci-o2micro.c --- linux-6.0.6/drivers/mmc/host/sdhci-pci-o2micro.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci-pci-o2micro.c 2023-01-18 18:27:39.000000000 +0000 @@ -32,6 +32,7 @@ #define O2_SD_CAPS 0xE0 #define O2_SD_ADMA1 0xE2 #define O2_SD_ADMA2 0xE7 +#define O2_SD_MISC_CTRL2 0xF0 #define O2_SD_INF_MOD 0xF1 #define O2_SD_MISC_CTRL4 0xFC #define O2_SD_MISC_CTRL 0x1C0 @@ -874,6 +875,12 @@ /* Set Tuning Windows to 5 */ pci_write_config_byte(chip->pdev, O2_SD_TUNING_CTRL, 0x55); + //Adjust 1st and 2nd CD debounce time + pci_read_config_dword(chip->pdev, O2_SD_MISC_CTRL2, &scratch_32); + scratch_32 &= 0xFFE7FFFF; + scratch_32 |= 0x00180000; + pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL2, scratch_32); + pci_write_config_dword(chip->pdev, O2_SD_DETECT_SETTING, 1); /* Lock WP */ ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch); diff -Nru linux-6.0.6/drivers/mmc/host/sdhci-sprd.c linux-6.0.12/drivers/mmc/host/sdhci-sprd.c --- linux-6.0.6/drivers/mmc/host/sdhci-sprd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci-sprd.c 2023-01-18 18:27:39.000000000 +0000 @@ -470,7 +470,7 @@ } if (IS_ERR(sprd_host->pinctrl)) - return 0; + goto reset; switch (ios->signal_voltage) { case MMC_SIGNAL_VOLTAGE_180: @@ -498,6 +498,8 @@ /* Wait for 300 ~ 500 us for pin state stable */ usleep_range(300, 500); + +reset: sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); return 0; diff -Nru linux-6.0.6/drivers/mmc/host/sdhci-tegra.c linux-6.0.12/drivers/mmc/host/sdhci-tegra.c --- linux-6.0.6/drivers/mmc/host/sdhci-tegra.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mmc/host/sdhci-tegra.c 2023-01-18 18:27:39.000000000 +0000 @@ -28,6 +28,7 @@ #include +#include "sdhci-cqhci.h" #include "sdhci-pltfm.h" #include "cqhci.h" @@ -367,7 +368,7 @@ const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; u32 misc_ctrl, clk_ctrl, pad_ctrl; - sdhci_reset(host, mask); + sdhci_and_cqhci_reset(host, mask); if (!(mask & SDHCI_RESET_ALL)) return; diff -Nru linux-6.0.6/drivers/mtd/mtdcore.c linux-6.0.12/drivers/mtd/mtdcore.c --- linux-6.0.6/drivers/mtd/mtdcore.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mtd/mtdcore.c 2023-01-18 18:27:39.000000000 +0000 @@ -562,7 +562,7 @@ if (!mtd_is_partition(mtd)) return; parent = mtd->parent; - parent_dn = dev_of_node(&parent->dev); + parent_dn = of_node_get(dev_of_node(&parent->dev)); if (!parent_dn) return; diff -Nru linux-6.0.6/drivers/mtd/nand/onenand/Kconfig linux-6.0.12/drivers/mtd/nand/onenand/Kconfig --- linux-6.0.6/drivers/mtd/nand/onenand/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mtd/nand/onenand/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -26,6 +26,7 @@ tristate "OneNAND on OMAP2/OMAP3 support" depends on ARCH_OMAP2 || ARCH_OMAP3 || (COMPILE_TEST && ARM) depends on OF || COMPILE_TEST + depends on OMAP_GPMC help Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC via the GPMC memory controller. diff -Nru linux-6.0.6/drivers/mtd/nand/raw/intel-nand-controller.c linux-6.0.12/drivers/mtd/nand/raw/intel-nand-controller.c --- linux-6.0.6/drivers/mtd/nand/raw/intel-nand-controller.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mtd/nand/raw/intel-nand-controller.c 2023-01-18 18:27:39.000000000 +0000 @@ -108,7 +108,6 @@ struct ebu_nand_cs { void __iomem *chipaddr; - dma_addr_t nand_pa; u32 addr_sel; }; @@ -596,13 +595,11 @@ ebu_host->dev = dev; nand_controller_init(&ebu_host->controller); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ebunand"); - ebu_host->ebu = devm_ioremap_resource(&pdev->dev, res); + ebu_host->ebu = devm_platform_ioremap_resource_byname(pdev, "ebunand"); if (IS_ERR(ebu_host->ebu)) return PTR_ERR(ebu_host->ebu); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsnand"); - ebu_host->hsnand = devm_ioremap_resource(&pdev->dev, res); + ebu_host->hsnand = devm_platform_ioremap_resource_byname(pdev, "hsnand"); if (IS_ERR(ebu_host->hsnand)) return PTR_ERR(ebu_host->hsnand); @@ -614,31 +611,35 @@ ret = of_property_read_u32(chip_np, "reg", &cs); if (ret) { dev_err(dev, "failed to get chip select: %d\n", ret); - return ret; + goto err_of_node_put; } if (cs >= MAX_CS) { dev_err(dev, "got invalid chip select: %d\n", cs); - return -EINVAL; + ret = -EINVAL; + goto err_of_node_put; } ebu_host->cs_num = cs; resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname); - ebu_host->cs[cs].chipaddr = devm_ioremap_resource(dev, res); - if (IS_ERR(ebu_host->cs[cs].chipaddr)) - return PTR_ERR(ebu_host->cs[cs].chipaddr); - ebu_host->cs[cs].nand_pa = res->start; + ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev, + resname); + if (IS_ERR(ebu_host->cs[cs].chipaddr)) { + ret = PTR_ERR(ebu_host->cs[cs].chipaddr); + goto err_of_node_put; + } ebu_host->clk = devm_clk_get(dev, NULL); - if (IS_ERR(ebu_host->clk)) - return dev_err_probe(dev, PTR_ERR(ebu_host->clk), - "failed to get clock\n"); + if (IS_ERR(ebu_host->clk)) { + ret = dev_err_probe(dev, PTR_ERR(ebu_host->clk), + "failed to get clock\n"); + goto err_of_node_put; + } ret = clk_prepare_enable(ebu_host->clk); if (ret) { dev_err(dev, "failed to enable clock: %d\n", ret); - return ret; + goto err_of_node_put; } ebu_host->clk_rate = clk_get_rate(ebu_host->clk); @@ -703,6 +704,8 @@ ebu_dma_cleanup(ebu_host); err_disable_unprepare_clk: clk_disable_unprepare(ebu_host->clk); +err_of_node_put: + of_node_put(chip_np); return ret; } diff -Nru linux-6.0.6/drivers/mtd/nand/raw/marvell_nand.c linux-6.0.12/drivers/mtd/nand/raw/marvell_nand.c --- linux-6.0.6/drivers/mtd/nand/raw/marvell_nand.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mtd/nand/raw/marvell_nand.c 2023-01-18 18:27:39.000000000 +0000 @@ -2672,7 +2672,7 @@ chip->controller = &nfc->controller; nand_set_flash_node(chip, np); - if (!of_property_read_bool(np, "marvell,nand-keep-config")) + if (of_property_read_bool(np, "marvell,nand-keep-config")) chip->options |= NAND_KEEP_TIMINGS; mtd = nand_to_mtd(chip); diff -Nru linux-6.0.6/drivers/mtd/nand/raw/qcom_nandc.c linux-6.0.12/drivers/mtd/nand/raw/qcom_nandc.c --- linux-6.0.6/drivers/mtd/nand/raw/qcom_nandc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mtd/nand/raw/qcom_nandc.c 2023-01-18 18:27:39.000000000 +0000 @@ -3167,16 +3167,18 @@ ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0); if (ret) - nand_cleanup(chip); + goto err; if (nandc->props->use_codeword_fixup) { ret = qcom_nand_host_parse_boot_partitions(nandc, host, dn); - if (ret) { - nand_cleanup(chip); - return ret; - } + if (ret) + goto err; } + return 0; + +err: + nand_cleanup(chip); return ret; } diff -Nru linux-6.0.6/drivers/mtd/nand/raw/tegra_nand.c linux-6.0.12/drivers/mtd/nand/raw/tegra_nand.c --- linux-6.0.6/drivers/mtd/nand/raw/tegra_nand.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mtd/nand/raw/tegra_nand.c 2023-01-18 18:27:39.000000000 +0000 @@ -1181,7 +1181,7 @@ pm_runtime_enable(&pdev->dev); err = pm_runtime_resume_and_get(&pdev->dev); if (err) - return err; + goto err_dis_pm; err = reset_control_reset(rst); if (err) { @@ -1215,6 +1215,8 @@ err_put_pm: pm_runtime_put_sync_suspend(ctrl->dev); pm_runtime_force_suspend(ctrl->dev); +err_dis_pm: + pm_runtime_disable(&pdev->dev); return err; } diff -Nru linux-6.0.6/drivers/mtd/parsers/bcm47xxpart.c linux-6.0.12/drivers/mtd/parsers/bcm47xxpart.c --- linux-6.0.6/drivers/mtd/parsers/bcm47xxpart.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mtd/parsers/bcm47xxpart.c 2023-01-18 18:27:39.000000000 +0000 @@ -233,11 +233,11 @@ } /* Read middle of the block */ - err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read, + err = mtd_read(master, offset + (blocksize / 2), 0x4, &bytes_read, (uint8_t *)buf); if (err && !mtd_is_bitflip(err)) { pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", - offset + 0x8000, err); + offset + (blocksize / 2), err); continue; } diff -Nru linux-6.0.6/drivers/mtd/spi-nor/core.c linux-6.0.12/drivers/mtd/spi-nor/core.c --- linux-6.0.6/drivers/mtd/spi-nor/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/mtd/spi-nor/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -2724,7 +2724,9 @@ */ WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET, "enabling reset hack; may not recover from unexpected reboots\n"); - return nor->params->set_4byte_addr_mode(nor, true); + err = nor->params->set_4byte_addr_mode(nor, true); + if (err && err != -ENOTSUPP) + return err; } return 0; diff -Nru linux-6.0.6/drivers/net/arcnet/com20020_cs.c linux-6.0.12/drivers/net/arcnet/com20020_cs.c --- linux-6.0.6/drivers/net/arcnet/com20020_cs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/arcnet/com20020_cs.c 2023-01-18 18:27:39.000000000 +0000 @@ -113,6 +113,7 @@ struct com20020_dev *info; struct net_device *dev; struct arcnet_local *lp; + int ret = -ENOMEM; dev_dbg(&p_dev->dev, "com20020_attach()\n"); @@ -142,12 +143,18 @@ info->dev = dev; p_dev->priv = info; - return com20020_config(p_dev); + ret = com20020_config(p_dev); + if (ret) + goto fail_config; + return 0; + +fail_config: + free_arcdev(dev); fail_alloc_dev: kfree(info); fail_alloc_info: - return -ENOMEM; + return ret; } /* com20020_attach */ static void com20020_detach(struct pcmcia_device *link) diff -Nru linux-6.0.6/drivers/net/bonding/bond_main.c linux-6.0.12/drivers/net/bonding/bond_main.c --- linux-6.0.6/drivers/net/bonding/bond_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/bonding/bond_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -3231,16 +3231,23 @@ struct slave *slave) { struct slave *curr_active_slave, *curr_arp_slave; - struct icmp6hdr *hdr = icmp6_hdr(skb); struct in6_addr *saddr, *daddr; + struct { + struct ipv6hdr ip6; + struct icmp6hdr icmp6; + } *combined, _combined; if (skb->pkt_type == PACKET_OTHERHOST || - skb->pkt_type == PACKET_LOOPBACK || - hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT) + skb->pkt_type == PACKET_LOOPBACK) goto out; - saddr = &ipv6_hdr(skb)->saddr; - daddr = &ipv6_hdr(skb)->daddr; + combined = skb_header_pointer(skb, 0, sizeof(_combined), &_combined); + if (!combined || combined->ip6.nexthdr != NEXTHDR_ICMP || + combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT) + goto out; + + saddr = &combined->ip6.saddr; + daddr = &combined->ip6.saddr; slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n", __func__, slave->dev->name, bond_slave_state(slave), diff -Nru linux-6.0.6/drivers/net/can/at91_can.c linux-6.0.12/drivers/net/can/at91_can.c --- linux-6.0.6/drivers/net/can/at91_can.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/at91_can.c 2023-01-18 18:27:39.000000000 +0000 @@ -452,7 +452,7 @@ unsigned int mb, prio; u32 reg_mid, reg_mcr; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; mb = get_tx_next_mb(priv); diff -Nru linux-6.0.6/drivers/net/can/can327.c linux-6.0.12/drivers/net/can/can327.c --- linux-6.0.6/drivers/net/can/can327.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/can327.c 2023-01-18 18:27:39.000000000 +0000 @@ -263,8 +263,10 @@ { lockdep_assert_held(&elm->lock); - if (!netif_running(elm->dev)) + if (!netif_running(elm->dev)) { + kfree_skb(skb); return; + } /* Queue for NAPI pickup. * rx-offload will update stats and LEDs for us. @@ -813,7 +815,7 @@ struct can327 *elm = netdev_priv(dev); struct can_frame *frame = (struct can_frame *)skb->data; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; /* We shouldn't get here after a hardware fault: diff -Nru linux-6.0.6/drivers/net/can/cc770/cc770.c linux-6.0.12/drivers/net/can/cc770/cc770.c --- linux-6.0.6/drivers/net/can/cc770/cc770.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/cc770/cc770.c 2023-01-18 18:27:39.000000000 +0000 @@ -429,7 +429,7 @@ struct cc770_priv *priv = netdev_priv(dev); unsigned int mo = obj2msgobj(CC770_OBJ_TX); - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; netif_stop_queue(dev); diff -Nru linux-6.0.6/drivers/net/can/cc770/cc770_isa.c linux-6.0.12/drivers/net/can/cc770/cc770_isa.c --- linux-6.0.6/drivers/net/can/cc770/cc770_isa.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/cc770/cc770_isa.c 2023-01-18 18:27:39.000000000 +0000 @@ -264,22 +264,24 @@ if (err) { dev_err(&pdev->dev, "couldn't register device (err=%d)\n", err); - goto exit_unmap; + goto exit_free; } dev_info(&pdev->dev, "device registered (reg_base=0x%p, irq=%d)\n", priv->reg_base, dev->irq); return 0; - exit_unmap: +exit_free: + free_cc770dev(dev); +exit_unmap: if (mem[idx]) iounmap(base); - exit_release: +exit_release: if (mem[idx]) release_mem_region(mem[idx], iosize); else release_region(port[idx], iosize); - exit: +exit: return err; } diff -Nru linux-6.0.6/drivers/net/can/c_can/c_can_main.c linux-6.0.12/drivers/net/can/c_can/c_can_main.c --- linux-6.0.6/drivers/net/can/c_can/c_can_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/c_can/c_can_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -457,7 +457,7 @@ struct c_can_tx_ring *tx_ring = &priv->tx; u32 idx, obj, cmd = IF_COMM_TX; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; if (c_can_tx_busy(priv, tx_ring)) diff -Nru linux-6.0.6/drivers/net/can/ctucanfd/ctucanfd_base.c linux-6.0.12/drivers/net/can/ctucanfd/ctucanfd_base.c --- linux-6.0.6/drivers/net/can/ctucanfd/ctucanfd_base.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/ctucanfd/ctucanfd_base.c 2023-01-18 18:27:39.000000000 +0000 @@ -600,7 +600,7 @@ bool ok; unsigned long flags; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; if (unlikely(!CTU_CAN_FD_TXTNF(priv))) { diff -Nru linux-6.0.6/drivers/net/can/dev/skb.c linux-6.0.12/drivers/net/can/dev/skb.c --- linux-6.0.6/drivers/net/can/dev/skb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/dev/skb.c 2023-01-18 18:27:39.000000000 +0000 @@ -5,7 +5,6 @@ */ #include -#include #include #define MOD_DESC "CAN device driver interface" @@ -300,7 +299,6 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb) { const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; - struct can_priv *priv = netdev_priv(dev); if (skb->protocol == htons(ETH_P_CAN)) { if (unlikely(skb->len != CAN_MTU || @@ -314,13 +312,8 @@ goto inval_skb; } - if (!can_skb_headroom_valid(dev, skb)) { - goto inval_skb; - } else if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) { - netdev_info_once(dev, - "interface in listen only mode, dropping skb\n"); + if (!can_skb_headroom_valid(dev, skb)) goto inval_skb; - } return false; diff -Nru linux-6.0.6/drivers/net/can/flexcan/flexcan-core.c linux-6.0.12/drivers/net/can/flexcan/flexcan-core.c --- linux-6.0.6/drivers/net/can/flexcan/flexcan-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/flexcan/flexcan-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -742,7 +742,7 @@ u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_fd_len2dlc(cfd->len)) << 16); int i; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; netif_stop_queue(dev); diff -Nru linux-6.0.6/drivers/net/can/grcan.c linux-6.0.12/drivers/net/can/grcan.c --- linux-6.0.6/drivers/net/can/grcan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/grcan.c 2023-01-18 18:27:39.000000000 +0000 @@ -1345,7 +1345,7 @@ unsigned long flags; u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; /* Trying to transmit in silent mode will generate error interrupts, but diff -Nru linux-6.0.6/drivers/net/can/ifi_canfd/ifi_canfd.c linux-6.0.12/drivers/net/can/ifi_canfd/ifi_canfd.c --- linux-6.0.6/drivers/net/can/ifi_canfd/ifi_canfd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/ifi_canfd/ifi_canfd.c 2023-01-18 18:27:39.000000000 +0000 @@ -860,7 +860,7 @@ u32 txst, txid, txdlc; int i; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; /* Check if the TX buffer is full */ diff -Nru linux-6.0.6/drivers/net/can/janz-ican3.c linux-6.0.12/drivers/net/can/janz-ican3.c --- linux-6.0.6/drivers/net/can/janz-ican3.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/janz-ican3.c 2023-01-18 18:27:39.000000000 +0000 @@ -1693,7 +1693,7 @@ void __iomem *desc_addr; unsigned long flags; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; spin_lock_irqsave(&mod->lock, flags); diff -Nru linux-6.0.6/drivers/net/can/kvaser_pciefd.c linux-6.0.12/drivers/net/can/kvaser_pciefd.c --- linux-6.0.6/drivers/net/can/kvaser_pciefd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/kvaser_pciefd.c 2023-01-18 18:27:39.000000000 +0000 @@ -775,7 +775,7 @@ int nwords; u8 count; - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; nwords = kvaser_pciefd_prepare_tx_packet(&packet, can, skb); diff -Nru linux-6.0.6/drivers/net/can/m_can/m_can.c linux-6.0.12/drivers/net/can/m_can/m_can.c --- linux-6.0.6/drivers/net/can/m_can/m_can.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/m_can/m_can.c 2023-01-18 18:27:39.000000000 +0000 @@ -1722,7 +1722,7 @@ { struct m_can_classdev *cdev = netdev_priv(dev); - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; if (cdev->is_peripheral) { @@ -1910,7 +1910,7 @@ cdev->hclk = devm_clk_get(cdev->dev, "hclk"); cdev->cclk = devm_clk_get(cdev->dev, "cclk"); - if (IS_ERR(cdev->cclk)) { + if (IS_ERR(cdev->hclk) || IS_ERR(cdev->cclk)) { dev_err(cdev->dev, "no clock found\n"); ret = -ENODEV; } diff -Nru linux-6.0.6/drivers/net/can/m_can/m_can_pci.c linux-6.0.12/drivers/net/can/m_can/m_can_pci.c --- linux-6.0.6/drivers/net/can/m_can/m_can_pci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/m_can/m_can_pci.c 2023-01-18 18:27:39.000000000 +0000 @@ -120,7 +120,7 @@ ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_ALL_TYPES); if (ret < 0) - return ret; + goto err_free_dev; mcan_class->dev = &pci->dev; mcan_class->net->irq = pci_irq_vector(pci, 0); @@ -132,7 +132,7 @@ ret = m_can_class_register(mcan_class); if (ret) - goto err; + goto err_free_irq; /* Enable interrupt control at CAN wrapper IP */ writel(0x1, base + CTL_CSR_INT_CTL_OFFSET); @@ -144,8 +144,10 @@ return 0; -err: +err_free_irq: pci_free_irq_vectors(pci); +err_free_dev: + m_can_class_free_dev(mcan_class->net); return ret; } @@ -161,6 +163,7 @@ writel(0x0, priv->base + CTL_CSR_INT_CTL_OFFSET); m_can_class_unregister(mcan_class); + m_can_class_free_dev(mcan_class->net); pci_free_irq_vectors(pci); } diff -Nru linux-6.0.6/drivers/net/can/mscan/mpc5xxx_can.c linux-6.0.12/drivers/net/can/mscan/mpc5xxx_can.c --- linux-6.0.6/drivers/net/can/mscan/mpc5xxx_can.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/mscan/mpc5xxx_can.c 2023-01-18 18:27:39.000000000 +0000 @@ -322,14 +322,14 @@ &mscan_clksrc); if (!priv->can.clock.freq) { dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n"); - goto exit_free_mscan; + goto exit_put_clock; } err = register_mscandev(dev, mscan_clksrc); if (err) { dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", DRV_NAME, err); - goto exit_free_mscan; + goto exit_put_clock; } dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n", @@ -337,7 +337,9 @@ return 0; -exit_free_mscan: +exit_put_clock: + if (data->put_clock) + data->put_clock(ofdev); free_candev(dev); exit_dispose_irq: irq_dispose_mapping(irq); diff -Nru linux-6.0.6/drivers/net/can/mscan/mscan.c linux-6.0.12/drivers/net/can/mscan/mscan.c --- linux-6.0.6/drivers/net/can/mscan/mscan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/mscan/mscan.c 2023-01-18 18:27:39.000000000 +0000 @@ -191,7 +191,7 @@ int i, rtr, buf_id; u32 can_id; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; out_8(®s->cantier, 0); diff -Nru linux-6.0.6/drivers/net/can/pch_can.c linux-6.0.12/drivers/net/can/pch_can.c --- linux-6.0.6/drivers/net/can/pch_can.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/pch_can.c 2023-01-18 18:27:39.000000000 +0000 @@ -882,7 +882,7 @@ int i; u32 id2; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; tx_obj_no = priv->tx_obj; diff -Nru linux-6.0.6/drivers/net/can/peak_canfd/peak_canfd.c linux-6.0.12/drivers/net/can/peak_canfd/peak_canfd.c --- linux-6.0.6/drivers/net/can/peak_canfd/peak_canfd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/peak_canfd/peak_canfd.c 2023-01-18 18:27:39.000000000 +0000 @@ -651,7 +651,7 @@ int room_left; u8 len; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; msg_size = ALIGN(sizeof(*msg) + cf->len, 4); diff -Nru linux-6.0.6/drivers/net/can/rcar/rcar_can.c linux-6.0.12/drivers/net/can/rcar/rcar_can.c --- linux-6.0.6/drivers/net/can/rcar/rcar_can.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/rcar/rcar_can.c 2023-01-18 18:27:39.000000000 +0000 @@ -590,7 +590,7 @@ struct can_frame *cf = (struct can_frame *)skb->data; u32 data, i; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */ diff -Nru linux-6.0.6/drivers/net/can/rcar/rcar_canfd.c linux-6.0.12/drivers/net/can/rcar/rcar_canfd.c --- linux-6.0.6/drivers/net/can/rcar/rcar_canfd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/rcar/rcar_canfd.c 2023-01-18 18:27:39.000000000 +0000 @@ -81,8 +81,7 @@ /* RSCFDnCFDGERFL / RSCFDnGERFL */ #define RCANFD_GERFL_EEF0_7 GENMASK(23, 16) -#define RCANFD_GERFL_EEF1 BIT(17) -#define RCANFD_GERFL_EEF0 BIT(16) +#define RCANFD_GERFL_EEF(ch) BIT(16 + (ch)) #define RCANFD_GERFL_CMPOF BIT(3) /* CAN FD only */ #define RCANFD_GERFL_THLES BIT(2) #define RCANFD_GERFL_MES BIT(1) @@ -90,7 +89,7 @@ #define RCANFD_GERFL_ERR(gpriv, x) \ ((x) & (reg_v3u(gpriv, RCANFD_GERFL_EEF0_7, \ - RCANFD_GERFL_EEF0 | RCANFD_GERFL_EEF1) | \ + RCANFD_GERFL_EEF(0) | RCANFD_GERFL_EEF(1)) | \ RCANFD_GERFL_MES | \ ((gpriv)->fdmode ? RCANFD_GERFL_CMPOF : 0))) @@ -936,12 +935,8 @@ u32 ridx = ch + RCANFD_RFFIFO_IDX; gerfl = rcar_canfd_read(priv->base, RCANFD_GERFL); - if ((gerfl & RCANFD_GERFL_EEF0) && (ch == 0)) { - netdev_dbg(ndev, "Ch0: ECC Error flag\n"); - stats->tx_dropped++; - } - if ((gerfl & RCANFD_GERFL_EEF1) && (ch == 1)) { - netdev_dbg(ndev, "Ch1: ECC Error flag\n"); + if (gerfl & RCANFD_GERFL_EEF(ch)) { + netdev_dbg(ndev, "Ch%u: ECC Error flag\n", ch); stats->tx_dropped++; } if (gerfl & RCANFD_GERFL_MES) { @@ -1157,11 +1152,13 @@ { struct rcar_canfd_channel *priv = gpriv->ch[ch]; u32 ridx = ch + RCANFD_RFFIFO_IDX; - u32 sts; + u32 sts, cc; /* Handle Rx interrupts */ sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(gpriv, ridx)); - if (likely(sts & RCANFD_RFSTS_RFIF)) { + cc = rcar_canfd_read(priv->base, RCANFD_RFCC(gpriv, ridx)); + if (likely(sts & RCANFD_RFSTS_RFIF && + cc & RCANFD_RFCC_RFIE)) { if (napi_schedule_prep(&priv->napi)) { /* Disable Rx FIFO interrupts */ rcar_canfd_clear_bit(priv->base, @@ -1244,11 +1241,9 @@ static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void *dev_id) { - struct rcar_canfd_global *gpriv = dev_id; - u32 ch; + struct rcar_canfd_channel *priv = dev_id; - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) - rcar_canfd_handle_channel_tx(gpriv, ch); + rcar_canfd_handle_channel_tx(priv->gpriv, priv->channel); return IRQ_HANDLED; } @@ -1276,11 +1271,9 @@ static irqreturn_t rcar_canfd_channel_err_interrupt(int irq, void *dev_id) { - struct rcar_canfd_global *gpriv = dev_id; - u32 ch; + struct rcar_canfd_channel *priv = dev_id; - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) - rcar_canfd_handle_channel_err(gpriv, ch); + rcar_canfd_handle_channel_err(priv->gpriv, priv->channel); return IRQ_HANDLED; } @@ -1483,7 +1476,7 @@ unsigned long flags; u32 ch = priv->channel; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; if (cf->can_id & CAN_EFF_FLAG) { @@ -1721,6 +1714,7 @@ priv->ndev = ndev; priv->base = gpriv->base; priv->channel = ch; + priv->gpriv = gpriv; priv->can.clock.freq = fcan_freq; dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq); @@ -1749,7 +1743,7 @@ } err = devm_request_irq(&pdev->dev, err_irq, rcar_canfd_channel_err_interrupt, 0, - irq_name, gpriv); + irq_name, priv); if (err) { dev_err(&pdev->dev, "devm_request_irq CH Err(%d) failed, error %d\n", err_irq, err); @@ -1763,7 +1757,7 @@ } err = devm_request_irq(&pdev->dev, tx_irq, rcar_canfd_channel_tx_interrupt, 0, - irq_name, gpriv); + irq_name, priv); if (err) { dev_err(&pdev->dev, "devm_request_irq Tx (%d) failed, error %d\n", tx_irq, err); @@ -1789,7 +1783,6 @@ priv->can.do_set_mode = rcar_canfd_do_set_mode; priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter; - priv->gpriv = gpriv; SET_NETDEV_DEV(ndev, &pdev->dev); netif_napi_add_weight(ndev, &priv->napi, rcar_canfd_rx_poll, diff -Nru linux-6.0.6/drivers/net/can/sja1000/sja1000.c linux-6.0.12/drivers/net/can/sja1000/sja1000.c --- linux-6.0.6/drivers/net/can/sja1000/sja1000.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/sja1000/sja1000.c 2023-01-18 18:27:39.000000000 +0000 @@ -291,7 +291,7 @@ u8 cmd_reg_val = 0x00; int i; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; netif_stop_queue(dev); diff -Nru linux-6.0.6/drivers/net/can/sja1000/sja1000_isa.c linux-6.0.12/drivers/net/can/sja1000/sja1000_isa.c --- linux-6.0.6/drivers/net/can/sja1000/sja1000_isa.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/sja1000/sja1000_isa.c 2023-01-18 18:27:39.000000000 +0000 @@ -202,22 +202,24 @@ if (err) { dev_err(&pdev->dev, "registering %s failed (err=%d)\n", DRV_NAME, err); - goto exit_unmap; + goto exit_free; } dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n", DRV_NAME, priv->reg_base, dev->irq); return 0; - exit_unmap: +exit_free: + free_sja1000dev(dev); +exit_unmap: if (mem[idx]) iounmap(base); - exit_release: +exit_release: if (mem[idx]) release_mem_region(mem[idx], iosize); else release_region(port[idx], iosize); - exit: +exit: return err; } diff -Nru linux-6.0.6/drivers/net/can/slcan/slcan-core.c linux-6.0.12/drivers/net/can/slcan/slcan-core.c --- linux-6.0.6/drivers/net/can/slcan/slcan-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/slcan/slcan-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -594,7 +594,7 @@ { struct slcan *sl = netdev_priv(dev); - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; spin_lock(&sl->lock); diff -Nru linux-6.0.6/drivers/net/can/softing/softing_main.c linux-6.0.12/drivers/net/can/softing/softing_main.c --- linux-6.0.6/drivers/net/can/softing/softing_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/softing/softing_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -60,7 +60,7 @@ struct can_frame *cf = (struct can_frame *)skb->data; uint8_t buf[DPRAM_TX_SIZE]; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; spin_lock(&card->spin); diff -Nru linux-6.0.6/drivers/net/can/spi/hi311x.c linux-6.0.12/drivers/net/can/spi/hi311x.c --- linux-6.0.6/drivers/net/can/spi/hi311x.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/spi/hi311x.c 2023-01-18 18:27:39.000000000 +0000 @@ -373,7 +373,7 @@ return NETDEV_TX_BUSY; } - if (can_dropped_invalid_skb(net, skb)) + if (can_dev_dropped_skb(net, skb)) return NETDEV_TX_OK; netif_stop_queue(net); diff -Nru linux-6.0.6/drivers/net/can/spi/mcp251x.c linux-6.0.12/drivers/net/can/spi/mcp251x.c --- linux-6.0.6/drivers/net/can/spi/mcp251x.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/spi/mcp251x.c 2023-01-18 18:27:39.000000000 +0000 @@ -789,7 +789,7 @@ return NETDEV_TX_BUSY; } - if (can_dropped_invalid_skb(net, skb)) + if (can_dev_dropped_skb(net, skb)) return NETDEV_TX_OK; netif_stop_queue(net); @@ -1415,11 +1415,14 @@ ret = mcp251x_gpio_setup(priv); if (ret) - goto error_probe; + goto out_unregister_candev; netdev_info(net, "MCP%x successfully initialized.\n", priv->model); return 0; +out_unregister_candev: + unregister_candev(net); + error_probe: destroy_workqueue(priv->wq); priv->wq = NULL; diff -Nru linux-6.0.6/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c linux-6.0.12/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c --- linux-6.0.6/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c 2023-01-18 18:27:39.000000000 +0000 @@ -172,7 +172,7 @@ u8 tx_head; int err; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; if (mcp251xfd_tx_busy(priv, tx_ring)) diff -Nru linux-6.0.6/drivers/net/can/sun4i_can.c linux-6.0.12/drivers/net/can/sun4i_can.c --- linux-6.0.6/drivers/net/can/sun4i_can.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/sun4i_can.c 2023-01-18 18:27:39.000000000 +0000 @@ -429,7 +429,7 @@ canid_t id; int i; - if (can_dropped_invalid_skb(dev, skb)) + if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; netif_stop_queue(dev); diff -Nru linux-6.0.6/drivers/net/can/ti_hecc.c linux-6.0.12/drivers/net/can/ti_hecc.c --- linux-6.0.6/drivers/net/can/ti_hecc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/ti_hecc.c 2023-01-18 18:27:39.000000000 +0000 @@ -470,7 +470,7 @@ u32 mbxno, mbx_mask, data; unsigned long flags; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; mbxno = get_tx_head_mb(priv); diff -Nru linux-6.0.6/drivers/net/can/usb/ems_usb.c linux-6.0.12/drivers/net/can/usb/ems_usb.c --- linux-6.0.6/drivers/net/can/usb/ems_usb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/ems_usb.c 2023-01-18 18:27:39.000000000 +0000 @@ -747,7 +747,7 @@ size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN + sizeof(struct cpc_can_msg); - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; /* create a URB, and a buffer for it, and copy the data to the URB */ diff -Nru linux-6.0.6/drivers/net/can/usb/esd_usb.c linux-6.0.12/drivers/net/can/usb/esd_usb.c --- linux-6.0.6/drivers/net/can/usb/esd_usb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/esd_usb.c 2023-01-18 18:27:39.000000000 +0000 @@ -725,7 +725,7 @@ int ret = NETDEV_TX_OK; size_t size = sizeof(struct esd_usb_msg); - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; /* create a URB, and a buffer for it, and copy the data to the URB */ diff -Nru linux-6.0.6/drivers/net/can/usb/etas_es58x/es58x_core.c linux-6.0.12/drivers/net/can/usb/etas_es58x/es58x_core.c --- linux-6.0.6/drivers/net/can/usb/etas_es58x/es58x_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/etas_es58x/es58x_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -1913,7 +1913,7 @@ unsigned int frame_len; int ret; - if (can_dropped_invalid_skb(netdev, skb)) { + if (can_dev_dropped_skb(netdev, skb)) { if (priv->tx_urb) goto xmit_commit; return NETDEV_TX_OK; @@ -2091,8 +2091,11 @@ netdev->dev_port = channel_idx; ret = register_candev(netdev); - if (ret) + if (ret) { + es58x_dev->netdev[channel_idx] = NULL; + free_candev(netdev); return ret; + } netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), es58x_dev->param->dql_min_limit); diff -Nru linux-6.0.6/drivers/net/can/usb/gs_usb.c linux-6.0.12/drivers/net/can/usb/gs_usb.c --- linux-6.0.6/drivers/net/can/usb/gs_usb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/gs_usb.c 2023-01-18 18:27:39.000000000 +0000 @@ -268,8 +268,6 @@ struct usb_anchor tx_submitted; atomic_t active_tx_urbs; - void *rxbuf[GS_MAX_RX_URBS]; - dma_addr_t rxbuf_dma[GS_MAX_RX_URBS]; }; /* usb interface struct */ @@ -587,9 +585,6 @@ if (urb->status) netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id); - - usb_free_coherent(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); } static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, @@ -605,7 +600,7 @@ unsigned int idx; struct gs_tx_context *txc; - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; /* find an empty context to keep track of transmission */ @@ -618,8 +613,7 @@ if (!urb) goto nomem_urb; - hf = usb_alloc_coherent(dev->udev, dev->hf_size_tx, GFP_ATOMIC, - &urb->transfer_dma); + hf = kmalloc(dev->hf_size_tx, GFP_ATOMIC); if (!hf) { netdev_err(netdev, "No memory left for USB buffer\n"); goto nomem_hf; @@ -663,7 +657,7 @@ hf, dev->hf_size_tx, gs_usb_xmit_callback, txc); - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags |= URB_FREE_BUFFER; usb_anchor_urb(urb, &dev->tx_submitted); can_put_echo_skb(skb, netdev, idx, 0); @@ -678,8 +672,6 @@ gs_free_tx_context(txc); usb_unanchor_urb(urb); - usb_free_coherent(dev->udev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); if (rc == -ENODEV) { netif_device_detach(netdev); @@ -699,8 +691,7 @@ return NETDEV_TX_OK; badidx: - usb_free_coherent(dev->udev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); + kfree(hf); nomem_hf: usb_free_urb(urb); @@ -744,7 +735,6 @@ for (i = 0; i < GS_MAX_RX_URBS; i++) { struct urb *urb; u8 *buf; - dma_addr_t buf_dma; /* alloc rx urb */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -752,10 +742,8 @@ return -ENOMEM; /* alloc rx buffer */ - buf = usb_alloc_coherent(dev->udev, - dev->parent->hf_size_rx, - GFP_KERNEL, - &buf_dma); + buf = kmalloc(dev->parent->hf_size_rx, + GFP_KERNEL); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); @@ -763,8 +751,6 @@ return -ENOMEM; } - urb->transfer_dma = buf_dma; - /* fill, anchor, and submit rx urb */ usb_fill_bulk_urb(urb, dev->udev, @@ -773,7 +759,7 @@ buf, dev->parent->hf_size_rx, gs_usb_receive_bulk_callback, parent); - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags |= URB_FREE_BUFFER; usb_anchor_urb(urb, &parent->rx_submitted); @@ -786,17 +772,10 @@ "usb_submit failed (err=%d)\n", rc); usb_unanchor_urb(urb); - usb_free_coherent(dev->udev, - sizeof(struct gs_host_frame), - buf, - buf_dma); usb_free_urb(urb); break; } - dev->rxbuf[i] = buf; - dev->rxbuf_dma[i] = buf_dma; - /* Drop reference, * USB core will take care of freeing it */ @@ -854,7 +833,6 @@ int rc; struct gs_can *dev = netdev_priv(netdev); struct gs_usb *parent = dev->parent; - unsigned int i; netif_stop_queue(netdev); @@ -862,11 +840,6 @@ parent->active_channels--; if (!parent->active_channels) { usb_kill_anchored_urbs(&parent->rx_submitted); - for (i = 0; i < GS_MAX_RX_URBS; i++) - usb_free_coherent(dev->udev, - sizeof(struct gs_host_frame), - dev->rxbuf[i], - dev->rxbuf_dma[i]); } /* Stop sending URBs */ diff -Nru linux-6.0.6/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c linux-6.0.12/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c --- linux-6.0.6/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -570,7 +570,7 @@ unsigned int i; unsigned long flags; - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; urb = usb_alloc_urb(0, GFP_ATOMIC); diff -Nru linux-6.0.6/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c linux-6.0.12/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c --- linux-6.0.6/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c 2023-01-18 18:27:39.000000000 +0000 @@ -1875,7 +1875,7 @@ { int err; - init_completion(&priv->start_comp); + reinit_completion(&priv->start_comp); err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_START_CHIP_REQ, priv->channel); @@ -1893,7 +1893,7 @@ { int err; - init_completion(&priv->stop_comp); + reinit_completion(&priv->stop_comp); /* Make sure we do not report invalid BUS_OFF from CMD_CHIP_STATE_EVENT * see comment in kvaser_usb_hydra_update_state() diff -Nru linux-6.0.6/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c linux-6.0.12/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c --- linux-6.0.6/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c 2023-01-18 18:27:39.000000000 +0000 @@ -1320,7 +1320,7 @@ { int err; - init_completion(&priv->start_comp); + reinit_completion(&priv->start_comp); err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP, priv->channel); @@ -1338,7 +1338,7 @@ { int err; - init_completion(&priv->stop_comp); + reinit_completion(&priv->stop_comp); err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP, priv->channel); diff -Nru linux-6.0.6/drivers/net/can/usb/mcba_usb.c linux-6.0.12/drivers/net/can/usb/mcba_usb.c --- linux-6.0.6/drivers/net/can/usb/mcba_usb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/mcba_usb.c 2023-01-18 18:27:39.000000000 +0000 @@ -311,7 +311,7 @@ .cmd_id = MBCA_CMD_TRANSMIT_MESSAGE_EV }; - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; ctx = mcba_usb_get_free_ctx(priv, cf); diff -Nru linux-6.0.6/drivers/net/can/usb/peak_usb/pcan_usb_core.c linux-6.0.12/drivers/net/can/usb/peak_usb/pcan_usb_core.c --- linux-6.0.6/drivers/net/can/usb/peak_usb/pcan_usb_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/peak_usb/pcan_usb_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -351,7 +351,7 @@ int i, err; size_t size = dev->adapter->tx_buffer_size; - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) diff -Nru linux-6.0.6/drivers/net/can/usb/ucan.c linux-6.0.12/drivers/net/can/usb/ucan.c --- linux-6.0.6/drivers/net/can/usb/ucan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/ucan.c 2023-01-18 18:27:39.000000000 +0000 @@ -1120,7 +1120,7 @@ struct can_frame *cf = (struct can_frame *)skb->data; /* check skb */ - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; /* allocate a context and slow down tx path, if fifo state is low */ diff -Nru linux-6.0.6/drivers/net/can/usb/usb_8dev.c linux-6.0.12/drivers/net/can/usb/usb_8dev.c --- linux-6.0.6/drivers/net/can/usb/usb_8dev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/usb/usb_8dev.c 2023-01-18 18:27:39.000000000 +0000 @@ -602,7 +602,7 @@ int i, err; size_t size = sizeof(struct usb_8dev_tx_msg); - if (can_dropped_invalid_skb(netdev, skb)) + if (can_dev_dropped_skb(netdev, skb)) return NETDEV_TX_OK; /* create a URB, and a buffer for it, and copy the data to the URB */ diff -Nru linux-6.0.6/drivers/net/can/xilinx_can.c linux-6.0.12/drivers/net/can/xilinx_can.c --- linux-6.0.6/drivers/net/can/xilinx_can.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/can/xilinx_can.c 2023-01-18 18:27:39.000000000 +0000 @@ -743,7 +743,7 @@ struct xcan_priv *priv = netdev_priv(ndev); int ret; - if (can_dropped_invalid_skb(ndev, skb)) + if (can_dev_dropped_skb(ndev, skb)) return NETDEV_TX_OK; if (priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES) diff -Nru linux-6.0.6/drivers/net/dsa/dsa_loop.c linux-6.0.12/drivers/net/dsa/dsa_loop.c --- linux-6.0.6/drivers/net/dsa/dsa_loop.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/dsa/dsa_loop.c 2023-01-18 18:27:39.000000000 +0000 @@ -378,6 +378,17 @@ #define NUM_FIXED_PHYS (DSA_LOOP_NUM_PORTS - 2) +static void dsa_loop_phydevs_unregister(void) +{ + unsigned int i; + + for (i = 0; i < NUM_FIXED_PHYS; i++) + if (!IS_ERR(phydevs[i])) { + fixed_phy_unregister(phydevs[i]); + phy_device_free(phydevs[i]); + } +} + static int __init dsa_loop_init(void) { struct fixed_phy_status status = { @@ -385,23 +396,23 @@ .speed = SPEED_100, .duplex = DUPLEX_FULL, }; - unsigned int i; + unsigned int i, ret; for (i = 0; i < NUM_FIXED_PHYS; i++) phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL); - return mdio_driver_register(&dsa_loop_drv); + ret = mdio_driver_register(&dsa_loop_drv); + if (ret) + dsa_loop_phydevs_unregister(); + + return ret; } module_init(dsa_loop_init); static void __exit dsa_loop_exit(void) { - unsigned int i; - mdio_driver_unregister(&dsa_loop_drv); - for (i = 0; i < NUM_FIXED_PHYS; i++) - if (!IS_ERR(phydevs[i])) - fixed_phy_unregister(phydevs[i]); + dsa_loop_phydevs_unregister(); } module_exit(dsa_loop_exit); diff -Nru linux-6.0.6/drivers/net/dsa/lan9303-core.c linux-6.0.12/drivers/net/dsa/lan9303-core.c --- linux-6.0.6/drivers/net/dsa/lan9303-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/dsa/lan9303-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -959,7 +959,7 @@ { .offset = LAN9303_MAC_TX_BRDCST_CNT_0, .name = "TxBroad", }, { .offset = LAN9303_MAC_TX_PAUSE_CNT_0, .name = "TxPause", }, { .offset = LAN9303_MAC_TX_MULCST_CNT_0, .name = "TxMulti", }, - { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "TxUnderRun", }, + { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "RxShort", }, { .offset = LAN9303_MAC_TX_64_CNT_0, .name = "Tx64Byte", }, { .offset = LAN9303_MAC_TX_127_CNT_0, .name = "Tx128Byte", }, { .offset = LAN9303_MAC_TX_255_CNT_0, .name = "Tx256Byte", }, diff -Nru linux-6.0.6/drivers/net/dsa/sja1105/sja1105_mdio.c linux-6.0.12/drivers/net/dsa/sja1105/sja1105_mdio.c --- linux-6.0.6/drivers/net/dsa/sja1105/sja1105_mdio.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/dsa/sja1105/sja1105_mdio.c 2023-01-18 18:27:39.000000000 +0000 @@ -256,6 +256,9 @@ u32 tmp; int rc; + if (reg & MII_ADDR_C45) + return -EOPNOTSUPP; + rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg, &tmp, NULL); if (rc < 0) @@ -272,6 +275,9 @@ const struct sja1105_regs *regs = priv->info->regs; u32 tmp = val; + if (reg & MII_ADDR_C45) + return -EOPNOTSUPP; + return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg, &tmp, NULL); } diff -Nru linux-6.0.6/drivers/net/ethernet/amazon/ena/ena_netdev.c linux-6.0.12/drivers/net/ethernet/amazon/ena/ena_netdev.c --- linux-6.0.6/drivers/net/ethernet/amazon/ena/ena_netdev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/amazon/ena/ena_netdev.c 2023-01-18 18:27:39.000000000 +0000 @@ -4545,13 +4545,19 @@ static int __init ena_init(void) { + int ret; + ena_wq = create_singlethread_workqueue(DRV_MODULE_NAME); if (!ena_wq) { pr_err("Failed to create workqueue\n"); return -ENOMEM; } - return pci_register_driver(&ena_pci_driver); + ret = pci_register_driver(&ena_pci_driver); + if (ret) + destroy_workqueue(ena_wq); + + return ret; } static void __exit ena_cleanup(void) diff -Nru linux-6.0.6/drivers/net/ethernet/amd/xgbe/xgbe.h linux-6.0.12/drivers/net/ethernet/amd/xgbe/xgbe.h --- linux-6.0.6/drivers/net/ethernet/amd/xgbe/xgbe.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/amd/xgbe/xgbe.h 2023-01-18 18:27:39.000000000 +0000 @@ -1013,6 +1013,7 @@ unsigned int tx_desc_prefetch; unsigned int rx_desc_prefetch; unsigned int an_cdr_workaround; + unsigned int enable_rrc; }; struct xgbe_prv_data { diff -Nru linux-6.0.6/drivers/net/ethernet/amd/xgbe/xgbe-pci.c linux-6.0.12/drivers/net/ethernet/amd/xgbe/xgbe-pci.c --- linux-6.0.6/drivers/net/ethernet/amd/xgbe/xgbe-pci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/amd/xgbe/xgbe-pci.c 2023-01-18 18:27:39.000000000 +0000 @@ -285,6 +285,9 @@ /* Yellow Carp devices do not need cdr workaround */ pdata->vdata->an_cdr_workaround = 0; + + /* Yellow Carp devices do not need rrc */ + pdata->vdata->enable_rrc = 0; } else { pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF; pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT; @@ -483,6 +486,7 @@ .tx_desc_prefetch = 5, .rx_desc_prefetch = 5, .an_cdr_workaround = 1, + .enable_rrc = 1, }; static struct xgbe_version_data xgbe_v2b = { @@ -498,6 +502,7 @@ .tx_desc_prefetch = 5, .rx_desc_prefetch = 5, .an_cdr_workaround = 1, + .enable_rrc = 1, }; static const struct pci_device_id xgbe_pci_table[] = { diff -Nru linux-6.0.6/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c linux-6.0.12/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c --- linux-6.0.6/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c 2023-01-18 18:27:39.000000000 +0000 @@ -239,6 +239,7 @@ #define XGBE_SFP_BASE_BR_1GBE_MAX 0x0d #define XGBE_SFP_BASE_BR_10GBE_MIN 0x64 #define XGBE_SFP_BASE_BR_10GBE_MAX 0x68 +#define XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX 0x78 #define XGBE_SFP_BASE_CU_CABLE_LEN 18 @@ -284,6 +285,8 @@ #define XGBE_BEL_FUSE_VENDOR "BEL-FUSE " #define XGBE_BEL_FUSE_PARTNO "1GBT-SFP06 " +#define XGBE_MOLEX_VENDOR "Molex Inc. " + struct xgbe_sfp_ascii { union { char vendor[XGBE_SFP_BASE_VENDOR_NAME_LEN + 1]; @@ -834,7 +837,11 @@ break; case XGBE_SFP_SPEED_10000: min = XGBE_SFP_BASE_BR_10GBE_MIN; - max = XGBE_SFP_BASE_BR_10GBE_MAX; + if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME], + XGBE_MOLEX_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN) == 0) + max = XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX; + else + max = XGBE_SFP_BASE_BR_10GBE_MAX; break; default: return false; @@ -1151,7 +1158,10 @@ } /* Determine the type of SFP */ - if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR) + if (phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE && + xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000)) + phy_data->sfp_base = XGBE_SFP_BASE_10000_CR; + else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR) phy_data->sfp_base = XGBE_SFP_BASE_10000_SR; else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LR) phy_data->sfp_base = XGBE_SFP_BASE_10000_LR; @@ -1167,9 +1177,6 @@ phy_data->sfp_base = XGBE_SFP_BASE_1000_CX; else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_T) phy_data->sfp_base = XGBE_SFP_BASE_1000_T; - else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) && - xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000)) - phy_data->sfp_base = XGBE_SFP_BASE_10000_CR; switch (phy_data->sfp_base) { case XGBE_SFP_BASE_1000_T: @@ -2640,7 +2647,7 @@ } /* No link, attempt a receiver reset cycle */ - if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) { + if (pdata->vdata->enable_rrc && phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) { phy_data->rrc_count = 0; xgbe_phy_rrc(pdata); } diff -Nru linux-6.0.6/drivers/net/ethernet/apm/xgene/xgene_enet_main.c linux-6.0.12/drivers/net/ethernet/apm/xgene/xgene_enet_main.c --- linux-6.0.6/drivers/net/ethernet/apm/xgene/xgene_enet_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/apm/xgene/xgene_enet_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1004,8 +1004,10 @@ xgene_enet_napi_enable(pdata); ret = xgene_enet_register_irq(ndev); - if (ret) + if (ret) { + xgene_enet_napi_disable(pdata); return ret; + } if (ndev->phydev) { phy_start(ndev->phydev); diff -Nru linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c --- linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c 2023-01-18 18:27:39.000000000 +0000 @@ -13,6 +13,7 @@ #include "aq_ptp.h" #include "aq_filters.h" #include "aq_macsec.h" +#include "aq_main.h" #include @@ -858,7 +859,7 @@ if (netif_running(ndev)) { ndev_running = true; - dev_close(ndev); + aq_ndev_close(ndev); } cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min); @@ -874,7 +875,7 @@ goto err_exit; if (ndev_running) - err = dev_open(ndev, NULL); + err = aq_ndev_open(ndev); err_exit: return err; diff -Nru linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c --- linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c 2023-01-18 18:27:39.000000000 +0000 @@ -585,6 +585,7 @@ ret = aq_mss_set_egress_sakey_record(hw, &key_rec, sa_idx); + memzero_explicit(&key_rec, sizeof(key_rec)); return ret; } @@ -932,6 +933,7 @@ ret = aq_mss_set_ingress_sakey_record(hw, &sa_key_record, sa_idx); + memzero_explicit(&sa_key_record, sizeof(sa_key_record)); return ret; } @@ -1451,26 +1453,57 @@ egress_sa_threshold_expired); } +#define AQ_LOCKED_MDO_DEF(mdo) \ +static int aq_locked_mdo_##mdo(struct macsec_context *ctx) \ +{ \ + struct aq_nic_s *nic = netdev_priv(ctx->netdev); \ + int ret; \ + mutex_lock(&nic->macsec_mutex); \ + ret = aq_mdo_##mdo(ctx); \ + mutex_unlock(&nic->macsec_mutex); \ + return ret; \ +} + +AQ_LOCKED_MDO_DEF(dev_open) +AQ_LOCKED_MDO_DEF(dev_stop) +AQ_LOCKED_MDO_DEF(add_secy) +AQ_LOCKED_MDO_DEF(upd_secy) +AQ_LOCKED_MDO_DEF(del_secy) +AQ_LOCKED_MDO_DEF(add_rxsc) +AQ_LOCKED_MDO_DEF(upd_rxsc) +AQ_LOCKED_MDO_DEF(del_rxsc) +AQ_LOCKED_MDO_DEF(add_rxsa) +AQ_LOCKED_MDO_DEF(upd_rxsa) +AQ_LOCKED_MDO_DEF(del_rxsa) +AQ_LOCKED_MDO_DEF(add_txsa) +AQ_LOCKED_MDO_DEF(upd_txsa) +AQ_LOCKED_MDO_DEF(del_txsa) +AQ_LOCKED_MDO_DEF(get_dev_stats) +AQ_LOCKED_MDO_DEF(get_tx_sc_stats) +AQ_LOCKED_MDO_DEF(get_tx_sa_stats) +AQ_LOCKED_MDO_DEF(get_rx_sc_stats) +AQ_LOCKED_MDO_DEF(get_rx_sa_stats) + const struct macsec_ops aq_macsec_ops = { - .mdo_dev_open = aq_mdo_dev_open, - .mdo_dev_stop = aq_mdo_dev_stop, - .mdo_add_secy = aq_mdo_add_secy, - .mdo_upd_secy = aq_mdo_upd_secy, - .mdo_del_secy = aq_mdo_del_secy, - .mdo_add_rxsc = aq_mdo_add_rxsc, - .mdo_upd_rxsc = aq_mdo_upd_rxsc, - .mdo_del_rxsc = aq_mdo_del_rxsc, - .mdo_add_rxsa = aq_mdo_add_rxsa, - .mdo_upd_rxsa = aq_mdo_upd_rxsa, - .mdo_del_rxsa = aq_mdo_del_rxsa, - .mdo_add_txsa = aq_mdo_add_txsa, - .mdo_upd_txsa = aq_mdo_upd_txsa, - .mdo_del_txsa = aq_mdo_del_txsa, - .mdo_get_dev_stats = aq_mdo_get_dev_stats, - .mdo_get_tx_sc_stats = aq_mdo_get_tx_sc_stats, - .mdo_get_tx_sa_stats = aq_mdo_get_tx_sa_stats, - .mdo_get_rx_sc_stats = aq_mdo_get_rx_sc_stats, - .mdo_get_rx_sa_stats = aq_mdo_get_rx_sa_stats, + .mdo_dev_open = aq_locked_mdo_dev_open, + .mdo_dev_stop = aq_locked_mdo_dev_stop, + .mdo_add_secy = aq_locked_mdo_add_secy, + .mdo_upd_secy = aq_locked_mdo_upd_secy, + .mdo_del_secy = aq_locked_mdo_del_secy, + .mdo_add_rxsc = aq_locked_mdo_add_rxsc, + .mdo_upd_rxsc = aq_locked_mdo_upd_rxsc, + .mdo_del_rxsc = aq_locked_mdo_del_rxsc, + .mdo_add_rxsa = aq_locked_mdo_add_rxsa, + .mdo_upd_rxsa = aq_locked_mdo_upd_rxsa, + .mdo_del_rxsa = aq_locked_mdo_del_rxsa, + .mdo_add_txsa = aq_locked_mdo_add_txsa, + .mdo_upd_txsa = aq_locked_mdo_upd_txsa, + .mdo_del_txsa = aq_locked_mdo_del_txsa, + .mdo_get_dev_stats = aq_locked_mdo_get_dev_stats, + .mdo_get_tx_sc_stats = aq_locked_mdo_get_tx_sc_stats, + .mdo_get_tx_sa_stats = aq_locked_mdo_get_tx_sa_stats, + .mdo_get_rx_sc_stats = aq_locked_mdo_get_rx_sc_stats, + .mdo_get_rx_sa_stats = aq_locked_mdo_get_rx_sa_stats, }; int aq_macsec_init(struct aq_nic_s *nic) @@ -1492,6 +1525,7 @@ nic->ndev->features |= NETIF_F_HW_MACSEC; nic->ndev->macsec_ops = &aq_macsec_ops; + mutex_init(&nic->macsec_mutex); return 0; } @@ -1515,7 +1549,7 @@ if (!nic->macsec_cfg) return 0; - rtnl_lock(); + mutex_lock(&nic->macsec_mutex); if (nic->aq_fw_ops->send_macsec_req) { struct macsec_cfg_request cfg = { 0 }; @@ -1564,7 +1598,7 @@ ret = aq_apply_macsec_cfg(nic); unlock: - rtnl_unlock(); + mutex_unlock(&nic->macsec_mutex); return ret; } @@ -1576,9 +1610,9 @@ if (!netif_carrier_ok(nic->ndev)) return; - rtnl_lock(); + mutex_lock(&nic->macsec_mutex); aq_check_txsa_expiration(nic); - rtnl_unlock(); + mutex_unlock(&nic->macsec_mutex); } int aq_macsec_rx_sa_cnt(struct aq_nic_s *nic) @@ -1589,21 +1623,30 @@ if (!cfg) return 0; + mutex_lock(&nic->macsec_mutex); + for (i = 0; i < AQ_MACSEC_MAX_SC; i++) { if (!test_bit(i, &cfg->rxsc_idx_busy)) continue; cnt += hweight_long(cfg->aq_rxsc[i].rx_sa_idx_busy); } + mutex_unlock(&nic->macsec_mutex); return cnt; } int aq_macsec_tx_sc_cnt(struct aq_nic_s *nic) { + int cnt; + if (!nic->macsec_cfg) return 0; - return hweight_long(nic->macsec_cfg->txsc_idx_busy); + mutex_lock(&nic->macsec_mutex); + cnt = hweight_long(nic->macsec_cfg->txsc_idx_busy); + mutex_unlock(&nic->macsec_mutex); + + return cnt; } int aq_macsec_tx_sa_cnt(struct aq_nic_s *nic) @@ -1614,12 +1657,15 @@ if (!cfg) return 0; + mutex_lock(&nic->macsec_mutex); + for (i = 0; i < AQ_MACSEC_MAX_SC; i++) { if (!test_bit(i, &cfg->txsc_idx_busy)) continue; cnt += hweight_long(cfg->aq_txsc[i].tx_sa_idx_busy); } + mutex_unlock(&nic->macsec_mutex); return cnt; } @@ -1691,6 +1737,8 @@ if (!cfg) return data; + mutex_lock(&nic->macsec_mutex); + aq_macsec_update_stats(nic); common_stats = &cfg->stats; @@ -1773,5 +1821,7 @@ data += i; + mutex_unlock(&nic->macsec_mutex); + return data; } diff -Nru linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_main.c linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_main.c --- linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -58,7 +58,7 @@ return ndev; } -static int aq_ndev_open(struct net_device *ndev) +int aq_ndev_open(struct net_device *ndev) { struct aq_nic_s *aq_nic = netdev_priv(ndev); int err = 0; @@ -88,7 +88,7 @@ return err; } -static int aq_ndev_close(struct net_device *ndev) +int aq_ndev_close(struct net_device *ndev) { struct aq_nic_s *aq_nic = netdev_priv(ndev); int err = 0; diff -Nru linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_main.h linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_main.h --- linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_main.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_main.h 2023-01-18 18:27:39.000000000 +0000 @@ -16,5 +16,7 @@ void aq_ndev_schedule_work(struct work_struct *work); struct net_device *aq_ndev_alloc(void); +int aq_ndev_open(struct net_device *ndev); +int aq_ndev_close(struct net_device *ndev); #endif /* AQ_MAIN_H */ diff -Nru linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_nic.h linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_nic.h --- linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/aq_nic.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/aq_nic.h 2023-01-18 18:27:39.000000000 +0000 @@ -157,6 +157,8 @@ struct mutex fwreq_mutex; #if IS_ENABLED(CONFIG_MACSEC) struct aq_macsec_cfg *macsec_cfg; + /* mutex to protect data in macsec_cfg */ + struct mutex macsec_mutex; #endif /* PTP support */ struct aq_ptp_s *aq_ptp; diff -Nru linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c --- linux-6.0.6/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c 2023-01-18 18:27:39.000000000 +0000 @@ -757,6 +757,7 @@ u16 table_index) { u16 packed_record[18]; + int ret; if (table_index >= NUMROWS_INGRESSSAKEYRECORD) return -EINVAL; @@ -789,9 +790,12 @@ packed_record[16] = rec->key_len & 0x3; - return set_raw_ingress_record(hw, packed_record, 18, 2, - ROWOFFSET_INGRESSSAKEYRECORD + - table_index); + ret = set_raw_ingress_record(hw, packed_record, 18, 2, + ROWOFFSET_INGRESSSAKEYRECORD + + table_index); + + memzero_explicit(packed_record, sizeof(packed_record)); + return ret; } int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw, @@ -1739,14 +1743,14 @@ ret = set_raw_egress_record(hw, packed_record, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + table_index); if (unlikely(ret)) - return ret; + goto clear_key; ret = set_raw_egress_record(hw, packed_record + 8, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + table_index - 32); - if (unlikely(ret)) - return ret; - return 0; +clear_key: + memzero_explicit(packed_record, sizeof(packed_record)); + return ret; } int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw, diff -Nru linux-6.0.6/drivers/net/ethernet/atheros/ag71xx.c linux-6.0.12/drivers/net/ethernet/atheros/ag71xx.c --- linux-6.0.6/drivers/net/ethernet/atheros/ag71xx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/atheros/ag71xx.c 2023-01-18 18:27:39.000000000 +0000 @@ -1427,7 +1427,7 @@ if (ret) { netif_err(ag, link, ndev, "phylink_of_phy_connect filed with err: %i\n", ret); - goto err; + return ret; } max_frame_len = ag71xx_max_frame_len(ndev->mtu); @@ -1448,6 +1448,7 @@ err: ag71xx_rings_cleanup(ag); + phylink_disconnect_phy(ag->phylink); return ret; } diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/bcm4908_enet.c linux-6.0.12/drivers/net/ethernet/broadcom/bcm4908_enet.c --- linux-6.0.6/drivers/net/ethernet/broadcom/bcm4908_enet.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/bcm4908_enet.c 2023-01-18 18:27:39.000000000 +0000 @@ -561,8 +561,6 @@ if (++ring->write_idx == ring->length - 1) ring->write_idx = 0; - enet->netdev->stats.tx_bytes += skb->len; - enet->netdev->stats.tx_packets++; return NETDEV_TX_OK; } @@ -635,6 +633,7 @@ struct bcm4908_enet_dma_ring_bd *buf_desc; struct bcm4908_enet_dma_ring_slot *slot; struct device *dev = enet->dev; + unsigned int bytes = 0; int handled = 0; while (handled < weight && tx_ring->read_idx != tx_ring->write_idx) { @@ -645,12 +644,17 @@ dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_TO_DEVICE); dev_kfree_skb(slot->skb); - if (++tx_ring->read_idx == tx_ring->length) - tx_ring->read_idx = 0; handled++; + bytes += slot->len; + + if (++tx_ring->read_idx == tx_ring->length) + tx_ring->read_idx = 0; } + enet->netdev->stats.tx_packets += handled; + enet->netdev->stats.tx_bytes += bytes; + if (handled < weight) { napi_complete_done(napi, handled); bcm4908_enet_dma_ring_intrs_on(enet, tx_ring); diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/bcmsysport.c linux-6.0.12/drivers/net/ethernet/broadcom/bcmsysport.c --- linux-6.0.6/drivers/net/ethernet/broadcom/bcmsysport.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/bcmsysport.c 2023-01-18 18:27:39.000000000 +0000 @@ -1991,6 +1991,9 @@ goto out_clk_disable; } + /* Indicate that the MAC is responsible for PHY PM */ + phydev->mac_managed_pm = true; + /* Reset house keeping link status */ priv->old_duplex = -1; priv->old_link = -1; diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/bgmac.c linux-6.0.12/drivers/net/ethernet/broadcom/bgmac.c --- linux-6.0.6/drivers/net/ethernet/broadcom/bgmac.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/bgmac.c 2023-01-18 18:27:39.000000000 +0000 @@ -1568,7 +1568,6 @@ phy_disconnect(bgmac->net_dev->phydev); netif_napi_del(&bgmac->napi); bgmac_dma_free(bgmac); - free_netdev(bgmac->net_dev); } EXPORT_SYMBOL_GPL(bgmac_enet_remove); diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c linux-6.0.12/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c --- linux-6.0.6/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c 2023-01-18 18:27:39.000000000 +0000 @@ -795,16 +795,20 @@ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid) { - struct pci_dev *dev; struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid); + struct pci_dev *dev; + bool pending; if (!vf) return false; dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn); - if (dev) - return bnx2x_is_pcie_pending(dev); - return false; + if (!dev) + return false; + pending = bnx2x_is_pcie_pending(dev); + pci_dev_put(dev); + + return pending; } int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid) diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/bnxt/bnxt.c linux-6.0.12/drivers/net/ethernet/broadcom/bnxt/bnxt.c --- linux-6.0.6/drivers/net/ethernet/broadcom/bnxt/bnxt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/bnxt/bnxt.c 2023-01-18 18:27:39.000000000 +0000 @@ -9983,17 +9983,12 @@ return -ENODEV; } -int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset) +static void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset) { struct bnxt_hw_resc *hw_resc = &bp->hw_resc; - int rc; if (!BNXT_NEW_RM(bp)) - return 0; /* no resource reservations required */ - - rc = bnxt_hwrm_func_resc_qcaps(bp, true); - if (rc) - netdev_err(bp->dev, "resc_qcaps failed\n"); + return; /* no resource reservations required */ hw_resc->resv_cp_rings = 0; hw_resc->resv_stat_ctxs = 0; @@ -10006,6 +10001,20 @@ bp->tx_nr_rings = 0; bp->rx_nr_rings = 0; } +} + +int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset) +{ + int rc; + + if (!BNXT_NEW_RM(bp)) + return 0; /* no resource reservations required */ + + rc = bnxt_hwrm_func_resc_qcaps(bp, true); + if (rc) + netdev_err(bp->dev, "resc_qcaps failed\n"); + + bnxt_clear_reservations(bp, fw_reset); return rc; } @@ -12894,8 +12903,8 @@ rcu_read_lock(); hlist_for_each_entry_rcu(fltr, head, hash) { if (bnxt_fltr_match(fltr, new_fltr)) { + rc = fltr->sw_id; rcu_read_unlock(); - rc = 0; goto err_free; } } @@ -13913,7 +13922,9 @@ pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT; struct net_device *netdev = pci_get_drvdata(pdev); struct bnxt *bp = netdev_priv(netdev); - int err = 0, off; + int retry = 0; + int err = 0; + int off; netdev_info(bp->dev, "PCI Slot Reset\n"); @@ -13941,11 +13952,36 @@ pci_restore_state(pdev); pci_save_state(pdev); + bnxt_inv_fw_health_reg(bp); + bnxt_try_map_fw_health_reg(bp); + + /* In some PCIe AER scenarios, firmware may take up to + * 10 seconds to become ready in the worst case. + */ + do { + err = bnxt_try_recover_fw(bp); + if (!err) + break; + retry++; + } while (retry < BNXT_FW_SLOT_RESET_RETRY); + + if (err) { + dev_err(&pdev->dev, "Firmware not ready\n"); + goto reset_exit; + } + err = bnxt_hwrm_func_reset(bp); if (!err) result = PCI_ERS_RESULT_RECOVERED; + + bnxt_ulp_irq_stop(bp); + bnxt_clear_int_mode(bp); + err = bnxt_init_int_mode(bp); + bnxt_ulp_irq_restart(bp, err); } +reset_exit: + bnxt_clear_reservations(bp, true); rtnl_unlock(); return result; @@ -14001,8 +14037,16 @@ static int __init bnxt_init(void) { + int err; + bnxt_debug_init(); - return pci_register_driver(&bnxt_pci_driver); + err = pci_register_driver(&bnxt_pci_driver); + if (err) { + bnxt_debug_exit(); + return err; + } + + return 0; } static void __exit bnxt_exit(void) diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c linux-6.0.12/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c --- linux-6.0.6/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c 2023-01-18 18:27:39.000000000 +0000 @@ -162,7 +162,7 @@ } reset_coalesce: - if (netif_running(dev)) { + if (test_bit(BNXT_STATE_OPEN, &bp->state)) { if (update_stats) { rc = bnxt_close_nic(bp, true, false); if (!rc) diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/bnxt/bnxt.h linux-6.0.12/drivers/net/ethernet/broadcom/bnxt/bnxt.h --- linux-6.0.6/drivers/net/ethernet/broadcom/bnxt/bnxt.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/bnxt/bnxt.h 2023-01-18 18:27:39.000000000 +0000 @@ -1621,6 +1621,7 @@ #define BNXT_FW_RETRY 5 #define BNXT_FW_IF_RETRY 10 +#define BNXT_FW_SLOT_RESET_RETRY 4 enum board_idx { BCM57301, diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c linux-6.0.12/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c --- linux-6.0.6/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c 2023-01-18 18:27:39.000000000 +0000 @@ -476,7 +476,8 @@ memset(ctx->resp, 0, PAGE_SIZE); req_type = le16_to_cpu(ctx->req->req_type); - if (BNXT_NO_FW_ACCESS(bp) && req_type != HWRM_FUNC_RESET) { + if (BNXT_NO_FW_ACCESS(bp) && + (req_type != HWRM_FUNC_RESET && req_type != HWRM_VER_GET)) { netdev_dbg(bp->dev, "hwrm req_type 0x%x skipped, FW channel down\n", req_type); goto exit; diff -Nru linux-6.0.6/drivers/net/ethernet/broadcom/Kconfig linux-6.0.12/drivers/net/ethernet/broadcom/Kconfig --- linux-6.0.6/drivers/net/ethernet/broadcom/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/broadcom/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -77,7 +77,7 @@ select BCM7XXX_PHY select MDIO_BCM_UNIMAC select DIMLIB - select BROADCOM_PHY if ARCH_BCM2835 + select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL) help This driver supports the built-in Ethernet MACs found in the Broadcom BCM7xxx Set Top Box family chipset. diff -Nru linux-6.0.6/drivers/net/ethernet/cadence/macb_main.c linux-6.0.12/drivers/net/ethernet/cadence/macb_main.c --- linux-6.0.6/drivers/net/ethernet/cadence/macb_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/cadence/macb_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -805,6 +805,7 @@ bp->phylink_config.dev = &dev->dev; bp->phylink_config.type = PHYLINK_NETDEV; + bp->phylink_config.mac_managed_pm = true; if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) { bp->phylink_config.poll_fixed_state = true; diff -Nru linux-6.0.6/drivers/net/ethernet/cavium/liquidio/lio_main.c linux-6.0.12/drivers/net/ethernet/cavium/liquidio/lio_main.c --- linux-6.0.6/drivers/net/ethernet/cavium/liquidio/lio_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/cavium/liquidio/lio_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1799,13 +1799,10 @@ ifstate_set(lio, LIO_IFSTATE_RUNNING); - if (OCTEON_CN23XX_PF(oct)) { - if (!oct->msix_on) - if (setup_tx_poll_fn(netdev)) - return -1; - } else { - if (setup_tx_poll_fn(netdev)) - return -1; + if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) { + ret = setup_tx_poll_fn(netdev); + if (ret) + goto err_poll; } netif_tx_start_all_queues(netdev); @@ -1818,7 +1815,7 @@ /* tell Octeon to start forwarding packets to host */ ret = send_rx_ctrl_cmd(lio, 1); if (ret) - return ret; + goto err_rx_ctrl; /* start periodical statistics fetch */ INIT_DELAYED_WORK(&lio->stats_wk.work, lio_fetch_stats); @@ -1829,6 +1826,27 @@ dev_info(&oct->pci_dev->dev, "%s interface is opened\n", netdev->name); + return 0; + +err_rx_ctrl: + if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) + cleanup_tx_poll_fn(netdev); +err_poll: + if (lio->ptp_clock) { + ptp_clock_unregister(lio->ptp_clock); + lio->ptp_clock = NULL; + } + + if (oct->props[lio->ifidx].napi_enabled == 1) { + list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list) + napi_disable(napi); + + oct->props[lio->ifidx].napi_enabled = 0; + + if (OCTEON_CN23XX_PF(oct)) + oct->droq[0]->ops.poll_mode = 0; + } + return ret; } diff -Nru linux-6.0.6/drivers/net/ethernet/cavium/thunder/thunder_bgx.c linux-6.0.12/drivers/net/ethernet/cavium/thunder/thunder_bgx.c --- linux-6.0.6/drivers/net/ethernet/cavium/thunder/thunder_bgx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/cavium/thunder/thunder_bgx.c 2023-01-18 18:27:39.000000000 +0000 @@ -1436,8 +1436,10 @@ return AE_OK; } - if (strncmp(string.pointer, bgx_sel, 4)) + if (strncmp(string.pointer, bgx_sel, 4)) { + kfree(string.pointer); return AE_OK; + } acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, bgx_acpi_register_phy, NULL, bgx, NULL); diff -Nru linux-6.0.6/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c linux-6.0.12/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c --- linux-6.0.6/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1302,6 +1302,7 @@ if (ret < 0) { CH_ERR(adap, "failed to bind qsets, err %d\n", ret); t3_intr_disable(adap); + quiesce_rx(adap); free_irq_resources(adap); err = ret; goto out; diff -Nru linux-6.0.6/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c linux-6.0.12/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c --- linux-6.0.6/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -858,7 +858,7 @@ */ err = t4vf_update_port_info(pi); if (err < 0) - return err; + goto err_unwind; /* * Note that this interface is up and start everything up ... diff -Nru linux-6.0.6/drivers/net/ethernet/davicom/dm9051.c linux-6.0.12/drivers/net/ethernet/davicom/dm9051.c --- linux-6.0.6/drivers/net/ethernet/davicom/dm9051.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/davicom/dm9051.c 2023-01-18 18:27:39.000000000 +0000 @@ -798,8 +798,10 @@ } ret = dm9051_stop_mrcmd(db); - if (ret) + if (ret) { + dev_kfree_skb(skb); return ret; + } skb->protocol = eth_type_trans(skb, db->ndev); if (db->ndev->features & NETIF_F_RXCSUM) diff -Nru linux-6.0.6/drivers/net/ethernet/engleder/tsnep_main.c linux-6.0.12/drivers/net/ethernet/engleder/tsnep_main.c --- linux-6.0.6/drivers/net/ethernet/engleder/tsnep_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/engleder/tsnep_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -504,6 +504,27 @@ return (budget != 0); } +static bool tsnep_tx_pending(struct tsnep_tx *tx) +{ + unsigned long flags; + struct tsnep_tx_entry *entry; + bool pending = false; + + spin_lock_irqsave(&tx->lock, flags); + + if (tx->read != tx->write) { + entry = &tx->entry[tx->read]; + if ((__le32_to_cpu(entry->desc_wb->properties) & + TSNEP_TX_DESC_OWNER_MASK) == + (entry->properties & TSNEP_TX_DESC_OWNER_MASK)) + pending = true; + } + + spin_unlock_irqrestore(&tx->lock, flags); + + return pending; +} + static int tsnep_tx_open(struct tsnep_adapter *adapter, void __iomem *addr, struct tsnep_tx *tx) { @@ -751,6 +772,19 @@ return done; } +static bool tsnep_rx_pending(struct tsnep_rx *rx) +{ + struct tsnep_rx_entry *entry; + + entry = &rx->entry[rx->read]; + if ((__le32_to_cpu(entry->desc_wb->properties) & + TSNEP_DESC_OWNER_COUNTER_MASK) == + (entry->properties & TSNEP_DESC_OWNER_COUNTER_MASK)) + return true; + + return false; +} + static int tsnep_rx_open(struct tsnep_adapter *adapter, void __iomem *addr, struct tsnep_rx *rx) { @@ -795,6 +829,17 @@ tsnep_rx_ring_cleanup(rx); } +static bool tsnep_pending(struct tsnep_queue *queue) +{ + if (queue->tx && tsnep_tx_pending(queue->tx)) + return true; + + if (queue->rx && tsnep_rx_pending(queue->rx)) + return true; + + return false; +} + static int tsnep_poll(struct napi_struct *napi, int budget) { struct tsnep_queue *queue = container_of(napi, struct tsnep_queue, @@ -815,9 +860,19 @@ if (!complete) return budget; - if (likely(napi_complete_done(napi, done))) + if (likely(napi_complete_done(napi, done))) { tsnep_enable_irq(queue->adapter, queue->irq_mask); + /* reschedule if work is already pending, prevent rotten packets + * which are transmitted or received after polling but before + * interrupt enable + */ + if (tsnep_pending(queue)) { + tsnep_disable_irq(queue->adapter, queue->irq_mask); + napi_schedule(napi); + } + } + return min(done, budget - 1); } diff -Nru linux-6.0.6/drivers/net/ethernet/freescale/enetc/enetc.c linux-6.0.12/drivers/net/ethernet/freescale/enetc/enetc.c --- linux-6.0.6/drivers/net/ethernet/freescale/enetc/enetc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/freescale/enetc/enetc.c 2023-01-18 18:27:39.000000000 +0000 @@ -2058,7 +2058,7 @@ /* enable Tx ints by setting pkt thr to 1 */ enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1); - tbmr = ENETC_TBMR_EN; + tbmr = ENETC_TBMR_EN | ENETC_TBMR_SET_PRIO(tx_ring->prio); if (tx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_TX) tbmr |= ENETC_TBMR_VIH; @@ -2090,7 +2090,12 @@ else enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, ENETC_RXB_DMA_SIZE); + /* Also prepare the consumer index in case page allocation never + * succeeds. In that case, hardware will never advance producer index + * to match consumer index, and will drop all frames. + */ enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0); + enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, 1); /* enable Rx ints by setting pkt thr to 1 */ enetc_rxbdr_wr(hw, idx, ENETC_RBICR0, ENETC_RBICR0_ICEN | 0x1); @@ -2116,13 +2121,14 @@ static void enetc_setup_bdrs(struct enetc_ndev_priv *priv) { + struct enetc_hw *hw = &priv->si->hw; int i; for (i = 0; i < priv->num_tx_rings; i++) - enetc_setup_txbdr(&priv->si->hw, priv->tx_ring[i]); + enetc_setup_txbdr(hw, priv->tx_ring[i]); for (i = 0; i < priv->num_rx_rings; i++) - enetc_setup_rxbdr(&priv->si->hw, priv->rx_ring[i]); + enetc_setup_rxbdr(hw, priv->rx_ring[i]); } static void enetc_clear_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) @@ -2155,13 +2161,14 @@ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv) { + struct enetc_hw *hw = &priv->si->hw; int i; for (i = 0; i < priv->num_tx_rings; i++) - enetc_clear_txbdr(&priv->si->hw, priv->tx_ring[i]); + enetc_clear_txbdr(hw, priv->tx_ring[i]); for (i = 0; i < priv->num_rx_rings; i++) - enetc_clear_rxbdr(&priv->si->hw, priv->rx_ring[i]); + enetc_clear_rxbdr(hw, priv->rx_ring[i]); udelay(1); } @@ -2169,13 +2176,13 @@ static int enetc_setup_irqs(struct enetc_ndev_priv *priv) { struct pci_dev *pdev = priv->si->pdev; + struct enetc_hw *hw = &priv->si->hw; int i, j, err; for (i = 0; i < priv->bdr_int_num; i++) { int irq = pci_irq_vector(pdev, ENETC_BDR_INT_BASE_IDX + i); struct enetc_int_vector *v = priv->int_vector[i]; int entry = ENETC_BDR_INT_BASE_IDX + i; - struct enetc_hw *hw = &priv->si->hw; snprintf(v->name, sizeof(v->name), "%s-rxtx%d", priv->ndev->name, i); @@ -2263,13 +2270,14 @@ static void enetc_clear_interrupts(struct enetc_ndev_priv *priv) { + struct enetc_hw *hw = &priv->si->hw; int i; for (i = 0; i < priv->num_tx_rings; i++) - enetc_txbdr_wr(&priv->si->hw, i, ENETC_TBIER, 0); + enetc_txbdr_wr(hw, i, ENETC_TBIER, 0); for (i = 0; i < priv->num_rx_rings; i++) - enetc_rxbdr_wr(&priv->si->hw, i, ENETC_RBIER, 0); + enetc_rxbdr_wr(hw, i, ENETC_RBIER, 0); } static int enetc_phylink_connect(struct net_device *ndev) @@ -2436,6 +2444,7 @@ { struct enetc_ndev_priv *priv = netdev_priv(ndev); struct tc_mqprio_qopt *mqprio = type_data; + struct enetc_hw *hw = &priv->si->hw; struct enetc_bdr *tx_ring; int num_stack_tx_queues; u8 num_tc; @@ -2452,7 +2461,8 @@ /* Reset all ring priorities to 0 */ for (i = 0; i < priv->num_tx_rings; i++) { tx_ring = priv->tx_ring[i]; - enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, 0); + tx_ring->prio = 0; + enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio); } return 0; @@ -2471,7 +2481,8 @@ */ for (i = 0; i < num_tc; i++) { tx_ring = priv->tx_ring[i]; - enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, i); + tx_ring->prio = i; + enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio); } /* Reset the number of netdev queues based on the TC count */ @@ -2584,19 +2595,21 @@ static void enetc_enable_rxvlan(struct net_device *ndev, bool en) { struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct enetc_hw *hw = &priv->si->hw; int i; for (i = 0; i < priv->num_rx_rings; i++) - enetc_bdr_enable_rxvlan(&priv->si->hw, i, en); + enetc_bdr_enable_rxvlan(hw, i, en); } static void enetc_enable_txvlan(struct net_device *ndev, bool en) { struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct enetc_hw *hw = &priv->si->hw; int i; for (i = 0; i < priv->num_tx_rings; i++) - enetc_bdr_enable_txvlan(&priv->si->hw, i, en); + enetc_bdr_enable_txvlan(hw, i, en); } void enetc_set_features(struct net_device *ndev, netdev_features_t features) diff -Nru linux-6.0.6/drivers/net/ethernet/freescale/enetc/enetc.h linux-6.0.12/drivers/net/ethernet/freescale/enetc/enetc.h --- linux-6.0.6/drivers/net/ethernet/freescale/enetc/enetc.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/freescale/enetc/enetc.h 2023-01-18 18:27:39.000000000 +0000 @@ -95,6 +95,7 @@ void __iomem *rcir; }; u16 index; + u16 prio; int bd_count; /* # of BDs */ int next_to_use; int next_to_clean; @@ -467,19 +468,20 @@ static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv) { + struct enetc_hw *hw = &priv->si->hw; u32 reg; - reg = enetc_port_rd(&priv->si->hw, ENETC_PSIDCAPR); + reg = enetc_port_rd(hw, ENETC_PSIDCAPR); priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK; /* Port stream filter capability */ - reg = enetc_port_rd(&priv->si->hw, ENETC_PSFCAPR); + reg = enetc_port_rd(hw, ENETC_PSFCAPR); priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK; /* Port stream gate capability */ - reg = enetc_port_rd(&priv->si->hw, ENETC_PSGCAPR); + reg = enetc_port_rd(hw, ENETC_PSGCAPR); priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK); priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16; /* Port flow meter capability */ - reg = enetc_port_rd(&priv->si->hw, ENETC_PFMCAPR); + reg = enetc_port_rd(hw, ENETC_PFMCAPR); priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK; } diff -Nru linux-6.0.6/drivers/net/ethernet/freescale/enetc/enetc_qos.c linux-6.0.12/drivers/net/ethernet/freescale/enetc/enetc_qos.c --- linux-6.0.6/drivers/net/ethernet/freescale/enetc/enetc_qos.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/freescale/enetc/enetc_qos.c 2023-01-18 18:27:39.000000000 +0000 @@ -17,8 +17,9 @@ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed) { + struct enetc_hw *hw = &priv->si->hw; u32 old_speed = priv->speed; - u32 pspeed; + u32 pspeed, tmp; if (speed == old_speed) return; @@ -39,16 +40,15 @@ } priv->speed = speed; - enetc_port_wr(&priv->si->hw, ENETC_PMR, - (enetc_port_rd(&priv->si->hw, ENETC_PMR) - & (~ENETC_PMR_PSPEED_MASK)) - | pspeed); + tmp = enetc_port_rd(hw, ENETC_PMR); + enetc_port_wr(hw, ENETC_PMR, (tmp & ~ENETC_PMR_PSPEED_MASK) | pspeed); } static int enetc_setup_taprio(struct net_device *ndev, struct tc_taprio_qopt_offload *admin_conf) { struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct enetc_hw *hw = &priv->si->hw; struct enetc_cbd cbd = {.cmd = 0}; struct tgs_gcl_conf *gcl_config; struct tgs_gcl_data *gcl_data; @@ -61,15 +61,13 @@ int err; int i; - if (admin_conf->num_entries > enetc_get_max_gcl_len(&priv->si->hw)) + if (admin_conf->num_entries > enetc_get_max_gcl_len(hw)) return -EINVAL; gcl_len = admin_conf->num_entries; - tge = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET); + tge = enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET); if (!admin_conf->enable) { - enetc_wr(&priv->si->hw, - ENETC_QBV_PTGCR_OFFSET, - tge & (~ENETC_QBV_TGE)); + enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE); priv->active_offloads &= ~ENETC_F_QBV; @@ -117,14 +115,11 @@ cbd.cls = BDCR_CMD_PORT_GCL; cbd.status_flags = 0; - enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET, - tge | ENETC_QBV_TGE); + enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge | ENETC_QBV_TGE); err = enetc_send_cmd(priv->si, &cbd); if (err) - enetc_wr(&priv->si->hw, - ENETC_QBV_PTGCR_OFFSET, - tge & (~ENETC_QBV_TGE)); + enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE); enetc_cbd_free_data_mem(priv->si, data_size, tmp, &dma); @@ -138,6 +133,8 @@ { struct tc_taprio_qopt_offload *taprio = type_data; struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct enetc_hw *hw = &priv->si->hw; + struct enetc_bdr *tx_ring; int err; int i; @@ -146,18 +143,20 @@ if (priv->tx_ring[i]->tsd_enable) return -EBUSY; - for (i = 0; i < priv->num_tx_rings; i++) - enetc_set_bdr_prio(&priv->si->hw, - priv->tx_ring[i]->index, - taprio->enable ? i : 0); + for (i = 0; i < priv->num_tx_rings; i++) { + tx_ring = priv->tx_ring[i]; + tx_ring->prio = taprio->enable ? i : 0; + enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio); + } err = enetc_setup_taprio(ndev, taprio); - - if (err) - for (i = 0; i < priv->num_tx_rings; i++) - enetc_set_bdr_prio(&priv->si->hw, - priv->tx_ring[i]->index, - taprio->enable ? 0 : i); + if (err) { + for (i = 0; i < priv->num_tx_rings; i++) { + tx_ring = priv->tx_ring[i]; + tx_ring->prio = taprio->enable ? 0 : i; + enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio); + } + } return err; } @@ -178,7 +177,7 @@ struct tc_cbs_qopt_offload *cbs = type_data; u32 port_transmit_rate = priv->speed; u8 tc_nums = netdev_get_num_tc(ndev); - struct enetc_si *si = priv->si; + struct enetc_hw *hw = &priv->si->hw; u32 hi_credit_bit, hi_credit_reg; u32 max_interference_size; u32 port_frame_max_size; @@ -199,15 +198,15 @@ * lower than this TC have been disabled. */ if (tc == prio_top && - enetc_get_cbs_enable(&si->hw, prio_next)) { + enetc_get_cbs_enable(hw, prio_next)) { dev_err(&ndev->dev, "Disable TC%d before disable TC%d\n", prio_next, tc); return -EINVAL; } - enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0); - enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0); + enetc_port_wr(hw, ENETC_PTCCBSR1(tc), 0); + enetc_port_wr(hw, ENETC_PTCCBSR0(tc), 0); return 0; } @@ -224,13 +223,13 @@ * higher than this TC have been enabled. */ if (tc == prio_next) { - if (!enetc_get_cbs_enable(&si->hw, prio_top)) { + if (!enetc_get_cbs_enable(hw, prio_top)) { dev_err(&ndev->dev, "Enable TC%d first before enable TC%d\n", prio_top, prio_next); return -EINVAL; } - bw_sum += enetc_get_cbs_bw(&si->hw, prio_top); + bw_sum += enetc_get_cbs_bw(hw, prio_top); } if (bw_sum + bw >= 100) { @@ -239,7 +238,7 @@ return -EINVAL; } - enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc)); + enetc_port_rd(hw, ENETC_PTCMSDUR(tc)); /* For top prio TC, the max_interfrence_size is maxSizedFrame. * @@ -259,8 +258,8 @@ u32 m0, ma, r0, ra; m0 = port_frame_max_size * 8; - ma = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(prio_top)) * 8; - ra = enetc_get_cbs_bw(&si->hw, prio_top) * + ma = enetc_port_rd(hw, ENETC_PTCMSDUR(prio_top)) * 8; + ra = enetc_get_cbs_bw(hw, prio_top) * port_transmit_rate * 10000ULL; r0 = port_transmit_rate * 1000000ULL; max_interference_size = m0 + ma + @@ -280,10 +279,10 @@ hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit, port_transmit_rate * 1000000ULL); - enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit_reg); + enetc_port_wr(hw, ENETC_PTCCBSR1(tc), hi_credit_reg); /* Set bw register and enable this traffic class */ - enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE); + enetc_port_wr(hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE); return 0; } @@ -293,6 +292,7 @@ struct enetc_ndev_priv *priv = netdev_priv(ndev); struct tc_etf_qopt_offload *qopt = type_data; u8 tc_nums = netdev_get_num_tc(ndev); + struct enetc_hw *hw = &priv->si->hw; int tc; if (!tc_nums) @@ -304,12 +304,11 @@ return -EINVAL; /* TSD and Qbv are mutually exclusive in hardware */ - if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE) + if (enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE) return -EBUSY; priv->tx_ring[tc]->tsd_enable = qopt->enable; - enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc), - qopt->enable ? ENETC_TSDE : 0); + enetc_port_wr(hw, ENETC_PTCTSDR(tc), qopt->enable ? ENETC_TSDE : 0); return 0; } diff -Nru linux-6.0.6/drivers/net/ethernet/freescale/fec_main.c linux-6.0.12/drivers/net/ethernet/freescale/fec_main.c --- linux-6.0.6/drivers/net/ethernet/freescale/fec_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/freescale/fec_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -657,7 +657,7 @@ dev_kfree_skb_any(skb); if (net_ratelimit()) netdev_err(ndev, "Tx DMA memory map failed\n"); - return NETDEV_TX_BUSY; + return NETDEV_TX_OK; } bdp->cbd_datlen = cpu_to_fec16(size); @@ -719,7 +719,7 @@ dev_kfree_skb_any(skb); if (net_ratelimit()) netdev_err(ndev, "Tx DMA memory map failed\n"); - return NETDEV_TX_BUSY; + return NETDEV_TX_OK; } } @@ -2347,6 +2347,31 @@ IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR, IEEE_R_FDXFC, IEEE_R_OCTETS_OK }; +/* for i.MX6ul */ +static u32 fec_enet_register_offset_6ul[] = { + FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0, + FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL, + FEC_X_CNTRL, FEC_ADDR_LOW, FEC_ADDR_HIGH, FEC_OPD, FEC_TXIC0, FEC_RXIC0, + FEC_HASH_TABLE_HIGH, FEC_HASH_TABLE_LOW, FEC_GRP_HASH_TABLE_HIGH, + FEC_GRP_HASH_TABLE_LOW, FEC_X_WMRK, FEC_R_DES_START_0, + FEC_X_DES_START_0, FEC_R_BUFF_SIZE_0, FEC_R_FIFO_RSFL, FEC_R_FIFO_RSEM, + FEC_R_FIFO_RAEM, FEC_R_FIFO_RAFL, FEC_RACC, + RMON_T_DROP, RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT, + RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG, + RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255, + RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2047, + RMON_T_P_GTE2048, RMON_T_OCTETS, + IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL, IEEE_T_DEF, + IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR, IEEE_T_SQE, + IEEE_T_FDXFC, IEEE_T_OCTETS_OK, + RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN, + RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB, + RMON_R_RESVD_O, RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255, + RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047, + RMON_R_P_GTE2048, RMON_R_OCTETS, + IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR, + IEEE_R_FDXFC, IEEE_R_OCTETS_OK +}; #else static __u32 fec_enet_register_version = 1; static u32 fec_enet_register_offset[] = { @@ -2371,7 +2396,24 @@ u32 *buf = (u32 *)regbuf; u32 i, off; int ret; +#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \ + defined(CONFIG_ARM64) || defined(CONFIG_COMPILE_TEST) + u32 *reg_list; + u32 reg_cnt; + if (!of_machine_is_compatible("fsl,imx6ul")) { + reg_list = fec_enet_register_offset; + reg_cnt = ARRAY_SIZE(fec_enet_register_offset); + } else { + reg_list = fec_enet_register_offset_6ul; + reg_cnt = ARRAY_SIZE(fec_enet_register_offset_6ul); + } +#else + /* coldfire */ + static u32 *reg_list = fec_enet_register_offset; + static const u32 reg_cnt = ARRAY_SIZE(fec_enet_register_offset); +#endif ret = pm_runtime_resume_and_get(dev); if (ret < 0) return; @@ -2380,8 +2422,8 @@ memset(buf, 0, regs->len); - for (i = 0; i < ARRAY_SIZE(fec_enet_register_offset); i++) { - off = fec_enet_register_offset[i]; + for (i = 0; i < reg_cnt; i++) { + off = reg_list[i]; if ((off == FEC_R_BOUND || off == FEC_R_FSTART) && !(fep->quirks & FEC_QUIRK_HAS_FRREG)) diff -Nru linux-6.0.6/drivers/net/ethernet/freescale/fman/mac.c linux-6.0.12/drivers/net/ethernet/freescale/fman/mac.c --- linux-6.0.6/drivers/net/ethernet/freescale/fman/mac.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/freescale/fman/mac.c 2023-01-18 18:27:39.000000000 +0000 @@ -882,12 +882,21 @@ return err; } +static int mac_remove(struct platform_device *pdev) +{ + struct mac_device *mac_dev = platform_get_drvdata(pdev); + + platform_device_unregister(mac_dev->priv->eth_dev); + return 0; +} + static struct platform_driver mac_driver = { .driver = { .name = KBUILD_MODNAME, .of_match_table = mac_match, }, .probe = mac_probe, + .remove = mac_remove, }; builtin_platform_driver(mac_driver); diff -Nru linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hnae3.h linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hnae3.h --- linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hnae3.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hnae3.h 2023-01-18 18:27:39.000000000 +0000 @@ -790,7 +790,6 @@ const struct hnae3_dcb_ops *dcb_ops; u16 int_rl_setting; - enum pkt_hash_types rss_type; void __iomem *io_base; }; diff -Nru linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c --- linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c 2023-01-18 18:27:39.000000000 +0000 @@ -191,23 +191,6 @@ return HCLGE_COMM_RSS_KEY_SIZE; } -void hclge_comm_get_rss_type(struct hnae3_handle *nic, - struct hclge_comm_rss_tuple_cfg *rss_tuple_sets) -{ - if (rss_tuple_sets->ipv4_tcp_en || - rss_tuple_sets->ipv4_udp_en || - rss_tuple_sets->ipv4_sctp_en || - rss_tuple_sets->ipv6_tcp_en || - rss_tuple_sets->ipv6_udp_en || - rss_tuple_sets->ipv6_sctp_en) - nic->kinfo.rss_type = PKT_HASH_TYPE_L4; - else if (rss_tuple_sets->ipv4_fragment_en || - rss_tuple_sets->ipv6_fragment_en) - nic->kinfo.rss_type = PKT_HASH_TYPE_L3; - else - nic->kinfo.rss_type = PKT_HASH_TYPE_NONE; -} - int hclge_comm_parse_rss_hfunc(struct hclge_comm_rss_cfg *rss_cfg, const u8 hfunc, u8 *hash_algo) { @@ -344,9 +327,6 @@ req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en; req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en; - if (is_pf) - hclge_comm_get_rss_type(nic, &rss_cfg->rss_tuple_sets); - ret = hclge_comm_cmd_send(hw, &desc, 1); if (ret) dev_err(&hw->cmq.csq.pdev->dev, diff -Nru linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h --- linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h 2023-01-18 18:27:39.000000000 +0000 @@ -95,8 +95,6 @@ }; u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle); -void hclge_comm_get_rss_type(struct hnae3_handle *nic, - struct hclge_comm_rss_tuple_cfg *rss_tuple_sets); void hclge_comm_rss_indir_init_cfg(struct hnae3_ae_dev *ae_dev, struct hclge_comm_rss_cfg *rss_cfg); int hclge_comm_get_rss_tuple(struct hclge_comm_rss_cfg *rss_cfg, int flow_type, diff -Nru linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c --- linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 2023-01-18 18:27:39.000000000 +0000 @@ -105,26 +105,28 @@ }; MODULE_DEVICE_TABLE(pci, hns3_pci_tbl); -#define HNS3_RX_PTYPE_ENTRY(ptype, l, s, t) \ +#define HNS3_RX_PTYPE_ENTRY(ptype, l, s, t, h) \ { ptype, \ l, \ CHECKSUM_##s, \ HNS3_L3_TYPE_##t, \ - 1 } + 1, \ + h} #define HNS3_RX_PTYPE_UNUSED_ENTRY(ptype) \ - { ptype, 0, CHECKSUM_NONE, HNS3_L3_TYPE_PARSE_FAIL, 0 } + { ptype, 0, CHECKSUM_NONE, HNS3_L3_TYPE_PARSE_FAIL, 0, \ + PKT_HASH_TYPE_NONE } static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = { HNS3_RX_PTYPE_UNUSED_ENTRY(0), - HNS3_RX_PTYPE_ENTRY(1, 0, COMPLETE, ARP), - HNS3_RX_PTYPE_ENTRY(2, 0, COMPLETE, RARP), - HNS3_RX_PTYPE_ENTRY(3, 0, COMPLETE, LLDP), - HNS3_RX_PTYPE_ENTRY(4, 0, COMPLETE, PARSE_FAIL), - HNS3_RX_PTYPE_ENTRY(5, 0, COMPLETE, PARSE_FAIL), - HNS3_RX_PTYPE_ENTRY(6, 0, COMPLETE, PARSE_FAIL), - HNS3_RX_PTYPE_ENTRY(7, 0, COMPLETE, CNM), - HNS3_RX_PTYPE_ENTRY(8, 0, NONE, PARSE_FAIL), + HNS3_RX_PTYPE_ENTRY(1, 0, COMPLETE, ARP, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(2, 0, COMPLETE, RARP, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(3, 0, COMPLETE, LLDP, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(4, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(5, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(6, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(7, 0, COMPLETE, CNM, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(8, 0, NONE, PARSE_FAIL, PKT_HASH_TYPE_NONE), HNS3_RX_PTYPE_UNUSED_ENTRY(9), HNS3_RX_PTYPE_UNUSED_ENTRY(10), HNS3_RX_PTYPE_UNUSED_ENTRY(11), @@ -132,36 +134,36 @@ HNS3_RX_PTYPE_UNUSED_ENTRY(13), HNS3_RX_PTYPE_UNUSED_ENTRY(14), HNS3_RX_PTYPE_UNUSED_ENTRY(15), - HNS3_RX_PTYPE_ENTRY(16, 0, COMPLETE, PARSE_FAIL), - HNS3_RX_PTYPE_ENTRY(17, 0, COMPLETE, IPV4), - HNS3_RX_PTYPE_ENTRY(18, 0, COMPLETE, IPV4), - HNS3_RX_PTYPE_ENTRY(19, 0, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(20, 0, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(21, 0, NONE, IPV4), - HNS3_RX_PTYPE_ENTRY(22, 0, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(23, 0, NONE, IPV4), - HNS3_RX_PTYPE_ENTRY(24, 0, NONE, IPV4), - HNS3_RX_PTYPE_ENTRY(25, 0, UNNECESSARY, IPV4), + HNS3_RX_PTYPE_ENTRY(16, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(17, 0, COMPLETE, IPV4, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(18, 0, COMPLETE, IPV4, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(19, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(20, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(21, 0, NONE, IPV4, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(22, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(23, 0, NONE, IPV4, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(24, 0, NONE, IPV4, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(25, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), HNS3_RX_PTYPE_UNUSED_ENTRY(26), HNS3_RX_PTYPE_UNUSED_ENTRY(27), HNS3_RX_PTYPE_UNUSED_ENTRY(28), - HNS3_RX_PTYPE_ENTRY(29, 0, COMPLETE, PARSE_FAIL), - HNS3_RX_PTYPE_ENTRY(30, 0, COMPLETE, PARSE_FAIL), - HNS3_RX_PTYPE_ENTRY(31, 0, COMPLETE, IPV4), - HNS3_RX_PTYPE_ENTRY(32, 0, COMPLETE, IPV4), - HNS3_RX_PTYPE_ENTRY(33, 1, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(34, 1, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(35, 1, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(36, 0, COMPLETE, IPV4), - HNS3_RX_PTYPE_ENTRY(37, 0, COMPLETE, IPV4), + HNS3_RX_PTYPE_ENTRY(29, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(30, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(31, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(32, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(33, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(34, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(35, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(36, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(37, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3), HNS3_RX_PTYPE_UNUSED_ENTRY(38), - HNS3_RX_PTYPE_ENTRY(39, 0, COMPLETE, IPV6), - HNS3_RX_PTYPE_ENTRY(40, 0, COMPLETE, IPV6), - HNS3_RX_PTYPE_ENTRY(41, 1, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(42, 1, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(43, 1, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(44, 0, COMPLETE, IPV6), - HNS3_RX_PTYPE_ENTRY(45, 0, COMPLETE, IPV6), + HNS3_RX_PTYPE_ENTRY(39, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(40, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(41, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(42, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(43, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(44, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(45, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), HNS3_RX_PTYPE_UNUSED_ENTRY(46), HNS3_RX_PTYPE_UNUSED_ENTRY(47), HNS3_RX_PTYPE_UNUSED_ENTRY(48), @@ -227,35 +229,35 @@ HNS3_RX_PTYPE_UNUSED_ENTRY(108), HNS3_RX_PTYPE_UNUSED_ENTRY(109), HNS3_RX_PTYPE_UNUSED_ENTRY(110), - HNS3_RX_PTYPE_ENTRY(111, 0, COMPLETE, IPV6), - HNS3_RX_PTYPE_ENTRY(112, 0, COMPLETE, IPV6), - HNS3_RX_PTYPE_ENTRY(113, 0, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(114, 0, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(115, 0, NONE, IPV6), - HNS3_RX_PTYPE_ENTRY(116, 0, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(117, 0, NONE, IPV6), - HNS3_RX_PTYPE_ENTRY(118, 0, NONE, IPV6), - HNS3_RX_PTYPE_ENTRY(119, 0, UNNECESSARY, IPV6), + HNS3_RX_PTYPE_ENTRY(111, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(112, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(113, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(114, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(115, 0, NONE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(116, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(117, 0, NONE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(118, 0, NONE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(119, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), HNS3_RX_PTYPE_UNUSED_ENTRY(120), HNS3_RX_PTYPE_UNUSED_ENTRY(121), HNS3_RX_PTYPE_UNUSED_ENTRY(122), - HNS3_RX_PTYPE_ENTRY(123, 0, COMPLETE, PARSE_FAIL), - HNS3_RX_PTYPE_ENTRY(124, 0, COMPLETE, PARSE_FAIL), - HNS3_RX_PTYPE_ENTRY(125, 0, COMPLETE, IPV4), - HNS3_RX_PTYPE_ENTRY(126, 0, COMPLETE, IPV4), - HNS3_RX_PTYPE_ENTRY(127, 1, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(128, 1, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(129, 1, UNNECESSARY, IPV4), - HNS3_RX_PTYPE_ENTRY(130, 0, COMPLETE, IPV4), - HNS3_RX_PTYPE_ENTRY(131, 0, COMPLETE, IPV4), + HNS3_RX_PTYPE_ENTRY(123, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(124, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE), + HNS3_RX_PTYPE_ENTRY(125, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(126, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(127, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(128, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(129, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(130, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(131, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3), HNS3_RX_PTYPE_UNUSED_ENTRY(132), - HNS3_RX_PTYPE_ENTRY(133, 0, COMPLETE, IPV6), - HNS3_RX_PTYPE_ENTRY(134, 0, COMPLETE, IPV6), - HNS3_RX_PTYPE_ENTRY(135, 1, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(136, 1, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(137, 1, UNNECESSARY, IPV6), - HNS3_RX_PTYPE_ENTRY(138, 0, COMPLETE, IPV6), - HNS3_RX_PTYPE_ENTRY(139, 0, COMPLETE, IPV6), + HNS3_RX_PTYPE_ENTRY(133, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(134, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(135, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(136, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(137, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4), + HNS3_RX_PTYPE_ENTRY(138, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), + HNS3_RX_PTYPE_ENTRY(139, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3), HNS3_RX_PTYPE_UNUSED_ENTRY(140), HNS3_RX_PTYPE_UNUSED_ENTRY(141), HNS3_RX_PTYPE_UNUSED_ENTRY(142), @@ -3734,8 +3736,8 @@ desc_cb->reuse_flag = 1; } else if (frag_size <= ring->rx_copybreak) { ret = hns3_handle_rx_copybreak(skb, i, ring, pull_len, desc_cb); - if (ret) - goto out; + if (!ret) + return; } out: @@ -4129,15 +4131,35 @@ } static void hns3_set_rx_skb_rss_type(struct hns3_enet_ring *ring, - struct sk_buff *skb, u32 rss_hash) + struct sk_buff *skb, u32 rss_hash, + u32 l234info, u32 ol_info) { - struct hnae3_handle *handle = ring->tqp->handle; - enum pkt_hash_types rss_type; + enum pkt_hash_types rss_type = PKT_HASH_TYPE_NONE; + struct net_device *netdev = ring_to_netdev(ring); + struct hns3_nic_priv *priv = netdev_priv(netdev); - if (rss_hash) - rss_type = handle->kinfo.rss_type; - else - rss_type = PKT_HASH_TYPE_NONE; + if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) { + u32 ptype = hnae3_get_field(ol_info, HNS3_RXD_PTYPE_M, + HNS3_RXD_PTYPE_S); + + rss_type = hns3_rx_ptype_tbl[ptype].hash_type; + } else { + int l3_type = hnae3_get_field(l234info, HNS3_RXD_L3ID_M, + HNS3_RXD_L3ID_S); + int l4_type = hnae3_get_field(l234info, HNS3_RXD_L4ID_M, + HNS3_RXD_L4ID_S); + + if (l3_type == HNS3_L3_TYPE_IPV4 || + l3_type == HNS3_L3_TYPE_IPV6) { + if (l4_type == HNS3_L4_TYPE_UDP || + l4_type == HNS3_L4_TYPE_TCP || + l4_type == HNS3_L4_TYPE_SCTP) + rss_type = PKT_HASH_TYPE_L4; + else if (l4_type == HNS3_L4_TYPE_IGMP || + l4_type == HNS3_L4_TYPE_ICMP) + rss_type = PKT_HASH_TYPE_L3; + } + } skb_set_hash(skb, rss_hash, rss_type); } @@ -4240,7 +4262,8 @@ ring->tqp_vector->rx_group.total_bytes += len; - hns3_set_rx_skb_rss_type(ring, skb, le32_to_cpu(desc->rx.rss_hash)); + hns3_set_rx_skb_rss_type(ring, skb, le32_to_cpu(desc->rx.rss_hash), + l234info, ol_info); return 0; } diff -Nru linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h --- linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 2023-01-18 18:27:39.000000000 +0000 @@ -404,6 +404,7 @@ u32 ip_summed : 2; u32 l3_type : 4; u32 valid : 1; + u32 hash_type: 3; }; struct ring_stats { diff -Nru linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c --- linux-6.0.6/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -3246,6 +3246,7 @@ hdev->hw.mac.autoneg = cmd.base.autoneg; hdev->hw.mac.speed = cmd.base.speed; hdev->hw.mac.duplex = cmd.base.duplex; + linkmode_copy(hdev->hw.mac.advertising, cmd.link_modes.advertising); return 0; } @@ -4662,7 +4663,6 @@ return ret; } - hclge_comm_get_rss_type(&vport->nic, &hdev->rss_cfg.rss_tuple_sets); return 0; } @@ -11374,9 +11374,12 @@ if (ret) goto err_msi_irq_uninit; - if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER && - !hnae3_dev_phy_imp_supported(hdev)) { - ret = hclge_mac_mdio_config(hdev); + if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) { + if (hnae3_dev_phy_imp_supported(hdev)) + ret = hclge_update_tp_port_info(hdev); + else + ret = hclge_mac_mdio_config(hdev); + if (ret) goto err_msi_irq_uninit; } diff -Nru linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c --- linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -85,6 +85,7 @@ struct tag_sml_funcfg_tbl *funcfg_table_elem; struct hinic_cmd_lt_rd *read_data; u16 out_size = sizeof(*read_data); + int ret = ~0; int err; read_data = kzalloc(sizeof(*read_data), GFP_KERNEL); @@ -111,20 +112,25 @@ switch (idx) { case VALID: - return funcfg_table_elem->dw0.bs.valid; + ret = funcfg_table_elem->dw0.bs.valid; + break; case RX_MODE: - return funcfg_table_elem->dw0.bs.nic_rx_mode; + ret = funcfg_table_elem->dw0.bs.nic_rx_mode; + break; case MTU: - return funcfg_table_elem->dw1.bs.mtu; + ret = funcfg_table_elem->dw1.bs.mtu; + break; case RQ_DEPTH: - return funcfg_table_elem->dw13.bs.cfg_rq_depth; + ret = funcfg_table_elem->dw13.bs.cfg_rq_depth; + break; case QUEUE_NUM: - return funcfg_table_elem->dw13.bs.cfg_q_num; + ret = funcfg_table_elem->dw13.bs.cfg_q_num; + break; } kfree(read_data); - return ~0; + return ret; } static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count, diff -Nru linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c --- linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c 2023-01-18 18:27:39.000000000 +0000 @@ -929,7 +929,7 @@ err_set_cmdq_depth: hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ); - + free_cmdq(&cmdqs->cmdq[HINIC_CMDQ_SYNC]); err_cmdq_ctxt: hinic_wqs_cmdq_free(&cmdqs->cmdq_pages, cmdqs->saved_wqs, HINIC_MAX_CMDQ_TYPES); diff -Nru linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c --- linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c 2023-01-18 18:27:39.000000000 +0000 @@ -883,7 +883,7 @@ if (err) return -EINVAL; - interrupt_info->lli_credit_cnt = temp_info.lli_timer_cnt; + interrupt_info->lli_credit_cnt = temp_info.lli_credit_cnt; interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt; err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, diff -Nru linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_main.c linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_main.c --- linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1478,8 +1478,15 @@ static int __init hinic_module_init(void) { + int ret; + hinic_dbg_register_debugfs(HINIC_DRV_NAME); - return pci_register_driver(&hinic_driver); + + ret = pci_register_driver(&hinic_driver); + if (ret) + hinic_dbg_unregister_debugfs(); + + return ret; } static void __exit hinic_module_exit(void) diff -Nru linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_sriov.c linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_sriov.c --- linux-6.0.6/drivers/net/ethernet/huawei/hinic/hinic_sriov.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/huawei/hinic/hinic_sriov.c 2023-01-18 18:27:39.000000000 +0000 @@ -1175,7 +1175,6 @@ dev_err(&hwdev->hwif->pdev->dev, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n", err, register_info.status, out_size); - hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC); return -EIO; } } else { diff -Nru linux-6.0.6/drivers/net/ethernet/ibm/ehea/ehea_main.c linux-6.0.12/drivers/net/ethernet/ibm/ehea/ehea_main.c --- linux-6.0.6/drivers/net/ethernet/ibm/ehea/ehea_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/ibm/ehea/ehea_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -2900,6 +2900,7 @@ ret = of_device_register(&port->ofdev); if (ret) { pr_err("failed to register device. ret=%d\n", ret); + put_device(&port->ofdev.dev); goto out; } diff -Nru linux-6.0.6/drivers/net/ethernet/ibm/ibmvnic.c linux-6.0.12/drivers/net/ethernet/ibm/ibmvnic.c --- linux-6.0.6/drivers/net/ethernet/ibm/ibmvnic.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/ibm/ibmvnic.c 2023-01-18 18:27:39.000000000 +0000 @@ -3007,19 +3007,19 @@ rwi = get_next_rwi(adapter); /* - * If there is another reset queued, free the previous rwi - * and process the new reset even if previous reset failed - * (the previous reset could have failed because of a fail - * over for instance, so process the fail over). - * * If there are no resets queued and the previous reset failed, * the adapter would be in an undefined state. So retry the * previous reset as a hard reset. + * + * Else, free the previous rwi and, if there is another reset + * queued, process the new reset even if previous reset failed + * (the previous reset could have failed because of a fail + * over for instance, so process the fail over). */ - if (rwi) - kfree(tmprwi); - else if (rc) + if (!rwi && rc) rwi = tmprwi; + else + kfree(tmprwi); if (rwi && (rwi->reset_reason == VNIC_RESET_FAILOVER || rwi->reset_reason == VNIC_RESET_MOBILITY || rc)) diff -Nru linux-6.0.6/drivers/net/ethernet/intel/e100.c linux-6.0.12/drivers/net/ethernet/intel/e100.c --- linux-6.0.6/drivers/net/ethernet/intel/e100.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/e100.c 2023-01-18 18:27:39.000000000 +0000 @@ -1741,11 +1741,8 @@ dma_addr = dma_map_single(&nic->pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); /* If we can't map the skb, have the upper layer try later */ - if (dma_mapping_error(&nic->pdev->dev, dma_addr)) { - dev_kfree_skb_any(skb); - skb = NULL; + if (dma_mapping_error(&nic->pdev->dev, dma_addr)) return -ENOMEM; - } /* * Use the last 4 bytes of the SKB payload packet as the CRC, used for diff -Nru linux-6.0.6/drivers/net/ethernet/intel/fm10k/fm10k_main.c linux-6.0.12/drivers/net/ethernet/intel/fm10k/fm10k_main.c --- linux-6.0.6/drivers/net/ethernet/intel/fm10k/fm10k_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/fm10k/fm10k_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -32,6 +32,8 @@ **/ static int __init fm10k_init_module(void) { + int ret; + pr_info("%s\n", fm10k_driver_string); pr_info("%s\n", fm10k_copyright); @@ -43,7 +45,13 @@ fm10k_dbg_init(); - return fm10k_register_pci_driver(); + ret = fm10k_register_pci_driver(); + if (ret) { + fm10k_dbg_exit(); + destroy_workqueue(fm10k_workqueue); + } + + return ret; } module_init(fm10k_init_module); diff -Nru linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_ethtool.c linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_ethtool.c --- linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_ethtool.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_ethtool.c 2023-01-18 18:27:39.000000000 +0000 @@ -3185,10 +3185,17 @@ if (cmd->flow_type == TCP_V4_FLOW || cmd->flow_type == UDP_V4_FLOW) { - if (i_set & I40E_L3_SRC_MASK) - cmd->data |= RXH_IP_SRC; - if (i_set & I40E_L3_DST_MASK) - cmd->data |= RXH_IP_DST; + if (hw->mac.type == I40E_MAC_X722) { + if (i_set & I40E_X722_L3_SRC_MASK) + cmd->data |= RXH_IP_SRC; + if (i_set & I40E_X722_L3_DST_MASK) + cmd->data |= RXH_IP_DST; + } else { + if (i_set & I40E_L3_SRC_MASK) + cmd->data |= RXH_IP_SRC; + if (i_set & I40E_L3_DST_MASK) + cmd->data |= RXH_IP_DST; + } } else if (cmd->flow_type == TCP_V6_FLOW || cmd->flow_type == UDP_V6_FLOW) { if (i_set & I40E_L3_V6_SRC_MASK) @@ -3546,12 +3553,15 @@ /** * i40e_get_rss_hash_bits - Read RSS Hash bits from register + * @hw: hw structure * @nfc: pointer to user request * @i_setc: bits currently set * * Returns value of bits to be set per user request **/ -static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc) +static u64 i40e_get_rss_hash_bits(struct i40e_hw *hw, + struct ethtool_rxnfc *nfc, + u64 i_setc) { u64 i_set = i_setc; u64 src_l3 = 0, dst_l3 = 0; @@ -3570,8 +3580,13 @@ dst_l3 = I40E_L3_V6_DST_MASK; } else if (nfc->flow_type == TCP_V4_FLOW || nfc->flow_type == UDP_V4_FLOW) { - src_l3 = I40E_L3_SRC_MASK; - dst_l3 = I40E_L3_DST_MASK; + if (hw->mac.type == I40E_MAC_X722) { + src_l3 = I40E_X722_L3_SRC_MASK; + dst_l3 = I40E_X722_L3_DST_MASK; + } else { + src_l3 = I40E_L3_SRC_MASK; + dst_l3 = I40E_L3_DST_MASK; + } } else { /* Any other flow type are not supported here */ return i_set; @@ -3589,6 +3604,7 @@ return i_set; } +#define FLOW_PCTYPES_SIZE 64 /** * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash * @pf: pointer to the physical function struct @@ -3601,9 +3617,11 @@ struct i40e_hw *hw = &pf->hw; u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) | ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32); - u8 flow_pctype = 0; + DECLARE_BITMAP(flow_pctypes, FLOW_PCTYPES_SIZE); u64 i_set, i_setc; + bitmap_zero(flow_pctypes, FLOW_PCTYPES_SIZE); + if (pf->flags & I40E_FLAG_MFP_ENABLED) { dev_err(&pf->pdev->dev, "Change of RSS hash input set is not supported when MFP mode is enabled\n"); @@ -3619,36 +3637,35 @@ switch (nfc->flow_type) { case TCP_V4_FLOW: - flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP; + set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, flow_pctypes); if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK); + set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK, + flow_pctypes); break; case TCP_V6_FLOW: - flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP; + set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, flow_pctypes); if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK); - if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK); + set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK, + flow_pctypes); break; case UDP_V4_FLOW: - flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP; - if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | - BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP); - + set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, flow_pctypes); + if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) { + set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP, + flow_pctypes); + set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP, + flow_pctypes); + } hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4); break; case UDP_V6_FLOW: - flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_UDP; - if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | - BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP); - + set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, flow_pctypes); + if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) { + set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP, + flow_pctypes); + set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP, + flow_pctypes); + } hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6); break; case AH_ESP_V4_FLOW: @@ -3681,17 +3698,20 @@ return -EINVAL; } - if (flow_pctype) { - i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, - flow_pctype)) | - ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, - flow_pctype)) << 32); - i_set = i40e_get_rss_hash_bits(nfc, i_setc); - i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_pctype), - (u32)i_set); - i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_pctype), - (u32)(i_set >> 32)); - hena |= BIT_ULL(flow_pctype); + if (bitmap_weight(flow_pctypes, FLOW_PCTYPES_SIZE)) { + u8 flow_id; + + for_each_set_bit(flow_id, flow_pctypes, FLOW_PCTYPES_SIZE) { + i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id)) | + ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id)) << 32); + i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc); + + i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id), + (u32)i_set); + i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id), + (u32)(i_set >> 32)); + hena |= BIT_ULL(flow_id); + } } i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena); diff -Nru linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_main.c linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_main.c --- linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -16652,6 +16652,8 @@ **/ static int __init i40e_init_module(void) { + int err; + pr_info("%s: %s\n", i40e_driver_name, i40e_driver_string); pr_info("%s: %s\n", i40e_driver_name, i40e_copyright); @@ -16669,7 +16671,14 @@ } i40e_dbg_init(); - return pci_register_driver(&i40e_driver); + err = pci_register_driver(&i40e_driver); + if (err) { + destroy_workqueue(i40e_wq); + i40e_dbg_exit(); + return err; + } + + return 0; } module_init(i40e_init_module); diff -Nru linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_type.h linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_type.h --- linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_type.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_type.h 2023-01-18 18:27:39.000000000 +0000 @@ -1404,6 +1404,10 @@ #define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000 /* INPUT SET MASK for RSS, flow director, and flexible payload */ +#define I40E_X722_L3_SRC_SHIFT 49 +#define I40E_X722_L3_SRC_MASK (0x3ULL << I40E_X722_L3_SRC_SHIFT) +#define I40E_X722_L3_DST_SHIFT 41 +#define I40E_X722_L3_DST_MASK (0x3ULL << I40E_X722_L3_DST_SHIFT) #define I40E_L3_SRC_SHIFT 47 #define I40E_L3_SRC_MASK (0x3ULL << I40E_L3_SRC_SHIFT) #define I40E_L3_V6_SRC_SHIFT 43 diff -Nru linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c --- linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c 2023-01-18 18:27:39.000000000 +0000 @@ -1536,10 +1536,12 @@ if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state)) return true; - /* If the VFs have been disabled, this means something else is - * resetting the VF, so we shouldn't continue. - */ - if (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) + /* Bail out if VFs are disabled. */ + if (test_bit(__I40E_VF_DISABLE, pf->state)) + return true; + + /* If VF is being reset already we don't need to continue. */ + if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) return true; i40e_trigger_vf_reset(vf, flr); @@ -1576,7 +1578,7 @@ i40e_cleanup_reset_vf(vf); i40e_flush(hw); - clear_bit(__I40E_VF_DISABLE, pf->state); + clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states); return true; } @@ -1609,8 +1611,12 @@ return false; /* Begin reset on all VFs at once */ - for (v = 0; v < pf->num_alloc_vfs; v++) - i40e_trigger_vf_reset(&pf->vf[v], flr); + for (v = 0; v < pf->num_alloc_vfs; v++) { + vf = &pf->vf[v]; + /* If VF is being reset no need to trigger reset again */ + if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) + i40e_trigger_vf_reset(&pf->vf[v], flr); + } /* HW requires some time to make sure it can flush the FIFO for a VF * when it resets it. Poll the VPGEN_VFRSTAT register for each VF in @@ -1626,9 +1632,11 @@ */ while (v < pf->num_alloc_vfs) { vf = &pf->vf[v]; - reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id)); - if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK)) - break; + if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) { + reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id)); + if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK)) + break; + } /* If the current VF has finished resetting, move on * to the next VF in sequence. @@ -1656,6 +1664,10 @@ if (pf->vf[v].lan_vsi_idx == 0) continue; + /* If VF is reset in another thread just continue */ + if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) + continue; + i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]); } @@ -1667,6 +1679,10 @@ if (pf->vf[v].lan_vsi_idx == 0) continue; + /* If VF is reset in another thread just continue */ + if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) + continue; + i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]); } @@ -1676,8 +1692,13 @@ mdelay(50); /* Finish the reset on each VF */ - for (v = 0; v < pf->num_alloc_vfs; v++) + for (v = 0; v < pf->num_alloc_vfs; v++) { + /* If VF is reset in another thread just continue */ + if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) + continue; + i40e_cleanup_reset_vf(&pf->vf[v]); + } i40e_flush(hw); clear_bit(__I40E_VF_DISABLE, pf->state); diff -Nru linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h --- linux-6.0.6/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h 2023-01-18 18:27:39.000000000 +0000 @@ -39,6 +39,7 @@ I40E_VF_STATE_MC_PROMISC, I40E_VF_STATE_UC_PROMISC, I40E_VF_STATE_PRE_ENABLE, + I40E_VF_STATE_RESETTING }; /* VF capabilities */ diff -Nru linux-6.0.6/drivers/net/ethernet/intel/iavf/iavf.h linux-6.0.12/drivers/net/ethernet/intel/iavf/iavf.h --- linux-6.0.6/drivers/net/ethernet/intel/iavf/iavf.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/iavf/iavf.h 2023-01-18 18:27:39.000000000 +0000 @@ -298,7 +298,6 @@ #define IAVF_FLAG_QUEUES_DISABLED BIT(17) #define IAVF_FLAG_SETUP_NETDEV_FEATURES BIT(18) #define IAVF_FLAG_REINIT_MSIX_NEEDED BIT(20) -#define IAVF_FLAG_INITIAL_MAC_SET BIT(23) /* duplicates for common code */ #define IAVF_FLAG_DCB_ENABLED 0 /* flags for admin queue service task */ diff -Nru linux-6.0.6/drivers/net/ethernet/intel/iavf/iavf_main.c linux-6.0.12/drivers/net/ethernet/intel/iavf/iavf_main.c --- linux-6.0.6/drivers/net/ethernet/intel/iavf/iavf_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/iavf/iavf_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1087,12 +1087,6 @@ if (ret) return ret; - /* If this is an initial set MAC during VF spawn do not wait */ - if (adapter->flags & IAVF_FLAG_INITIAL_MAC_SET) { - adapter->flags &= ~IAVF_FLAG_INITIAL_MAC_SET; - return 0; - } - ret = wait_event_interruptible_timeout(adapter->vc_waitqueue, iavf_is_mac_set_handled(netdev, addr->sa_data), msecs_to_jiffies(2500)); @@ -2605,8 +2599,6 @@ ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr); } - adapter->flags |= IAVF_FLAG_INITIAL_MAC_SET; - adapter->tx_desc_count = IAVF_DEFAULT_TXD; adapter->rx_desc_count = IAVF_DEFAULT_RXD; err = iavf_init_interrupt_scheme(adapter); @@ -2921,7 +2913,6 @@ iavf_free_queues(adapter); memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE); iavf_shutdown_adminq(&adapter->hw); - adapter->netdev->flags &= ~IFF_UP; adapter->flags &= ~IAVF_FLAG_RESET_PENDING; iavf_change_state(adapter, __IAVF_DOWN); wake_up(&adapter->down_waitqueue); @@ -3021,6 +3012,11 @@ iavf_disable_vf(adapter); mutex_unlock(&adapter->client_lock); mutex_unlock(&adapter->crit_lock); + if (netif_running(netdev)) { + rtnl_lock(); + dev_close(netdev); + rtnl_unlock(); + } return; /* Do not attempt to reinit. It's dead, Jim. */ } @@ -3033,6 +3029,7 @@ if (running) { netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); adapter->link_up = false; iavf_napi_disable_all(adapter); } @@ -3172,6 +3169,16 @@ mutex_unlock(&adapter->client_lock); mutex_unlock(&adapter->crit_lock); + + if (netif_running(netdev)) { + /* Close device to ensure that Tx queues will not be started + * during netif_device_attach() at the end of the reset task. + */ + rtnl_lock(); + dev_close(netdev); + rtnl_unlock(); + } + dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); reset_finish: rtnl_lock(); @@ -5035,23 +5042,21 @@ static void iavf_remove(struct pci_dev *pdev) { struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev); - struct net_device *netdev = adapter->netdev; struct iavf_fdir_fltr *fdir, *fdirtmp; struct iavf_vlan_filter *vlf, *vlftmp; + struct iavf_cloud_filter *cf, *cftmp; struct iavf_adv_rss *rss, *rsstmp; struct iavf_mac_filter *f, *ftmp; - struct iavf_cloud_filter *cf, *cftmp; - struct iavf_hw *hw = &adapter->hw; + struct net_device *netdev; + struct iavf_hw *hw; int err; - /* When reboot/shutdown is in progress no need to do anything - * as the adapter is already REMOVE state that was set during - * iavf_shutdown() callback. - */ - if (adapter->state == __IAVF_REMOVE) + netdev = adapter->netdev; + hw = &adapter->hw; + + if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) return; - set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section); /* Wait until port initialization is complete. * There are flows where register/unregister netdev may race. */ @@ -5191,6 +5196,8 @@ **/ static int __init iavf_init_module(void) { + int ret; + pr_info("iavf: %s\n", iavf_driver_string); pr_info("%s\n", iavf_copyright); @@ -5201,7 +5208,12 @@ pr_err("%s: Failed to create workqueue\n", iavf_driver_name); return -ENOMEM; } - return pci_register_driver(&iavf_driver); + + ret = pci_register_driver(&iavf_driver); + if (ret) + destroy_workqueue(iavf_wq); + + return ret; } module_init(iavf_init_module); diff -Nru linux-6.0.6/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c linux-6.0.12/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c --- linux-6.0.6/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c 2023-01-18 18:27:39.000000000 +0000 @@ -2438,6 +2438,8 @@ list_for_each_entry(f, &adapter->vlan_filter_list, list) { if (f->is_new_vlan) { f->is_new_vlan = false; + if (!f->vlan.vid) + continue; if (f->vlan.tpid == ETH_P_8021Q) set_bit(f->vlan.vid, adapter->vsi.active_cvlans); diff -Nru linux-6.0.6/drivers/net/ethernet/intel/ice/ice_base.c linux-6.0.12/drivers/net/ethernet/intel/ice/ice_base.c --- linux-6.0.6/drivers/net/ethernet/intel/ice/ice_base.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/ice/ice_base.c 2023-01-18 18:27:39.000000000 +0000 @@ -959,7 +959,7 @@ * associated to the queue to schedule NAPI handler */ q_vector = ring->q_vector; - if (q_vector) + if (q_vector && !(vsi->vf && ice_is_vf_disabled(vsi->vf))) ice_trigger_sw_intr(hw, q_vector); status = ice_dis_vsi_txq(vsi->port_info, txq_meta->vsi_idx, diff -Nru linux-6.0.6/drivers/net/ethernet/intel/ice/ice_lib.c linux-6.0.12/drivers/net/ethernet/intel/ice/ice_lib.c --- linux-6.0.6/drivers/net/ethernet/intel/ice/ice_lib.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/ice/ice_lib.c 2023-01-18 18:27:39.000000000 +0000 @@ -2223,6 +2223,31 @@ } /** + * ice_vsi_is_rx_queue_active + * @vsi: the VSI being configured + * + * Return true if at least one queue is active. + */ +bool ice_vsi_is_rx_queue_active(struct ice_vsi *vsi) +{ + struct ice_pf *pf = vsi->back; + struct ice_hw *hw = &pf->hw; + int i; + + ice_for_each_rxq(vsi, i) { + u32 rx_reg; + int pf_q; + + pf_q = vsi->rxq_map[i]; + rx_reg = rd32(hw, QRX_CTRL(pf_q)); + if (rx_reg & QRX_CTRL_QENA_STAT_M) + return true; + } + + return false; +} + +/** * ice_vsi_is_vlan_pruning_ena - check if VLAN pruning is enabled or not * @vsi: VSI to check whether or not VLAN pruning is enabled. * diff -Nru linux-6.0.6/drivers/net/ethernet/intel/ice/ice_lib.h linux-6.0.12/drivers/net/ethernet/intel/ice/ice_lib.h --- linux-6.0.6/drivers/net/ethernet/intel/ice/ice_lib.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/ice/ice_lib.h 2023-01-18 18:27:39.000000000 +0000 @@ -127,4 +127,5 @@ bool ice_is_feature_supported(struct ice_pf *pf, enum ice_feature f); void ice_clear_feature_support(struct ice_pf *pf, enum ice_feature f); void ice_init_feature_support(struct ice_pf *pf); +bool ice_vsi_is_rx_queue_active(struct ice_vsi *vsi); #endif /* !_ICE_LIB_H_ */ diff -Nru linux-6.0.6/drivers/net/ethernet/intel/ice/ice_vf_lib.c linux-6.0.12/drivers/net/ethernet/intel/ice/ice_vf_lib.c --- linux-6.0.6/drivers/net/ethernet/intel/ice/ice_vf_lib.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/ice/ice_vf_lib.c 2023-01-18 18:27:39.000000000 +0000 @@ -576,7 +576,10 @@ return -EINVAL; } ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id); - ice_vsi_stop_all_rx_rings(vsi); + + if (ice_vsi_is_rx_queue_active(vsi)) + ice_vsi_stop_all_rx_rings(vsi); + dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n", vf->vf_id); return 0; diff -Nru linux-6.0.6/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c linux-6.0.12/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c --- linux-6.0.6/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -4869,6 +4869,8 @@ **/ static int __init ixgbevf_init_module(void) { + int err; + pr_info("%s\n", ixgbevf_driver_string); pr_info("%s\n", ixgbevf_copyright); ixgbevf_wq = create_singlethread_workqueue(ixgbevf_driver_name); @@ -4877,7 +4879,13 @@ return -ENOMEM; } - return pci_register_driver(&ixgbevf_driver); + err = pci_register_driver(&ixgbevf_driver); + if (err) { + destroy_workqueue(ixgbevf_wq); + return err; + } + + return 0; } module_init(ixgbevf_init_module); diff -Nru linux-6.0.6/drivers/net/ethernet/lantiq_etop.c linux-6.0.12/drivers/net/ethernet/lantiq_etop.c --- linux-6.0.6/drivers/net/ethernet/lantiq_etop.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/lantiq_etop.c 2023-01-18 18:27:39.000000000 +0000 @@ -485,7 +485,6 @@ len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) { - dev_kfree_skb_any(skb); netdev_err(dev, "tx ring full\n"); netif_tx_stop_queue(txq); return NETDEV_TX_BUSY; diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/mv643xx_eth.c linux-6.0.12/drivers/net/ethernet/marvell/mv643xx_eth.c --- linux-6.0.6/drivers/net/ethernet/marvell/mv643xx_eth.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/mv643xx_eth.c 2023-01-18 18:27:39.000000000 +0000 @@ -2481,6 +2481,7 @@ for (i = 0; i < mp->rxq_count; i++) rxq_deinit(mp->rxq + i); out: + napi_disable(&mp->napi); free_irq(dev->irq, dev); return err; diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c linux-6.0.12/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c --- linux-6.0.6/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -7352,6 +7352,7 @@ struct mvpp2 *priv) { struct resource *res; + void __iomem *base; res = platform_get_resource(pdev, IORESOURCE_MEM, 2); if (!res) { @@ -7362,9 +7363,12 @@ return 0; } - priv->cm3_base = devm_ioremap_resource(&pdev->dev, res); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); - return PTR_ERR_OR_ZERO(priv->cm3_base); + priv->cm3_base = base; + return 0; } static int mvpp2_probe(struct platform_device *pdev) diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeon_ep/octep_main.c linux-6.0.12/drivers/net/ethernet/marvell/octeon_ep/octep_main.c --- linux-6.0.6/drivers/net/ethernet/marvell/octeon_ep/octep_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeon_ep/octep_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -521,14 +521,12 @@ octep_oq_dbell_init(oct); ret = octep_get_link_status(oct); - if (ret) + if (ret > 0) octep_link_up(netdev); return 0; set_queues_err: - octep_napi_disable(oct); - octep_napi_delete(oct); octep_clean_irqs(oct); setup_irq_err: octep_free_oqs(oct); @@ -958,7 +956,7 @@ ret = octep_ctrl_mbox_init(ctrl_mbox); if (ret) { dev_err(&pdev->dev, "Failed to initialize control mbox\n"); - return -1; + goto unsupported_dev; } oct->ctrl_mbox_ifstats_offset = OCTEP_CTRL_MBOX_SZ(ctrl_mbox->h2fq.elem_sz, ctrl_mbox->h2fq.elem_cnt, @@ -968,6 +966,10 @@ return 0; unsupported_dev: + for (i = 0; i < OCTEP_MMIO_REGIONS; i++) + iounmap(oct->mmio[i].hw_addr); + + kfree(oct->conf); return -1; } @@ -1070,7 +1072,11 @@ netdev->max_mtu = OCTEP_MAX_MTU; netdev->mtu = OCTEP_DEFAULT_MTU; - octep_get_mac_addr(octep_dev, octep_dev->mac_addr); + err = octep_get_mac_addr(octep_dev, octep_dev->mac_addr); + if (err) { + dev_err(&pdev->dev, "Failed to get mac address\n"); + goto register_dev_err; + } eth_hw_addr_set(netdev, octep_dev->mac_addr); err = register_netdev(netdev); diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c --- linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -535,6 +535,8 @@ sprintf(lmac, "LMAC%d", lmac_id); seq_printf(filp, "%s\t0x%x\t\tNIX%d\t\t%s\t%s\n", dev_name(&pdev->dev), pcifunc, blkid, cgx, lmac); + + pci_dev_put(pdev); } return 0; } @@ -2221,6 +2223,7 @@ } } + pci_dev_put(pdev); return 0; } diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c --- linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c 2023-01-18 18:27:39.000000000 +0000 @@ -4979,6 +4979,8 @@ ipolicer->ref_count = devm_kcalloc(rvu->dev, ipolicer->band_prof.max, sizeof(u16), GFP_KERNEL); + if (!ipolicer->ref_count) + return -ENOMEM; } /* Set policer timeunit to 2us ie (19 + 1) * 100 nsec = 2us */ diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c --- linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c 2023-01-18 18:27:39.000000000 +0000 @@ -62,15 +62,18 @@ pfvf->sdp_info = devm_kzalloc(rvu->dev, sizeof(struct sdp_node_info), GFP_KERNEL); - if (!pfvf->sdp_info) + if (!pfvf->sdp_info) { + pci_dev_put(pdev); return -ENOMEM; + } dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]); - put_device(&pdev->dev); i++; } + pci_dev_put(pdev); + return 0; } diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c --- linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c 2023-01-18 18:27:39.000000000 +0000 @@ -863,6 +863,7 @@ } sq->head = 0; + sq->cons_head = 0; sq->sqe_per_sqb = (pfvf->hw.sqb_size / sq->sqe_size) - 1; sq->num_sqbs = (qset->sqe_cnt + sq->sqe_per_sqb) / sq->sqe_per_sqb; /* Set SQE threshold to 10% of total SQEs */ diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c --- linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c 2023-01-18 18:27:39.000000000 +0000 @@ -15,6 +15,7 @@ #include #include #include +#include #include "otx2_reg.h" #include "otx2_common.h" @@ -1161,6 +1162,59 @@ } EXPORT_SYMBOL(otx2_set_real_num_queues); +static char *nix_sqoperr_e_str[NIX_SQOPERR_MAX] = { + "NIX_SQOPERR_OOR", + "NIX_SQOPERR_CTX_FAULT", + "NIX_SQOPERR_CTX_POISON", + "NIX_SQOPERR_DISABLED", + "NIX_SQOPERR_SIZE_ERR", + "NIX_SQOPERR_OFLOW", + "NIX_SQOPERR_SQB_NULL", + "NIX_SQOPERR_SQB_FAULT", + "NIX_SQOPERR_SQE_SZ_ZERO", +}; + +static char *nix_mnqerr_e_str[NIX_MNQERR_MAX] = { + "NIX_MNQERR_SQ_CTX_FAULT", + "NIX_MNQERR_SQ_CTX_POISON", + "NIX_MNQERR_SQB_FAULT", + "NIX_MNQERR_SQB_POISON", + "NIX_MNQERR_TOTAL_ERR", + "NIX_MNQERR_LSO_ERR", + "NIX_MNQERR_CQ_QUERY_ERR", + "NIX_MNQERR_MAX_SQE_SIZE_ERR", + "NIX_MNQERR_MAXLEN_ERR", + "NIX_MNQERR_SQE_SIZEM1_ZERO", +}; + +static char *nix_snd_status_e_str[NIX_SND_STATUS_MAX] = { + "NIX_SND_STATUS_GOOD", + "NIX_SND_STATUS_SQ_CTX_FAULT", + "NIX_SND_STATUS_SQ_CTX_POISON", + "NIX_SND_STATUS_SQB_FAULT", + "NIX_SND_STATUS_SQB_POISON", + "NIX_SND_STATUS_HDR_ERR", + "NIX_SND_STATUS_EXT_ERR", + "NIX_SND_STATUS_JUMP_FAULT", + "NIX_SND_STATUS_JUMP_POISON", + "NIX_SND_STATUS_CRC_ERR", + "NIX_SND_STATUS_IMM_ERR", + "NIX_SND_STATUS_SG_ERR", + "NIX_SND_STATUS_MEM_ERR", + "NIX_SND_STATUS_INVALID_SUBDC", + "NIX_SND_STATUS_SUBDC_ORDER_ERR", + "NIX_SND_STATUS_DATA_FAULT", + "NIX_SND_STATUS_DATA_POISON", + "NIX_SND_STATUS_NPC_DROP_ACTION", + "NIX_SND_STATUS_LOCK_VIOL", + "NIX_SND_STATUS_NPC_UCAST_CHAN_ERR", + "NIX_SND_STATUS_NPC_MCAST_CHAN_ERR", + "NIX_SND_STATUS_NPC_MCAST_ABORT", + "NIX_SND_STATUS_NPC_VTAG_PTR_ERR", + "NIX_SND_STATUS_NPC_VTAG_SIZE_ERR", + "NIX_SND_STATUS_SEND_STATS_ERR", +}; + static irqreturn_t otx2_q_intr_handler(int irq, void *data) { struct otx2_nic *pf = data; @@ -1194,46 +1248,67 @@ /* SQ */ for (qidx = 0; qidx < pf->hw.tot_tx_queues; qidx++) { + u64 sq_op_err_dbg, mnq_err_dbg, snd_err_dbg; + u8 sq_op_err_code, mnq_err_code, snd_err_code; + + /* Below debug registers captures first errors corresponding to + * those registers. We don't have to check against SQ qid as + * these are fatal errors. + */ + ptr = otx2_get_regaddr(pf, NIX_LF_SQ_OP_INT); val = otx2_atomic64_add((qidx << 44), ptr); otx2_write64(pf, NIX_LF_SQ_OP_INT, (qidx << 44) | (val & NIX_SQINT_BITS)); - if (!(val & (NIX_SQINT_BITS | BIT_ULL(42)))) - continue; - if (val & BIT_ULL(42)) { netdev_err(pf->netdev, "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", qidx, otx2_read64(pf, NIX_LF_ERR_INT)); - } else { - if (val & BIT_ULL(NIX_SQINT_LMT_ERR)) { - netdev_err(pf->netdev, "SQ%lld: LMT store error NIX_LF_SQ_OP_ERR_DBG:0x%llx", - qidx, - otx2_read64(pf, - NIX_LF_SQ_OP_ERR_DBG)); - otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG, - BIT_ULL(44)); - } - if (val & BIT_ULL(NIX_SQINT_MNQ_ERR)) { - netdev_err(pf->netdev, "SQ%lld: Meta-descriptor enqueue error NIX_LF_MNQ_ERR_DGB:0x%llx\n", - qidx, - otx2_read64(pf, NIX_LF_MNQ_ERR_DBG)); - otx2_write64(pf, NIX_LF_MNQ_ERR_DBG, - BIT_ULL(44)); - } - if (val & BIT_ULL(NIX_SQINT_SEND_ERR)) { - netdev_err(pf->netdev, "SQ%lld: Send error, NIX_LF_SEND_ERR_DBG 0x%llx", - qidx, - otx2_read64(pf, - NIX_LF_SEND_ERR_DBG)); - otx2_write64(pf, NIX_LF_SEND_ERR_DBG, - BIT_ULL(44)); - } - if (val & BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL)) - netdev_err(pf->netdev, "SQ%lld: SQB allocation failed", - qidx); + goto done; } + sq_op_err_dbg = otx2_read64(pf, NIX_LF_SQ_OP_ERR_DBG); + if (!(sq_op_err_dbg & BIT(44))) + goto chk_mnq_err_dbg; + + sq_op_err_code = FIELD_GET(GENMASK(7, 0), sq_op_err_dbg); + netdev_err(pf->netdev, "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(%llx) err=%s\n", + qidx, sq_op_err_dbg, nix_sqoperr_e_str[sq_op_err_code]); + + otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG, BIT_ULL(44)); + + if (sq_op_err_code == NIX_SQOPERR_SQB_NULL) + goto chk_mnq_err_dbg; + + /* Err is not NIX_SQOPERR_SQB_NULL, call aq function to read SQ structure. + * TODO: But we are in irq context. How to call mbox functions which does sleep + */ + +chk_mnq_err_dbg: + mnq_err_dbg = otx2_read64(pf, NIX_LF_MNQ_ERR_DBG); + if (!(mnq_err_dbg & BIT(44))) + goto chk_snd_err_dbg; + + mnq_err_code = FIELD_GET(GENMASK(7, 0), mnq_err_dbg); + netdev_err(pf->netdev, "SQ%lld: NIX_LF_MNQ_ERR_DBG(%llx) err=%s\n", + qidx, mnq_err_dbg, nix_mnqerr_e_str[mnq_err_code]); + otx2_write64(pf, NIX_LF_MNQ_ERR_DBG, BIT_ULL(44)); + +chk_snd_err_dbg: + snd_err_dbg = otx2_read64(pf, NIX_LF_SEND_ERR_DBG); + if (snd_err_dbg & BIT(44)) { + snd_err_code = FIELD_GET(GENMASK(7, 0), snd_err_dbg); + netdev_err(pf->netdev, "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s\n", + qidx, snd_err_dbg, nix_snd_status_e_str[snd_err_code]); + otx2_write64(pf, NIX_LF_SEND_ERR_DBG, BIT_ULL(44)); + } + +done: + /* Print values and reset */ + if (val & BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL)) + netdev_err(pf->netdev, "SQ%lld: SQB allocation failed", + qidx); + schedule_work(&pf->reset_task); } diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h --- linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h 2023-01-18 18:27:39.000000000 +0000 @@ -274,4 +274,61 @@ BIT_ULL(NIX_SQINT_SEND_ERR) | \ BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL)) +enum nix_sqoperr_e { + NIX_SQOPERR_OOR = 0, + NIX_SQOPERR_CTX_FAULT = 1, + NIX_SQOPERR_CTX_POISON = 2, + NIX_SQOPERR_DISABLED = 3, + NIX_SQOPERR_SIZE_ERR = 4, + NIX_SQOPERR_OFLOW = 5, + NIX_SQOPERR_SQB_NULL = 6, + NIX_SQOPERR_SQB_FAULT = 7, + NIX_SQOPERR_SQE_SZ_ZERO = 8, + NIX_SQOPERR_MAX, +}; + +enum nix_mnqerr_e { + NIX_MNQERR_SQ_CTX_FAULT = 0, + NIX_MNQERR_SQ_CTX_POISON = 1, + NIX_MNQERR_SQB_FAULT = 2, + NIX_MNQERR_SQB_POISON = 3, + NIX_MNQERR_TOTAL_ERR = 4, + NIX_MNQERR_LSO_ERR = 5, + NIX_MNQERR_CQ_QUERY_ERR = 6, + NIX_MNQERR_MAX_SQE_SIZE_ERR = 7, + NIX_MNQERR_MAXLEN_ERR = 8, + NIX_MNQERR_SQE_SIZEM1_ZERO = 9, + NIX_MNQERR_MAX, +}; + +enum nix_snd_status_e { + NIX_SND_STATUS_GOOD = 0x0, + NIX_SND_STATUS_SQ_CTX_FAULT = 0x1, + NIX_SND_STATUS_SQ_CTX_POISON = 0x2, + NIX_SND_STATUS_SQB_FAULT = 0x3, + NIX_SND_STATUS_SQB_POISON = 0x4, + NIX_SND_STATUS_HDR_ERR = 0x5, + NIX_SND_STATUS_EXT_ERR = 0x6, + NIX_SND_STATUS_JUMP_FAULT = 0x7, + NIX_SND_STATUS_JUMP_POISON = 0x8, + NIX_SND_STATUS_CRC_ERR = 0x9, + NIX_SND_STATUS_IMM_ERR = 0x10, + NIX_SND_STATUS_SG_ERR = 0x11, + NIX_SND_STATUS_MEM_ERR = 0x12, + NIX_SND_STATUS_INVALID_SUBDC = 0x13, + NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x14, + NIX_SND_STATUS_DATA_FAULT = 0x15, + NIX_SND_STATUS_DATA_POISON = 0x16, + NIX_SND_STATUS_NPC_DROP_ACTION = 0x17, + NIX_SND_STATUS_LOCK_VIOL = 0x18, + NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x19, + NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x20, + NIX_SND_STATUS_NPC_MCAST_ABORT = 0x21, + NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x22, + NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x23, + NIX_SND_STATUS_SEND_MEM_FAULT = 0x24, + NIX_SND_STATUS_SEND_STATS_ERR = 0x25, + NIX_SND_STATUS_MAX, +}; + #endif /* OTX2_STRUCT_H */ diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c --- linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c 2023-01-18 18:27:39.000000000 +0000 @@ -435,6 +435,7 @@ struct otx2_cq_queue *cq, int budget) { int tx_pkts = 0, tx_bytes = 0, qidx; + struct otx2_snd_queue *sq; struct nix_cqe_tx_s *cqe; int processed_cqe = 0; @@ -445,6 +446,9 @@ return 0; process_cqe: + qidx = cq->cq_idx - pfvf->hw.rx_queues; + sq = &pfvf->qset.sq[qidx]; + while (likely(processed_cqe < budget) && cq->pend_cqe) { cqe = (struct nix_cqe_tx_s *)otx2_get_next_cqe(cq); if (unlikely(!cqe)) { @@ -452,18 +456,20 @@ return 0; break; } + if (cq->cq_type == CQ_XDP) { - qidx = cq->cq_idx - pfvf->hw.rx_queues; - otx2_xdp_snd_pkt_handler(pfvf, &pfvf->qset.sq[qidx], - cqe); + otx2_xdp_snd_pkt_handler(pfvf, sq, cqe); } else { - otx2_snd_pkt_handler(pfvf, cq, - &pfvf->qset.sq[cq->cint_idx], - cqe, budget, &tx_pkts, &tx_bytes); + otx2_snd_pkt_handler(pfvf, cq, sq, cqe, budget, + &tx_pkts, &tx_bytes); } + cqe->hdr.cqe_type = NIX_XQE_TYPE_INVALID; processed_cqe++; cq->pend_cqe--; + + sq->cons_head++; + sq->cons_head &= (sq->sqe_cnt - 1); } /* Free CQEs to HW */ @@ -972,17 +978,17 @@ { struct netdev_queue *txq = netdev_get_tx_queue(netdev, qidx); struct otx2_nic *pfvf = netdev_priv(netdev); - int offset, num_segs, free_sqe; + int offset, num_segs, free_desc; struct nix_sqe_hdr_s *sqe_hdr; - /* Check if there is room for new SQE. - * 'Num of SQBs freed to SQ's pool - SQ's Aura count' - * will give free SQE count. + /* Check if there is enough room between producer + * and consumer index. */ - free_sqe = (sq->num_sqbs - *sq->aura_fc_addr) * sq->sqe_per_sqb; + free_desc = (sq->cons_head - sq->head - 1 + sq->sqe_cnt) & (sq->sqe_cnt - 1); + if (free_desc < sq->sqe_thresh) + return false; - if (free_sqe < sq->sqe_thresh || - free_sqe < otx2_get_sqe_count(pfvf, skb)) + if (free_desc < otx2_get_sqe_count(pfvf, skb)) return false; num_segs = skb_shinfo(skb)->nr_frags + 1; diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h --- linux-6.0.6/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h 2023-01-18 18:27:39.000000000 +0000 @@ -79,6 +79,7 @@ struct otx2_snd_queue { u8 aura_id; u16 head; + u16 cons_head; u16 sqe_size; u32 sqe_cnt; u16 num_sqbs; diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/prestera/prestera_main.c linux-6.0.12/drivers/net/ethernet/marvell/prestera/prestera_main.c --- linux-6.0.6/drivers/net/ethernet/marvell/prestera/prestera_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/prestera/prestera_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -730,6 +730,7 @@ return 0; err_sfp_bind: + unregister_netdev(dev); err_register_netdev: prestera_port_list_del(port); err_port_init: diff -Nru linux-6.0.6/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c linux-6.0.12/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c --- linux-6.0.6/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c 2023-01-18 18:27:39.000000000 +0000 @@ -776,6 +776,7 @@ int prestera_rxtx_switch_init(struct prestera_switch *sw) { struct prestera_rxtx *rxtx; + int err; rxtx = kzalloc(sizeof(*rxtx), GFP_KERNEL); if (!rxtx) @@ -783,7 +784,11 @@ sw->rxtx = rxtx; - return prestera_sdma_switch_init(sw); + err = prestera_sdma_switch_init(sw); + if (err) + kfree(rxtx); + + return err; } void prestera_rxtx_switch_fini(struct prestera_switch *sw) diff -Nru linux-6.0.6/drivers/net/ethernet/mediatek/mtk_eth_soc.c linux-6.0.12/drivers/net/ethernet/mediatek/mtk_eth_soc.c --- linux-6.0.6/drivers/net/ethernet/mediatek/mtk_eth_soc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mediatek/mtk_eth_soc.c 2023-01-18 18:27:39.000000000 +0000 @@ -2363,8 +2363,10 @@ data + NET_SKB_PAD + eth->ip_align, ring->buf_size, DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(eth->dma_dev, - dma_addr))) + dma_addr))) { + skb_free_frag(data); return -ENOMEM; + } } rxd->rxd1 = (unsigned int)dma_addr; ring->data[i] = data; @@ -2979,8 +2981,10 @@ u32 gdm_config = MTK_GDMA_TO_PDMA; err = mtk_start_dma(eth); - if (err) + if (err) { + phylink_disconnect_phy(mac->phylink); return err; + } if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0) gdm_config = MTK_GDMA_TO_PPE; @@ -4103,12 +4107,12 @@ eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2); if (!eth->ppe) { err = -ENOMEM; - goto err_free_dev; + goto err_deinit_mdio; } err = mtk_eth_offload_init(eth); if (err) - goto err_free_dev; + goto err_deinit_mdio; } for (i = 0; i < MTK_MAX_DEVS; i++) { diff -Nru linux-6.0.6/drivers/net/ethernet/mediatek/mtk_star_emac.c linux-6.0.12/drivers/net/ethernet/mediatek/mtk_star_emac.c --- linux-6.0.6/drivers/net/ethernet/mediatek/mtk_star_emac.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mediatek/mtk_star_emac.c 2023-01-18 18:27:39.000000000 +0000 @@ -1026,6 +1026,8 @@ return 0; err_free_irq: + napi_disable(&priv->rx_napi); + napi_disable(&priv->tx_napi); free_irq(ndev->irq, ndev); err_free_skbs: mtk_star_free_rx_skbs(priv); diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx4/qp.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx4/qp.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx4/qp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx4/qp.c 2023-01-18 18:27:39.000000000 +0000 @@ -697,7 +697,8 @@ err = mlx4_bitmap_init(*bitmap + k, 1, MLX4_QP_TABLE_RAW_ETH_SIZE - 1, 0, 0); - mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0); + if (!err) + mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0); } if (err) diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/cmd.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/cmd.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/cmd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/cmd.c 2023-01-18 18:27:39.000000000 +0000 @@ -45,6 +45,8 @@ #include "mlx5_core.h" #include "lib/eq.h" #include "lib/tout.h" +#define CREATE_TRACE_POINTS +#include "diag/cmd_tracepoint.h" enum { CMD_IF_REV = 5, @@ -785,27 +787,14 @@ static void cmd_status_print(struct mlx5_core_dev *dev, void *in, void *out) { u16 opcode, op_mod; - u32 syndrome; - u8 status; u16 uid; - int err; - - syndrome = MLX5_GET(mbox_out, out, syndrome); - status = MLX5_GET(mbox_out, out, status); opcode = MLX5_GET(mbox_in, in, opcode); op_mod = MLX5_GET(mbox_in, in, op_mod); uid = MLX5_GET(mbox_in, in, uid); - err = cmd_status_to_err(status); - if (!uid && opcode != MLX5_CMD_OP_DESTROY_MKEY) mlx5_cmd_out_err(dev, opcode, op_mod, out); - else - mlx5_core_dbg(dev, - "%s(0x%x) op_mod(0x%x) uid(%d) failed, status %s(0x%x), syndrome (0x%x), err(%d)\n", - mlx5_command_str(opcode), opcode, op_mod, uid, - cmd_status_str(status), status, syndrome, err); } int mlx5_cmd_check(struct mlx5_core_dev *dev, int err, void *in, void *out) @@ -1016,6 +1005,7 @@ cmd_ent_get(ent); set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); + cmd_ent_get(ent); /* for the _real_ FW event on completion */ /* Skip sending command to fw if internal error */ if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) { ent->ret = -ENXIO; @@ -1023,7 +1013,6 @@ return; } - cmd_ent_get(ent); /* for the _real_ FW event on completion */ /* ring doorbell after the descriptor is valid */ mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx); wmb(); @@ -1508,8 +1497,8 @@ return -EFAULT; err = sscanf(outlen_str, "%d", &outlen); - if (err < 0) - return err; + if (err != 1) + return -EINVAL; ptr = kzalloc(outlen, GFP_KERNEL); if (!ptr) @@ -1672,8 +1661,8 @@ cmd_ent_put(ent); /* timeout work was canceled */ if (!forced || /* Real FW completion */ - pci_channel_offline(dev->pdev) || /* FW is inaccessible */ - dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) + mlx5_cmd_is_down(dev) || /* No real FW completion is expected */ + !opcode_allowed(cmd, ent->op)) cmd_ent_put(ent); ent->ts2 = ktime_get_ns(); @@ -1770,12 +1759,17 @@ struct mlx5_cmd *cmd = &dev->cmd; int i; - for (i = 0; i < cmd->max_reg_cmds; i++) - while (down_trylock(&cmd->sem)) + for (i = 0; i < cmd->max_reg_cmds; i++) { + while (down_trylock(&cmd->sem)) { mlx5_cmd_trigger_completions(dev); + cond_resched(); + } + } - while (down_trylock(&cmd->pages_sem)) + while (down_trylock(&cmd->pages_sem)) { mlx5_cmd_trigger_completions(dev); + cond_resched(); + } /* Unlock cmdif */ up(&cmd->pages_sem); @@ -1887,6 +1881,16 @@ return err; } +static void mlx5_cmd_err_trace(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod, void *out) +{ + u32 syndrome = MLX5_GET(mbox_out, out, syndrome); + u8 status = MLX5_GET(mbox_out, out, status); + + trace_mlx5_cmd(mlx5_command_str(opcode), opcode, op_mod, + cmd_status_str(status), status, syndrome, + cmd_status_to_err(status)); +} + static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status, u32 syndrome, int err) { @@ -1909,7 +1913,7 @@ } /* preserve -EREMOTEIO for outbox.status != OK, otherwise return err as is */ -static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, void *out) +static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, u16 op_mod, void *out) { u32 syndrome = MLX5_GET(mbox_out, out, syndrome); u8 status = MLX5_GET(mbox_out, out, status); @@ -1917,8 +1921,10 @@ if (err == -EREMOTEIO) /* -EREMOTEIO is preserved */ err = -EIO; - if (!err && status != MLX5_CMD_STAT_OK) + if (!err && status != MLX5_CMD_STAT_OK) { err = -EREMOTEIO; + mlx5_cmd_err_trace(dev, opcode, op_mod, out); + } cmd_status_log(dev, opcode, status, syndrome, err); return err; @@ -1946,9 +1952,9 @@ { int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, false); u16 opcode = MLX5_GET(mbox_in, in, opcode); + u16 op_mod = MLX5_GET(mbox_in, in, op_mod); - err = cmd_status_err(dev, err, opcode, out); - return err; + return cmd_status_err(dev, err, opcode, op_mod, out); } EXPORT_SYMBOL(mlx5_cmd_do); @@ -1992,8 +1998,9 @@ { int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, true); u16 opcode = MLX5_GET(mbox_in, in, opcode); + u16 op_mod = MLX5_GET(mbox_in, in, op_mod); - err = cmd_status_err(dev, err, opcode, out); + err = cmd_status_err(dev, err, opcode, op_mod, out); return mlx5_cmd_check(dev, err, in, out); } EXPORT_SYMBOL(mlx5_cmd_exec_polling); @@ -2004,7 +2011,7 @@ ctx->dev = dev; /* Starts at 1 to avoid doing wake_up if we are not cleaning up */ atomic_set(&ctx->num_inflight, 1); - init_waitqueue_head(&ctx->wait); + init_completion(&ctx->inflight_done); } EXPORT_SYMBOL(mlx5_cmd_init_async_ctx); @@ -2018,8 +2025,8 @@ */ void mlx5_cmd_cleanup_async_ctx(struct mlx5_async_ctx *ctx) { - atomic_dec(&ctx->num_inflight); - wait_event(ctx->wait, atomic_read(&ctx->num_inflight) == 0); + if (!atomic_dec_and_test(&ctx->num_inflight)) + wait_for_completion(&ctx->inflight_done); } EXPORT_SYMBOL(mlx5_cmd_cleanup_async_ctx); @@ -2029,10 +2036,10 @@ struct mlx5_async_ctx *ctx; ctx = work->ctx; - status = cmd_status_err(ctx->dev, status, work->opcode, work->out); + status = cmd_status_err(ctx->dev, status, work->opcode, work->op_mod, work->out); work->user_callback(status, work); if (atomic_dec_and_test(&ctx->num_inflight)) - wake_up(&ctx->wait); + complete(&ctx->inflight_done); } int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size, @@ -2044,13 +2051,14 @@ work->ctx = ctx; work->user_callback = callback; work->opcode = MLX5_GET(mbox_in, in, opcode); + work->op_mod = MLX5_GET(mbox_in, in, op_mod); work->out = out; if (WARN_ON(!atomic_inc_not_zero(&ctx->num_inflight))) return -EIO; ret = cmd_exec(ctx->dev, in, in_size, out, out_size, mlx5_cmd_exec_cb_handler, work, false); if (ret && atomic_dec_and_test(&ctx->num_inflight)) - wake_up(&ctx->wait); + complete(&ctx->inflight_done); return ret; } diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h 1970-01-01 00:00:00.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h 2023-01-18 18:27:39.000000000 +0000 @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ +/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mlx5 + +#if !defined(_MLX5_CMD_TP_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _MLX5_CMD_TP_H_ + +#include +#include + +TRACE_EVENT(mlx5_cmd, + TP_PROTO(const char *command_str, u16 opcode, u16 op_mod, + const char *status_str, u8 status, u32 syndrome, int err), + TP_ARGS(command_str, opcode, op_mod, status_str, status, syndrome, err), + TP_STRUCT__entry(__string(command_str, command_str) + __field(u16, opcode) + __field(u16, op_mod) + __string(status_str, status_str) + __field(u8, status) + __field(u32, syndrome) + __field(int, err) + ), + TP_fast_assign(__assign_str(command_str, command_str); + __entry->opcode = opcode; + __entry->op_mod = op_mod; + __assign_str(status_str, status_str); + __entry->status = status; + __entry->syndrome = syndrome; + __entry->err = err; + ), + TP_printk("%s(0x%x) op_mod(0x%x) failed, status %s(0x%x), syndrome (0x%x), err(%d)", + __get_str(command_str), __entry->opcode, __entry->op_mod, + __get_str(status_str), __entry->status, __entry->syndrome, + __entry->err) +); + +#endif /* _MLX5_CMD_TP_H_ */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ./diag +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE cmd_tracepoint +#include diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c 2023-01-18 18:27:39.000000000 +0000 @@ -638,7 +638,7 @@ trace_timestamp = (timestamp_event.timestamp & MASK_52_7) | (str_frmt->timestamp & MASK_6_0); else - trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) | + trace_timestamp = ((timestamp_event.timestamp - 1) & MASK_52_7) | (str_frmt->timestamp & MASK_6_0); mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp); diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h 2023-01-18 18:27:39.000000000 +0000 @@ -6,6 +6,7 @@ #include "en.h" #include "en_stats.h" +#include "en/txrx.h" #include #define MLX5E_PTP_CHANNEL_IX 0 @@ -68,6 +69,14 @@ fk.ports.dst == htons(PTP_EV_PORT)); } +static inline bool mlx5e_ptpsq_fifo_has_room(struct mlx5e_txqsq *sq) +{ + if (!sq->ptpsq) + return true; + + return mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo); +} + int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params, u8 lag_port, struct mlx5e_ptp **cp); void mlx5e_ptp_close(struct mlx5e_ptp *c); diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c 2023-01-18 18:27:39.000000000 +0000 @@ -164,6 +164,36 @@ return err; } +static int +mlx5_esw_bridge_changeupper_validate_netdev(void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct netdev_notifier_changeupper_info *info = ptr; + struct net_device *upper = info->upper_dev; + struct net_device *lower; + struct list_head *iter; + + if (!netif_is_bridge_master(upper) || !netif_is_lag_master(dev)) + return 0; + + netdev_for_each_lower_dev(dev, lower, iter) { + struct mlx5_core_dev *mdev; + struct mlx5e_priv *priv; + + if (!mlx5e_eswitch_rep(lower)) + continue; + + priv = netdev_priv(lower); + mdev = priv->mdev; + if (!mlx5_lag_is_active(mdev)) + return -EAGAIN; + if (!mlx5_lag_is_shared_fdb(mdev)) + return -EOPNOTSUPP; + } + + return 0; +} + static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb, unsigned long event, void *ptr) { @@ -171,6 +201,7 @@ switch (event) { case NETDEV_PRECHANGEUPPER: + err = mlx5_esw_bridge_changeupper_validate_netdev(ptr); break; case NETDEV_CHANGEUPPER: diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c 2023-01-18 18:27:39.000000000 +0000 @@ -6,70 +6,42 @@ #include "en/tc_priv.h" #include "mlx5_core.h" -/* Must be aligned with enum flow_action_id. */ static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = { - &mlx5e_tc_act_accept, - &mlx5e_tc_act_drop, - &mlx5e_tc_act_trap, - &mlx5e_tc_act_goto, - &mlx5e_tc_act_mirred, - &mlx5e_tc_act_mirred, - &mlx5e_tc_act_redirect_ingress, - NULL, /* FLOW_ACTION_MIRRED_INGRESS, */ - &mlx5e_tc_act_vlan, - &mlx5e_tc_act_vlan, - &mlx5e_tc_act_vlan_mangle, - &mlx5e_tc_act_tun_encap, - &mlx5e_tc_act_tun_decap, - &mlx5e_tc_act_pedit, - &mlx5e_tc_act_pedit, - &mlx5e_tc_act_csum, - NULL, /* FLOW_ACTION_MARK, */ - &mlx5e_tc_act_ptype, - NULL, /* FLOW_ACTION_PRIORITY, */ - NULL, /* FLOW_ACTION_WAKE, */ - NULL, /* FLOW_ACTION_QUEUE, */ - &mlx5e_tc_act_sample, - &mlx5e_tc_act_police, - &mlx5e_tc_act_ct, - NULL, /* FLOW_ACTION_CT_METADATA, */ - &mlx5e_tc_act_mpls_push, - &mlx5e_tc_act_mpls_pop, - NULL, /* FLOW_ACTION_MPLS_MANGLE, */ - NULL, /* FLOW_ACTION_GATE, */ - NULL, /* FLOW_ACTION_PPPOE_PUSH, */ - NULL, /* FLOW_ACTION_JUMP, */ - NULL, /* FLOW_ACTION_PIPE, */ - &mlx5e_tc_act_vlan, - &mlx5e_tc_act_vlan, + [FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept, + [FLOW_ACTION_DROP] = &mlx5e_tc_act_drop, + [FLOW_ACTION_TRAP] = &mlx5e_tc_act_trap, + [FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto, + [FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred, + [FLOW_ACTION_MIRRED] = &mlx5e_tc_act_mirred, + [FLOW_ACTION_REDIRECT_INGRESS] = &mlx5e_tc_act_redirect_ingress, + [FLOW_ACTION_VLAN_PUSH] = &mlx5e_tc_act_vlan, + [FLOW_ACTION_VLAN_POP] = &mlx5e_tc_act_vlan, + [FLOW_ACTION_VLAN_MANGLE] = &mlx5e_tc_act_vlan_mangle, + [FLOW_ACTION_TUNNEL_ENCAP] = &mlx5e_tc_act_tun_encap, + [FLOW_ACTION_TUNNEL_DECAP] = &mlx5e_tc_act_tun_decap, + [FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit, + [FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit, + [FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum, + [FLOW_ACTION_PTYPE] = &mlx5e_tc_act_ptype, + [FLOW_ACTION_SAMPLE] = &mlx5e_tc_act_sample, + [FLOW_ACTION_POLICE] = &mlx5e_tc_act_police, + [FLOW_ACTION_CT] = &mlx5e_tc_act_ct, + [FLOW_ACTION_MPLS_PUSH] = &mlx5e_tc_act_mpls_push, + [FLOW_ACTION_MPLS_POP] = &mlx5e_tc_act_mpls_pop, + [FLOW_ACTION_VLAN_PUSH_ETH] = &mlx5e_tc_act_vlan, + [FLOW_ACTION_VLAN_POP_ETH] = &mlx5e_tc_act_vlan, }; -/* Must be aligned with enum flow_action_id. */ static struct mlx5e_tc_act *tc_acts_nic[NUM_FLOW_ACTIONS] = { - &mlx5e_tc_act_accept, - &mlx5e_tc_act_drop, - NULL, /* FLOW_ACTION_TRAP, */ - &mlx5e_tc_act_goto, - &mlx5e_tc_act_mirred_nic, - NULL, /* FLOW_ACTION_MIRRED, */ - NULL, /* FLOW_ACTION_REDIRECT_INGRESS, */ - NULL, /* FLOW_ACTION_MIRRED_INGRESS, */ - NULL, /* FLOW_ACTION_VLAN_PUSH, */ - NULL, /* FLOW_ACTION_VLAN_POP, */ - NULL, /* FLOW_ACTION_VLAN_MANGLE, */ - NULL, /* FLOW_ACTION_TUNNEL_ENCAP, */ - NULL, /* FLOW_ACTION_TUNNEL_DECAP, */ - &mlx5e_tc_act_pedit, - &mlx5e_tc_act_pedit, - &mlx5e_tc_act_csum, - &mlx5e_tc_act_mark, - NULL, /* FLOW_ACTION_PTYPE, */ - NULL, /* FLOW_ACTION_PRIORITY, */ - NULL, /* FLOW_ACTION_WAKE, */ - NULL, /* FLOW_ACTION_QUEUE, */ - NULL, /* FLOW_ACTION_SAMPLE, */ - NULL, /* FLOW_ACTION_POLICE, */ - &mlx5e_tc_act_ct, + [FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept, + [FLOW_ACTION_DROP] = &mlx5e_tc_act_drop, + [FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto, + [FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred_nic, + [FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit, + [FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit, + [FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum, + [FLOW_ACTION_MARK] = &mlx5e_tc_act_mark, + [FLOW_ACTION_CT] = &mlx5e_tc_act_ct, }; /** diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h 2023-01-18 18:27:39.000000000 +0000 @@ -96,6 +96,7 @@ struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS]; struct mlx5e_tc_flow *peer_flow; struct mlx5e_mod_hdr_handle *mh; /* attached mod header instance */ + struct mlx5e_mod_hdr_handle *slow_mh; /* attached mod header instance for slow path */ struct mlx5e_hairpin_entry *hpe; /* attached hairpin instance */ struct list_head hairpin; /* flows sharing the same hairpin */ struct list_head peer; /* flows with peer flow */ @@ -111,6 +112,7 @@ struct completion del_hw_done; struct mlx5_flow_attr *attr; struct list_head attrs; + u32 chain_mapping; }; struct mlx5_flow_handle * diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c 2023-01-18 18:27:39.000000000 +0000 @@ -224,15 +224,16 @@ list_for_each_entry(flow, flow_list, tmp_list) { if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW)) continue; - spec = &flow->attr->parse_attr->spec; - - /* update from encap rule to slow path rule */ - rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec); attr = mlx5e_tc_get_encap_attr(flow); esw_attr = attr->esw_attr; /* mark the flow's encap dest as non-valid */ esw_attr->dests[flow->tmp_entry_index].flags &= ~MLX5_ESW_DEST_ENCAP_VALID; + esw_attr->dests[flow->tmp_entry_index].pkt_reformat = NULL; + + /* update from encap rule to slow path rule */ + spec = &flow->attr->parse_attr->spec; + rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec); if (IS_ERR(rule)) { err = PTR_ERR(rule); @@ -251,6 +252,7 @@ /* we know that the encap is valid */ e->flags &= ~MLX5_ENCAP_ENTRY_VALID; mlx5_packet_reformat_dealloc(priv->mdev, e->pkt_reformat); + e->pkt_reformat = NULL; } static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow, @@ -762,8 +764,7 @@ struct net_device *mirred_dev, int out_index, struct netlink_ext_ack *extack, - struct net_device **encap_dev, - bool *encap_valid) + struct net_device **encap_dev) { struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5e_tc_flow_parse_attr *parse_attr; @@ -878,9 +879,8 @@ if (e->flags & MLX5_ENCAP_ENTRY_VALID) { attr->esw_attr->dests[out_index].pkt_reformat = e->pkt_reformat; attr->esw_attr->dests[out_index].flags |= MLX5_ESW_DEST_ENCAP_VALID; - *encap_valid = true; } else { - *encap_valid = false; + flow_flag_set(flow, SLOW); } mutex_unlock(&esw->offloads.encap_tbl_lock); diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h 2023-01-18 18:27:39.000000000 +0000 @@ -17,8 +17,7 @@ struct net_device *mirred_dev, int out_index, struct netlink_ext_ack *extack, - struct net_device **encap_dev, - bool *encap_valid); + struct net_device **encap_dev); int mlx5e_attach_decap(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow, diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h 2023-01-18 18:27:39.000000000 +0000 @@ -11,6 +11,27 @@ #define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start)) +/* IPSEC inline data includes: + * 1. ESP trailer: up to 255 bytes of padding, 1 byte for pad length, 1 byte for + * next header. + * 2. ESP authentication data: 16 bytes for ICV. + */ +#define MLX5E_MAX_TX_IPSEC_DS DIV_ROUND_UP(sizeof(struct mlx5_wqe_inline_seg) + \ + 255 + 1 + 1 + 16, MLX5_SEND_WQE_DS) + +/* 366 should be big enough to cover all L2, L3 and L4 headers with possible + * encapsulations. + */ +#define MLX5E_MAX_TX_INLINE_DS DIV_ROUND_UP(366 - INL_HDR_START_SZ + VLAN_HLEN, \ + MLX5_SEND_WQE_DS) + +/* Sync the calculation with mlx5e_sq_calc_wqe_attr. */ +#define MLX5E_MAX_TX_WQEBBS DIV_ROUND_UP(MLX5E_TX_WQE_EMPTY_DS_COUNT + \ + MLX5E_MAX_TX_INLINE_DS + \ + MLX5E_MAX_TX_IPSEC_DS + \ + MAX_SKB_FRAGS + 1, \ + MLX5_SEND_WQEBB_NUM_DS) + #define MLX5E_RX_ERR_CQE(cqe) (get_cqe_opcode(cqe) != MLX5_CQE_RESP_SEND) static inline @@ -58,6 +79,12 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq); static inline bool +mlx5e_skb_fifo_has_room(struct mlx5e_skb_fifo *fifo) +{ + return (*fifo->pc - *fifo->cc) < fifo->mask; +} + +static inline bool mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n) { return (mlx5_wq_cyc_ctr2ix(wq, cc - pc) >= n) || (cc == pc); @@ -418,6 +445,8 @@ static inline u16 mlx5e_stop_room_for_wqe(struct mlx5_core_dev *mdev, u16 wqe_size) { + WARN_ON_ONCE(PAGE_SIZE / MLX5_SEND_WQE_BB < mlx5e_get_max_sq_wqebbs(mdev)); + /* A WQE must not cross the page boundary, hence two conditions: * 1. Its size must not exceed the page size. * 2. If the WQE size is X, and the space remaining in a page is less @@ -430,7 +459,6 @@ "wqe_size %u is greater than max SQ WQEBBs %u", wqe_size, mlx5e_get_max_sq_wqebbs(mdev)); - return MLX5E_STOP_ROOM(wqe_size); } diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c 2023-01-18 18:27:39.000000000 +0000 @@ -101,7 +101,6 @@ struct xfrm_replay_state_esn *replay_esn; u32 seq_bottom = 0; u8 overlap; - u32 *esn; if (!(sa_entry->x->props.flags & XFRM_STATE_ESN)) { sa_entry->esn_state.trigger = 0; @@ -116,11 +115,9 @@ sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x, htonl(seq_bottom)); - esn = &sa_entry->esn_state.esn; sa_entry->esn_state.trigger = 1; if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) { - ++(*esn); sa_entry->esn_state.overlap = 0; return true; } else if (unlikely(!overlap && diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en_main.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en_main.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -5514,6 +5514,13 @@ if (priv->fs) priv->fs->state_destroy = !test_bit(MLX5E_STATE_DESTROYING, &priv->state); + /* Validate the max_wqe_size_sq capability. */ + if (WARN_ON_ONCE(mlx5e_get_max_sq_wqebbs(priv->mdev) < MLX5E_MAX_TX_WQEBBS)) { + mlx5_core_warn(priv->mdev, "MLX5E: Max SQ WQEBBs firmware capability: %u, needed %lu\n", + mlx5e_get_max_sq_wqebbs(priv->mdev), MLX5E_MAX_TX_WQEBBS); + return -EIO; + } + /* max number of channels may have changed */ max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile); if (priv->channels.params.num_channels > max_nch) { diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c 2023-01-18 18:27:39.000000000 +0000 @@ -1394,8 +1394,13 @@ struct mlx5e_tc_flow *flow, struct mlx5_flow_spec *spec) { + struct mlx5e_tc_mod_hdr_acts mod_acts = {}; + struct mlx5e_mod_hdr_handle *mh = NULL; struct mlx5_flow_attr *slow_attr; struct mlx5_flow_handle *rule; + bool fwd_and_modify_cap; + u32 chain_mapping = 0; + int err; slow_attr = mlx5_alloc_flow_attr(MLX5_FLOW_NAMESPACE_FDB); if (!slow_attr) @@ -1406,13 +1411,56 @@ slow_attr->esw_attr->split_count = 0; slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH; + fwd_and_modify_cap = MLX5_CAP_ESW_FLOWTABLE((esw)->dev, fdb_modify_header_fwd_to_table); + if (!fwd_and_modify_cap) + goto skip_restore; + + err = mlx5_chains_get_chain_mapping(esw_chains(esw), flow->attr->chain, &chain_mapping); + if (err) + goto err_get_chain; + + err = mlx5e_tc_match_to_reg_set(esw->dev, &mod_acts, MLX5_FLOW_NAMESPACE_FDB, + CHAIN_TO_REG, chain_mapping); + if (err) + goto err_reg_set; + + mh = mlx5e_mod_hdr_attach(esw->dev, get_mod_hdr_table(flow->priv, flow), + MLX5_FLOW_NAMESPACE_FDB, &mod_acts); + if (IS_ERR(mh)) { + err = PTR_ERR(mh); + goto err_attach; + } + + slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; + slow_attr->modify_hdr = mlx5e_mod_hdr_get(mh); + +skip_restore: rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, slow_attr); - if (!IS_ERR(rule)) - flow_flag_set(flow, SLOW); + if (IS_ERR(rule)) { + err = PTR_ERR(rule); + goto err_offload; + } + + flow->slow_mh = mh; + flow->chain_mapping = chain_mapping; + flow_flag_set(flow, SLOW); + mlx5e_mod_hdr_dealloc(&mod_acts); kfree(slow_attr); return rule; + +err_offload: + if (fwd_and_modify_cap) + mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), mh); +err_attach: +err_reg_set: + if (fwd_and_modify_cap) + mlx5_chains_put_chain_mapping(esw_chains(esw), chain_mapping); +err_get_chain: + mlx5e_mod_hdr_dealloc(&mod_acts); + kfree(slow_attr); + return ERR_PTR(err); } void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw, @@ -1430,7 +1478,17 @@ slow_attr->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; slow_attr->esw_attr->split_count = 0; slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH; + if (flow->slow_mh) { + slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; + slow_attr->modify_hdr = mlx5e_mod_hdr_get(flow->slow_mh); + } mlx5e_tc_unoffload_fdb_rules(esw, flow, slow_attr); + if (flow->slow_mh) { + mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), flow->slow_mh); + mlx5_chains_put_chain_mapping(esw_chains(esw), flow->chain_mapping); + flow->chain_mapping = 0; + flow->slow_mh = NULL; + } flow_flag_clear(flow, SLOW); kfree(slow_attr); } @@ -1562,7 +1620,6 @@ struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr, struct netlink_ext_ack *extack, - bool *encap_valid, bool *vf_tun) { struct mlx5e_tc_flow_parse_attr *parse_attr; @@ -1579,7 +1636,6 @@ parse_attr = attr->parse_attr; esw_attr = attr->esw_attr; *vf_tun = false; - *encap_valid = true; for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) { struct net_device *out_dev; @@ -1596,7 +1652,7 @@ goto out; } err = mlx5e_attach_encap(priv, flow, attr, out_dev, out_index, - extack, &encap_dev, encap_valid); + extack, &encap_dev); dev_put(out_dev); if (err) goto out; @@ -1660,8 +1716,8 @@ struct mlx5e_tc_flow_parse_attr *parse_attr; struct mlx5_flow_attr *attr = flow->attr; struct mlx5_esw_flow_attr *esw_attr; - bool vf_tun, encap_valid; u32 max_prio, max_chain; + bool vf_tun; int err = 0; parse_attr = attr->parse_attr; @@ -1751,7 +1807,7 @@ esw_attr->int_port = int_port; } - err = set_encap_dests(priv, flow, attr, extack, &encap_valid, &vf_tun); + err = set_encap_dests(priv, flow, attr, extack, &vf_tun); if (err) goto err_out; @@ -1781,7 +1837,7 @@ * (1) there's no error * (2) there's an encap action and we don't have valid neigh */ - if (!encap_valid || flow_flag_test(flow, SLOW)) + if (flow_flag_test(flow, SLOW)) flow->rule[0] = mlx5e_tc_offload_to_slow_path(esw, flow, &parse_attr->spec); else flow->rule[0] = mlx5e_tc_offload_fdb_rules(esw, flow, &parse_attr->spec, attr); @@ -3679,7 +3735,7 @@ struct mlx5e_post_act *post_act = get_post_action(flow->priv); struct mlx5_flow_attr *attr, *next_attr = NULL; struct mlx5e_post_act_handle *handle; - bool vf_tun, encap_valid = true; + bool vf_tun; int err; /* This is going in reverse order as needed. @@ -3701,13 +3757,10 @@ if (list_is_last(&attr->list, &flow->attrs)) break; - err = set_encap_dests(flow->priv, flow, attr, extack, &encap_valid, &vf_tun); + err = set_encap_dests(flow->priv, flow, attr, extack, &vf_tun); if (err) goto out_free; - if (!encap_valid) - flow_flag_set(flow, SLOW); - err = actions_prepare_mod_hdr_actions(flow->priv, flow, attr, extack); if (err) goto out_free; @@ -3994,6 +4047,7 @@ struct mlx5e_tc_flow_parse_attr *parse_attr; struct mlx5_flow_attr *attr = flow->attr; struct mlx5_esw_flow_attr *esw_attr; + struct net_device *filter_dev; int err; err = flow_action_supported(flow_action, extack); @@ -4002,6 +4056,7 @@ esw_attr = attr->esw_attr; parse_attr = attr->parse_attr; + filter_dev = parse_attr->filter_dev; parse_state = &parse_attr->parse_state; mlx5e_tc_act_init_parse_state(parse_state, flow, flow_action, extack); parse_state->ct_priv = get_ct_priv(priv); @@ -4011,13 +4066,21 @@ return err; /* Forward to/from internal port can only have 1 dest */ - if ((netif_is_ovs_master(parse_attr->filter_dev) || esw_attr->dest_int_port) && + if ((netif_is_ovs_master(filter_dev) || esw_attr->dest_int_port) && esw_attr->out_count > 1) { NL_SET_ERR_MSG_MOD(extack, "Rules with internal port can have only one destination"); return -EOPNOTSUPP; } + /* Forward from tunnel/internal port to internal port is not supported */ + if ((mlx5e_get_tc_tun(filter_dev) || netif_is_ovs_master(filter_dev)) && + esw_attr->dest_int_port) { + NL_SET_ERR_MSG_MOD(extack, + "Forwarding from tunnel/internal port to internal port is not supported"); + return -EOPNOTSUPP; + } + err = actions_prepare_mod_hdr_actions(priv, flow, attr, extack); if (err) return err; @@ -4671,12 +4734,6 @@ return -EOPNOTSUPP; } - if (act->police.rate_pkt_ps) { - NL_SET_ERR_MSG_MOD(extack, - "QoS offload not support packets per second"); - return -EOPNOTSUPP; - } - return 0; } diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c 2023-01-18 18:27:39.000000000 +0000 @@ -304,6 +304,8 @@ u16 ds_cnt_inl = 0; u16 ds_cnt_ids = 0; + /* Sync the calculation with MLX5E_MAX_TX_WQEBBS. */ + if (attr->insz) ds_cnt_ids = DIV_ROUND_UP(sizeof(struct mlx5_wqe_inline_seg) + attr->insz, MLX5_SEND_WQE_DS); @@ -316,6 +318,9 @@ inl += VLAN_HLEN; ds_cnt_inl = DIV_ROUND_UP(inl, MLX5_SEND_WQE_DS); + if (WARN_ON_ONCE(ds_cnt_inl > MLX5E_MAX_TX_INLINE_DS)) + netdev_warn(skb->dev, "ds_cnt_inl = %u > max %u\n", ds_cnt_inl, + (u16)MLX5E_MAX_TX_INLINE_DS); ds_cnt += ds_cnt_inl; } @@ -391,6 +396,11 @@ if (unlikely(sq->ptpsq)) { mlx5e_skb_cb_hwtstamp_init(skb); mlx5e_skb_fifo_push(&sq->ptpsq->skb_fifo, skb); + if (!netif_tx_queue_stopped(sq->txq) && + !mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo)) { + netif_tx_stop_queue(sq->txq); + sq->stats->stopped++; + } skb_get(skb); } @@ -867,6 +877,7 @@ if (netif_tx_queue_stopped(sq->txq) && mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, sq->stop_room) && + mlx5e_ptpsq_fifo_has_room(sq) && !test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) { netif_tx_wake_queue(sq->txq); stats->wake++; diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c 2023-01-18 18:27:39.000000000 +0000 @@ -1363,6 +1363,9 @@ esw_offloads_del_send_to_vport_meta_rules(esw); devl_rate_nodes_destroy(devlink); } + /* Destroy legacy fdb when disabling sriov in legacy mode. */ + if (esw->mode == MLX5_ESWITCH_LEGACY) + mlx5_eswitch_disable_locked(esw); esw->esw_funcs.num_vfs = 0; @@ -1388,12 +1391,14 @@ esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", esw->esw_funcs.num_vfs, esw->enabled_vports); - esw->fdb_table.flags &= ~MLX5_ESW_FDB_CREATED; - if (esw->mode == MLX5_ESWITCH_OFFLOADS) - esw_offloads_disable(esw); - else if (esw->mode == MLX5_ESWITCH_LEGACY) - esw_legacy_disable(esw); - mlx5_esw_acls_ns_cleanup(esw); + if (esw->fdb_table.flags & MLX5_ESW_FDB_CREATED) { + esw->fdb_table.flags &= ~MLX5_ESW_FDB_CREATED; + if (esw->mode == MLX5_ESWITCH_OFFLOADS) + esw_offloads_disable(esw); + else if (esw->mode == MLX5_ESWITCH_LEGACY) + esw_legacy_disable(esw); + mlx5_esw_acls_ns_cleanup(esw); + } if (esw->mode == MLX5_ESWITCH_OFFLOADS) devl_rate_nodes_destroy(devlink); diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h 2023-01-18 18:27:39.000000000 +0000 @@ -731,6 +731,14 @@ struct mlx5_eswitch *slave_esw); int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw); +static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw) +{ + if (mlx5_esw_allowed(esw)) + return esw->esw_funcs.num_vfs; + + return 0; +} + #else /* CONFIG_MLX5_ESWITCH */ /* eswitch API stubs */ static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; } diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c 2023-01-18 18:27:39.000000000 +0000 @@ -431,7 +431,7 @@ mlx5_lag_mpesw_is_activated(esw->dev)) dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_UPLINK; } - if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) { + if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP_VALID) { if (pkt_reformat) { flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; flow_act->pkt_reformat = esw_attr->dests[attr_idx].pkt_reformat; @@ -2207,7 +2207,7 @@ static int esw_offloads_start(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack) { - int err, err1; + int err; esw->mode = MLX5_ESWITCH_OFFLOADS; err = mlx5_eswitch_enable_locked(esw, esw->dev->priv.sriov.num_vfs); @@ -2215,11 +2215,6 @@ NL_SET_ERR_MSG_MOD(extack, "Failed setting eswitch to offloads"); esw->mode = MLX5_ESWITCH_LEGACY; - err1 = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS); - if (err1) { - NL_SET_ERR_MSG_MOD(extack, - "Failed setting eswitch back to legacy"); - } mlx5_rescan_drivers(esw->dev); } if (esw->offloads.inline_mode == MLX5_INLINE_MODE_NONE) { @@ -3272,19 +3267,19 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack) { - int err, err1; + int err; esw->mode = MLX5_ESWITCH_LEGACY; + + /* If changing from switchdev to legacy mode without sriov enabled, + * no need to create legacy fdb. + */ + if (!mlx5_sriov_is_enabled(esw->dev)) + return 0; + err = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS); - if (err) { + if (err) NL_SET_ERR_MSG_MOD(extack, "Failed setting eswitch to legacy"); - esw->mode = MLX5_ESWITCH_OFFLOADS; - err1 = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS); - if (err1) { - NL_SET_ERR_MSG_MOD(extack, - "Failed setting eswitch back to offloads"); - } - } return err; } diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c 2023-01-18 18:27:39.000000000 +0000 @@ -30,9 +30,9 @@ sizeof(dest->vport.num), hash); hash = jhash((const void *)&dest->vport.vhca_id, sizeof(dest->vport.num), hash); - if (dest->vport.pkt_reformat) - hash = jhash(dest->vport.pkt_reformat, - sizeof(*dest->vport.pkt_reformat), + if (flow_act->pkt_reformat) + hash = jhash(flow_act->pkt_reformat, + sizeof(*flow_act->pkt_reformat), hash); return hash; } @@ -53,9 +53,11 @@ if (ret) return ret; - return dest1->vport.pkt_reformat && dest2->vport.pkt_reformat ? - memcmp(dest1->vport.pkt_reformat, dest2->vport.pkt_reformat, - sizeof(*dest1->vport.pkt_reformat)) : 0; + if (flow_act1->pkt_reformat && flow_act2->pkt_reformat) + return memcmp(flow_act1->pkt_reformat, flow_act2->pkt_reformat, + sizeof(*flow_act1->pkt_reformat)); + + return !(flow_act1->pkt_reformat == flow_act2->pkt_reformat); } static int @@ -310,6 +312,8 @@ for (curr_dest = 0; curr_dest < num_vport_dests; curr_dest++) { struct mlx5_termtbl_handle *tt = attr->dests[curr_dest].termtbl; + attr->dests[curr_dest].termtbl = NULL; + /* search for the destination associated with the * current term table */ diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c 2023-01-18 18:27:39.000000000 +0000 @@ -9,7 +9,8 @@ MLX5_FW_RESET_FLAGS_RESET_REQUESTED, MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, MLX5_FW_RESET_FLAGS_PENDING_COMP, - MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS + MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS, + MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED }; struct mlx5_fw_reset { @@ -152,7 +153,8 @@ mlx5_unload_one(dev); if (mlx5_health_wait_pci_up(dev)) mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n"); - mlx5_load_one(dev, false); + else + mlx5_load_one(dev, false); devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0, BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE)); @@ -358,6 +360,23 @@ err = -ETIMEDOUT; } + do { + err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, ®16); + if (err) + return err; + if (reg16 == dev_id) + break; + msleep(20); + } while (!time_after(jiffies, timeout)); + + if (reg16 == dev_id) { + mlx5_core_info(dev, "Firmware responds to PCI config cycles again\n"); + } else { + mlx5_core_err(dev, "Firmware is not responsive (0x%04x) after %llu ms\n", + reg16, mlx5_tout_ms(dev, PCI_TOGGLE)); + err = -ETIMEDOUT; + } + restore: list_for_each_entry(sdev, &bridge_bus->devices, bus_list) { pci_cfg_access_unlock(sdev); @@ -388,7 +407,7 @@ err = mlx5_pci_link_toggle(dev); if (err) { mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, no reset done, err %d\n", err); - goto done; + set_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags); } mlx5_enter_error_state(dev, true); @@ -464,6 +483,10 @@ goto out; } err = fw_reset->ret; + if (test_and_clear_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags)) { + mlx5_unload_one_devl_locked(dev); + mlx5_load_one_devl_locked(dev, false); + } out: clear_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags); return err; diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c 2023-01-18 18:27:39.000000000 +0000 @@ -648,10 +648,13 @@ return false; #ifdef CONFIG_MLX5_ESWITCH - dev = ldev->pf[MLX5_LAG_P1].dev; - if ((mlx5_sriov_is_enabled(dev)) && !is_mdev_switchdev_mode(dev)) - return false; + for (i = 0; i < ldev->ports; i++) { + dev = ldev->pf[i].dev; + if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev)) + return false; + } + dev = ldev->pf[MLX5_LAG_P1].dev; mode = mlx5_eswitch_mode(dev); for (i = 0; i < ldev->ports; i++) if (mlx5_eswitch_mode(ldev->pf[i].dev) != mode) diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c 2023-01-18 18:27:39.000000000 +0000 @@ -3,6 +3,7 @@ #include #include +#include "clock.h" #include "aso.h" #include "wq.h" @@ -179,6 +180,7 @@ { void *in, *sqc, *wq; int inlen, err; + u8 ts_format; inlen = MLX5_ST_SZ_BYTES(create_sq_in) + sizeof(u64) * sq->wq_ctrl.buf.npages; @@ -195,6 +197,11 @@ MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST); MLX5_SET(sqc, sqc, flush_in_error_en, 1); + ts_format = mlx5_is_real_time_sq(mdev) ? + MLX5_TIMESTAMP_FORMAT_REAL_TIME : + MLX5_TIMESTAMP_FORMAT_FREE_RUNNING; + MLX5_SET(sqc, sqc, ts_format, ts_format); + MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC); MLX5_SET(wq, wq, uar_page, mdev->mlx5e_res.hw_objs.bfreg.index); MLX5_SET(wq, wq, log_wq_pg_sz, sq->wq_ctrl.buf.page_shift - diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -122,7 +122,7 @@ { struct mlx5_mpfs *mpfs = dev->priv.mpfs; - if (!MLX5_ESWITCH_MANAGER(dev)) + if (!mpfs) return; WARN_ON(!hlist_empty(mpfs->hash)); @@ -137,7 +137,7 @@ int err = 0; u32 index; - if (!MLX5_ESWITCH_MANAGER(dev)) + if (!mpfs) return 0; mutex_lock(&mpfs->lock); @@ -185,7 +185,7 @@ int err = 0; u32 index; - if (!MLX5_ESWITCH_MANAGER(dev)) + if (!mpfs) return 0; mutex_lock(&mpfs->lock); diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/main.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/main.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1759,7 +1759,8 @@ res = state == pci_channel_io_perm_failure ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; - mlx5_pci_trace(dev, "Exit, result = %d, %s\n", res, result2str(res)); + mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, result = %d, %s\n", + __func__, dev->state, dev->pci_status, res, result2str(res)); return res; } @@ -1798,7 +1799,8 @@ struct mlx5_core_dev *dev = pci_get_drvdata(pdev); int err; - mlx5_pci_trace(dev, "Enter\n"); + mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Enter\n", + __func__, dev->state, dev->pci_status); err = mlx5_pci_enable_device(dev); if (err) { @@ -1820,7 +1822,8 @@ res = PCI_ERS_RESULT_RECOVERED; out: - mlx5_pci_trace(dev, "Exit, err = %d, result = %d, %s\n", err, res, result2str(res)); + mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, err = %d, result = %d, %s\n", + __func__, dev->state, dev->pci_status, err, res, result2str(res)); return res; } @@ -1833,6 +1836,10 @@ err = mlx5_load_one(dev, false); + if (!err) + devlink_health_reporter_state_update(dev->priv.health.fw_fatal_reporter, + DEVLINK_HEALTH_REPORTER_STATE_HEALTHY); + mlx5_pci_trace(dev, "Done, err = %d, device %s\n", err, !err ? "recovered" : "Failed"); } diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c 2023-01-18 18:27:39.000000000 +0000 @@ -18,6 +18,10 @@ phys_addr_t base_address; u64 sf_bar_length; struct notifier_block nb; + struct mutex table_lock; /* Serializes sf life cycle and vhca state change handler */ + struct workqueue_struct *active_wq; + struct work_struct work; + u8 stop_active_wq:1; struct mlx5_core_dev *dev; }; @@ -168,6 +172,7 @@ return 0; sf_index = event->function_id - base_id; + mutex_lock(&table->table_lock); sf_dev = xa_load(&table->devices, sf_index); switch (event->new_vhca_state) { case MLX5_VHCA_STATE_INVALID: @@ -191,6 +196,7 @@ default: break; } + mutex_unlock(&table->table_lock); return 0; } @@ -215,6 +221,78 @@ return 0; } +static void mlx5_sf_dev_add_active_work(struct work_struct *work) +{ + struct mlx5_sf_dev_table *table = container_of(work, struct mlx5_sf_dev_table, work); + u32 out[MLX5_ST_SZ_DW(query_vhca_state_out)] = {}; + struct mlx5_core_dev *dev = table->dev; + u16 max_functions; + u16 function_id; + u16 sw_func_id; + int err = 0; + u8 state; + int i; + + max_functions = mlx5_sf_max_functions(dev); + function_id = MLX5_CAP_GEN(dev, sf_base_id); + for (i = 0; i < max_functions; i++, function_id++) { + if (table->stop_active_wq) + return; + err = mlx5_cmd_query_vhca_state(dev, function_id, out, sizeof(out)); + if (err) + /* A failure of specific vhca doesn't mean others will + * fail as well. + */ + continue; + state = MLX5_GET(query_vhca_state_out, out, vhca_state_context.vhca_state); + if (state != MLX5_VHCA_STATE_ACTIVE) + continue; + + sw_func_id = MLX5_GET(query_vhca_state_out, out, vhca_state_context.sw_function_id); + mutex_lock(&table->table_lock); + /* Don't probe device which is already probe */ + if (!xa_load(&table->devices, i)) + mlx5_sf_dev_add(dev, i, function_id, sw_func_id); + /* There is a race where SF got inactive after the query + * above. e.g.: the query returns that the state of the + * SF is active, and after that the eswitch manager set it to + * inactive. + * This case cannot be managed in SW, since the probing of the + * SF is on one system, and the inactivation is on a different + * system. + * If the inactive is done after the SF perform init_hca(), + * the SF will fully probe and then removed. If it was + * done before init_hca(), the SF probe will fail. + */ + mutex_unlock(&table->table_lock); + } +} + +/* In case SFs are generated externally, probe active SFs */ +static int mlx5_sf_dev_queue_active_work(struct mlx5_sf_dev_table *table) +{ + if (MLX5_CAP_GEN(table->dev, eswitch_manager)) + return 0; /* the table is local */ + + /* Use a workqueue to probe active SFs, which are in large + * quantity and may take up to minutes to probe. + */ + table->active_wq = create_singlethread_workqueue("mlx5_active_sf"); + if (!table->active_wq) + return -ENOMEM; + INIT_WORK(&table->work, &mlx5_sf_dev_add_active_work); + queue_work(table->active_wq, &table->work); + return 0; +} + +static void mlx5_sf_dev_destroy_active_work(struct mlx5_sf_dev_table *table) +{ + if (table->active_wq) { + table->stop_active_wq = true; + destroy_workqueue(table->active_wq); + } +} + void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev) { struct mlx5_sf_dev_table *table; @@ -240,11 +318,17 @@ table->base_address = pci_resource_start(dev->pdev, 2); table->max_sfs = max_sfs; xa_init(&table->devices); + mutex_init(&table->table_lock); dev->priv.sf_dev_table = table; err = mlx5_vhca_event_notifier_register(dev, &table->nb); if (err) goto vhca_err; + + err = mlx5_sf_dev_queue_active_work(table); + if (err) + goto add_active_err; + err = mlx5_sf_dev_vhca_arm_all(table); if (err) goto arm_err; @@ -252,6 +336,8 @@ return; arm_err: + mlx5_sf_dev_destroy_active_work(table); +add_active_err: mlx5_vhca_event_notifier_unregister(dev, &table->nb); vhca_err: table->max_sfs = 0; @@ -279,7 +365,9 @@ if (!table) return; + mlx5_sf_dev_destroy_active_work(table); mlx5_vhca_event_notifier_unregister(dev, &table->nb); + mutex_destroy(&table->table_lock); /* Now that event handler is not running, it is safe to destroy * the sf device without race. diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c 2023-01-18 18:27:39.000000000 +0000 @@ -1200,7 +1200,8 @@ } remove_from_nic_tbl: - mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher); + if (!nic_matcher->rules) + mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher); free_hw_ste: mlx5dr_domain_nic_unlock(nic_dmn); diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c 2023-01-18 18:27:39.000000000 +0000 @@ -46,7 +46,7 @@ int mlx5dr_table_set_miss_action(struct mlx5dr_table *tbl, struct mlx5dr_action *action) { - int ret; + int ret = -EOPNOTSUPP; if (action && action->action_type != DR_ACTION_TYP_FT) return -EOPNOTSUPP; @@ -67,6 +67,9 @@ goto out; } + if (ret) + goto out; + /* Release old action */ if (tbl->miss_action) refcount_dec(&tbl->miss_action->refcount); diff -Nru linux-6.0.6/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c linux-6.0.12/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c --- linux-6.0.6/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c 2023-01-18 18:27:39.000000000 +0000 @@ -3470,6 +3470,8 @@ u16 vid; vxlan_fdb_info = &switchdev_work->vxlan_fdb_info; + if (!vxlan_fdb_info->offloaded) + return; bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev); if (!bridge_device) diff -Nru linux-6.0.6/drivers/net/ethernet/micrel/ksz884x.c linux-6.0.12/drivers/net/ethernet/micrel/ksz884x.c --- linux-6.0.6/drivers/net/ethernet/micrel/ksz884x.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/micrel/ksz884x.c 2023-01-18 18:27:39.000000000 +0000 @@ -6851,7 +6851,7 @@ char banner[sizeof(version)]; struct ksz_switch *sw = NULL; - result = pci_enable_device(pdev); + result = pcim_enable_device(pdev); if (result) return result; diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c --- linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c 2023-01-18 18:27:39.000000000 +0000 @@ -656,7 +656,15 @@ stats->rx_dropped = dev->stats.rx_dropped + lan966x->stats[idx + SYS_COUNT_RX_LONG] + lan966x->stats[idx + SYS_COUNT_DR_LOCAL] + - lan966x->stats[idx + SYS_COUNT_DR_TAIL]; + lan966x->stats[idx + SYS_COUNT_DR_TAIL] + + lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] + + lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] + + lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] + + lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] + + lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] + + lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] + + lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] + + lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7]; for (i = 0; i < LAN966X_NUM_TC; i++) { stats->rx_dropped += @@ -708,6 +716,9 @@ snprintf(queue_name, sizeof(queue_name), "%s-stats", dev_name(lan966x->dev)); lan966x->stats_queue = create_singlethread_workqueue(queue_name); + if (!lan966x->stats_queue) + return -ENOMEM; + INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work); queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work, LAN966X_STATS_CHECK_DELAY); diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c --- linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c 2023-01-18 18:27:39.000000000 +0000 @@ -309,6 +309,7 @@ lan966x, FDMA_CH_DB_DISCARD); tx->activated = false; + tx->last_in_use = -1; } static void lan966x_fdma_tx_reload(struct lan966x_tx *tx) @@ -413,13 +414,15 @@ /* Get the received frame and unmap it */ db = &rx->dcbs[rx->dcb_index].db[rx->db_index]; page = rx->page[rx->dcb_index][rx->db_index]; + + dma_sync_single_for_cpu(lan966x->dev, (dma_addr_t)db->dataptr, + FDMA_DCB_STATUS_BLOCKL(db->status), + DMA_FROM_DEVICE); + skb = build_skb(page_address(page), PAGE_SIZE << rx->page_order); if (unlikely(!skb)) goto unmap_page; - dma_unmap_single(lan966x->dev, (dma_addr_t)db->dataptr, - FDMA_DCB_STATUS_BLOCKL(db->status), - DMA_FROM_DEVICE); skb_put(skb, FDMA_DCB_STATUS_BLOCKL(db->status)); lan966x_ifh_get_src_port(skb->data, &src_port); @@ -428,6 +431,10 @@ if (WARN_ON(src_port >= lan966x->num_phys_ports)) goto free_skb; + dma_unmap_single_attrs(lan966x->dev, (dma_addr_t)db->dataptr, + PAGE_SIZE << rx->page_order, DMA_FROM_DEVICE, + DMA_ATTR_SKIP_CPU_SYNC); + skb->dev = lan966x->ports[src_port]->dev; skb_pull(skb, IFH_LEN * sizeof(u32)); @@ -453,9 +460,9 @@ free_skb: kfree_skb(skb); unmap_page: - dma_unmap_page(lan966x->dev, (dma_addr_t)db->dataptr, - FDMA_DCB_STATUS_BLOCKL(db->status), - DMA_FROM_DEVICE); + dma_unmap_single_attrs(lan966x->dev, (dma_addr_t)db->dataptr, + PAGE_SIZE << rx->page_order, DMA_FROM_DEVICE, + DMA_ATTR_SKIP_CPU_SYNC); __free_pages(page, rx->page_order); return NULL; @@ -667,12 +674,14 @@ int i; for (i = 0; i < lan966x->num_phys_ports; ++i) { + struct lan966x_port *port; int mtu; - if (!lan966x->ports[i]) + port = lan966x->ports[i]; + if (!port) continue; - mtu = lan966x->ports[i]->dev->mtu; + mtu = lan_rd(lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); if (mtu > max_mtu) max_mtu = mtu; } @@ -687,17 +696,14 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu) { - void *rx_dcbs, *tx_dcbs, *tx_dcbs_buf; - dma_addr_t rx_dma, tx_dma; + dma_addr_t rx_dma; + void *rx_dcbs; u32 size; int err; /* Store these for later to free them */ rx_dma = lan966x->rx.dma; - tx_dma = lan966x->tx.dma; rx_dcbs = lan966x->rx.dcbs; - tx_dcbs = lan966x->tx.dcbs; - tx_dcbs_buf = lan966x->tx.dcbs_buf; napi_synchronize(&lan966x->napi); napi_disable(&lan966x->napi); @@ -715,17 +721,6 @@ size = ALIGN(size, PAGE_SIZE); dma_free_coherent(lan966x->dev, size, rx_dcbs, rx_dma); - lan966x_fdma_tx_disable(&lan966x->tx); - err = lan966x_fdma_tx_alloc(&lan966x->tx); - if (err) - goto restore_tx; - - size = sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX; - size = ALIGN(size, PAGE_SIZE); - dma_free_coherent(lan966x->dev, size, tx_dcbs, tx_dma); - - kfree(tx_dcbs_buf); - lan966x_fdma_wakeup_netdev(lan966x); napi_enable(&lan966x->napi); @@ -735,11 +730,6 @@ lan966x->rx.dcbs = rx_dcbs; lan966x_fdma_rx_start(&lan966x->rx); -restore_tx: - lan966x->tx.dma = tx_dma; - lan966x->tx.dcbs = tx_dcbs; - lan966x->tx.dcbs_buf = tx_dcbs_buf; - return err; } @@ -751,6 +741,8 @@ max_mtu = lan966x_fdma_get_max_mtu(lan966x); max_mtu += IFH_LEN * sizeof(u32); + max_mtu += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + max_mtu += VLAN_HLEN * 2; if (round_up(max_mtu, PAGE_SIZE) / PAGE_SIZE - 1 == lan966x->rx.page_order) diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_main.c linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_main.c --- linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -385,7 +385,7 @@ int old_mtu = dev->mtu; int err; - lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(new_mtu), + lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(new_mtu)), lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); dev->mtu = new_mtu; @@ -394,7 +394,7 @@ err = lan966x_fdma_change_mtu(lan966x); if (err) { - lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(old_mtu), + lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(old_mtu)), lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port)); dev->mtu = old_mtu; } diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_main.h linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_main.h --- linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_main.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_main.h 2023-01-18 18:27:39.000000000 +0000 @@ -24,6 +24,8 @@ #define LAN966X_BUFFER_MEMORY (160 * 1024) #define LAN966X_BUFFER_MIN_SZ 60 +#define LAN966X_HW_MTU(mtu) ((mtu) + ETH_HLEN + ETH_FCS_LEN) + #define PGID_AGGR 64 #define PGID_SRC 80 #define PGID_ENTRIES 89 diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h --- linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h 2023-01-18 18:27:39.000000000 +0000 @@ -444,6 +444,21 @@ #define DEV_MAC_MAXLEN_CFG_MAX_LEN_GET(x)\ FIELD_GET(DEV_MAC_MAXLEN_CFG_MAX_LEN, x) +/* DEV:MAC_CFG_STATUS:MAC_TAGS_CFG */ +#define DEV_MAC_TAGS_CFG(t) __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 12, 0, 1, 4) + +#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA BIT(1) +#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(x)\ + FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x) +#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_GET(x)\ + FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x) + +#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0) +#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\ + FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x) +#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\ + FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x) + /* DEV:MAC_CFG_STATUS:MAC_IFG_CFG */ #define DEV_MAC_IFG_CFG(t) __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 20, 0, 1, 4) diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c --- linux-6.0.6/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c 2023-01-18 18:27:39.000000000 +0000 @@ -169,6 +169,12 @@ ANA_VLAN_CFG_VLAN_POP_CNT, lan966x, ANA_VLAN_CFG(port->chip_port)); + lan_rmw(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(port->vlan_aware) | + DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(port->vlan_aware), + DEV_MAC_TAGS_CFG_VLAN_AWR_ENA | + DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, + lan966x, DEV_MAC_TAGS_CFG(port->chip_port)); + /* Drop frames with multicast source address */ val = ANA_DROP_CFG_DROP_MC_SMAC_ENA_SET(1); if (port->vlan_aware && !pvid) diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c linux-6.0.12/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c --- linux-6.0.6/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c 2023-01-18 18:27:39.000000000 +0000 @@ -1253,6 +1253,9 @@ snprintf(queue_name, sizeof(queue_name), "%s-stats", dev_name(sparx5->dev)); sparx5->stats_queue = create_singlethread_workqueue(queue_name); + if (!sparx5->stats_queue) + return -ENOMEM; + INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work); queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work, SPX5_STATS_CHECK_DELAY); diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/sparx5/sparx5_main.c linux-6.0.12/drivers/net/ethernet/microchip/sparx5/sparx5_main.c --- linux-6.0.6/drivers/net/ethernet/microchip/sparx5/sparx5_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/sparx5/sparx5_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -657,6 +657,9 @@ snprintf(queue_name, sizeof(queue_name), "%s-mact", dev_name(sparx5->dev)); sparx5->mact_queue = create_singlethread_workqueue(queue_name); + if (!sparx5->mact_queue) + return -ENOMEM; + INIT_DELAYED_WORK(&sparx5->mact_work, sparx5_mact_pull_work); queue_delayed_work(sparx5->mact_queue, &sparx5->mact_work, SPX5_MACT_PULL_DELAY); diff -Nru linux-6.0.6/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c linux-6.0.12/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c --- linux-6.0.6/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c 2023-01-18 18:27:39.000000000 +0000 @@ -103,7 +103,7 @@ err = phylink_of_phy_connect(port->phylink, port->of_node, 0); if (err) { netdev_err(ndev, "Could not attach to PHY\n"); - return err; + goto err_connect; } phylink_start(port->phylink); @@ -115,10 +115,20 @@ err = sparx5_serdes_set(port->sparx5, port, &port->conf); else err = phy_power_on(port->serdes); - if (err) + if (err) { netdev_err(ndev, "%s failed\n", __func__); + goto out_power; + } } + return 0; + +out_power: + phylink_stop(port->phylink); + phylink_disconnect_phy(port->phylink); +err_connect: + sparx5_port_enable(port, false); + return err; } diff -Nru linux-6.0.6/drivers/net/ethernet/neterion/s2io.c linux-6.0.12/drivers/net/ethernet/neterion/s2io.c --- linux-6.0.6/drivers/net/ethernet/neterion/s2io.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/neterion/s2io.c 2023-01-18 18:27:39.000000000 +0000 @@ -7128,9 +7128,8 @@ if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", dev->name); - s2io_reset(sp); - free_rx_buffers(sp); - return -ENOMEM; + ret = -ENOMEM; + goto err_fill_buff; } DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i, ring->rx_bufs_left); @@ -7168,18 +7167,16 @@ /* Enable Rx Traffic and interrupts on the NIC */ if (start_nic(sp)) { DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name); - s2io_reset(sp); - free_rx_buffers(sp); - return -ENODEV; + ret = -ENODEV; + goto err_out; } /* Add interrupt service routine */ if (s2io_add_isr(sp) != 0) { if (sp->config.intr_type == MSI_X) s2io_rem_isr(sp); - s2io_reset(sp); - free_rx_buffers(sp); - return -ENODEV; + ret = -ENODEV; + goto err_out; } timer_setup(&sp->alarm_timer, s2io_alarm_handle, 0); @@ -7199,6 +7196,20 @@ } return 0; + +err_out: + if (config->napi) { + if (config->intr_type == MSI_X) { + for (i = 0; i < sp->config.rx_ring_num; i++) + napi_disable(&sp->mac_control.rings[i].napi); + } else { + napi_disable(&sp->napi); + } + } +err_fill_buff: + s2io_reset(sp); + free_rx_buffers(sp); + return ret; } /** diff -Nru linux-6.0.6/drivers/net/ethernet/netronome/nfp/nfp_devlink.c linux-6.0.12/drivers/net/ethernet/netronome/nfp/nfp_devlink.c --- linux-6.0.6/drivers/net/ethernet/netronome/nfp/nfp_devlink.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/netronome/nfp/nfp_devlink.c 2023-01-18 18:27:39.000000000 +0000 @@ -341,7 +341,7 @@ return ret; attrs.split = eth_port.is_split; - attrs.splittable = !attrs.split; + attrs.splittable = eth_port.port_lanes > 1 && !attrs.split; attrs.lanes = eth_port.port_lanes; attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; attrs.phys.port_number = eth_port.label_port; diff -Nru linux-6.0.6/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c linux-6.0.12/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c --- linux-6.0.6/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c 2023-01-18 18:27:39.000000000 +0000 @@ -1395,6 +1395,9 @@ u8 data; port = nfp_port_from_netdev(netdev); + if (!port) + return -EOPNOTSUPP; + /* update port state to get latest interface */ set_bit(NFP_PORT_CHANGED, &port->flags); eth_port = nfp_port_get_eth_port(port); @@ -1440,15 +1443,15 @@ if (data < 0x3) { modinfo->type = ETH_MODULE_SFF_8436; - modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; + modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN; } else { modinfo->type = ETH_MODULE_SFF_8636; - modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; + modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN; } break; case NFP_INTERFACE_QSFP28: modinfo->type = ETH_MODULE_SFF_8636; - modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; + modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN; break; default: netdev_err(netdev, "Unsupported module 0x%x detected\n", diff -Nru linux-6.0.6/drivers/net/ethernet/ni/nixge.c linux-6.0.12/drivers/net/ethernet/ni/nixge.c --- linux-6.0.6/drivers/net/ethernet/ni/nixge.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/ni/nixge.c 2023-01-18 18:27:39.000000000 +0000 @@ -249,25 +249,26 @@ struct sk_buff *skb; int i; - for (i = 0; i < RX_BD_NUM; i++) { - phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], - phys); - - dma_unmap_single(ndev->dev.parent, phys_addr, - NIXGE_MAX_JUMBO_FRAME_SIZE, - DMA_FROM_DEVICE); - - skb = (struct sk_buff *)(uintptr_t) - nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], - sw_id_offset); - dev_kfree_skb(skb); - } + if (priv->rx_bd_v) { + for (i = 0; i < RX_BD_NUM; i++) { + phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], + phys); + + dma_unmap_single(ndev->dev.parent, phys_addr, + NIXGE_MAX_JUMBO_FRAME_SIZE, + DMA_FROM_DEVICE); + + skb = (struct sk_buff *)(uintptr_t) + nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], + sw_id_offset); + dev_kfree_skb(skb); + } - if (priv->rx_bd_v) dma_free_coherent(ndev->dev.parent, sizeof(*priv->rx_bd_v) * RX_BD_NUM, priv->rx_bd_v, priv->rx_bd_p); + } if (priv->tx_skb) devm_kfree(ndev->dev.parent, priv->tx_skb); @@ -900,6 +901,7 @@ err_rx_irq: free_irq(priv->tx_irq, ndev); err_tx_irq: + napi_disable(&priv->napi); phy_stop(phy); phy_disconnect(phy); tasklet_kill(&priv->dma_err_tasklet); diff -Nru linux-6.0.6/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c linux-6.0.12/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c --- linux-6.0.6/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1143,6 +1143,7 @@ buffer_info->dma = 0; buffer_info->time_stamp = 0; tx_ring->next_to_use = ring_num; + dev_kfree_skb_any(skb); return; } buffer_info->mapped = true; @@ -2459,6 +2460,7 @@ unregister_netdev(netdev); pch_gbe_phy_hw_reset(&adapter->hw); + pci_dev_put(adapter->ptp_pdev); free_netdev(netdev); } @@ -2534,7 +2536,7 @@ /* setup the private structure */ ret = pch_gbe_sw_init(adapter); if (ret) - goto err_free_netdev; + goto err_put_dev; /* Initialize PHY */ ret = pch_gbe_init_phy(adapter); @@ -2592,6 +2594,8 @@ err_free_adapter: pch_gbe_phy_hw_reset(&adapter->hw); +err_put_dev: + pci_dev_put(adapter->ptp_pdev); err_free_netdev: free_netdev(netdev); return ret; diff -Nru linux-6.0.6/drivers/net/ethernet/pensando/ionic/ionic_main.c linux-6.0.12/drivers/net/ethernet/pensando/ionic/ionic_main.c --- linux-6.0.6/drivers/net/ethernet/pensando/ionic/ionic_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/pensando/ionic/ionic_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -687,8 +687,14 @@ static int __init ionic_init_module(void) { + int ret; + ionic_debugfs_create(); - return ionic_bus_register_driver(); + ret = ionic_bus_register_driver(); + if (ret) + ionic_debugfs_destroy(); + + return ret; } static void __exit ionic_cleanup_module(void) diff -Nru linux-6.0.6/drivers/net/ethernet/qlogic/qla3xxx.c linux-6.0.12/drivers/net/ethernet/qlogic/qla3xxx.c --- linux-6.0.6/drivers/net/ethernet/qlogic/qla3xxx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/qlogic/qla3xxx.c 2023-01-18 18:27:39.000000000 +0000 @@ -2471,6 +2471,7 @@ skb_shinfo(skb)->nr_frags); if (tx_cb->seg_count == -1) { netdev_err(ndev, "%s: invalid segment count!\n", __func__); + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } diff -Nru linux-6.0.6/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c linux-6.0.12/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c --- linux-6.0.6/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c 2023-01-18 18:27:39.000000000 +0000 @@ -2991,7 +2991,7 @@ QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val); dev_info(&adapter->pdev->dev, "%s: lock recovery initiated\n", __func__); - msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY); + mdelay(QLC_83XX_DRV_LOCK_RECOVERY_DELAY); val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK); id = ((val >> 2) & 0xF); if (id == adapter->portnum) { @@ -3027,7 +3027,7 @@ if (status) break; - msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY); + mdelay(QLC_83XX_DRV_LOCK_WAIT_DELAY); i++; if (i == 1) diff -Nru linux-6.0.6/drivers/net/ethernet/renesas/ravb_main.c linux-6.0.12/drivers/net/ethernet/renesas/ravb_main.c --- linux-6.0.6/drivers/net/ethernet/renesas/ravb_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/renesas/ravb_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -3013,6 +3013,7 @@ ret = ravb_open(ndev); if (ret < 0) return ret; + ravb_set_rx_mode(ndev); netif_device_attach(ndev); } diff -Nru linux-6.0.6/drivers/net/ethernet/sfc/ef100_netdev.c linux-6.0.12/drivers/net/ethernet/sfc/ef100_netdev.c --- linux-6.0.6/drivers/net/ethernet/sfc/ef100_netdev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/sfc/ef100_netdev.c 2023-01-18 18:27:39.000000000 +0000 @@ -217,6 +217,7 @@ skb->len, skb->data_len, channel->channel); if (!efx->n_channels || !efx->n_tx_channels || !channel) { netif_stop_queue(net_dev); + dev_kfree_skb_any(skb); goto err; } diff -Nru linux-6.0.6/drivers/net/ethernet/sfc/efx.c linux-6.0.12/drivers/net/ethernet/sfc/efx.c --- linux-6.0.6/drivers/net/ethernet/sfc/efx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/sfc/efx.c 2023-01-18 18:27:39.000000000 +0000 @@ -1059,8 +1059,10 @@ /* Allocate and initialise a struct net_device */ net_dev = alloc_etherdev_mq(sizeof(probe_data), EFX_MAX_CORE_TX_QUEUES); - if (!net_dev) - return -ENOMEM; + if (!net_dev) { + rc = -ENOMEM; + goto fail0; + } probe_ptr = netdev_priv(net_dev); *probe_ptr = probe_data; efx->net_dev = net_dev; @@ -1132,6 +1134,8 @@ WARN_ON(rc > 0); netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc); free_netdev(net_dev); + fail0: + kfree(probe_data); return rc; } diff -Nru linux-6.0.6/drivers/net/ethernet/socionext/netsec.c linux-6.0.12/drivers/net/ethernet/socionext/netsec.c --- linux-6.0.6/drivers/net/ethernet/socionext/netsec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/socionext/netsec.c 2023-01-18 18:27:39.000000000 +0000 @@ -1961,11 +1961,13 @@ ret = PTR_ERR(priv->phydev); dev_err(priv->dev, "get_phy_device err(%d)\n", ret); priv->phydev = NULL; + mdiobus_unregister(bus); return -ENODEV; } ret = phy_device_register(priv->phydev); if (ret) { + phy_device_free(priv->phydev); mdiobus_unregister(bus); dev_err(priv->dev, "phy_device_register err(%d)\n", ret); diff -Nru linux-6.0.6/drivers/net/ethernet/socionext/sni_ave.c linux-6.0.12/drivers/net/ethernet/socionext/sni_ave.c --- linux-6.0.6/drivers/net/ethernet/socionext/sni_ave.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/socionext/sni_ave.c 2023-01-18 18:27:39.000000000 +0000 @@ -1229,6 +1229,8 @@ phy_support_asym_pause(phydev); + phydev->mac_managed_pm = true; + phy_attached_info(phydev); return 0; @@ -1757,6 +1759,10 @@ ave_global_reset(ndev); + ret = phy_init_hw(ndev->phydev); + if (ret) + return ret; + ave_ethtool_get_wol(ndev, &wol); wol.wolopts = priv->wolopts; __ave_ethtool_set_wol(ndev, &wol); diff -Nru linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c --- linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -749,6 +749,8 @@ if (fc & FLOW_RX) { pr_debug("\tReceive Flow-Control ON\n"); flow |= GMAC_RX_FLOW_CTRL_RFE; + } else { + pr_debug("\tReceive Flow-Control OFF\n"); } writel(flow, ioaddr + GMAC_RX_FLOW_CTRL); diff -Nru linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c --- linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c 2023-01-18 18:27:39.000000000 +0000 @@ -630,7 +630,6 @@ { plat->rx_queues_to_use = 8; plat->tx_queues_to_use = 8; - plat->clk_ptp_rate = 200000000; plat->use_phy_wol = 1; plat->safety_feat_cfg->tsoee = 1; @@ -655,6 +654,8 @@ plat->serdes_powerup = intel_serdes_powerup; plat->serdes_powerdown = intel_serdes_powerdown; + plat->clk_ptp_rate = 204800000; + return ehl_common_data(pdev, plat); } @@ -668,6 +669,8 @@ plat->bus_id = 1; plat->phy_interface = PHY_INTERFACE_MODE_RGMII; + plat->clk_ptp_rate = 204800000; + return ehl_common_data(pdev, plat); } @@ -684,6 +687,8 @@ plat->bus_id = 2; plat->addr64 = 32; + plat->clk_ptp_rate = 200000000; + intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ); return ehl_common_data(pdev, plat); @@ -723,6 +728,8 @@ plat->bus_id = 3; plat->addr64 = 32; + plat->clk_ptp_rate = 200000000; + intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ); return ehl_common_data(pdev, plat); @@ -758,7 +765,7 @@ { plat->rx_queues_to_use = 6; plat->tx_queues_to_use = 4; - plat->clk_ptp_rate = 200000000; + plat->clk_ptp_rate = 204800000; plat->speed_mode_2500 = intel_speed_mode_2500; plat->safety_feat_cfg->tsoee = 1; diff -Nru linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c --- linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c 2023-01-18 18:27:39.000000000 +0000 @@ -51,7 +51,6 @@ struct stmmac_resources res; struct device_node *np; int ret, i, phy_mode; - bool mdio = false; np = dev_of_node(&pdev->dev); @@ -69,29 +68,31 @@ if (!plat) return -ENOMEM; + plat->mdio_node = of_get_child_by_name(np, "mdio"); if (plat->mdio_node) { - dev_err(&pdev->dev, "Found MDIO subnode\n"); - mdio = true; - } + dev_info(&pdev->dev, "Found MDIO subnode\n"); - if (mdio) { plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(*plat->mdio_bus_data), GFP_KERNEL); - if (!plat->mdio_bus_data) - return -ENOMEM; + if (!plat->mdio_bus_data) { + ret = -ENOMEM; + goto err_put_node; + } plat->mdio_bus_data->needs_reset = true; } plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), GFP_KERNEL); - if (!plat->dma_cfg) - return -ENOMEM; + if (!plat->dma_cfg) { + ret = -ENOMEM; + goto err_put_node; + } /* Enable pci device */ ret = pci_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", __func__); - return ret; + goto err_put_node; } /* Get the base address of device */ @@ -100,7 +101,7 @@ continue; ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); if (ret) - return ret; + goto err_disable_device; break; } @@ -111,7 +112,8 @@ phy_mode = device_get_phy_mode(&pdev->dev); if (phy_mode < 0) { dev_err(&pdev->dev, "phy_mode not found\n"); - return phy_mode; + ret = phy_mode; + goto err_disable_device; } plat->phy_interface = phy_mode; @@ -128,6 +130,7 @@ if (res.irq < 0) { dev_err(&pdev->dev, "IRQ macirq not found\n"); ret = -ENODEV; + goto err_disable_msi; } res.wol_irq = of_irq_get_byname(np, "eth_wake_irq"); @@ -140,15 +143,31 @@ if (res.lpi_irq < 0) { dev_err(&pdev->dev, "IRQ eth_lpi not found\n"); ret = -ENODEV; + goto err_disable_msi; } - return stmmac_dvr_probe(&pdev->dev, plat, &res); + ret = stmmac_dvr_probe(&pdev->dev, plat, &res); + if (ret) + goto err_disable_msi; + + return ret; + +err_disable_msi: + pci_disable_msi(pdev); +err_disable_device: + pci_disable_device(pdev); +err_put_node: + of_node_put(plat->mdio_node); + return ret; } static void loongson_dwmac_remove(struct pci_dev *pdev) { + struct net_device *ndev = dev_get_drvdata(&pdev->dev); + struct stmmac_priv *priv = netdev_priv(ndev); int i; + of_node_put(priv->plat->mdio_node); stmmac_dvr_remove(&pdev->dev); for (i = 0; i < PCI_STD_NUM_BARS; i++) { @@ -158,6 +177,7 @@ break; } + pci_disable_msi(pdev); pci_disable_device(pdev); } diff -Nru linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c --- linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 2023-01-18 18:27:39.000000000 +0000 @@ -272,11 +272,9 @@ if (ret) return ret; - devm_add_action_or_reset(dwmac->dev, - (void(*)(void *))clk_disable_unprepare, - dwmac->rgmii_tx_clk); - - return 0; + return devm_add_action_or_reset(dwmac->dev, + (void(*)(void *))clk_disable_unprepare, + clk); } static int meson8b_init_rgmii_delays(struct meson8b_dwmac *dwmac) diff -Nru linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c --- linux-6.0.6/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1061,8 +1061,16 @@ ctrl |= priv->hw->link.duplex; /* Flow Control operation */ - if (tx_pause && rx_pause) - stmmac_mac_flow_ctrl(priv, duplex); + if (rx_pause && tx_pause) + priv->flow_ctrl = FLOW_AUTO; + else if (rx_pause && !tx_pause) + priv->flow_ctrl = FLOW_RX; + else if (!rx_pause && tx_pause) + priv->flow_ctrl = FLOW_TX; + else + priv->flow_ctrl = FLOW_OFF; + + stmmac_mac_flow_ctrl(priv, duplex); if (ctrl != old_ctrl) writel(ctrl, priv->ioaddr + MAC_CTRL_REG); @@ -6564,6 +6572,9 @@ struct stmmac_priv *priv = netdev_priv(dev); u32 chan; + /* Ensure tx function is not running */ + netif_tx_disable(dev); + /* Disable NAPI process */ stmmac_disable_all_queues(priv); diff -Nru linux-6.0.6/drivers/net/ethernet/sunplus/spl2sw_driver.c linux-6.0.12/drivers/net/ethernet/sunplus/spl2sw_driver.c --- linux-6.0.6/drivers/net/ethernet/sunplus/spl2sw_driver.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/sunplus/spl2sw_driver.c 2023-01-18 18:27:39.000000000 +0000 @@ -286,7 +286,6 @@ if (ret) { dev_err(&pdev->dev, "Failed to register net device \"%s\"!\n", ndev->name); - free_netdev(ndev); *r_ndev = NULL; return ret; } diff -Nru linux-6.0.6/drivers/net/ethernet/ti/am65-cpsw-nuss.c linux-6.0.12/drivers/net/ethernet/ti/am65-cpsw-nuss.c --- linux-6.0.6/drivers/net/ethernet/ti/am65-cpsw-nuss.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/ti/am65-cpsw-nuss.c 2023-01-18 18:27:39.000000000 +0000 @@ -2061,7 +2061,7 @@ for (i = 0; i < common->port_num; i++) { port = &common->ports[i]; - if (port->ndev) + if (port->ndev && port->ndev->reg_state == NETREG_REGISTERED) unregister_netdev(port->ndev); } } @@ -2791,7 +2791,6 @@ if (ret < 0) return ret; - am65_cpsw_nuss_phylink_cleanup(common); am65_cpsw_unregister_devlink(common); am65_cpsw_unregister_notifiers(common); @@ -2799,6 +2798,7 @@ * dma_deconfigure(dev) before devres_release_all(dev) */ am65_cpsw_nuss_cleanup_ndev(common); + am65_cpsw_nuss_phylink_cleanup(common); of_platform_device_destroy(common->mdio_dev, NULL); diff -Nru linux-6.0.6/drivers/net/ethernet/ti/cpsw.c linux-6.0.12/drivers/net/ethernet/ti/cpsw.c --- linux-6.0.6/drivers/net/ethernet/ti/cpsw.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/ti/cpsw.c 2023-01-18 18:27:39.000000000 +0000 @@ -854,6 +854,8 @@ err_cleanup: if (!cpsw->usage_count) { + napi_disable(&cpsw->napi_rx); + napi_disable(&cpsw->napi_tx); cpdma_ctlr_stop(cpsw->dma); cpsw_destroy_xdp_rxqs(cpsw); } diff -Nru linux-6.0.6/drivers/net/ethernet/tundra/tsi108_eth.c linux-6.0.12/drivers/net/ethernet/tundra/tsi108_eth.c --- linux-6.0.6/drivers/net/ethernet/tundra/tsi108_eth.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ethernet/tundra/tsi108_eth.c 2023-01-18 18:27:39.000000000 +0000 @@ -1303,12 +1303,15 @@ data->rxring = dma_alloc_coherent(&data->pdev->dev, rxring_size, &data->rxdma, GFP_KERNEL); - if (!data->rxring) + if (!data->rxring) { + free_irq(data->irq_num, dev); return -ENOMEM; + } data->txring = dma_alloc_coherent(&data->pdev->dev, txring_size, &data->txdma, GFP_KERNEL); if (!data->txring) { + free_irq(data->irq_num, dev); dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring, data->rxdma); return -ENOMEM; diff -Nru linux-6.0.6/drivers/net/hamradio/bpqether.c linux-6.0.12/drivers/net/hamradio/bpqether.c --- linux-6.0.6/drivers/net/hamradio/bpqether.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/hamradio/bpqether.c 2023-01-18 18:27:39.000000000 +0000 @@ -533,7 +533,7 @@ if (!net_eq(dev_net(dev), &init_net)) return NOTIFY_DONE; - if (!dev_is_ethdev(dev)) + if (!dev_is_ethdev(dev) && !bpq_get_ax25_dev(dev)) return NOTIFY_DONE; switch (event) { diff -Nru linux-6.0.6/drivers/net/ipvlan/ipvlan.h linux-6.0.12/drivers/net/ipvlan/ipvlan.h --- linux-6.0.6/drivers/net/ipvlan/ipvlan.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ipvlan/ipvlan.h 2023-01-18 18:27:39.000000000 +0000 @@ -98,6 +98,7 @@ struct sk_buff_head backlog; int count; struct ida ida; + netdevice_tracker dev_tracker; }; struct ipvl_skb_cb { diff -Nru linux-6.0.6/drivers/net/ipvlan/ipvlan_main.c linux-6.0.12/drivers/net/ipvlan/ipvlan_main.c --- linux-6.0.6/drivers/net/ipvlan/ipvlan_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ipvlan/ipvlan_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -83,6 +83,7 @@ if (err) goto err; + netdev_hold(dev, &port->dev_tracker, GFP_KERNEL); return 0; err: @@ -95,6 +96,7 @@ struct ipvl_port *port = ipvlan_port_get_rtnl(dev); struct sk_buff *skb; + netdev_put(dev, &port->dev_tracker); if (port->mode == IPVLAN_MODE_L3S) ipvlan_l3s_unregister(port); netdev_rx_handler_unregister(dev); diff -Nru linux-6.0.6/drivers/net/macsec.c linux-6.0.12/drivers/net/macsec.c --- linux-6.0.6/drivers/net/macsec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/macsec.c 2023-01-18 18:27:39.000000000 +0000 @@ -1427,7 +1427,8 @@ return NULL; } -static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci) +static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci, + bool active) { struct macsec_rx_sc *rx_sc; struct macsec_dev *macsec; @@ -1451,7 +1452,7 @@ } rx_sc->sci = sci; - rx_sc->active = true; + rx_sc->active = active; refcount_set(&rx_sc->refcnt, 1); secy = &macsec_priv(dev)->secy; @@ -1860,6 +1861,7 @@ secy->key_len); err = macsec_offload(ops->mdo_add_rxsa, &ctx); + memzero_explicit(ctx.sa.key, secy->key_len); if (err) goto cleanup; } @@ -1904,7 +1906,7 @@ struct macsec_rx_sc *rx_sc; struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1]; struct macsec_secy *secy; - bool was_active; + bool active = true; int ret; if (!attrs[MACSEC_ATTR_IFINDEX]) @@ -1926,16 +1928,15 @@ secy = &macsec_priv(dev)->secy; sci = nla_get_sci(tb_rxsc[MACSEC_RXSC_ATTR_SCI]); - rx_sc = create_rx_sc(dev, sci); + if (tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]) + active = nla_get_u8(tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]); + + rx_sc = create_rx_sc(dev, sci, active); if (IS_ERR(rx_sc)) { rtnl_unlock(); return PTR_ERR(rx_sc); } - was_active = rx_sc->active; - if (tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]) - rx_sc->active = !!nla_get_u8(tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]); - if (macsec_is_offloaded(netdev_priv(dev))) { const struct macsec_ops *ops; struct macsec_context ctx; @@ -1959,7 +1960,8 @@ return 0; cleanup: - rx_sc->active = was_active; + del_rx_sc(secy, sci); + free_rx_sc(rx_sc); rtnl_unlock(); return ret; } @@ -2102,6 +2104,7 @@ secy->key_len); err = macsec_offload(ops->mdo_add_txsa, &ctx); + memzero_explicit(ctx.sa.key, secy->key_len); if (err) goto cleanup; } @@ -2598,7 +2601,7 @@ struct macsec_tx_sc *tx_sc = &secy->tx_sc; int i; - if (secy->n_rx_sc > 0) + if (secy->rx_sc) return true; for (i = 0; i < MACSEC_NUM_AN; i++) @@ -2682,11 +2685,6 @@ if (ret) goto rollback; - /* Force features update, since they are different for SW MACSec and - * HW offloading cases. - */ - netdev_update_features(dev); - rtnl_unlock(); return 0; @@ -3454,16 +3452,9 @@ return ret; } -#define SW_MACSEC_FEATURES \ +#define MACSEC_FEATURES \ (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST) -/* If h/w offloading is enabled, use real device features save for - * VLAN_FEATURES - they require additional ops - * HW_MACSEC - no reason to report it - */ -#define REAL_DEV_FEATURES(dev) \ - ((dev)->features & ~(NETIF_F_VLAN_FEATURES | NETIF_F_HW_MACSEC)) - static int macsec_dev_init(struct net_device *dev) { struct macsec_dev *macsec = macsec_priv(dev); @@ -3480,12 +3471,8 @@ return err; } - if (macsec_is_offloaded(macsec)) { - dev->features = REAL_DEV_FEATURES(real_dev); - } else { - dev->features = real_dev->features & SW_MACSEC_FEATURES; - dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE; - } + dev->features = real_dev->features & MACSEC_FEATURES; + dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE; dev->needed_headroom = real_dev->needed_headroom + MACSEC_NEEDED_HEADROOM; @@ -3517,10 +3504,7 @@ struct macsec_dev *macsec = macsec_priv(dev); struct net_device *real_dev = macsec->real_dev; - if (macsec_is_offloaded(macsec)) - return REAL_DEV_FEATURES(real_dev); - - features &= (real_dev->features & SW_MACSEC_FEATURES) | + features &= (real_dev->features & MACSEC_FEATURES) | NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES; features |= NETIF_F_LLTX; @@ -3871,7 +3855,6 @@ if (macsec_is_offloaded(macsec)) { const struct macsec_ops *ops; struct macsec_context ctx; - int ret; ops = macsec_get_ops(netdev_priv(dev), &ctx); if (!ops) { diff -Nru linux-6.0.6/drivers/net/macvlan.c linux-6.0.12/drivers/net/macvlan.c --- linux-6.0.6/drivers/net/macvlan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/macvlan.c 2023-01-18 18:27:39.000000000 +0000 @@ -141,7 +141,7 @@ u32 idx = macvlan_eth_hash(addr); struct hlist_head *h = &vlan->port->vlan_source_hash[idx]; - hlist_for_each_entry_rcu(entry, h, hlist) { + hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) { if (ether_addr_equal_64bits(entry->addr, addr) && entry->vlan == vlan) return entry; @@ -1192,7 +1192,7 @@ { ether_setup(dev); - dev->min_mtu = 0; + /* ether_setup() has set dev->min_mtu to ETH_MIN_MTU. */ dev->max_mtu = ETH_MAX_MTU; dev->priv_flags &= ~IFF_TX_SKB_SHARING; netif_keep_dst(dev); @@ -1533,8 +1533,10 @@ /* the macvlan port may be freed by macvlan_uninit when fail to register. * so we destroy the macvlan port only when it's valid. */ - if (create && macvlan_port_get_rtnl(lowerdev)) + if (create && macvlan_port_get_rtnl(lowerdev)) { + macvlan_flush_sources(port, vlan); macvlan_port_destroy(port->dev); + } return err; } EXPORT_SYMBOL_GPL(macvlan_common_newlink); @@ -1645,7 +1647,7 @@ struct hlist_head *h = &vlan->port->vlan_source_hash[i]; struct macvlan_source_entry *entry; - hlist_for_each_entry_rcu(entry, h, hlist) { + hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) { if (entry->vlan != vlan) continue; if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr)) diff -Nru linux-6.0.6/drivers/net/mctp/mctp-i2c.c linux-6.0.12/drivers/net/mctp/mctp-i2c.c --- linux-6.0.6/drivers/net/mctp/mctp-i2c.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/mctp/mctp-i2c.c 2023-01-18 18:27:39.000000000 +0000 @@ -43,6 +43,7 @@ enum { MCTP_I2C_FLOW_STATE_NEW = 0, MCTP_I2C_FLOW_STATE_ACTIVE, + MCTP_I2C_FLOW_STATE_INVALID, }; /* List of all struct mctp_i2c_client @@ -374,12 +375,18 @@ */ if (!key->valid) { state = MCTP_I2C_TX_FLOW_INVALID; - - } else if (key->dev_flow_state == MCTP_I2C_FLOW_STATE_NEW) { - key->dev_flow_state = MCTP_I2C_FLOW_STATE_ACTIVE; - state = MCTP_I2C_TX_FLOW_NEW; } else { - state = MCTP_I2C_TX_FLOW_EXISTING; + switch (key->dev_flow_state) { + case MCTP_I2C_FLOW_STATE_NEW: + key->dev_flow_state = MCTP_I2C_FLOW_STATE_ACTIVE; + state = MCTP_I2C_TX_FLOW_NEW; + break; + case MCTP_I2C_FLOW_STATE_ACTIVE: + state = MCTP_I2C_TX_FLOW_EXISTING; + break; + default: + state = MCTP_I2C_TX_FLOW_INVALID; + } } spin_unlock_irqrestore(&key->lock, flags); @@ -617,21 +624,31 @@ { struct mctp_i2c_dev *midev = netdev_priv(mdev->dev); + bool queue_release = false; unsigned long flags; spin_lock_irqsave(&midev->lock, flags); - midev->release_count++; - spin_unlock_irqrestore(&midev->lock, flags); - - /* Ensure we have a release operation queued, through the fake - * marker skb + /* if we have seen the flow/key previously, we need to pair the + * original lock with a release */ - spin_lock(&midev->tx_queue.lock); - if (!midev->unlock_marker.next) - __skb_queue_tail(&midev->tx_queue, &midev->unlock_marker); - spin_unlock(&midev->tx_queue.lock); + if (key->dev_flow_state == MCTP_I2C_FLOW_STATE_ACTIVE) { + midev->release_count++; + queue_release = true; + } + key->dev_flow_state = MCTP_I2C_FLOW_STATE_INVALID; + spin_unlock_irqrestore(&midev->lock, flags); - wake_up(&midev->tx_wq); + if (queue_release) { + /* Ensure we have a release operation queued, through the fake + * marker skb + */ + spin_lock(&midev->tx_queue.lock); + if (!midev->unlock_marker.next) + __skb_queue_tail(&midev->tx_queue, + &midev->unlock_marker); + spin_unlock(&midev->tx_queue.lock); + wake_up(&midev->tx_wq); + } } static const struct net_device_ops mctp_i2c_ops = { diff -Nru linux-6.0.6/drivers/net/mdio/fwnode_mdio.c linux-6.0.12/drivers/net/mdio/fwnode_mdio.c --- linux-6.0.6/drivers/net/mdio/fwnode_mdio.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/mdio/fwnode_mdio.c 2023-01-18 18:27:39.000000000 +0000 @@ -120,7 +120,7 @@ /* Associate the fwnode with the device structure so it * can be looked up later. */ - phy->mdio.dev.fwnode = child; + phy->mdio.dev.fwnode = fwnode_handle_get(child); /* All data is now stored in the phy struct, so register it */ rc = phy_device_register(phy); diff -Nru linux-6.0.6/drivers/net/mhi_net.c linux-6.0.12/drivers/net/mhi_net.c --- linux-6.0.6/drivers/net/mhi_net.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/mhi_net.c 2023-01-18 18:27:39.000000000 +0000 @@ -343,6 +343,8 @@ kfree_skb(mhi_netdev->skbagg_head); + free_netdev(ndev); + dev_set_drvdata(&mhi_dev->dev, NULL); } diff -Nru linux-6.0.6/drivers/net/netdevsim/bus.c linux-6.0.12/drivers/net/netdevsim/bus.c --- linux-6.0.6/drivers/net/netdevsim/bus.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/netdevsim/bus.c 2023-01-18 18:27:39.000000000 +0000 @@ -117,6 +117,10 @@ static void nsim_bus_dev_release(struct device *dev) { + struct nsim_bus_dev *nsim_bus_dev; + + nsim_bus_dev = container_of(dev, struct nsim_bus_dev, dev); + kfree(nsim_bus_dev); } static struct device_type nsim_bus_dev_type = { @@ -291,6 +295,8 @@ err_nsim_bus_dev_id_free: ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id); + put_device(&nsim_bus_dev->dev); + nsim_bus_dev = NULL; err_nsim_bus_dev_free: kfree(nsim_bus_dev); return ERR_PTR(err); @@ -300,9 +306,8 @@ { /* Disallow using nsim_bus_dev */ smp_store_release(&nsim_bus_dev->init, false); - device_unregister(&nsim_bus_dev->dev); ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id); - kfree(nsim_bus_dev); + device_unregister(&nsim_bus_dev->dev); } static struct device_driver nsim_driver = { diff -Nru linux-6.0.6/drivers/net/netdevsim/dev.c linux-6.0.12/drivers/net/netdevsim/dev.c --- linux-6.0.6/drivers/net/netdevsim/dev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/netdevsim/dev.c 2023-01-18 18:27:39.000000000 +0000 @@ -309,8 +309,10 @@ if (IS_ERR(nsim_dev->ddir)) return PTR_ERR(nsim_dev->ddir); nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir); - if (IS_ERR(nsim_dev->ports_ddir)) - return PTR_ERR(nsim_dev->ports_ddir); + if (IS_ERR(nsim_dev->ports_ddir)) { + err = PTR_ERR(nsim_dev->ports_ddir); + goto err_ddir; + } debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir, &nsim_dev->fw_update_status); debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir, @@ -346,7 +348,7 @@ nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir); if (IS_ERR(nsim_dev->nodes_ddir)) { err = PTR_ERR(nsim_dev->nodes_ddir); - goto err_out; + goto err_ports_ddir; } debugfs_create_bool("fail_trap_drop_counter_get", 0600, nsim_dev->ddir, @@ -354,8 +356,9 @@ nsim_udp_tunnels_debugfs_create(nsim_dev); return 0; -err_out: +err_ports_ddir: debugfs_remove_recursive(nsim_dev->ports_ddir); +err_ddir: debugfs_remove_recursive(nsim_dev->ddir); return err; } @@ -442,7 +445,7 @@ ¶ms); if (err) { pr_err("Failed to register IPv4 top resource\n"); - goto out; + goto err_out; } err = devl_resource_register(devlink, "fib", (u64)-1, @@ -450,7 +453,7 @@ NSIM_RESOURCE_IPV4, ¶ms); if (err) { pr_err("Failed to register IPv4 FIB resource\n"); - return err; + goto err_out; } err = devl_resource_register(devlink, "fib-rules", (u64)-1, @@ -458,7 +461,7 @@ NSIM_RESOURCE_IPV4, ¶ms); if (err) { pr_err("Failed to register IPv4 FIB rules resource\n"); - return err; + goto err_out; } /* Resources for IPv6 */ @@ -468,7 +471,7 @@ ¶ms); if (err) { pr_err("Failed to register IPv6 top resource\n"); - goto out; + goto err_out; } err = devl_resource_register(devlink, "fib", (u64)-1, @@ -476,7 +479,7 @@ NSIM_RESOURCE_IPV6, ¶ms); if (err) { pr_err("Failed to register IPv6 FIB resource\n"); - return err; + goto err_out; } err = devl_resource_register(devlink, "fib-rules", (u64)-1, @@ -484,7 +487,7 @@ NSIM_RESOURCE_IPV6, ¶ms); if (err) { pr_err("Failed to register IPv6 FIB rules resource\n"); - return err; + goto err_out; } /* Resources for nexthops */ @@ -492,8 +495,14 @@ NSIM_RESOURCE_NEXTHOPS, DEVLINK_RESOURCE_ID_PARENT_TOP, ¶ms); + if (err) { + pr_err("Failed to register NEXTHOPS resource\n"); + goto err_out; + } + return 0; -out: +err_out: + devl_resources_unregister(devlink); return err; } @@ -1666,6 +1675,7 @@ ARRAY_SIZE(nsim_devlink_params)); devl_resources_unregister(devlink); kfree(nsim_dev->vfconfigs); + kfree(nsim_dev->fa_cookie); devl_unlock(devlink); devlink_free(devlink); dev_set_drvdata(&nsim_bus_dev->dev, NULL); diff -Nru linux-6.0.6/drivers/net/ntb_netdev.c linux-6.0.12/drivers/net/ntb_netdev.c --- linux-6.0.6/drivers/net/ntb_netdev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/ntb_netdev.c 2023-01-18 18:27:39.000000000 +0000 @@ -484,7 +484,14 @@ rc = ntb_transport_register_client_dev(KBUILD_MODNAME); if (rc) return rc; - return ntb_transport_register_client(&ntb_netdev_client); + + rc = ntb_transport_register_client(&ntb_netdev_client); + if (rc) { + ntb_transport_unregister_client_dev(KBUILD_MODNAME); + return rc; + } + + return 0; } module_init(ntb_netdev_init_module); diff -Nru linux-6.0.6/drivers/net/phy/at803x.c linux-6.0.12/drivers/net/phy/at803x.c --- linux-6.0.6/drivers/net/phy/at803x.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/phy/at803x.c 2023-01-18 18:27:39.000000000 +0000 @@ -862,8 +862,10 @@ .wolopts = 0, }; - if (ccr < 0) + if (ccr < 0) { + ret = ccr; goto err; + } mode_cfg = ccr & AT803X_MODE_CFG_MASK; switch (mode_cfg) { diff -Nru linux-6.0.6/drivers/net/phy/dp83867.c linux-6.0.12/drivers/net/phy/dp83867.c --- linux-6.0.6/drivers/net/phy/dp83867.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/phy/dp83867.c 2023-01-18 18:27:39.000000000 +0000 @@ -682,6 +682,13 @@ */ dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN / 2; + /* For non-OF device, the RX and TX FIFO depths are taken from + * default value. So, we init RX & TX FIFO depths here + * so that it is configured correctly later in dp83867_config_init(); + */ + dp83867->tx_fifo_depth = DP83867_PHYCR_FIFO_DEPTH_4_B_NIB; + dp83867->rx_fifo_depth = DP83867_PHYCR_FIFO_DEPTH_4_B_NIB; + return 0; } #endif /* CONFIG_OF_MDIO */ diff -Nru linux-6.0.6/drivers/net/phy/marvell.c linux-6.0.12/drivers/net/phy/marvell.c --- linux-6.0.6/drivers/net/phy/marvell.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/phy/marvell.c 2023-01-18 18:27:39.000000000 +0000 @@ -2015,14 +2015,16 @@ if (err < 0) return err; - /* FIXME: Based on trial and error test, it seem 1G need to have - * delay between soft reset and loopback enablement. - */ - if (phydev->speed == SPEED_1000) - msleep(1000); + err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, + BMCR_LOOPBACK); - return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, - BMCR_LOOPBACK); + if (!err) { + /* It takes some time for PHY device to switch + * into/out-of loopback mode. + */ + msleep(1000); + } + return err; } else { err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, 0); if (err < 0) diff -Nru linux-6.0.6/drivers/net/phy/mdio_bus.c linux-6.0.12/drivers/net/phy/mdio_bus.c --- linux-6.0.6/drivers/net/phy/mdio_bus.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/phy/mdio_bus.c 2023-01-18 18:27:39.000000000 +0000 @@ -583,7 +583,7 @@ } for (i = 0; i < PHY_MAX_ADDR; i++) { - if ((bus->phy_mask & (1 << i)) == 0) { + if ((bus->phy_mask & BIT(i)) == 0) { struct phy_device *phydev; phydev = mdiobus_scan(bus, i); diff -Nru linux-6.0.6/drivers/net/phy/mscc/mscc_macsec.c linux-6.0.12/drivers/net/phy/mscc/mscc_macsec.c --- linux-6.0.6/drivers/net/phy/mscc/mscc_macsec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/phy/mscc/mscc_macsec.c 2023-01-18 18:27:39.000000000 +0000 @@ -632,6 +632,7 @@ list_del(&flow->list); clear_bit(flow->index, bitmap); + memzero_explicit(flow->key, sizeof(flow->key)); kfree(flow); } diff -Nru linux-6.0.6/drivers/net/phy/phy_device.c linux-6.0.12/drivers/net/phy/phy_device.c --- linux-6.0.6/drivers/net/phy/phy_device.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/phy/phy_device.c 2023-01-18 18:27:39.000000000 +0000 @@ -216,6 +216,7 @@ static void phy_device_release(struct device *dev) { + fwnode_handle_put(dev->fwnode); kfree(to_phy_device(dev)); } @@ -1518,6 +1519,7 @@ error_module_put: module_put(d->driver->owner); + d->driver = NULL; error_put_device: put_device(d); if (ndev_owner != bus->owner) diff -Nru linux-6.0.6/drivers/net/thunderbolt.c linux-6.0.12/drivers/net/thunderbolt.c --- linux-6.0.6/drivers/net/thunderbolt.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/thunderbolt.c 2023-01-18 18:27:39.000000000 +0000 @@ -1379,12 +1379,21 @@ TBNET_MATCH_FRAGS_ID | TBNET_64K_FRAMES); ret = tb_register_property_dir("network", tbnet_dir); - if (ret) { - tb_property_free_dir(tbnet_dir); - return ret; - } + if (ret) + goto err_free_dir; - return tb_register_service_driver(&tbnet_driver); + ret = tb_register_service_driver(&tbnet_driver); + if (ret) + goto err_unregister; + + return 0; + +err_unregister: + tb_unregister_property_dir("network", tbnet_dir); +err_free_dir: + tb_property_free_dir(tbnet_dir); + + return ret; } module_init(tbnet_init); diff -Nru linux-6.0.6/drivers/net/tun.c linux-6.0.12/drivers/net/tun.c --- linux-6.0.6/drivers/net/tun.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/tun.c 2023-01-18 18:27:39.000000000 +0000 @@ -686,7 +686,6 @@ if (tun) xdp_rxq_info_unreg(&tfile->xdp_rxq); ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free); - sock_put(&tfile->sk); } } @@ -702,6 +701,9 @@ if (dev) netdev_state_change(dev); rtnl_unlock(); + + if (clean) + sock_put(&tfile->sk); } static void tun_detach_all(struct net_device *dev) @@ -1459,7 +1461,8 @@ int err; int i; - if (it->nr_segs > MAX_SKB_FRAGS + 1) + if (it->nr_segs > MAX_SKB_FRAGS + 1 || + len > (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN)) return ERR_PTR(-EMSGSIZE); local_bh_disable(); @@ -1966,17 +1969,25 @@ skb_headlen(skb)); if (unlikely(headlen > skb_headlen(skb))) { + WARN_ON_ONCE(1); + err = -ENOMEM; dev_core_stats_rx_dropped_inc(tun->dev); +napi_busy: napi_free_frags(&tfile->napi); rcu_read_unlock(); mutex_unlock(&tfile->napi_mutex); - WARN_ON(1); - return -ENOMEM; + return err; } - local_bh_disable(); - napi_gro_frags(&tfile->napi); - local_bh_enable(); + if (likely(napi_schedule_prep(&tfile->napi))) { + local_bh_disable(); + napi_gro_frags(&tfile->napi); + napi_complete(&tfile->napi); + local_bh_enable(); + } else { + err = -EBUSY; + goto napi_busy; + } mutex_unlock(&tfile->napi_mutex); } else if (tfile->napi_enabled) { struct sk_buff_head *queue = &tfile->sk.sk_write_queue; diff -Nru linux-6.0.6/drivers/net/usb/cdc_ncm.c linux-6.0.12/drivers/net/usb/cdc_ncm.c --- linux-6.0.6/drivers/net/usb/cdc_ncm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/usb/cdc_ncm.c 2023-01-18 18:27:39.000000000 +0000 @@ -1915,6 +1915,7 @@ .status = cdc_ncm_status, .rx_fixup = cdc_ncm_rx_fixup, .tx_fixup = cdc_ncm_tx_fixup, + .set_rx_mode = usbnet_cdc_update_filter, }; /* Same as cdc_ncm_info, but with FLAG_WWAN */ diff -Nru linux-6.0.6/drivers/net/usb/qmi_wwan.c linux-6.0.12/drivers/net/usb/qmi_wwan.c --- linux-6.0.6/drivers/net/usb/qmi_wwan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/usb/qmi_wwan.c 2023-01-18 18:27:39.000000000 +0000 @@ -1357,6 +1357,7 @@ {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1057, 2)}, /* Telit FN980 */ diff -Nru linux-6.0.6/drivers/net/usb/smsc95xx.c linux-6.0.12/drivers/net/usb/smsc95xx.c --- linux-6.0.6/drivers/net/usb/smsc95xx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/usb/smsc95xx.c 2023-01-18 18:27:39.000000000 +0000 @@ -66,6 +66,7 @@ spinlock_t mac_cr_lock; u8 features; u8 suspend_flags; + bool is_internal_phy; struct irq_chip irqchip; struct irq_domain *irqdomain; struct fwnode_handle *irqfwnode; @@ -252,6 +253,43 @@ mutex_unlock(&dev->phy_mutex); } +static int smsc95xx_mdiobus_reset(struct mii_bus *bus) +{ + struct smsc95xx_priv *pdata; + struct usbnet *dev; + u32 val; + int ret; + + dev = bus->priv; + pdata = dev->driver_priv; + + if (pdata->is_internal_phy) + return 0; + + mutex_lock(&dev->phy_mutex); + + ret = smsc95xx_read_reg(dev, PM_CTRL, &val); + if (ret < 0) + goto reset_out; + + val |= PM_CTL_PHY_RST_; + + ret = smsc95xx_write_reg(dev, PM_CTRL, val); + if (ret < 0) + goto reset_out; + + /* Driver has no knowledge at this point about the external PHY. + * The 802.3 specifies that the reset process shall + * be completed within 0.5 s. + */ + fsleep(500000); + +reset_out: + mutex_unlock(&dev->phy_mutex); + + return 0; +} + static int smsc95xx_mdiobus_read(struct mii_bus *bus, int phy_id, int idx) { struct usbnet *dev = bus->priv; @@ -1052,7 +1090,6 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) { struct smsc95xx_priv *pdata; - bool is_internal_phy; char usb_path[64]; int ret, phy_irq; u32 val; @@ -1133,13 +1170,14 @@ if (ret < 0) goto free_mdio; - is_internal_phy = !(val & HW_CFG_PSEL_); - if (is_internal_phy) + pdata->is_internal_phy = !(val & HW_CFG_PSEL_); + if (pdata->is_internal_phy) pdata->mdiobus->phy_mask = ~(1u << SMSC95XX_INTERNAL_PHY_ID); pdata->mdiobus->priv = dev; pdata->mdiobus->read = smsc95xx_mdiobus_read; pdata->mdiobus->write = smsc95xx_mdiobus_write; + pdata->mdiobus->reset = smsc95xx_mdiobus_reset; pdata->mdiobus->name = "smsc95xx-mdiobus"; pdata->mdiobus->parent = &dev->udev->dev; @@ -1160,7 +1198,7 @@ } pdata->phydev->irq = phy_irq; - pdata->phydev->is_internal = is_internal_phy; + pdata->phydev->is_internal = pdata->is_internal_phy; /* detect device revision as different features may be available */ ret = smsc95xx_read_reg(dev, ID_REV, &val); diff -Nru linux-6.0.6/drivers/net/virtio_net.c linux-6.0.12/drivers/net/virtio_net.c --- linux-6.0.6/drivers/net/virtio_net.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/virtio_net.c 2023-01-18 18:27:39.000000000 +0000 @@ -3933,12 +3933,11 @@ return 0; free_unregister_netdev: - virtio_reset_device(vdev); - unregister_netdev(dev); free_failover: net_failover_destroy(vi->failover); free_vqs: + virtio_reset_device(vdev); cancel_delayed_work_sync(&vi->refill); free_receive_page_frags(vi); virtnet_del_vqs(vi); diff -Nru linux-6.0.6/drivers/net/wan/lapbether.c linux-6.0.12/drivers/net/wan/lapbether.c --- linux-6.0.6/drivers/net/wan/lapbether.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wan/lapbether.c 2023-01-18 18:27:39.000000000 +0000 @@ -325,6 +325,7 @@ err = lapb_register(dev, &lapbeth_callbacks); if (err != LAPB_OK) { + napi_disable(&lapbeth->napi); pr_err("lapb_register error: %d\n", err); return -ENODEV; } @@ -446,7 +447,7 @@ if (dev_net(dev) != &init_net) return NOTIFY_DONE; - if (!dev_is_ethdev(dev)) + if (!dev_is_ethdev(dev) && !lapbeth_get_x25_dev(dev)) return NOTIFY_DONE; switch (event) { diff -Nru linux-6.0.6/drivers/net/wireless/ath/ath11k/qmi.h linux-6.0.12/drivers/net/wireless/ath/ath11k/qmi.h --- linux-6.0.6/drivers/net/wireless/ath/ath11k/qmi.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wireless/ath/ath11k/qmi.h 2023-01-18 18:27:39.000000000 +0000 @@ -27,7 +27,7 @@ #define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52 #define ATH11K_QMI_CALDB_SIZE 0x480000 #define ATH11K_QMI_BDF_EXT_STR_LENGTH 0x20 -#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 3 +#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 5 #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 diff -Nru linux-6.0.6/drivers/net/wireless/ath/ath11k/reg.c linux-6.0.12/drivers/net/wireless/ath/ath11k/reg.c --- linux-6.0.6/drivers/net/wireless/ath/ath11k/reg.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wireless/ath/ath11k/reg.c 2023-01-18 18:27:39.000000000 +0000 @@ -287,11 +287,7 @@ goto err; } - rtnl_lock(); - wiphy_lock(ar->hw->wiphy); - ret = regulatory_set_wiphy_regd_sync(ar->hw->wiphy, regd_copy); - wiphy_unlock(ar->hw->wiphy); - rtnl_unlock(); + ret = regulatory_set_wiphy_regd(ar->hw->wiphy, regd_copy); kfree(regd_copy); diff -Nru linux-6.0.6/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c linux-6.0.12/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --- linux-6.0.6/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c 2023-01-18 18:27:39.000000000 +0000 @@ -228,6 +228,10 @@ brcmf_fweh_event_name(event->code), event->code, event->emsg.ifidx, event->emsg.bsscfgidx, event->emsg.addr); + if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) { + bphy_err(drvr, "invalid bsscfg index: %u\n", event->emsg.bsscfgidx); + goto event_free; + } /* convert event message */ emsg_be = &event->emsg; diff -Nru linux-6.0.6/drivers/net/wireless/cisco/airo.c linux-6.0.12/drivers/net/wireless/cisco/airo.c --- linux-6.0.6/drivers/net/wireless/cisco/airo.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wireless/cisco/airo.c 2023-01-18 18:27:39.000000000 +0000 @@ -5232,7 +5232,7 @@ return -1; } -static int set_wep_key(struct airo_info *ai, u16 index, const char *key, +static int set_wep_key(struct airo_info *ai, u16 index, const u8 *key, u16 keylen, int perm, int lock) { static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 }; @@ -5283,7 +5283,7 @@ struct net_device *dev = pde_data(inode); struct airo_info *ai = dev->ml_priv; int i, rc; - char key[16]; + u8 key[16]; u16 index = 0; int j = 0; @@ -5311,12 +5311,22 @@ } for (i = 0; i < 16*3 && data->wbuffer[i+j]; i++) { + int val; + + if (i % 3 == 2) + continue; + + val = hex_to_bin(data->wbuffer[i+j]); + if (val < 0) { + airo_print_err(ai->dev->name, "WebKey passed invalid key hex"); + return; + } switch(i%3) { case 0: - key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4; + key[i/3] = (u8)val << 4; break; case 1: - key[i/3] |= hex_to_bin(data->wbuffer[i+j]); + key[i/3] |= (u8)val; break; } } diff -Nru linux-6.0.6/drivers/net/wireless/mac80211_hwsim.c linux-6.0.12/drivers/net/wireless/mac80211_hwsim.c --- linux-6.0.6/drivers/net/wireless/mac80211_hwsim.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wireless/mac80211_hwsim.c 2023-01-18 18:27:39.000000000 +0000 @@ -910,6 +910,7 @@ struct hwsim_vif_priv *vp = (void *)vif->drv_priv; struct sk_buff *skb; struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *cb; if (!vp->assoc) return; @@ -931,6 +932,10 @@ memcpy(hdr->addr2, mac, ETH_ALEN); memcpy(hdr->addr3, vp->bssid, ETH_ALEN); + cb = IEEE80211_SKB_CB(skb); + cb->control.rates[0].count = 1; + cb->control.rates[1].idx = -1; + rcu_read_lock(); mac80211_hwsim_tx_frame(data->hw, skb, rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan); diff -Nru linux-6.0.6/drivers/net/wireless/microchip/wilc1000/cfg80211.c linux-6.0.12/drivers/net/wireless/microchip/wilc1000/cfg80211.c --- linux-6.0.6/drivers/net/wireless/microchip/wilc1000/cfg80211.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wireless/microchip/wilc1000/cfg80211.c 2023-01-18 18:27:39.000000000 +0000 @@ -956,30 +956,51 @@ return; while (index + sizeof(*e) <= len) { + u16 attr_size; + e = (struct wilc_attr_entry *)&buf[index]; - if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST) + attr_size = le16_to_cpu(e->attr_len); + + if (index + sizeof(*e) + attr_size > len) + return; + + if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST && + attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e))) ch_list_idx = index; - else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL) + else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL && + attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e))) op_ch_idx = index; + if (ch_list_idx && op_ch_idx) break; - index += le16_to_cpu(e->attr_len) + sizeof(*e); + + index += sizeof(*e) + attr_size; } if (ch_list_idx) { - u16 attr_size; - struct wilc_ch_list_elem *e; - int i; + u16 elem_size; ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx]; - attr_size = le16_to_cpu(ch_list->attr_len); - for (i = 0; i < attr_size;) { + /* the number of bytes following the final 'elem' member */ + elem_size = le16_to_cpu(ch_list->attr_len) - + (sizeof(*ch_list) - sizeof(struct wilc_attr_entry)); + for (unsigned int i = 0; i < elem_size;) { + struct wilc_ch_list_elem *e; + e = (struct wilc_ch_list_elem *)(ch_list->elem + i); + + i += sizeof(*e); + if (i > elem_size) + break; + + i += e->no_of_channels; + if (i > elem_size) + break; + if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) { memset(e->ch_list, sta_ch, e->no_of_channels); break; } - i += e->no_of_channels; } } diff -Nru linux-6.0.6/drivers/net/wireless/microchip/wilc1000/hif.c linux-6.0.12/drivers/net/wireless/microchip/wilc1000/hif.c --- linux-6.0.6/drivers/net/wireless/microchip/wilc1000/hif.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wireless/microchip/wilc1000/hif.c 2023-01-18 18:27:39.000000000 +0000 @@ -482,14 +482,25 @@ rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len); if (rsn_ie) { + int rsn_ie_len = sizeof(struct element) + rsn_ie[1]; int offset = 8; - param->mode_802_11i = 2; - param->rsn_found = true; /* extract RSN capabilities */ - offset += (rsn_ie[offset] * 4) + 2; - offset += (rsn_ie[offset] * 4) + 2; - memcpy(param->rsn_cap, &rsn_ie[offset], 2); + if (offset < rsn_ie_len) { + /* skip over pairwise suites */ + offset += (rsn_ie[offset] * 4) + 2; + + if (offset < rsn_ie_len) { + /* skip over authentication suites */ + offset += (rsn_ie[offset] * 4) + 2; + + if (offset + 1 < rsn_ie_len) { + param->mode_802_11i = 2; + param->rsn_found = true; + memcpy(param->rsn_cap, &rsn_ie[offset], 2); + } + } + } } if (param->rsn_found) { diff -Nru linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_coredump.c linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_coredump.c --- linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_coredump.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_coredump.c 2023-01-18 18:27:39.000000000 +0000 @@ -2,6 +2,7 @@ /* * Copyright (C) 2020-2021 Intel Corporation. */ +#include #include "iosm_ipc_coredump.h" diff -Nru linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_devlink.c linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_devlink.c --- linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_devlink.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_devlink.c 2023-01-18 18:27:39.000000000 +0000 @@ -2,6 +2,7 @@ /* * Copyright (C) 2020-2021 Intel Corporation. */ +#include #include "iosm_ipc_chnl_cfg.h" #include "iosm_ipc_coredump.h" diff -Nru linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c --- linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c 2023-01-18 18:27:39.000000000 +0000 @@ -91,6 +91,14 @@ } ipc_chnl_cfg_get(&chnl_cfg, ipc_imem->nr_of_channels); + + if (ipc_imem->mmio->mux_protocol == MUX_AGGREGATION && + ipc_imem->nr_of_channels == IPC_MEM_IP_CHL_ID_0) { + chnl_cfg.ul_nr_of_entries = IPC_MEM_MAX_TDS_MUX_AGGR_UL; + chnl_cfg.dl_nr_of_entries = IPC_MEM_MAX_TDS_MUX_AGGR_DL; + chnl_cfg.dl_buf_size = IPC_MEM_MAX_ADB_BUF_SIZE; + } + ipc_imem_channel_init(ipc_imem, IPC_CTYPE_WWAN, chnl_cfg, IRQ_MOD_OFF); diff -Nru linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c --- linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_mux_codec.c 2023-01-18 18:27:39.000000000 +0000 @@ -365,7 +365,8 @@ /* Pass the DL packet to the netif layer. */ static int ipc_mux_net_receive(struct iosm_mux *ipc_mux, int if_id, struct iosm_wwan *wwan, u32 offset, - u8 service_class, struct sk_buff *skb) + u8 service_class, struct sk_buff *skb, + u32 pkt_len) { struct sk_buff *dest_skb = skb_clone(skb, GFP_ATOMIC); @@ -373,7 +374,7 @@ return -ENOMEM; skb_pull(dest_skb, offset); - skb_set_tail_pointer(dest_skb, dest_skb->len); + skb_trim(dest_skb, pkt_len); /* Pass the packet to the netif layer. */ dest_skb->priority = service_class; @@ -429,7 +430,7 @@ static void ipc_mux_dl_adgh_decode(struct iosm_mux *ipc_mux, struct sk_buff *skb) { - u32 pad_len, packet_offset; + u32 pad_len, packet_offset, adgh_len; struct iosm_wwan *wwan; struct mux_adgh *adgh; u8 *block = skb->data; @@ -470,10 +471,12 @@ packet_offset = sizeof(*adgh) + pad_len; if_id += ipc_mux->wwan_q_offset; + adgh_len = le16_to_cpu(adgh->length); /* Pass the packet to the netif layer */ rc = ipc_mux_net_receive(ipc_mux, if_id, wwan, packet_offset, - adgh->service_class, skb); + adgh->service_class, skb, + adgh_len - packet_offset); if (rc) { dev_err(ipc_mux->dev, "mux adgh decoding error"); return; @@ -547,7 +550,7 @@ int if_id, int nr_of_dg) { u32 dl_head_pad_len = ipc_mux->session[if_id].dl_head_pad_len; - u32 packet_offset, i, rc; + u32 packet_offset, i, rc, dg_len; for (i = 0; i < nr_of_dg; i++, dg++) { if (le32_to_cpu(dg->datagram_index) @@ -562,11 +565,12 @@ packet_offset = le32_to_cpu(dg->datagram_index) + dl_head_pad_len; + dg_len = le16_to_cpu(dg->datagram_length); /* Pass the packet to the netif layer. */ rc = ipc_mux_net_receive(ipc_mux, if_id, ipc_mux->wwan, packet_offset, - dg->service_class, - skb); + dg->service_class, skb, + dg_len - dl_head_pad_len); if (rc) goto dg_error; } @@ -1207,10 +1211,9 @@ qlth_n_ql_size, ul_list); ipc_mux_ul_adb_finish(ipc_mux); if (ipc_mux_ul_adb_allocate(ipc_mux, adb, &ipc_mux->size_needed, - IOSM_AGGR_MUX_SIG_ADBH)) { - dev_kfree_skb(src_skb); + IOSM_AGGR_MUX_SIG_ADBH)) return -ENOMEM; - } + ipc_mux->size_needed = le32_to_cpu(adb->adbh->block_length); ipc_mux->size_needed += offsetof(struct mux_adth, dg); @@ -1471,8 +1474,7 @@ ipc_mux->ul_data_pend_bytes); /* Reset the skb settings. */ - skb->tail = 0; - skb->len = 0; + skb_trim(skb, 0); /* Add the consumed ADB to the free list. */ skb_queue_tail((&ipc_mux->ul_adb.free_list), skb); diff -Nru linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_mux.h linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_mux.h --- linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_mux.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_mux.h 2023-01-18 18:27:39.000000000 +0000 @@ -10,6 +10,7 @@ #define IPC_MEM_MAX_UL_DG_ENTRIES 100 #define IPC_MEM_MAX_TDS_MUX_AGGR_UL 60 +#define IPC_MEM_MAX_TDS_MUX_AGGR_DL 60 #define IPC_MEM_MAX_ADB_BUF_SIZE (16 * 1024) #define IPC_MEM_MAX_UL_ADB_BUF_SIZE IPC_MEM_MAX_ADB_BUF_SIZE diff -Nru linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_pcie.c linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_pcie.c --- linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_pcie.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_pcie.c 2023-01-18 18:27:39.000000000 +0000 @@ -232,6 +232,7 @@ */ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev) { + enum ipc_pcie_sleep_state sleep_state = IPC_PCIE_D0L12; union acpi_object *object; acpi_handle handle_acpi; @@ -242,12 +243,16 @@ } object = acpi_evaluate_dsm(handle_acpi, &wwan_acpi_guid, 0, 3, NULL); + if (!object) + goto default_ret; + + if (object->integer.value == 3) + sleep_state = IPC_PCIE_D3L2; - if (object && object->integer.value == 3) - return IPC_PCIE_D3L2; + ACPI_FREE(object); default_ret: - return IPC_PCIE_D0L12; + return sleep_state; } static int ipc_pcie_probe(struct pci_dev *pci, diff -Nru linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_protocol.h linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_protocol.h --- linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_protocol.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_protocol.h 2023-01-18 18:27:39.000000000 +0000 @@ -122,7 +122,7 @@ struct iosm_imem *imem; struct ipc_rsp *rsp_ring[IPC_MEM_MSG_ENTRIES]; struct device *dev; - phys_addr_t phy_ap_shm; + dma_addr_t phy_ap_shm; u32 old_msg_tail; }; diff -Nru linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_wwan.c linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_wwan.c --- linux-6.0.6/drivers/net/wwan/iosm/iosm_ipc_wwan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/iosm/iosm_ipc_wwan.c 2023-01-18 18:27:39.000000000 +0000 @@ -168,6 +168,7 @@ iosm_dev->max_mtu = ETH_MAX_MTU; iosm_dev->flags = IFF_POINTOPOINT | IFF_NOARP; + iosm_dev->needs_free_netdev = true; iosm_dev->netdev_ops = &ipc_inm_ops; } diff -Nru linux-6.0.6/drivers/net/wwan/mhi_wwan_mbim.c linux-6.0.12/drivers/net/wwan/mhi_wwan_mbim.c --- linux-6.0.6/drivers/net/wwan/mhi_wwan_mbim.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/mhi_wwan_mbim.c 2023-01-18 18:27:39.000000000 +0000 @@ -582,6 +582,7 @@ ndev->min_mtu = ETH_MIN_MTU; ndev->max_mtu = MHI_MAX_BUF_SZ - ndev->needed_headroom; ndev->tx_queue_len = 1000; + ndev->needs_free_netdev = true; } static const struct wwan_ops mhi_mbim_wwan_ops = { diff -Nru linux-6.0.6/drivers/net/wwan/t7xx/t7xx_modem_ops.c linux-6.0.12/drivers/net/wwan/t7xx/t7xx_modem_ops.c --- linux-6.0.6/drivers/net/wwan/t7xx/t7xx_modem_ops.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/net/wwan/t7xx/t7xx_modem_ops.c 2023-01-18 18:27:39.000000000 +0000 @@ -165,6 +165,8 @@ return -EFAULT; } + kfree(buffer.pointer); + #endif return 0; } diff -Nru linux-6.0.6/drivers/nfc/fdp/fdp.c linux-6.0.12/drivers/nfc/fdp/fdp.c --- linux-6.0.6/drivers/nfc/fdp/fdp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nfc/fdp/fdp.c 2023-01-18 18:27:39.000000000 +0000 @@ -249,11 +249,19 @@ static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb) { struct fdp_nci_info *info = nci_get_drvdata(ndev); + int ret; if (atomic_dec_and_test(&info->data_pkt_counter)) info->data_pkt_counter_cb(ndev); - return info->phy_ops->write(info->phy, skb); + ret = info->phy_ops->write(info->phy, skb); + if (ret < 0) { + kfree_skb(skb); + return ret; + } + + consume_skb(skb); + return 0; } static int fdp_nci_request_firmware(struct nci_dev *ndev) diff -Nru linux-6.0.6/drivers/nfc/nfcmrvl/i2c.c linux-6.0.12/drivers/nfc/nfcmrvl/i2c.c --- linux-6.0.6/drivers/nfc/nfcmrvl/i2c.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nfc/nfcmrvl/i2c.c 2023-01-18 18:27:39.000000000 +0000 @@ -132,10 +132,15 @@ ret = -EREMOTEIO; } else ret = 0; + } + + if (ret) { kfree_skb(skb); + return ret; } - return ret; + consume_skb(skb); + return 0; } static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv, diff -Nru linux-6.0.6/drivers/nfc/nxp-nci/core.c linux-6.0.12/drivers/nfc/nxp-nci/core.c --- linux-6.0.6/drivers/nfc/nxp-nci/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nfc/nxp-nci/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -80,10 +80,13 @@ return -EINVAL; r = info->phy_ops->write(info->phy_id, skb); - if (r < 0) + if (r < 0) { kfree_skb(skb); + return r; + } - return r; + consume_skb(skb); + return 0; } static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev, diff -Nru linux-6.0.6/drivers/nfc/s3fwrn5/core.c linux-6.0.12/drivers/nfc/s3fwrn5/core.c --- linux-6.0.6/drivers/nfc/s3fwrn5/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nfc/s3fwrn5/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -110,11 +110,15 @@ } ret = s3fwrn5_write(info, skb); - if (ret < 0) + if (ret < 0) { kfree_skb(skb); + mutex_unlock(&info->mutex); + return ret; + } + consume_skb(skb); mutex_unlock(&info->mutex); - return ret; + return 0; } static int s3fwrn5_nci_post_setup(struct nci_dev *ndev) diff -Nru linux-6.0.6/drivers/nfc/st-nci/se.c linux-6.0.12/drivers/nfc/st-nci/se.c --- linux-6.0.6/drivers/nfc/st-nci/se.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nfc/st-nci/se.c 2023-01-18 18:27:39.000000000 +0000 @@ -312,6 +312,8 @@ int r = 0; struct device *dev = &ndev->nfc_dev->dev; struct nfc_evt_transaction *transaction; + u32 aid_len; + u8 params_len; pr_debug("connectivity gate event: %x\n", event); @@ -325,26 +327,47 @@ * Description Tag Length * AID 81 5 to 16 * PARAMETERS 82 0 to 255 + * + * The key differences are aid storage length is variably sized + * in the packet, but fixed in nfc_evt_transaction, and that + * the aid_len is u8 in the packet, but u32 in the structure, + * and the tags in the packet are not included in + * nfc_evt_transaction. + * + * size(b): 1 1 5-16 1 1 0-255 + * offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4 + * mem name: aid_tag(M) aid_len aid params_tag(M) params_len params + * example: 0x81 5-16 X 0x82 0-255 X */ - if (skb->len < NFC_MIN_AID_LENGTH + 2 && - skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) + if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) return -EPROTO; - transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL); - if (!transaction) - return -ENOMEM; + aid_len = skb->data[1]; - transaction->aid_len = skb->data[1]; - memcpy(transaction->aid, &skb->data[2], transaction->aid_len); + if (skb->len < aid_len + 4 || + aid_len > sizeof(transaction->aid)) + return -EPROTO; - /* Check next byte is PARAMETERS tag (82) */ - if (skb->data[transaction->aid_len + 2] != - NFC_EVT_TRANSACTION_PARAMS_TAG) + params_len = skb->data[aid_len + 3]; + + /* Verify PARAMETERS tag is (82), and final check that there is + * enough space in the packet to read everything. + */ + if (skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG || + skb->len < aid_len + 4 + params_len) return -EPROTO; - transaction->params_len = skb->data[transaction->aid_len + 3]; - memcpy(transaction->params, skb->data + - transaction->aid_len + 4, transaction->params_len); + transaction = devm_kzalloc(dev, sizeof(*transaction) + + params_len, GFP_KERNEL); + if (!transaction) + return -ENOMEM; + + transaction->aid_len = aid_len; + transaction->params_len = params_len; + + memcpy(transaction->aid, &skb->data[2], aid_len); + memcpy(transaction->params, &skb->data[aid_len + 4], + params_len); r = nfc_se_transaction(ndev->nfc_dev, host, transaction); break; diff -Nru linux-6.0.6/drivers/nfc/virtual_ncidev.c linux-6.0.12/drivers/nfc/virtual_ncidev.c --- linux-6.0.6/drivers/nfc/virtual_ncidev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nfc/virtual_ncidev.c 2023-01-18 18:27:39.000000000 +0000 @@ -54,16 +54,19 @@ mutex_lock(&nci_mutex); if (state != virtual_ncidev_enabled) { mutex_unlock(&nci_mutex); + kfree_skb(skb); return 0; } if (send_buff) { mutex_unlock(&nci_mutex); + kfree_skb(skb); return -1; } send_buff = skb_copy(skb, GFP_KERNEL); mutex_unlock(&nci_mutex); wake_up_interruptible(&wq); + consume_skb(skb); return 0; } diff -Nru linux-6.0.6/drivers/nvme/host/core.c linux-6.0.12/drivers/nvme/host/core.c --- linux-6.0.6/drivers/nvme/host/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nvme/host/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -675,6 +675,7 @@ if (req->mq_hctx->type == HCTX_TYPE_POLL) req->cmd_flags |= REQ_POLLED; nvme_clear_nvme_request(req); + req->rq_flags |= RQF_QUIET; memcpy(nvme_req(req)->cmd, cmd, sizeof(*cmd)); } EXPORT_SYMBOL_GPL(nvme_init_request); @@ -1037,7 +1038,6 @@ goto out; } - req->rq_flags |= RQF_QUIET; ret = nvme_execute_rq(req, at_head); if (result && ret >= 0) *result = nvme_req(req)->result; @@ -1225,7 +1225,6 @@ rq->timeout = ctrl->kato * HZ; rq->end_io = nvme_keep_alive_end_io; rq->end_io_data = ctrl; - rq->rq_flags |= RQF_QUIET; blk_execute_rq_nowait(rq, false); } @@ -4298,7 +4297,7 @@ mutex_unlock(&ns->ctrl->subsys->lock); /* guarantee not available in head->list */ - synchronize_rcu(); + synchronize_srcu(&ns->head->srcu); if (!nvme_ns_head_multipath(ns->head)) nvme_cdev_del(&ns->cdev, &ns->cdev_device); diff -Nru linux-6.0.6/drivers/nvme/host/ioctl.c linux-6.0.12/drivers/nvme/host/ioctl.c --- linux-6.0.6/drivers/nvme/host/ioctl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nvme/host/ioctl.c 2023-01-18 18:27:39.000000000 +0000 @@ -764,11 +764,17 @@ case NVME_IOCTL_IO_CMD: return nvme_dev_user_cmd(ctrl, argp); case NVME_IOCTL_RESET: + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; dev_warn(ctrl->device, "resetting controller\n"); return nvme_reset_ctrl_sync(ctrl); case NVME_IOCTL_SUBSYS_RESET: + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; return nvme_reset_subsystem(ctrl); case NVME_IOCTL_RESCAN: + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; nvme_queue_scan(ctrl); return 0; default: diff -Nru linux-6.0.6/drivers/nvme/host/multipath.c linux-6.0.12/drivers/nvme/host/multipath.c --- linux-6.0.6/drivers/nvme/host/multipath.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nvme/host/multipath.c 2023-01-18 18:27:39.000000000 +0000 @@ -174,11 +174,14 @@ struct nvme_ns_head *head = ns->head; sector_t capacity = get_capacity(head->disk); int node; + int srcu_idx; + srcu_idx = srcu_read_lock(&head->srcu); list_for_each_entry_rcu(ns, &head->list, siblings) { if (capacity != get_capacity(ns->disk)) clear_bit(NVME_NS_READY, &ns->flags); } + srcu_read_unlock(&head->srcu, srcu_idx); for_each_node(node) rcu_assign_pointer(head->current_path[node], NULL); diff -Nru linux-6.0.6/drivers/nvme/host/nvme.h linux-6.0.12/drivers/nvme/host/nvme.h --- linux-6.0.6/drivers/nvme/host/nvme.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nvme/host/nvme.h 2023-01-18 18:27:39.000000000 +0000 @@ -602,11 +602,23 @@ static inline void nvme_should_fail(struct request *req) {} #endif +bool nvme_wait_reset(struct nvme_ctrl *ctrl); +int nvme_try_sched_reset(struct nvme_ctrl *ctrl); + static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl) { + int ret; + if (!ctrl->subsystem) return -ENOTTY; - return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); + if (!nvme_wait_reset(ctrl)) + return -EBUSY; + + ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); + if (ret) + return ret; + + return nvme_try_sched_reset(ctrl); } /* @@ -712,7 +724,6 @@ void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl); bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, enum nvme_ctrl_state new_state); -bool nvme_wait_reset(struct nvme_ctrl *ctrl); int nvme_disable_ctrl(struct nvme_ctrl *ctrl); int nvme_enable_ctrl(struct nvme_ctrl *ctrl); int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl); @@ -802,7 +813,6 @@ void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); int nvme_reset_ctrl(struct nvme_ctrl *ctrl); int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); -int nvme_try_sched_reset(struct nvme_ctrl *ctrl); int nvme_delete_ctrl(struct nvme_ctrl *ctrl); void nvme_queue_scan(struct nvme_ctrl *ctrl); int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi, diff -Nru linux-6.0.6/drivers/nvme/host/pci.c linux-6.0.12/drivers/nvme/host/pci.c --- linux-6.0.6/drivers/nvme/host/pci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nvme/host/pci.c 2023-01-18 18:27:39.000000000 +0000 @@ -1438,7 +1438,6 @@ abort_req->end_io = abort_endio; abort_req->end_io_data = NULL; - abort_req->rq_flags |= RQF_QUIET; blk_execute_rq_nowait(abort_req, false); /* @@ -2489,7 +2488,6 @@ req->end_io_data = nvmeq; init_completion(&nvmeq->delete_done); - req->rq_flags |= RQF_QUIET; blk_execute_rq_nowait(req, false); return 0; } @@ -3488,6 +3486,8 @@ NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_DEVICE(0x1344, 0x5407), /* Micron Technology Inc NVMe SSD */ .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN }, + { PCI_DEVICE(0x1344, 0x6001), /* Micron Nitro NVMe */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, { PCI_DEVICE(0x1c5c, 0x174a), /* SK Hynix P31 SSD */ @@ -3508,6 +3508,18 @@ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(0x2646, 0x5018), /* KINGSTON OM8SFP4xxxxP OS21012 NVMe SSD */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x2646, 0x5016), /* KINGSTON OM3PGP4xxxxP OS21011 NVMe SSD */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x2646, 0x501A), /* KINGSTON OM8PGP4xxxxP OS21005 NVMe SSD */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x2646, 0x501B), /* KINGSTON OM8PGP4xxxxQ OS21005 NVMe SSD */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x2646, 0x501E), /* KINGSTON OM3PGP4xxxxQ OS21011 NVMe SSD */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x1f40, 0x5236), /* Netac Technologies Co. NV7000 NVMe SSD */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1e4B, 0x1001), /* MAXIO MAP1001 */ .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1e4B, 0x1002), /* MAXIO MAP1002 */ diff -Nru linux-6.0.6/drivers/nvme/target/auth.c linux-6.0.12/drivers/nvme/target/auth.c --- linux-6.0.6/drivers/nvme/target/auth.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nvme/target/auth.c 2023-01-18 18:27:39.000000000 +0000 @@ -45,9 +45,11 @@ if (!dhchap_secret) return -ENOMEM; if (set_ctrl) { + kfree(host->dhchap_ctrl_secret); host->dhchap_ctrl_secret = strim(dhchap_secret); host->dhchap_ctrl_key_hash = key_hash; } else { + kfree(host->dhchap_secret); host->dhchap_secret = strim(dhchap_secret); host->dhchap_key_hash = key_hash; } diff -Nru linux-6.0.6/drivers/nvme/target/configfs.c linux-6.0.12/drivers/nvme/target/configfs.c --- linux-6.0.6/drivers/nvme/target/configfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nvme/target/configfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -1215,6 +1215,7 @@ const char *page, size_t count) { int pos = 0, len; + char *val; if (subsys->subsys_discovered) { pr_err("Can't set model number. %s is already assigned\n", @@ -1237,9 +1238,11 @@ return -EINVAL; } - subsys->model_number = kmemdup_nul(page, len, GFP_KERNEL); - if (!subsys->model_number) + val = kmemdup_nul(page, len, GFP_KERNEL); + if (!val) return -ENOMEM; + kfree(subsys->model_number); + subsys->model_number = val; return count; } @@ -1811,6 +1814,7 @@ #ifdef CONFIG_NVME_TARGET_AUTH kfree(host->dhchap_secret); + kfree(host->dhchap_ctrl_secret); #endif kfree(host); } diff -Nru linux-6.0.6/drivers/nvmem/rmem.c linux-6.0.12/drivers/nvmem/rmem.c --- linux-6.0.6/drivers/nvmem/rmem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/nvmem/rmem.c 2023-01-18 18:27:39.000000000 +0000 @@ -37,9 +37,9 @@ * but as of Dec 2020 this isn't possible on arm64. */ addr = memremap(priv->mem->base, available, MEMREMAP_WB); - if (IS_ERR(addr)) { + if (!addr) { dev_err(priv->dev, "Failed to remap memory region\n"); - return PTR_ERR(addr); + return -ENOMEM; } count = memory_read_from_buffer(val, bytes, &off, addr, available); diff -Nru linux-6.0.6/drivers/of/property.c linux-6.0.12/drivers/of/property.c --- linux-6.0.6/drivers/of/property.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/of/property.c 2023-01-18 18:27:39.000000000 +0000 @@ -993,8 +993,10 @@ nargs, index, &of_args); if (ret < 0) return ret; - if (!args) + if (!args) { + of_node_put(of_args.np); return 0; + } args->nargs = of_args.args_count; args->fwnode = of_fwnode_handle(of_args.np); diff -Nru linux-6.0.6/drivers/parisc/iosapic.c linux-6.0.12/drivers/parisc/iosapic.c --- linux-6.0.6/drivers/parisc/iosapic.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/parisc/iosapic.c 2023-01-18 18:27:39.000000000 +0000 @@ -866,6 +866,7 @@ return vi->txn_irq; } +EXPORT_SYMBOL(iosapic_serial_irq); #endif diff -Nru linux-6.0.6/drivers/parport/parport_pc.c linux-6.0.12/drivers/parport/parport_pc.c --- linux-6.0.6/drivers/parport/parport_pc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/parport/parport_pc.c 2023-01-18 18:27:39.000000000 +0000 @@ -468,7 +468,7 @@ const unsigned char *bufp = buf; size_t left = length; unsigned long expire = jiffies + port->physport->cad->timeout; - const int fifo = FIFO(port); + const unsigned long fifo = FIFO(port); int poll_for = 8; /* 80 usecs */ const struct parport_pc_private *priv = port->physport->private_data; const int fifo_depth = priv->fifo_depth; diff -Nru linux-6.0.6/drivers/pci/controller/pci-hyperv.c linux-6.0.12/drivers/pci/controller/pci-hyperv.c --- linux-6.0.6/drivers/pci/controller/pci-hyperv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pci/controller/pci-hyperv.c 2023-01-18 18:27:39.000000000 +0000 @@ -1613,8 +1613,8 @@ } static u32 hv_compose_msi_req_v1( - struct pci_create_interrupt *int_pkt, const struct cpumask *affinity, - u32 slot, u8 vector, u8 vector_count) + struct pci_create_interrupt *int_pkt, + u32 slot, u8 vector, u16 vector_count) { int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE; int_pkt->wslot.slot = slot; @@ -1632,6 +1632,35 @@ } /* + * The vCPU selected by hv_compose_multi_msi_req_get_cpu() and + * hv_compose_msi_req_get_cpu() is a "dummy" vCPU because the final vCPU to be + * interrupted is specified later in hv_irq_unmask() and communicated to Hyper-V + * via the HVCALL_RETARGET_INTERRUPT hypercall. But the choice of dummy vCPU is + * not irrelevant because Hyper-V chooses the physical CPU to handle the + * interrupts based on the vCPU specified in message sent to the vPCI VSP in + * hv_compose_msi_msg(). Hyper-V's choice of pCPU is not visible to the guest, + * but assigning too many vPCI device interrupts to the same pCPU can cause a + * performance bottleneck. So we spread out the dummy vCPUs to influence Hyper-V + * to spread out the pCPUs that it selects. + * + * For the single-MSI and MSI-X cases, it's OK for hv_compose_msi_req_get_cpu() + * to always return the same dummy vCPU, because a second call to + * hv_compose_msi_msg() contains the "real" vCPU, causing Hyper-V to choose a + * new pCPU for the interrupt. But for the multi-MSI case, the second call to + * hv_compose_msi_msg() exits without sending a message to the vPCI VSP, so the + * original dummy vCPU is used. This dummy vCPU must be round-robin'ed so that + * the pCPUs are spread out. All interrupts for a multi-MSI device end up using + * the same pCPU, even though the vCPUs will be spread out by later calls + * to hv_irq_unmask(), but that is the best we can do now. + * + * With Hyper-V in Nov 2022, the HVCALL_RETARGET_INTERRUPT hypercall does *not* + * cause Hyper-V to reselect the pCPU based on the specified vCPU. Such an + * enhancement is planned for a future version. With that enhancement, the + * dummy vCPU selection won't matter, and interrupts for the same multi-MSI + * device will be spread across multiple pCPUs. + */ + +/* * Create MSI w/ dummy vCPU set targeting just one vCPU, overwritten * by subsequent retarget in hv_irq_unmask(). */ @@ -1640,18 +1669,39 @@ return cpumask_first_and(affinity, cpu_online_mask); } -static u32 hv_compose_msi_req_v2( - struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity, - u32 slot, u8 vector, u8 vector_count) +/* + * Make sure the dummy vCPU values for multi-MSI don't all point to vCPU0. + */ +static int hv_compose_multi_msi_req_get_cpu(void) { + static DEFINE_SPINLOCK(multi_msi_cpu_lock); + + /* -1 means starting with CPU 0 */ + static int cpu_next = -1; + + unsigned long flags; int cpu; + spin_lock_irqsave(&multi_msi_cpu_lock, flags); + + cpu_next = cpumask_next_wrap(cpu_next, cpu_online_mask, nr_cpu_ids, + false); + cpu = cpu_next; + + spin_unlock_irqrestore(&multi_msi_cpu_lock, flags); + + return cpu; +} + +static u32 hv_compose_msi_req_v2( + struct pci_create_interrupt2 *int_pkt, int cpu, + u32 slot, u8 vector, u16 vector_count) +{ int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE2; int_pkt->wslot.slot = slot; int_pkt->int_desc.vector = vector; int_pkt->int_desc.vector_count = vector_count; int_pkt->int_desc.delivery_mode = DELIVERY_MODE; - cpu = hv_compose_msi_req_get_cpu(affinity); int_pkt->int_desc.processor_array[0] = hv_cpu_number_to_vp_number(cpu); int_pkt->int_desc.processor_count = 1; @@ -1660,18 +1710,15 @@ } static u32 hv_compose_msi_req_v3( - struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity, - u32 slot, u32 vector, u8 vector_count) + struct pci_create_interrupt3 *int_pkt, int cpu, + u32 slot, u32 vector, u16 vector_count) { - int cpu; - int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE3; int_pkt->wslot.slot = slot; int_pkt->int_desc.vector = vector; int_pkt->int_desc.reserved = 0; int_pkt->int_desc.vector_count = vector_count; int_pkt->int_desc.delivery_mode = DELIVERY_MODE; - cpu = hv_compose_msi_req_get_cpu(affinity); int_pkt->int_desc.processor_array[0] = hv_cpu_number_to_vp_number(cpu); int_pkt->int_desc.processor_count = 1; @@ -1701,7 +1748,12 @@ struct compose_comp_ctxt comp; struct tran_int_desc *int_desc; struct msi_desc *msi_desc; - u8 vector, vector_count; + /* + * vector_count should be u16: see hv_msi_desc, hv_msi_desc2 + * and hv_msi_desc3. vector must be u32: see hv_msi_desc3. + */ + u16 vector_count; + u32 vector; struct { struct pci_packet pci_pkt; union { @@ -1710,12 +1762,18 @@ struct pci_create_interrupt3 v3; } int_pkts; } __packed ctxt; + bool multi_msi; u64 trans_id; u32 size; int ret; + int cpu; + + msi_desc = irq_data_get_msi_desc(data); + multi_msi = !msi_desc->pci.msi_attrib.is_msix && + msi_desc->nvec_used > 1; /* Reuse the previous allocation */ - if (data->chip_data) { + if (data->chip_data && multi_msi) { int_desc = data->chip_data; msg->address_hi = int_desc->address >> 32; msg->address_lo = int_desc->address & 0xffffffff; @@ -1723,7 +1781,6 @@ return; } - msi_desc = irq_data_get_msi_desc(data); pdev = msi_desc_to_pci_dev(msi_desc); dest = irq_data_get_effective_affinity_mask(data); pbus = pdev->bus; @@ -1733,11 +1790,18 @@ if (!hpdev) goto return_null_message; + /* Free any previous message that might have already been composed. */ + if (data->chip_data && !multi_msi) { + int_desc = data->chip_data; + data->chip_data = NULL; + hv_int_desc_free(hpdev, int_desc); + } + int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC); if (!int_desc) goto drop_reference; - if (!msi_desc->pci.msi_attrib.is_msix && msi_desc->nvec_used > 1) { + if (multi_msi) { /* * If this is not the first MSI of Multi MSI, we already have * a mapping. Can exit early. @@ -1762,11 +1826,18 @@ */ vector = 32; vector_count = msi_desc->nvec_used; + cpu = hv_compose_multi_msi_req_get_cpu(); } else { vector = hv_msi_get_int_vector(data); vector_count = 1; + cpu = hv_compose_msi_req_get_cpu(dest); } + /* + * hv_compose_msi_req_v1 and v2 are for x86 only, meaning 'vector' + * can't exceed u8. Cast 'vector' down to u8 for v1/v2 explicitly + * for better readability. + */ memset(&ctxt, 0, sizeof(ctxt)); init_completion(&comp.comp_pkt.host_event); ctxt.pci_pkt.completion_func = hv_pci_compose_compl; @@ -1775,24 +1846,23 @@ switch (hbus->protocol_version) { case PCI_PROTOCOL_VERSION_1_1: size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1, - dest, hpdev->desc.win_slot.slot, - vector, + (u8)vector, vector_count); break; case PCI_PROTOCOL_VERSION_1_2: case PCI_PROTOCOL_VERSION_1_3: size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2, - dest, + cpu, hpdev->desc.win_slot.slot, - vector, + (u8)vector, vector_count); break; case PCI_PROTOCOL_VERSION_1_4: size = hv_compose_msi_req_v3(&ctxt.int_pkts.v3, - dest, + cpu, hpdev->desc.win_slot.slot, vector, vector_count); diff -Nru linux-6.0.6/drivers/phy/qualcomm/phy-qcom-qmp-combo.c linux-6.0.12/drivers/phy/qualcomm/phy-qcom-qmp-combo.c --- linux-6.0.6/drivers/phy/qualcomm/phy-qcom-qmp-combo.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/phy/qualcomm/phy-qcom-qmp-combo.c 2023-01-18 18:27:39.000000000 +0000 @@ -1914,7 +1914,7 @@ static void qcom_qmp_phy_combo_disable_autonomous_mode(struct qmp_phy *qphy) { const struct qmp_phy_cfg *cfg = qphy->cfg; - void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs_usb; + void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs; void __iomem *pcs_misc = qphy->pcs_misc; /* Disable i/o clamp_n on resume for normal mode */ diff -Nru linux-6.0.6/drivers/phy/ralink/phy-mt7621-pci.c linux-6.0.12/drivers/phy/ralink/phy-mt7621-pci.c --- linux-6.0.6/drivers/phy/ralink/phy-mt7621-pci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/phy/ralink/phy-mt7621-pci.c 2023-01-18 18:27:39.000000000 +0000 @@ -280,7 +280,8 @@ } static const struct soc_device_attribute mt7621_pci_quirks_match[] = { - { .soc_id = "mt7621", .revision = "E2" } + { .soc_id = "mt7621", .revision = "E2" }, + { /* sentinel */ } }; static const struct regmap_config mt7621_pci_phy_regmap_config = { diff -Nru linux-6.0.6/drivers/phy/st/phy-stm32-usbphyc.c linux-6.0.12/drivers/phy/st/phy-stm32-usbphyc.c --- linux-6.0.6/drivers/phy/st/phy-stm32-usbphyc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/phy/st/phy-stm32-usbphyc.c 2023-01-18 18:27:39.000000000 +0000 @@ -710,6 +710,8 @@ ret = of_property_read_u32(child, "reg", &index); if (ret || index > usbphyc->nphys) { dev_err(&phy->dev, "invalid reg property: %d\n", ret); + if (!ret) + ret = -EINVAL; goto put_child; } diff -Nru linux-6.0.6/drivers/pinctrl/devicetree.c linux-6.0.12/drivers/pinctrl/devicetree.c --- linux-6.0.6/drivers/pinctrl/devicetree.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/devicetree.c 2023-01-18 18:27:39.000000000 +0000 @@ -220,6 +220,8 @@ for (state = 0; ; state++) { /* Retrieve the pinctrl-* property */ propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); + if (!propname) + return -ENOMEM; prop = of_find_property(np, propname, &size); kfree(propname); if (!prop) { diff -Nru linux-6.0.6/drivers/pinctrl/intel/pinctrl-intel.c linux-6.0.12/drivers/pinctrl/intel/pinctrl-intel.c --- linux-6.0.6/drivers/pinctrl/intel/pinctrl-intel.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/intel/pinctrl-intel.c 2023-01-18 18:27:39.000000000 +0000 @@ -436,9 +436,14 @@ writel(value, padcfg0); } +static int __intel_gpio_get_gpio_mode(u32 value) +{ + return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; +} + static int intel_gpio_get_gpio_mode(void __iomem *padcfg0) { - return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; + return __intel_gpio_get_gpio_mode(readl(padcfg0)); } static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) @@ -1675,6 +1680,7 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin) { const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin); + u32 value; if (!pd || !intel_pad_usable(pctrl, pin)) return false; @@ -1689,6 +1695,25 @@ gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin))) return true; + /* + * The firmware on some systems may configure GPIO pins to be + * an interrupt source in so called "direct IRQ" mode. In such + * cases the GPIO controller driver has no idea if those pins + * are being used or not. At the same time, there is a known bug + * in the firmwares that don't restore the pin settings correctly + * after suspend, i.e. by an unknown reason the Rx value becomes + * inverted. + * + * Hence, let's save and restore the pins that are configured + * as GPIOs in the input mode with GPIROUTIOXAPIC bit set. + * + * See https://bugzilla.kernel.org/show_bug.cgi?id=214749. + */ + value = readl(intel_get_padcfg(pctrl, pin, PADCFG0)); + if ((value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) && + (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO)) + return true; + return false; } diff -Nru linux-6.0.6/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c linux-6.0.12/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c --- linux-6.0.6/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 2023-01-18 18:27:39.000000000 +0000 @@ -709,6 +709,9 @@ { int err, rsel_val; + if (!pullup && arg == MTK_DISABLE) + return 0; + if (hw->rsel_si_unit) { /* find pin rsel_index from pin_rsel array*/ err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val); diff -Nru linux-6.0.6/drivers/pinctrl/pinctrl-ingenic.c linux-6.0.12/drivers/pinctrl/pinctrl-ingenic.c --- linux-6.0.6/drivers/pinctrl/pinctrl-ingenic.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/pinctrl-ingenic.c 2023-01-18 18:27:39.000000000 +0000 @@ -667,7 +667,7 @@ static const struct group_desc jz4755_groups[] = { INGENIC_PIN_GROUP("uart0-data", jz4755_uart0_data, 0), INGENIC_PIN_GROUP("uart0-hwflow", jz4755_uart0_hwflow, 0), - INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 0), + INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 1), INGENIC_PIN_GROUP("uart2-data", jz4755_uart2_data, 1), INGENIC_PIN_GROUP("ssi-dt-b", jz4755_ssi_dt_b, 0), INGENIC_PIN_GROUP("ssi-dt-f", jz4755_ssi_dt_f, 0), @@ -721,7 +721,7 @@ "ssi-ce1-b", "ssi-ce1-f", }; static const char *jz4755_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", }; -static const char *jz4755_mmc1_groups[] = { "mmc0-1bit", "mmc0-4bit", }; +static const char *jz4755_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", }; static const char *jz4755_i2c_groups[] = { "i2c-data", }; static const char *jz4755_cim_groups[] = { "cim-data", }; static const char *jz4755_lcd_groups[] = { diff -Nru linux-6.0.6/drivers/pinctrl/pinctrl-ocelot.c linux-6.0.12/drivers/pinctrl/pinctrl-ocelot.c --- linux-6.0.6/drivers/pinctrl/pinctrl-ocelot.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/pinctrl-ocelot.c 2023-01-18 18:27:39.000000000 +0000 @@ -1863,19 +1863,28 @@ if (val & bit) ack = true; + /* Try to clear any rising edges */ + if (!active && ack) + regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio), + bit, bit); + /* Enable the interrupt now */ gpiochip_enable_irq(chip, gpio); regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio), bit, bit); /* - * In case the interrupt line is still active and the interrupt - * controller has not seen any changes in the interrupt line, then it - * means that there happen another interrupt while the line was active. + * In case the interrupt line is still active then it means that + * there happen another interrupt while the line was active. * So we missed that one, so we need to kick the interrupt again * handler. */ - if (active && !ack) { + regmap_read(info->map, REG(OCELOT_GPIO_IN, info, gpio), &val); + if ((!(val & bit) && trigger_level == IRQ_TYPE_LEVEL_LOW) || + (val & bit && trigger_level == IRQ_TYPE_LEVEL_HIGH)) + active = true; + + if (active) { struct ocelot_irq_work *work; work = kmalloc(sizeof(*work), GFP_ATOMIC); diff -Nru linux-6.0.6/drivers/pinctrl/pinctrl-rockchip.c linux-6.0.12/drivers/pinctrl/pinctrl-rockchip.c --- linux-6.0.6/drivers/pinctrl/pinctrl-rockchip.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/pinctrl-rockchip.c 2023-01-18 18:27:39.000000000 +0000 @@ -632,14 +632,54 @@ } static struct rockchip_mux_route_data px30_mux_route_data[] = { + RK_MUXROUTE_SAME(2, RK_PB4, 1, 0x184, BIT(16 + 7)), /* cif-d0m0 */ + RK_MUXROUTE_SAME(3, RK_PA1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d0m1 */ + RK_MUXROUTE_SAME(2, RK_PB6, 1, 0x184, BIT(16 + 7)), /* cif-d1m0 */ + RK_MUXROUTE_SAME(3, RK_PA2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d1m1 */ RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */ RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */ + RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x184, BIT(16 + 7)), /* cif-d3m0 */ + RK_MUXROUTE_SAME(3, RK_PA5, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d3m1 */ + RK_MUXROUTE_SAME(2, RK_PA2, 1, 0x184, BIT(16 + 7)), /* cif-d4m0 */ + RK_MUXROUTE_SAME(3, RK_PA7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d4m1 */ + RK_MUXROUTE_SAME(2, RK_PA3, 1, 0x184, BIT(16 + 7)), /* cif-d5m0 */ + RK_MUXROUTE_SAME(3, RK_PB0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d5m1 */ + RK_MUXROUTE_SAME(2, RK_PA4, 1, 0x184, BIT(16 + 7)), /* cif-d6m0 */ + RK_MUXROUTE_SAME(3, RK_PB1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d6m1 */ + RK_MUXROUTE_SAME(2, RK_PA5, 1, 0x184, BIT(16 + 7)), /* cif-d7m0 */ + RK_MUXROUTE_SAME(3, RK_PB4, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d7m1 */ + RK_MUXROUTE_SAME(2, RK_PA6, 1, 0x184, BIT(16 + 7)), /* cif-d8m0 */ + RK_MUXROUTE_SAME(3, RK_PB6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d8m1 */ + RK_MUXROUTE_SAME(2, RK_PA7, 1, 0x184, BIT(16 + 7)), /* cif-d9m0 */ + RK_MUXROUTE_SAME(3, RK_PB7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d9m1 */ + RK_MUXROUTE_SAME(2, RK_PB7, 1, 0x184, BIT(16 + 7)), /* cif-d10m0 */ + RK_MUXROUTE_SAME(3, RK_PC6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d10m1 */ + RK_MUXROUTE_SAME(2, RK_PC0, 1, 0x184, BIT(16 + 7)), /* cif-d11m0 */ + RK_MUXROUTE_SAME(3, RK_PC7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d11m1 */ + RK_MUXROUTE_SAME(2, RK_PB0, 1, 0x184, BIT(16 + 7)), /* cif-vsyncm0 */ + RK_MUXROUTE_SAME(3, RK_PD1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-vsyncm1 */ + RK_MUXROUTE_SAME(2, RK_PB1, 1, 0x184, BIT(16 + 7)), /* cif-hrefm0 */ + RK_MUXROUTE_SAME(3, RK_PD2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-hrefm1 */ + RK_MUXROUTE_SAME(2, RK_PB2, 1, 0x184, BIT(16 + 7)), /* cif-clkinm0 */ + RK_MUXROUTE_SAME(3, RK_PD3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkinm1 */ + RK_MUXROUTE_SAME(2, RK_PB3, 1, 0x184, BIT(16 + 7)), /* cif-clkoutm0 */ + RK_MUXROUTE_SAME(3, RK_PD0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkoutm1 */ RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */ RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */ + RK_MUXROUTE_SAME(3, RK_PD3, 2, 0x184, BIT(16 + 8)), /* pdm-sdi0m0 */ + RK_MUXROUTE_SAME(2, RK_PC5, 2, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-sdi0m1 */ RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */ RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */ + RK_MUXROUTE_SAME(1, RK_PD2, 2, 0x184, BIT(16 + 10)), /* uart2-txm0 */ + RK_MUXROUTE_SAME(2, RK_PB4, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-txm1 */ RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */ RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */ + RK_MUXROUTE_SAME(0, RK_PC0, 2, 0x184, BIT(16 + 9)), /* uart3-txm0 */ + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-txm1 */ + RK_MUXROUTE_SAME(0, RK_PC2, 2, 0x184, BIT(16 + 9)), /* uart3-ctsm0 */ + RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-ctsm1 */ + RK_MUXROUTE_SAME(0, RK_PC3, 2, 0x184, BIT(16 + 9)), /* uart3-rtsm0 */ + RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rtsm1 */ }; static struct rockchip_mux_route_data rk3128_mux_route_data[] = { diff -Nru linux-6.0.6/drivers/pinctrl/pinctrl-single.c linux-6.0.12/drivers/pinctrl/pinctrl-single.c --- linux-6.0.6/drivers/pinctrl/pinctrl-single.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/pinctrl-single.c 2023-01-18 18:27:39.000000000 +0000 @@ -727,7 +727,7 @@ mux_bytes = pcs->width / BITS_PER_BYTE; - if (pcs->bits_per_mux) { + if (pcs->bits_per_mux && pcs->fmask) { pcs->bits_per_pin = fls(pcs->fmask); nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin; } else { diff -Nru linux-6.0.6/drivers/pinctrl/pinctrl-zynqmp.c linux-6.0.12/drivers/pinctrl/pinctrl-zynqmp.c --- linux-6.0.6/drivers/pinctrl/pinctrl-zynqmp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/pinctrl-zynqmp.c 2023-01-18 18:27:39.000000000 +0000 @@ -412,10 +412,6 @@ break; case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: - param = PM_PINCTRL_CONFIG_TRI_STATE; - arg = PM_PINCTRL_TRI_STATE_ENABLE; - ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); - break; case PIN_CONFIG_MODE_LOW_POWER: /* * These cases are mentioned in dts but configurable @@ -424,11 +420,6 @@ */ ret = 0; break; - case PIN_CONFIG_OUTPUT_ENABLE: - param = PM_PINCTRL_CONFIG_TRI_STATE; - arg = PM_PINCTRL_TRI_STATE_DISABLE; - ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); - break; default: dev_warn(pctldev->dev, "unsupported configuration parameter '%u'\n", diff -Nru linux-6.0.6/drivers/pinctrl/qcom/pinctrl-msm.c linux-6.0.12/drivers/pinctrl/qcom/pinctrl-msm.c --- linux-6.0.6/drivers/pinctrl/qcom/pinctrl-msm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/qcom/pinctrl-msm.c 2023-01-18 18:27:39.000000000 +0000 @@ -51,6 +51,7 @@ * detection. * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller * @disabled_for_mux: These IRQs were disabled because we muxed away. + * @ever_gpio: This bit is set the first time we mux a pin to gpio_func. * @soc: Reference to soc_data of platform specific data. * @regs: Base addresses for the TLMM tiles. * @phys_base: Physical base address @@ -72,6 +73,7 @@ DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO); DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO); DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO); + DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO); const struct msm_pinctrl_soc_data *soc; void __iomem *regs[MAX_NR_TILES]; @@ -218,6 +220,25 @@ val = msm_readl_ctl(pctrl, g); + /* + * If this is the first time muxing to GPIO and the direction is + * output, make sure that we're not going to be glitching the pin + * by reading the current state of the pin and setting it as the + * output. + */ + if (i == gpio_func && (val & BIT(g->oe_bit)) && + !test_and_set_bit(group, pctrl->ever_gpio)) { + u32 io_val = msm_readl_io(pctrl, g); + + if (io_val & BIT(g->in_bit)) { + if (!(io_val & BIT(g->out_bit))) + msm_writel_io(io_val | BIT(g->out_bit), pctrl, g); + } else { + if (io_val & BIT(g->out_bit)) + msm_writel_io(io_val & ~BIT(g->out_bit), pctrl, g); + } + } + if (egpio_func && i == egpio_func) { if (val & BIT(g->egpio_present)) val &= ~BIT(g->egpio_enable); diff -Nru linux-6.0.6/drivers/pinctrl/qcom/pinctrl-sc8280xp.c linux-6.0.12/drivers/pinctrl/qcom/pinctrl-sc8280xp.c --- linux-6.0.6/drivers/pinctrl/qcom/pinctrl-sc8280xp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/pinctrl/qcom/pinctrl-sc8280xp.c 2023-01-18 18:27:39.000000000 +0000 @@ -1873,8 +1873,8 @@ [225] = PINGROUP(225, hs3_mi2s, phase_flag, _, _, _, _, egpio), [226] = PINGROUP(226, hs3_mi2s, phase_flag, _, _, _, _, egpio), [227] = PINGROUP(227, hs3_mi2s, phase_flag, _, _, _, _, egpio), - [228] = UFS_RESET(ufs_reset, 0xf1004), - [229] = UFS_RESET(ufs1_reset, 0xf3004), + [228] = UFS_RESET(ufs_reset, 0xf1000), + [229] = UFS_RESET(ufs1_reset, 0xf3000), [230] = SDC_QDSD_PINGROUP(sdc2_clk, 0xe8000, 14, 6), [231] = SDC_QDSD_PINGROUP(sdc2_cmd, 0xe8000, 11, 3), [232] = SDC_QDSD_PINGROUP(sdc2_data, 0xe8000, 9, 0), diff -Nru linux-6.0.6/drivers/platform/surface/aggregator/ssh_packet_layer.c linux-6.0.12/drivers/platform/surface/aggregator/ssh_packet_layer.c --- linux-6.0.6/drivers/platform/surface/aggregator/ssh_packet_layer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/surface/aggregator/ssh_packet_layer.c 2023-01-18 18:27:39.000000000 +0000 @@ -1596,16 +1596,32 @@ ssh_ptl_tx_wakeup_packet(ptl); } -static bool ssh_ptl_rx_retransmit_check(struct ssh_ptl *ptl, u8 seq) +static bool ssh_ptl_rx_retransmit_check(struct ssh_ptl *ptl, const struct ssh_frame *frame) { int i; /* + * Ignore unsequenced packets. On some devices (notably Surface Pro 9), + * unsequenced events will always be sent with SEQ=0x00. Attempting to + * detect retransmission would thus just block all events. + * + * While sequence numbers would also allow detection of retransmitted + * packets in unsequenced communication, they have only ever been used + * to cover edge-cases in sequenced transmission. In particular, the + * only instance of packets being retransmitted (that we are aware of) + * is due to an ACK timeout. As this does not happen in unsequenced + * communication, skip the retransmission check for those packets + * entirely. + */ + if (frame->type == SSH_FRAME_TYPE_DATA_NSQ) + return false; + + /* * Check if SEQ has been seen recently (i.e. packet was * re-transmitted and we should ignore it). */ for (i = 0; i < ARRAY_SIZE(ptl->rx.blocked.seqs); i++) { - if (likely(ptl->rx.blocked.seqs[i] != seq)) + if (likely(ptl->rx.blocked.seqs[i] != frame->seq)) continue; ptl_dbg(ptl, "ptl: ignoring repeated data packet\n"); @@ -1613,7 +1629,7 @@ } /* Update list of blocked sequence IDs. */ - ptl->rx.blocked.seqs[ptl->rx.blocked.offset] = seq; + ptl->rx.blocked.seqs[ptl->rx.blocked.offset] = frame->seq; ptl->rx.blocked.offset = (ptl->rx.blocked.offset + 1) % ARRAY_SIZE(ptl->rx.blocked.seqs); @@ -1624,7 +1640,7 @@ const struct ssh_frame *frame, const struct ssam_span *payload) { - if (ssh_ptl_rx_retransmit_check(ptl, frame->seq)) + if (ssh_ptl_rx_retransmit_check(ptl, frame)) return; ptl->ops.data_received(ptl, payload); diff -Nru linux-6.0.6/drivers/platform/surface/surface_aggregator_registry.c linux-6.0.12/drivers/platform/surface/surface_aggregator_registry.c --- linux-6.0.6/drivers/platform/surface/surface_aggregator_registry.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/surface/surface_aggregator_registry.c 2023-01-18 18:27:39.000000000 +0000 @@ -234,6 +234,19 @@ NULL, }; +/* Devices for Surface Laptop 5. */ +static const struct software_node *ssam_node_group_sl5[] = { + &ssam_node_root, + &ssam_node_bat_ac, + &ssam_node_bat_main, + &ssam_node_tmp_pprof, + &ssam_node_hid_main_keyboard, + &ssam_node_hid_main_touchpad, + &ssam_node_hid_main_iid5, + &ssam_node_hid_sam_ucm_ucsi, + NULL, +}; + /* Devices for Surface Laptop Studio. */ static const struct software_node *ssam_node_group_sls[] = { &ssam_node_root, @@ -268,6 +281,7 @@ NULL, }; +/* Devices for Surface Pro 8 */ static const struct software_node *ssam_node_group_sp8[] = { &ssam_node_root, &ssam_node_hub_kip, @@ -284,6 +298,23 @@ NULL, }; +/* Devices for Surface Pro 9 */ +static const struct software_node *ssam_node_group_sp9[] = { + &ssam_node_root, + &ssam_node_hub_kip, + &ssam_node_bat_ac, + &ssam_node_bat_main, + &ssam_node_tmp_pprof, + /* TODO: Tablet mode switch (via POS subsystem) */ + &ssam_node_hid_kip_keyboard, + &ssam_node_hid_kip_penstash, + &ssam_node_hid_kip_touchpad, + &ssam_node_hid_kip_fwupd, + &ssam_node_hid_sam_sensors, + &ssam_node_hid_sam_ucm_ucsi, + NULL, +}; + /* -- SSAM platform/meta-hub driver. ---------------------------------------- */ @@ -303,6 +334,9 @@ /* Surface Pro 8 */ { "MSHW0263", (unsigned long)ssam_node_group_sp8 }, + /* Surface Pro 9 */ + { "MSHW0343", (unsigned long)ssam_node_group_sp9 }, + /* Surface Book 2 */ { "MSHW0107", (unsigned long)ssam_node_group_gen5 }, @@ -324,6 +358,9 @@ /* Surface Laptop 4 (13", Intel) */ { "MSHW0250", (unsigned long)ssam_node_group_sl3 }, + /* Surface Laptop 5 */ + { "MSHW0350", (unsigned long)ssam_node_group_sl5 }, + /* Surface Laptop Go 1 */ { "MSHW0118", (unsigned long)ssam_node_group_slg1 }, diff -Nru linux-6.0.6/drivers/platform/x86/acer-wmi.c linux-6.0.12/drivers/platform/x86/acer-wmi.c --- linux-6.0.6/drivers/platform/x86/acer-wmi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/acer-wmi.c 2023-01-18 18:27:39.000000000 +0000 @@ -566,6 +566,15 @@ }, { .callback = set_force_caps, + .ident = "Acer Aspire Switch V 10 SW5-017", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"), + }, + .driver_data = (void *)ACER_CAP_KBD_DOCK, + }, + { + .callback = set_force_caps, .ident = "Acer One 10 (S1003)", .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), diff -Nru linux-6.0.6/drivers/platform/x86/amd/pmc.c linux-6.0.12/drivers/platform/x86/amd/pmc.c --- linux-6.0.6/drivers/platform/x86/amd/pmc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/amd/pmc.c 2023-01-18 18:27:39.000000000 +0000 @@ -151,9 +151,7 @@ struct device *dev; struct pci_dev *rdev; struct mutex lock; /* generic mutex lock */ -#if IS_ENABLED(CONFIG_DEBUG_FS) struct dentry *dbgfs_dir; -#endif /* CONFIG_DEBUG_FS */ }; static bool enable_stb; @@ -276,7 +274,6 @@ .release = amd_pmc_stb_debugfs_release_v2, }; -#if defined(CONFIG_SUSPEND) || defined(CONFIG_DEBUG_FS) static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev) { if (dev->cpu_id == AMD_CPU_ID_PCO) { @@ -351,7 +348,6 @@ memcpy_fromio(table, pdev->smu_virt_addr, sizeof(struct smu_metrics)); return 0; } -#endif /* CONFIG_SUSPEND || CONFIG_DEBUG_FS */ #ifdef CONFIG_SUSPEND static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev) @@ -369,7 +365,6 @@ } #endif -#ifdef CONFIG_DEBUG_FS static int smu_fw_info_show(struct seq_file *s, void *unused) { struct amd_pmc_dev *dev = s->private; @@ -504,15 +499,6 @@ &amd_pmc_stb_debugfs_fops); } } -#else -static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev) -{ -} - -static inline void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev) -{ -} -#endif /* CONFIG_DEBUG_FS */ static void amd_pmc_dump_registers(struct amd_pmc_dev *dev) { @@ -932,6 +918,7 @@ {"AMDI0006", 0}, {"AMDI0007", 0}, {"AMDI0008", 0}, + {"AMDI0009", 0}, {"AMD0004", 0}, {"AMD0005", 0}, { } diff -Nru linux-6.0.6/drivers/platform/x86/asus-wmi.c linux-6.0.12/drivers/platform/x86/asus-wmi.c --- linux-6.0.6/drivers/platform/x86/asus-wmi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/asus-wmi.c 2023-01-18 18:27:39.000000000 +0000 @@ -1656,6 +1656,8 @@ pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, cpu_to_le32(ports_available)); + pci_dev_put(xhci_pdev); + pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n", orig_ports_available, ports_available); } diff -Nru linux-6.0.6/drivers/platform/x86/hp-wmi.c linux-6.0.12/drivers/platform/x86/hp-wmi.c --- linux-6.0.6/drivers/platform/x86/hp-wmi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/hp-wmi.c 2023-01-18 18:27:39.000000000 +0000 @@ -90,6 +90,7 @@ HPWMI_PEAKSHIFT_PERIOD = 0x0F, HPWMI_BATTERY_CHARGE_PERIOD = 0x10, HPWMI_SANITIZATION_MODE = 0x17, + HPWMI_SMART_EXPERIENCE_APP = 0x21, }; /* @@ -857,6 +858,8 @@ break; case HPWMI_SANITIZATION_MODE: break; + case HPWMI_SMART_EXPERIENCE_APP: + break; default: pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); break; @@ -1298,8 +1301,16 @@ wwan_rfkill = NULL; rfkill2_count = 0; - if (hp_wmi_rfkill_setup(device)) - hp_wmi_rfkill2_setup(device); + /* + * In pre-2009 BIOS, command 1Bh return 0x4 to indicate that + * BIOS no longer controls the power for the wireless + * devices. All features supported by this command will no + * longer be supported. + */ + if (!hp_wmi_bios_2009_later()) { + if (hp_wmi_rfkill_setup(device)) + hp_wmi_rfkill2_setup(device); + } err = hp_wmi_hwmon_init(); diff -Nru linux-6.0.6/drivers/platform/x86/ideapad-laptop.c linux-6.0.12/drivers/platform/x86/ideapad-laptop.c --- linux-6.0.6/drivers/platform/x86/ideapad-laptop.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/ideapad-laptop.c 2023-01-18 18:27:39.000000000 +0000 @@ -136,6 +136,7 @@ bool dytc : 1; bool fan_mode : 1; bool fn_lock : 1; + bool set_fn_lock_led : 1; bool hw_rfkill_switch : 1; bool kbd_bl : 1; bool touchpad_ctrl_via_ec : 1; @@ -154,7 +155,21 @@ static bool allow_v4_dytc; module_param(allow_v4_dytc, bool, 0444); -MODULE_PARM_DESC(allow_v4_dytc, "Enable DYTC version 4 platform-profile support."); +MODULE_PARM_DESC(allow_v4_dytc, + "Enable DYTC version 4 platform-profile support. " + "If you need this please report this to: platform-driver-x86@vger.kernel.org"); + +static bool hw_rfkill_switch; +module_param(hw_rfkill_switch, bool, 0444); +MODULE_PARM_DESC(hw_rfkill_switch, + "Enable rfkill support for laptops with a hw on/off wifi switch/slider. " + "If you need this please report this to: platform-driver-x86@vger.kernel.org"); + +static bool set_fn_lock_led; +module_param(set_fn_lock_led, bool, 0444); +MODULE_PARM_DESC(set_fn_lock_led, + "Enable driver based updates of the fn-lock LED on fn-lock changes. " + "If you need this please report this to: platform-driver-x86@vger.kernel.org"); /* * ACPI Helpers @@ -1501,6 +1516,9 @@ ideapad_input_report(priv, value); break; case 208: + if (!priv->features.set_fn_lock_led) + break; + if (!eval_hals(priv->adev->handle, &result)) { bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result); @@ -1514,6 +1532,18 @@ } #endif +/* On some models we need to call exec_sals(SALS_FNLOCK_ON/OFF) to set the LED */ +static const struct dmi_system_id set_fn_lock_led_list[] = { + { + /* https://bugzilla.kernel.org/show_bug.cgi?id=212671 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion R7000P2020H"), + } + }, + {} +}; + /* * Some ideapads have a hardware rfkill switch, but most do not have one. * Reading VPCCMD_R_RF always results in 0 on models without a hardware rfkill, @@ -1533,15 +1563,41 @@ {} }; +static const struct dmi_system_id no_touchpad_switch_list[] = { + { + .ident = "Lenovo Yoga 3 Pro 1370", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3"), + }, + }, + { + .ident = "ZhaoYang K4e-IML", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ZhaoYang K4e-IML"), + }, + }, + {} +}; + static void ideapad_check_features(struct ideapad_private *priv) { acpi_handle handle = priv->adev->handle; unsigned long val; - priv->features.hw_rfkill_switch = dmi_check_system(hw_rfkill_list); + priv->features.set_fn_lock_led = + set_fn_lock_led || dmi_check_system(set_fn_lock_led_list); + priv->features.hw_rfkill_switch = + hw_rfkill_switch || dmi_check_system(hw_rfkill_list); /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */ - priv->features.touchpad_ctrl_via_ec = !acpi_dev_present("ELAN0634", NULL, -1); + if (acpi_dev_present("ELAN0634", NULL, -1)) + priv->features.touchpad_ctrl_via_ec = 0; + else if (dmi_check_system(no_touchpad_switch_list)) + priv->features.touchpad_ctrl_via_ec = 0; + else + priv->features.touchpad_ctrl_via_ec = 1; if (!read_ec_data(handle, VPCCMD_R_FAN, &val)) priv->features.fan_mode = true; diff -Nru linux-6.0.6/drivers/platform/x86/intel/hid.c linux-6.0.12/drivers/platform/x86/intel/hid.c --- linux-6.0.6/drivers/platform/x86/intel/hid.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/intel/hid.c 2023-01-18 18:27:39.000000000 +0000 @@ -27,6 +27,9 @@ {"INTC1051", 0}, {"INTC1054", 0}, {"INTC1070", 0}, + {"INTC1076", 0}, + {"INTC1077", 0}, + {"INTC1078", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, intel_hid_ids); diff -Nru linux-6.0.6/drivers/platform/x86/intel/pmc/core.c linux-6.0.12/drivers/platform/x86/intel/pmc/core.c --- linux-6.0.6/drivers/platform/x86/intel/pmc/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/intel/pmc/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -1914,6 +1914,8 @@ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &tgl_reg_map), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &adl_reg_map), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &adl_reg_map), {} }; diff -Nru linux-6.0.6/drivers/platform/x86/intel/pmc/pltdrv.c linux-6.0.12/drivers/platform/x86/intel/pmc/pltdrv.c --- linux-6.0.6/drivers/platform/x86/intel/pmc/pltdrv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/intel/pmc/pltdrv.c 2023-01-18 18:27:39.000000000 +0000 @@ -18,6 +18,8 @@ #include #include +#include + static void intel_pmc_core_release(struct device *dev) { kfree(dev); @@ -53,6 +55,13 @@ if (acpi_dev_present("INT33A1", NULL, -1)) return -ENODEV; + /* + * Skip forcefully attaching the device for VMs. Make an exception for + * Xen dom0, which does have full hardware access. + */ + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR) && !xen_initial_domain()) + return -ENODEV; + if (!x86_match_cpu(intel_pmc_core_platform_ids)) return -ENODEV; diff -Nru linux-6.0.6/drivers/platform/x86/intel/pmt/class.c linux-6.0.12/drivers/platform/x86/intel/pmt/class.c --- linux-6.0.6/drivers/platform/x86/intel/pmt/class.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/intel/pmt/class.c 2023-01-18 18:27:39.000000000 +0000 @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -19,6 +20,7 @@ #define PMT_XA_START 0 #define PMT_XA_MAX INT_MAX #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) +#define GUID_SPR_PUNIT 0x9956f43f bool intel_pmt_is_early_client_hw(struct device *dev) { @@ -33,6 +35,29 @@ } EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw); +static inline int +pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count) +{ + int i, remain; + u64 *buf = to; + + if (!IS_ALIGNED((unsigned long)from, 8)) + return -EFAULT; + + for (i = 0; i < count/8; i++) + buf[i] = readq(&from[i]); + + /* Copy any remaining bytes */ + remain = count % 8; + if (remain) { + u64 tmp = readq(&from[i]); + + memcpy(&buf[i], &tmp, remain); + } + + return count; +} + /* * sysfs */ @@ -54,7 +79,11 @@ if (count > entry->size - off) count = entry->size - off; - memcpy_fromio(buf, entry->base + off, count); + if (entry->guid == GUID_SPR_PUNIT) + /* PUNIT on SPR only supports aligned 64-bit read */ + count = pmt_memcpy64_fromio(buf, entry->base + off, count); + else + memcpy_fromio(buf, entry->base + off, count); return count; } diff -Nru linux-6.0.6/drivers/platform/x86/p2sb.c linux-6.0.12/drivers/platform/x86/p2sb.c --- linux-6.0.6/drivers/platform/x86/p2sb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/p2sb.c 2023-01-18 18:27:39.000000000 +0000 @@ -19,26 +19,23 @@ #define P2SBC 0xe0 #define P2SBC_HIDE BIT(8) +#define P2SB_DEVFN_DEFAULT PCI_DEVFN(31, 1) + static const struct x86_cpu_id p2sb_cpu_ids[] = { X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, PCI_DEVFN(13, 0)), - X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, PCI_DEVFN(31, 1)), - X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D, PCI_DEVFN(31, 1)), - X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, PCI_DEVFN(31, 1)), - X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, PCI_DEVFN(31, 1)), - X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, PCI_DEVFN(31, 1)), - X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, PCI_DEVFN(31, 1)), {} }; static int p2sb_get_devfn(unsigned int *devfn) { + unsigned int fn = P2SB_DEVFN_DEFAULT; const struct x86_cpu_id *id; id = x86_match_cpu(p2sb_cpu_ids); - if (!id) - return -ENODEV; + if (id) + fn = (unsigned int)id->driver_data; - *devfn = (unsigned int)id->driver_data; + *devfn = fn; return 0; } diff -Nru linux-6.0.6/drivers/platform/x86/thinkpad_acpi.c linux-6.0.12/drivers/platform/x86/thinkpad_acpi.c --- linux-6.0.6/drivers/platform/x86/thinkpad_acpi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/thinkpad_acpi.c 2023-01-18 18:27:39.000000000 +0000 @@ -263,6 +263,8 @@ #define TPACPI_DBG_BRGHT 0x0020 #define TPACPI_DBG_MIXER 0x0040 +#define FAN_NOT_PRESENT 65535 + #define strlencmp(a, b) (strncmp((a), (b), strlen(b))) @@ -4495,6 +4497,14 @@ DMI_MATCH(DMI_PRODUCT_NAME, "21A0"), } }, + { + .ident = "P14s Gen2 AMD", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), + } + }, {} }; @@ -8876,7 +8886,7 @@ /* Try and probe the 2nd fan */ tp_features.second_fan = 1; /* needed for get_speed to work */ res = fan2_get_speed(&speed); - if (res >= 0) { + if (res >= 0 && speed != FAN_NOT_PRESENT) { /* It responded - so let's assume it's there */ tp_features.second_fan = 1; tp_features.second_fan_ctl = 1; diff -Nru linux-6.0.6/drivers/platform/x86/touchscreen_dmi.c linux-6.0.12/drivers/platform/x86/touchscreen_dmi.c --- linux-6.0.6/drivers/platform/x86/touchscreen_dmi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/platform/x86/touchscreen_dmi.c 2023-01-18 18:27:39.000000000 +0000 @@ -770,6 +770,22 @@ .properties = predia_basic_props, }; +static const struct property_entry rca_cambio_w101_v2_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 4), + PROPERTY_ENTRY_U32("touchscreen-min-y", 20), + PROPERTY_ENTRY_U32("touchscreen-size-x", 1644), + PROPERTY_ENTRY_U32("touchscreen-size-y", 874), + PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), + PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rca-cambio-w101-v2.fw"), + PROPERTY_ENTRY_U32("silead,max-fingers", 10), + { } +}; + +static const struct ts_dmi_data rca_cambio_w101_v2_data = { + .acpi_name = "MSSL1680:00", + .properties = rca_cambio_w101_v2_props, +}; + static const struct property_entry rwc_nanote_p8_props[] = { PROPERTY_ENTRY_U32("touchscreen-min-y", 46), PROPERTY_ENTRY_U32("touchscreen-size-x", 1728), @@ -1410,6 +1426,15 @@ }, }, { + /* RCA Cambio W101 v2 */ + /* https://github.com/onitake/gsl-firmware/discussions/193 */ + .driver_data = (void *)&rca_cambio_w101_v2_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "RCA"), + DMI_MATCH(DMI_PRODUCT_NAME, "W101SA23T1"), + }, + }, + { /* RWC NANOTE P8 */ .driver_data = (void *)&rwc_nanote_p8_data, .matches = { diff -Nru linux-6.0.6/drivers/power/supply/ab8500_btemp.c linux-6.0.12/drivers/power/supply/ab8500_btemp.c --- linux-6.0.6/drivers/power/supply/ab8500_btemp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/power/supply/ab8500_btemp.c 2023-01-18 18:27:39.000000000 +0000 @@ -725,7 +725,14 @@ /* Get thermal zone and ADC */ di->tz = thermal_zone_get_zone_by_name("battery-thermal"); if (IS_ERR(di->tz)) { - return dev_err_probe(dev, PTR_ERR(di->tz), + ret = PTR_ERR(di->tz); + /* + * This usually just means we are probing before the thermal + * zone, so just defer. + */ + if (ret == -ENODEV) + ret = -EPROBE_DEFER; + return dev_err_probe(dev, ret, "failed to get battery thermal zone\n"); } di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl"); diff -Nru linux-6.0.6/drivers/power/supply/ip5xxx_power.c linux-6.0.12/drivers/power/supply/ip5xxx_power.c --- linux-6.0.6/drivers/power/supply/ip5xxx_power.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/power/supply/ip5xxx_power.c 2023-01-18 18:27:39.000000000 +0000 @@ -352,7 +352,7 @@ ret = ip5xxx_battery_read_adc(ip5xxx, IP5XXX_BATIADC_DAT0, IP5XXX_BATIADC_DAT1, &raw); - val->intval = DIV_ROUND_CLOSEST(raw * 745985, 1000); + val->intval = DIV_ROUND_CLOSEST(raw * 149197, 200); return 0; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: diff -Nru linux-6.0.6/drivers/regulator/core.c linux-6.0.12/drivers/regulator/core.c --- linux-6.0.6/drivers/regulator/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/regulator/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -5138,6 +5138,7 @@ { struct regulator_dev *rdev = dev_get_drvdata(dev); + debugfs_remove_recursive(rdev->debugfs); kfree(rdev->constraints); of_node_put(rdev->dev.of_node); kfree(rdev); @@ -5616,11 +5617,15 @@ mutex_lock(®ulator_list_mutex); regulator_ena_gpio_free(rdev); mutex_unlock(®ulator_list_mutex); + put_device(&rdev->dev); + rdev = NULL; clean: if (dangling_of_gpiod) gpiod_put(config->ena_gpiod); + if (rdev && rdev->dev.of_node) + of_node_put(rdev->dev.of_node); + kfree(rdev); kfree(config); - put_device(&rdev->dev); rinse: if (dangling_cfg_gpiod) gpiod_put(cfg->ena_gpiod); @@ -5649,7 +5654,6 @@ mutex_lock(®ulator_list_mutex); - debugfs_remove_recursive(rdev->debugfs); WARN_ON(rdev->open_count); regulator_remove_coupling(rdev); unset_regulator_supplies(rdev); diff -Nru linux-6.0.6/drivers/regulator/rt5759-regulator.c linux-6.0.12/drivers/regulator/rt5759-regulator.c --- linux-6.0.6/drivers/regulator/rt5759-regulator.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/regulator/rt5759-regulator.c 2023-01-18 18:27:39.000000000 +0000 @@ -243,6 +243,7 @@ if (priv->chip_type == CHIP_TYPE_RT5759A) reg_desc->uV_step = RT5759A_STEP_UV; + memset(®_cfg, 0, sizeof(reg_cfg)); reg_cfg.dev = priv->dev; reg_cfg.of_node = np; reg_cfg.init_data = of_get_regulator_init_data(priv->dev, np, reg_desc); diff -Nru linux-6.0.6/drivers/regulator/twl6030-regulator.c linux-6.0.12/drivers/regulator/twl6030-regulator.c --- linux-6.0.6/drivers/regulator/twl6030-regulator.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/regulator/twl6030-regulator.c 2023-01-18 18:27:39.000000000 +0000 @@ -530,6 +530,7 @@ #define TWL6032_ADJUSTABLE_LDO(label, offset) \ static const struct twlreg_info TWL6032_INFO_##label = { \ .base = offset, \ + .features = TWL6032_SUBCLASS, \ .desc = { \ .name = #label, \ .id = TWL6032_REG_##label, \ @@ -562,6 +563,7 @@ #define TWL6032_ADJUSTABLE_SMPS(label, offset) \ static const struct twlreg_info TWLSMPS_INFO_##label = { \ .base = offset, \ + .features = TWL6032_SUBCLASS, \ .desc = { \ .name = #label, \ .id = TWL6032_REG_##label, \ diff -Nru linux-6.0.6/drivers/s390/block/dasd_eckd.c linux-6.0.12/drivers/s390/block/dasd_eckd.c --- linux-6.0.6/drivers/s390/block/dasd_eckd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/s390/block/dasd_eckd.c 2023-01-18 18:27:39.000000000 +0000 @@ -4681,7 +4681,6 @@ struct dasd_device *basedev; struct req_iterator iter; struct dasd_ccw_req *cqr; - unsigned int first_offs; unsigned int trkcount; unsigned long *idaws; unsigned int size; @@ -4715,7 +4714,6 @@ last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) / DASD_RAW_SECTORS_PER_TRACK; trkcount = last_trk - first_trk + 1; - first_offs = 0; if (rq_data_dir(req) == READ) cmd = DASD_ECKD_CCW_READ_TRACK; @@ -4759,13 +4757,13 @@ if (use_prefix) { prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev, - startdev, 1, first_offs + 1, trkcount, 0, 0); + startdev, 1, 0, trkcount, 0, 0); } else { define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0); ccw[-1].flags |= CCW_FLAG_CC; data += sizeof(struct DE_eckd_data); - locate_record_ext(ccw++, data, first_trk, first_offs + 1, + locate_record_ext(ccw++, data, first_trk, 0, trkcount, cmd, basedev, 0, 0); } diff -Nru linux-6.0.6/drivers/s390/block/dcssblk.c linux-6.0.12/drivers/s390/block/dcssblk.c --- linux-6.0.6/drivers/s390/block/dcssblk.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/s390/block/dcssblk.c 2023-01-18 18:27:39.000000000 +0000 @@ -636,6 +636,7 @@ dev_info->gd->minors = DCSSBLK_MINORS_PER_DISK; dev_info->gd->fops = &dcssblk_devops; dev_info->gd->private_data = dev_info; + dev_info->gd->flags |= GENHD_FL_NO_PART; blk_queue_logical_block_size(dev_info->gd->queue, 4096); blk_queue_flag_set(QUEUE_FLAG_DAX, dev_info->gd->queue); diff -Nru linux-6.0.6/drivers/s390/cio/css.c linux-6.0.12/drivers/s390/cio/css.c --- linux-6.0.6/drivers/s390/cio/css.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/s390/cio/css.c 2023-01-18 18:27:39.000000000 +0000 @@ -753,13 +753,9 @@ { struct idset *set = data; struct subchannel *sch = to_subchannel(dev); - struct ccw_device *cdev; - if (sch->st == SUBCHANNEL_TYPE_IO) { - cdev = sch_get_cdev(sch); - if (cdev && cdev->online) - idset_sch_del(set, sch->schid); - } + if (sch->st == SUBCHANNEL_TYPE_IO && sch->config.ena) + idset_sch_del(set, sch->schid); return 0; } diff -Nru linux-6.0.6/drivers/s390/crypto/ap_bus.c linux-6.0.12/drivers/s390/crypto/ap_bus.c --- linux-6.0.6/drivers/s390/crypto/ap_bus.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/s390/crypto/ap_bus.c 2023-01-18 18:27:39.000000000 +0000 @@ -233,8 +233,11 @@ if (!ap_qci_info) return; ap_qci_info_old = kzalloc(sizeof(*ap_qci_info_old), GFP_KERNEL); - if (!ap_qci_info_old) + if (!ap_qci_info_old) { + kfree(ap_qci_info); + ap_qci_info = NULL; return; + } if (ap_fetch_qci_info(ap_qci_info) != 0) { kfree(ap_qci_info); kfree(ap_qci_info_old); diff -Nru linux-6.0.6/drivers/s390/crypto/zcrypt_msgtype6.c linux-6.0.12/drivers/s390/crypto/zcrypt_msgtype6.c --- linux-6.0.6/drivers/s390/crypto/zcrypt_msgtype6.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/s390/crypto/zcrypt_msgtype6.c 2023-01-18 18:27:39.000000000 +0000 @@ -342,7 +342,10 @@ }; struct { struct type6_hdr hdr; - struct CPRBX cprbx; + union { + struct CPRBX cprbx; + DECLARE_FLEX_ARRAY(u8, userdata); + }; } __packed * msg = ap_msg->msg; int rcblen = CEIL4(xcrb->request_control_blk_length); @@ -403,7 +406,8 @@ msg->hdr.fromcardlen2 = xcrb->reply_data_length; /* prepare CPRB */ - if (z_copy_from_user(userspace, &msg->cprbx, xcrb->request_control_blk_addr, + if (z_copy_from_user(userspace, msg->userdata, + xcrb->request_control_blk_addr, xcrb->request_control_blk_length)) return -EFAULT; if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > @@ -469,9 +473,14 @@ struct { struct type6_hdr hdr; - struct ep11_cprb cprbx; - unsigned char pld_tag; /* fixed value 0x30 */ - unsigned char pld_lenfmt; /* payload length format */ + union { + struct { + struct ep11_cprb cprbx; + unsigned char pld_tag; /* fixed value 0x30 */ + unsigned char pld_lenfmt; /* length format */ + } __packed; + DECLARE_FLEX_ARRAY(u8, userdata); + }; } __packed * msg = ap_msg->msg; struct pld_hdr { @@ -500,7 +509,7 @@ msg->hdr.fromcardlen1 = xcrb->resp_len; /* Import CPRB data from the ioctl input parameter */ - if (z_copy_from_user(userspace, &msg->cprbx.cprb_len, + if (z_copy_from_user(userspace, msg->userdata, (char __force __user *)xcrb->req, xcrb->req_len)) { return -EFAULT; } diff -Nru linux-6.0.6/drivers/s390/scsi/zfcp_fsf.c linux-6.0.12/drivers/s390/scsi/zfcp_fsf.c --- linux-6.0.6/drivers/s390/scsi/zfcp_fsf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/s390/scsi/zfcp_fsf.c 2023-01-18 18:27:39.000000000 +0000 @@ -884,7 +884,7 @@ const bool is_srb = zfcp_fsf_req_is_status_read_buffer(req); struct zfcp_adapter *adapter = req->adapter; struct zfcp_qdio *qdio = adapter->qdio; - int req_id = req->req_id; + unsigned long req_id = req->req_id; zfcp_reqlist_add(adapter->req_list, req); diff -Nru linux-6.0.6/drivers/scsi/ibmvscsi/ibmvfc.c linux-6.0.12/drivers/scsi/ibmvscsi/ibmvfc.c --- linux-6.0.6/drivers/scsi/ibmvscsi/ibmvfc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/scsi/ibmvscsi/ibmvfc.c 2023-01-18 18:27:39.000000000 +0000 @@ -708,8 +708,13 @@ memset(vhost->async_crq.msgs.async, 0, PAGE_SIZE); vhost->async_crq.cur = 0; - list_for_each_entry(tgt, &vhost->targets, queue) - ibmvfc_del_tgt(tgt); + list_for_each_entry(tgt, &vhost->targets, queue) { + if (vhost->client_migrated) + tgt->need_login = 1; + else + ibmvfc_del_tgt(tgt); + } + scsi_block_requests(vhost->host); ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT); vhost->job_step = ibmvfc_npiv_login; @@ -3235,9 +3240,12 @@ /* We need to re-setup the interpartition connection */ dev_info(vhost->dev, "Partition migrated, Re-enabling adapter\n"); vhost->client_migrated = 1; + + scsi_block_requests(vhost->host); ibmvfc_purge_requests(vhost, DID_REQUEUE); - ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN); + ibmvfc_set_host_state(vhost, IBMVFC_LINK_DOWN); ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_REENABLE); + wake_up(&vhost->work_wait_q); } else if (crq->format == IBMVFC_PARTNER_FAILED || crq->format == IBMVFC_PARTNER_DEREGISTER) { dev_err(vhost->dev, "Host partner adapter deregistered or failed (rc=%d)\n", crq->format); ibmvfc_purge_requests(vhost, DID_ERROR); diff -Nru linux-6.0.6/drivers/scsi/mpi3mr/mpi3mr_os.c linux-6.0.12/drivers/scsi/mpi3mr/mpi3mr_os.c --- linux-6.0.6/drivers/scsi/mpi3mr/mpi3mr_os.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/scsi/mpi3mr/mpi3mr_os.c 2023-01-18 18:27:39.000000000 +0000 @@ -2930,7 +2930,8 @@ } if (scmd->result != (DID_OK << 16) && (scmd->cmnd[0] != ATA_12) && - (scmd->cmnd[0] != ATA_16)) { + (scmd->cmnd[0] != ATA_16) && + mrioc->logging_level & MPI3_DEBUG_SCSI_ERROR) { ioc_info(mrioc, "%s :scmd->result 0x%x\n", __func__, scmd->result); scsi_print_command(scmd); diff -Nru linux-6.0.6/drivers/scsi/qla2xxx/qla_attr.c linux-6.0.12/drivers/scsi/qla2xxx/qla_attr.c --- linux-6.0.6/drivers/scsi/qla2xxx/qla_attr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/scsi/qla2xxx/qla_attr.c 2023-01-18 18:27:39.000000000 +0000 @@ -3330,11 +3330,34 @@ .bsg_timeout = qla24xx_bsg_timeout, }; +static uint +qla2x00_get_host_supported_speeds(scsi_qla_host_t *vha, uint speeds) +{ + uint supported_speeds = FC_PORTSPEED_UNKNOWN; + + if (speeds & FDMI_PORT_SPEED_64GB) + supported_speeds |= FC_PORTSPEED_64GBIT; + if (speeds & FDMI_PORT_SPEED_32GB) + supported_speeds |= FC_PORTSPEED_32GBIT; + if (speeds & FDMI_PORT_SPEED_16GB) + supported_speeds |= FC_PORTSPEED_16GBIT; + if (speeds & FDMI_PORT_SPEED_8GB) + supported_speeds |= FC_PORTSPEED_8GBIT; + if (speeds & FDMI_PORT_SPEED_4GB) + supported_speeds |= FC_PORTSPEED_4GBIT; + if (speeds & FDMI_PORT_SPEED_2GB) + supported_speeds |= FC_PORTSPEED_2GBIT; + if (speeds & FDMI_PORT_SPEED_1GB) + supported_speeds |= FC_PORTSPEED_1GBIT; + + return supported_speeds; +} + void qla2x00_init_host_attr(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; - u32 speeds = FC_PORTSPEED_UNKNOWN; + u32 speeds = 0, fdmi_speed = 0; fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count; fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); @@ -3344,7 +3367,8 @@ fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; - speeds = qla25xx_fdmi_port_speed_capability(ha); + fdmi_speed = qla25xx_fdmi_port_speed_capability(ha); + speeds = qla2x00_get_host_supported_speeds(vha, fdmi_speed); fc_host_supported_speeds(vha->host) = speeds; } diff -Nru linux-6.0.6/drivers/scsi/scsi_debug.c linux-6.0.12/drivers/scsi/scsi_debug.c --- linux-6.0.6/drivers/scsi/scsi_debug.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/scsi/scsi_debug.c 2023-01-18 18:27:39.000000000 +0000 @@ -1899,6 +1899,13 @@ arr[14] |= 0x40; } + /* + * Since the scsi_debug READ CAPACITY implementation always reports the + * total disk capacity, set RC BASIS = 1 for host-managed ZBC devices. + */ + if (devip->zmodel == BLK_ZONED_HM) + arr[12] |= 1 << 4; + arr[15] = sdebug_lowest_aligned & 0xff; if (have_dif_prot) { @@ -7316,8 +7323,12 @@ dev_set_name(&sdbg_host->dev, "adapter%d", sdebug_num_hosts); error = device_register(&sdbg_host->dev); - if (error) + if (error) { + spin_lock(&sdebug_host_list_lock); + list_del(&sdbg_host->host_list); + spin_unlock(&sdebug_host_list_lock); goto clean; + } ++sdebug_num_hosts; return 0; diff -Nru linux-6.0.6/drivers/scsi/scsi_sysfs.c linux-6.0.12/drivers/scsi/scsi_sysfs.c --- linux-6.0.6/drivers/scsi/scsi_sysfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/scsi/scsi_sysfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -828,6 +828,14 @@ } mutex_lock(&sdev->state_mutex); + switch (sdev->sdev_state) { + case SDEV_RUNNING: + case SDEV_OFFLINE: + break; + default: + mutex_unlock(&sdev->state_mutex); + return -EINVAL; + } if (sdev->sdev_state == SDEV_RUNNING && state == SDEV_RUNNING) { ret = 0; } else { diff -Nru linux-6.0.6/drivers/scsi/scsi_transport_iscsi.c linux-6.0.12/drivers/scsi/scsi_transport_iscsi.c --- linux-6.0.6/drivers/scsi/scsi_transport_iscsi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/scsi/scsi_transport_iscsi.c 2023-01-18 18:27:39.000000000 +0000 @@ -231,7 +231,7 @@ dev_set_name(&ep->dev, "ep-%d", id); err = device_register(&ep->dev); if (err) - goto free_id; + goto put_dev; err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group); if (err) @@ -245,10 +245,12 @@ device_unregister(&ep->dev); return NULL; -free_id: +put_dev: mutex_lock(&iscsi_ep_idr_mutex); idr_remove(&iscsi_ep_idr, id); mutex_unlock(&iscsi_ep_idr_mutex); + put_device(&ep->dev); + return NULL; free_ep: kfree(ep); return NULL; @@ -766,7 +768,7 @@ err = device_register(&iface->dev); if (err) - goto free_iface; + goto put_dev; err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group); if (err) @@ -780,9 +782,8 @@ device_unregister(&iface->dev); return NULL; -free_iface: - put_device(iface->dev.parent); - kfree(iface); +put_dev: + put_device(&iface->dev); return NULL; } EXPORT_SYMBOL_GPL(iscsi_create_iface); @@ -1251,15 +1252,15 @@ err = device_register(&fnode_sess->dev); if (err) - goto free_fnode_sess; + goto put_dev; if (dd_size) fnode_sess->dd_data = &fnode_sess[1]; return fnode_sess; -free_fnode_sess: - kfree(fnode_sess); +put_dev: + put_device(&fnode_sess->dev); return NULL; } EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess); @@ -1299,15 +1300,15 @@ err = device_register(&fnode_conn->dev); if (err) - goto free_fnode_conn; + goto put_dev; if (dd_size) fnode_conn->dd_data = &fnode_conn[1]; return fnode_conn; -free_fnode_conn: - kfree(fnode_conn); +put_dev: + put_device(&fnode_conn->dev); return NULL; } EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn); @@ -4815,7 +4816,7 @@ dev_set_name(&priv->dev, "%s", tt->name); err = device_register(&priv->dev); if (err) - goto free_priv; + goto put_dev; err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group); if (err) @@ -4850,8 +4851,8 @@ unregister_dev: device_unregister(&priv->dev); return NULL; -free_priv: - kfree(priv); +put_dev: + put_device(&priv->dev); return NULL; } EXPORT_SYMBOL_GPL(iscsi_register_transport); diff -Nru linux-6.0.6/drivers/scsi/scsi_transport_sas.c linux-6.0.12/drivers/scsi/scsi_transport_sas.c --- linux-6.0.6/drivers/scsi/scsi_transport_sas.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/scsi/scsi_transport_sas.c 2023-01-18 18:27:39.000000000 +0000 @@ -722,12 +722,17 @@ int error; error = device_add(&phy->dev); - if (!error) { - transport_add_device(&phy->dev); - transport_configure_device(&phy->dev); + if (error) + return error; + + error = transport_add_device(&phy->dev); + if (error) { + device_del(&phy->dev); + return error; } + transport_configure_device(&phy->dev); - return error; + return 0; } EXPORT_SYMBOL(sas_phy_add); diff -Nru linux-6.0.6/drivers/scsi/storvsc_drv.c linux-6.0.12/drivers/scsi/storvsc_drv.c --- linux-6.0.6/drivers/scsi/storvsc_drv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/scsi/storvsc_drv.c 2023-01-18 18:27:39.000000000 +0000 @@ -300,16 +300,21 @@ }; /* - * SRB status codes and masks; a subset of the codes used here. + * SRB status codes and masks. In the 8-bit field, the two high order bits + * are flags, while the remaining 6 bits are an integer status code. The + * definitions here include only the subset of the integer status codes that + * are tested for in this driver. */ - #define SRB_STATUS_AUTOSENSE_VALID 0x80 #define SRB_STATUS_QUEUE_FROZEN 0x40 -#define SRB_STATUS_INVALID_LUN 0x20 -#define SRB_STATUS_SUCCESS 0x01 -#define SRB_STATUS_ABORTED 0x02 -#define SRB_STATUS_ERROR 0x04 -#define SRB_STATUS_DATA_OVERRUN 0x12 + +/* SRB status integer codes */ +#define SRB_STATUS_SUCCESS 0x01 +#define SRB_STATUS_ABORTED 0x02 +#define SRB_STATUS_ERROR 0x04 +#define SRB_STATUS_INVALID_REQUEST 0x06 +#define SRB_STATUS_DATA_OVERRUN 0x12 +#define SRB_STATUS_INVALID_LUN 0x20 #define SRB_STATUS(status) \ (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN)) @@ -966,38 +971,25 @@ void (*process_err_fn)(struct work_struct *work); struct hv_host_device *host_dev = shost_priv(host); - /* - * In some situations, Hyper-V sets multiple bits in the - * srb_status, such as ABORTED and ERROR. So process them - * individually, with the most specific bits first. - */ + switch (SRB_STATUS(vm_srb->srb_status)) { + case SRB_STATUS_ERROR: + case SRB_STATUS_ABORTED: + case SRB_STATUS_INVALID_REQUEST: + if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) { + /* Check for capacity change */ + if ((asc == 0x2a) && (ascq == 0x9)) { + process_err_fn = storvsc_device_scan; + /* Retry the I/O that triggered this. */ + set_host_byte(scmnd, DID_REQUEUE); + goto do_work; + } - if (vm_srb->srb_status & SRB_STATUS_INVALID_LUN) { - set_host_byte(scmnd, DID_NO_CONNECT); - process_err_fn = storvsc_remove_lun; - goto do_work; - } - - if (vm_srb->srb_status & SRB_STATUS_ABORTED) { - if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID && - /* Capacity data has changed */ - (asc == 0x2a) && (ascq == 0x9)) { - process_err_fn = storvsc_device_scan; /* - * Retry the I/O that triggered this. + * Otherwise, let upper layer deal with the + * error when sense message is present */ - set_host_byte(scmnd, DID_REQUEUE); - goto do_work; - } - } - - if (vm_srb->srb_status & SRB_STATUS_ERROR) { - /* - * Let upper layer deal with error when - * sense message is present. - */ - if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) return; + } /* * If there is an error; offline the device since all @@ -1020,6 +1012,13 @@ default: set_host_byte(scmnd, DID_ERROR); } + return; + + case SRB_STATUS_INVALID_LUN: + set_host_byte(scmnd, DID_NO_CONNECT); + process_err_fn = storvsc_remove_lun; + goto do_work; + } return; diff -Nru linux-6.0.6/drivers/siox/siox-core.c linux-6.0.12/drivers/siox/siox-core.c --- linux-6.0.6/drivers/siox/siox-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/siox/siox-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -839,6 +839,8 @@ err_device_register: /* don't care to make the buffer smaller again */ + put_device(&sdevice->dev); + sdevice = NULL; err_buf_alloc: siox_master_unlock(smaster); diff -Nru linux-6.0.6/drivers/slimbus/Kconfig linux-6.0.12/drivers/slimbus/Kconfig --- linux-6.0.6/drivers/slimbus/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/slimbus/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -23,7 +23,7 @@ config SLIM_QCOM_NGD_CTRL tristate "Qualcomm SLIMbus Satellite Non-Generic Device Component" depends on HAS_IOMEM && DMA_ENGINE && NET && QCOM_RPROC_COMMON - depends on ARCH_QCOM || COMPILE_TEST + depends on ARCH_QCOM || (COMPILE_TEST && !QCOM_RPROC_COMMON) select QCOM_QMI_HELPERS select QCOM_PDR_HELPERS help diff -Nru linux-6.0.6/drivers/slimbus/stream.c linux-6.0.12/drivers/slimbus/stream.c --- linux-6.0.6/drivers/slimbus/stream.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/slimbus/stream.c 2023-01-18 18:27:39.000000000 +0000 @@ -67,10 +67,10 @@ 384000, 768000, 0, /* Reserved */ - 110250, - 220500, - 441000, - 882000, + 11025, + 22050, + 44100, + 88200, 176400, 352800, 705600, diff -Nru linux-6.0.6/drivers/soc/imx/soc-imx8m.c linux-6.0.12/drivers/soc/imx/soc-imx8m.c --- linux-6.0.6/drivers/soc/imx/soc-imx8m.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/soc/imx/soc-imx8m.c 2023-01-18 18:27:39.000000000 +0000 @@ -11,6 +11,7 @@ #include #include #include +#include #define REV_B1 0x21 @@ -56,6 +57,7 @@ void __iomem *ocotp_base; u32 magic; u32 rev; + struct clk *clk; np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp"); if (!np) @@ -63,6 +65,13 @@ ocotp_base = of_iomap(np, 0); WARN_ON(!ocotp_base); + clk = of_clk_get_by_name(np, NULL); + if (!clk) { + WARN_ON(!clk); + return 0; + } + + clk_prepare_enable(clk); /* * SOC revision on older imx8mq is not available in fuses so query @@ -79,6 +88,8 @@ soc_uid <<= 32; soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW); + clk_disable_unprepare(clk); + clk_put(clk); iounmap(ocotp_base); of_node_put(np); diff -Nru linux-6.0.6/drivers/soundwire/qcom.c linux-6.0.12/drivers/soundwire/qcom.c --- linux-6.0.6/drivers/soundwire/qcom.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/soundwire/qcom.c 2023-01-18 18:27:39.000000000 +0000 @@ -344,6 +344,9 @@ if (swrm_wait_for_wr_fifo_avail(swrm)) return SDW_CMD_FAIL_OTHER; + if (cmd_id == SWR_BROADCAST_CMD_ID) + reinit_completion(&swrm->broadcast); + /* Its assumed that write is okay as we do not get any status back */ swrm->reg_write(swrm, SWRM_CMD_FIFO_WR_CMD, val); @@ -377,6 +380,12 @@ val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr); + /* + * Check for outstanding cmd wrt. write fifo depth to avoid + * overflow as read will also increase write fifo cnt. + */ + swrm_wait_for_wr_fifo_avail(swrm); + /* wait for FIFO RD to complete to avoid overflow */ usleep_range(100, 105); swrm->reg_write(swrm, SWRM_CMD_FIFO_RD_CMD, val); diff -Nru linux-6.0.6/drivers/spi/spi-aspeed-smc.c linux-6.0.12/drivers/spi/spi-aspeed-smc.c --- linux-6.0.6/drivers/spi/spi-aspeed-smc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/spi/spi-aspeed-smc.c 2023-01-18 18:27:39.000000000 +0000 @@ -398,7 +398,7 @@ windows[cs].cs = cs; windows[cs].size = data->segment_end(aspi, reg_val) - data->segment_start(aspi, reg_val); - windows[cs].offset = cs ? windows[cs - 1].offset + windows[cs - 1].size : 0; + windows[cs].offset = data->segment_start(aspi, reg_val) - aspi->ahb_base_phy; dev_vdbg(aspi->dev, "CE%d offset=0x%.8x size=0x%x\n", cs, windows[cs].offset, windows[cs].size); } diff -Nru linux-6.0.6/drivers/spi/spi-dw-dma.c linux-6.0.12/drivers/spi/spi-dw-dma.c --- linux-6.0.6/drivers/spi/spi-dw-dma.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/spi/spi-dw-dma.c 2023-01-18 18:27:39.000000000 +0000 @@ -128,12 +128,15 @@ dw_spi_dma_sg_burst_init(dws); + pci_dev_put(dma_dev); + return 0; free_rxchan: dma_release_channel(dws->rxchan); dws->rxchan = NULL; err_exit: + pci_dev_put(dma_dev); return -EBUSY; } diff -Nru linux-6.0.6/drivers/spi/spi-imx.c linux-6.0.12/drivers/spi/spi-imx.c --- linux-6.0.6/drivers/spi/spi-imx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/spi/spi-imx.c 2023-01-18 18:27:39.000000000 +0000 @@ -444,8 +444,7 @@ unsigned int pre, post; unsigned int fin = spi_imx->spi_clk; - if (unlikely(fspi > fin)) - return 0; + fspi = min(fspi, fin); post = fls(fin) - fls(fspi); if (fin > fspi << post) @@ -1608,6 +1607,13 @@ return spi_imx_pio_transfer_slave(spi, transfer); /* + * If we decided in spi_imx_can_dma() that we want to do a DMA + * transfer, the SPI transfer has already been mapped, so we + * have to do the DMA transfer here. + */ + if (spi_imx->usedma) + return spi_imx_dma_transfer(spi_imx, transfer); + /* * Calculate the estimated time in us the transfer runs. Find * the number of Hz per byte per polling limit. */ @@ -1618,9 +1624,6 @@ if (transfer->len < byte_limit) return spi_imx_poll_transfer(spi, transfer); - if (spi_imx->usedma) - return spi_imx_dma_transfer(spi_imx, transfer); - return spi_imx_pio_transfer(spi, transfer); } diff -Nru linux-6.0.6/drivers/spi/spi-intel.c linux-6.0.12/drivers/spi/spi-intel.c --- linux-6.0.6/drivers/spi/spi-intel.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/spi/spi-intel.c 2023-01-18 18:27:39.000000000 +0000 @@ -52,17 +52,17 @@ #define FRACC 0x50 #define FREG(n) (0x54 + ((n) * 4)) -#define FREG_BASE_MASK 0x3fff +#define FREG_BASE_MASK GENMASK(14, 0) #define FREG_LIMIT_SHIFT 16 -#define FREG_LIMIT_MASK (0x03fff << FREG_LIMIT_SHIFT) +#define FREG_LIMIT_MASK GENMASK(30, 16) /* Offset is from @ispi->pregs */ #define PR(n) ((n) * 4) #define PR_WPE BIT(31) #define PR_LIMIT_SHIFT 16 -#define PR_LIMIT_MASK (0x3fff << PR_LIMIT_SHIFT) +#define PR_LIMIT_MASK GENMASK(30, 16) #define PR_RPE BIT(15) -#define PR_BASE_MASK 0x3fff +#define PR_BASE_MASK GENMASK(14, 0) /* Offsets are from @ispi->sregs */ #define SSFSTS_CTL 0x00 @@ -114,7 +114,7 @@ #define ERASE_OPCODE_SHIFT 8 #define ERASE_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) #define ERASE_64K_OPCODE_SHIFT 16 -#define ERASE_64K_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) +#define ERASE_64K_OPCODE_MASK (0xff << ERASE_64K_OPCODE_SHIFT) #define INTEL_SPI_TIMEOUT 5000 /* ms */ #define INTEL_SPI_FIFO_SZ 64 diff -Nru linux-6.0.6/drivers/spi/spi-mt65xx.c linux-6.0.12/drivers/spi/spi-mt65xx.c --- linux-6.0.6/drivers/spi/spi-mt65xx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/spi/spi-mt65xx.c 2023-01-18 18:27:39.000000000 +0000 @@ -551,14 +551,17 @@ writel(cmd, mdata->base + SPI_CMD_REG); } -static int mtk_spi_get_mult_delta(u32 xfer_len) +static int mtk_spi_get_mult_delta(struct mtk_spi *mdata, u32 xfer_len) { - u32 mult_delta; + u32 mult_delta = 0; - if (xfer_len > MTK_SPI_PACKET_SIZE) - mult_delta = xfer_len % MTK_SPI_PACKET_SIZE; - else - mult_delta = 0; + if (mdata->dev_comp->ipm_design) { + if (xfer_len > MTK_SPI_IPM_PACKET_SIZE) + mult_delta = xfer_len % MTK_SPI_IPM_PACKET_SIZE; + } else { + if (xfer_len > MTK_SPI_PACKET_SIZE) + mult_delta = xfer_len % MTK_SPI_PACKET_SIZE; + } return mult_delta; } @@ -570,22 +573,22 @@ if (mdata->tx_sgl_len && mdata->rx_sgl_len) { if (mdata->tx_sgl_len > mdata->rx_sgl_len) { - mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len); + mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len); mdata->xfer_len = mdata->rx_sgl_len - mult_delta; mdata->rx_sgl_len = mult_delta; mdata->tx_sgl_len -= mdata->xfer_len; } else { - mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len); + mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len); mdata->xfer_len = mdata->tx_sgl_len - mult_delta; mdata->tx_sgl_len = mult_delta; mdata->rx_sgl_len -= mdata->xfer_len; } } else if (mdata->tx_sgl_len) { - mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len); + mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len); mdata->xfer_len = mdata->tx_sgl_len - mult_delta; mdata->tx_sgl_len = mult_delta; } else if (mdata->rx_sgl_len) { - mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len); + mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len); mdata->xfer_len = mdata->rx_sgl_len - mult_delta; mdata->rx_sgl_len = mult_delta; } diff -Nru linux-6.0.6/drivers/spi/spi-qup.c linux-6.0.12/drivers/spi/spi-qup.c --- linux-6.0.6/drivers/spi/spi-qup.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/spi/spi-qup.c 2023-01-18 18:27:39.000000000 +0000 @@ -1057,6 +1057,8 @@ else master->num_chipselect = num_cs; + master->use_gpio_descriptors = true; + master->max_native_cs = SPI_NUM_CHIPSELECTS; master->bus_num = pdev->id; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); diff -Nru linux-6.0.6/drivers/spi/spi-stm32.c linux-6.0.12/drivers/spi/spi-stm32.c --- linux-6.0.6/drivers/spi/spi-stm32.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/spi/spi-stm32.c 2023-01-18 18:27:39.000000000 +0000 @@ -434,7 +434,7 @@ u32 div, mbrdiv; /* Ensure spi->clk_rate is even */ - div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz); + div = DIV_ROUND_CLOSEST(spi->clk_rate & ~0x1, speed_hz); /* * SPI framework set xfer->speed_hz to master->max_speed_hz if @@ -886,6 +886,7 @@ static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL * 10, 1); + ratelimit_set_flags(&rs, RATELIMIT_MSG_ON_RELEASE); if (__ratelimit(&rs)) dev_dbg_ratelimited(spi->dev, "Communication suspended\n"); if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) diff -Nru linux-6.0.6/drivers/spi/spi-tegra210-quad.c linux-6.0.12/drivers/spi/spi-tegra210-quad.c --- linux-6.0.6/drivers/spi/spi-tegra210-quad.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/spi/spi-tegra210-quad.c 2023-01-18 18:27:39.000000000 +0000 @@ -720,6 +720,9 @@ static void tegra_qspi_deinit_dma(struct tegra_qspi *tqspi) { + if (!tqspi->soc_data->has_dma) + return; + if (tqspi->tx_dma_buf) { dma_free_coherent(tqspi->dev, tqspi->dma_buf_size, tqspi->tx_dma_buf, tqspi->tx_dma_phys); @@ -750,6 +753,9 @@ u32 *dma_buf; int err; + if (!tqspi->soc_data->has_dma) + return 0; + dma_chan = dma_request_chan(tqspi->dev, "rx"); if (IS_ERR(dma_chan)) { err = PTR_ERR(dma_chan); @@ -918,8 +924,9 @@ static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_device *spi) { struct tegra_qspi_client_data *cdata; + struct tegra_qspi *tqspi = spi_master_get_devdata(spi->master); - cdata = devm_kzalloc(&spi->dev, sizeof(*cdata), GFP_KERNEL); + cdata = devm_kzalloc(tqspi->dev, sizeof(*cdata), GFP_KERNEL); if (!cdata) return NULL; @@ -1157,6 +1164,11 @@ msg->actual_length += xfer->len; transfer_phase++; } + if (!xfer->cs_change) { + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); + } + ret = 0; exit: msg->status = ret; diff -Nru linux-6.0.6/drivers/staging/media/atomisp/pci/sh_css_params.c linux-6.0.12/drivers/staging/media/atomisp/pci/sh_css_params.c --- linux-6.0.6/drivers/staging/media/atomisp/pci/sh_css_params.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/staging/media/atomisp/pci/sh_css_params.c 2023-01-18 18:27:39.000000000 +0000 @@ -950,8 +950,8 @@ params->fpn_config.data = NULL; } if (!params->fpn_config.data) { - params->fpn_config.data = kvmalloc(height * width * - sizeof(short), GFP_KERNEL); + params->fpn_config.data = kvmalloc(array3_size(height, width, sizeof(short)), + GFP_KERNEL); if (!params->fpn_config.data) { IA_CSS_ERROR("out of memory"); IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM); diff -Nru linux-6.0.6/drivers/staging/media/hantro/hantro_drv.c linux-6.0.12/drivers/staging/media/hantro/hantro_drv.c --- linux-6.0.6/drivers/staging/media/hantro/hantro_drv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/staging/media/hantro/hantro_drv.c 2023-01-18 18:27:39.000000000 +0000 @@ -251,6 +251,11 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) { + struct hantro_ctx *ctx; + + ctx = container_of(ctrl->handler, + struct hantro_ctx, ctrl_handler); + if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) { const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps; @@ -272,6 +277,8 @@ if (sps->bit_depth_luma_minus8 != 0) /* Only 8-bit is supported */ return -EINVAL; + + ctx->bit_depth = sps->bit_depth_luma_minus8 + 8; } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) { const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame; diff -Nru linux-6.0.6/drivers/staging/media/hantro/hantro_g2_hevc_dec.c linux-6.0.12/drivers/staging/media/hantro/hantro_g2_hevc_dec.c --- linux-6.0.6/drivers/staging/media/hantro/hantro_g2_hevc_dec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/staging/media/hantro/hantro_g2_hevc_dec.c 2023-01-18 18:27:39.000000000 +0000 @@ -12,7 +12,7 @@ static size_t hantro_hevc_chroma_offset(struct hantro_ctx *ctx) { - return ctx->dst_fmt.width * ctx->dst_fmt.height; + return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8; } static size_t hantro_hevc_motion_vectors_offset(struct hantro_ctx *ctx) diff -Nru linux-6.0.6/drivers/staging/media/hantro/hantro_hevc.c linux-6.0.12/drivers/staging/media/hantro/hantro_hevc.c --- linux-6.0.6/drivers/staging/media/hantro/hantro_hevc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/staging/media/hantro/hantro_hevc.c 2023-01-18 18:27:39.000000000 +0000 @@ -104,7 +104,7 @@ hevc_dec->tile_bsd.cpu = NULL; } - size = VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1); + size = (VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8; hevc_dec->tile_filter.cpu = dma_alloc_coherent(vpu->dev, size, &hevc_dec->tile_filter.dma, GFP_KERNEL); @@ -112,7 +112,7 @@ goto err_free_tile_buffers; hevc_dec->tile_filter.size = size; - size = VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1); + size = (VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8; hevc_dec->tile_sao.cpu = dma_alloc_coherent(vpu->dev, size, &hevc_dec->tile_sao.dma, GFP_KERNEL); diff -Nru linux-6.0.6/drivers/staging/media/meson/vdec/vdec.c linux-6.0.12/drivers/staging/media/meson/vdec/vdec.c --- linux-6.0.6/drivers/staging/media/meson/vdec/vdec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/staging/media/meson/vdec/vdec.c 2023-01-18 18:27:39.000000000 +0000 @@ -1102,6 +1102,7 @@ err_vdev_release: video_device_release(vdev); + v4l2_device_unregister(&core->v4l2_dev); return ret; } @@ -1110,6 +1111,7 @@ struct amvdec_core *core = platform_get_drvdata(pdev); video_unregister_device(core->vdev_dec); + v4l2_device_unregister(&core->v4l2_dev); return 0; } diff -Nru linux-6.0.6/drivers/staging/media/sunxi/cedrus/Kconfig linux-6.0.12/drivers/staging/media/sunxi/cedrus/Kconfig --- linux-6.0.6/drivers/staging/media/sunxi/cedrus/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/staging/media/sunxi/cedrus/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -2,6 +2,7 @@ config VIDEO_SUNXI_CEDRUS tristate "Allwinner Cedrus VPU driver" depends on VIDEO_DEV + depends on RESET_CONTROLLER depends on HAS_DMA depends on OF select MEDIA_CONTROLLER diff -Nru linux-6.0.6/drivers/target/loopback/tcm_loop.c linux-6.0.12/drivers/target/loopback/tcm_loop.c --- linux-6.0.6/drivers/target/loopback/tcm_loop.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/target/loopback/tcm_loop.c 2023-01-18 18:27:39.000000000 +0000 @@ -397,6 +397,7 @@ ret = device_register(&tl_hba->dev); if (ret) { pr_err("device_register() failed for tl_hba->dev: %d\n", ret); + put_device(&tl_hba->dev); return -ENODEV; } @@ -1073,7 +1074,7 @@ */ ret = tcm_loop_setup_hba_bus(tl_hba, tcm_loop_hba_no_cnt); if (ret) - goto out; + return ERR_PTR(ret); sh = tl_hba->sh; tcm_loop_hba_no_cnt++; diff -Nru linux-6.0.6/drivers/tee/optee/device.c linux-6.0.12/drivers/tee/optee/device.c --- linux-6.0.6/drivers/tee/optee/device.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/tee/optee/device.c 2023-01-18 18:27:39.000000000 +0000 @@ -80,7 +80,7 @@ rc = device_register(&optee_device->dev); if (rc) { pr_err("device registration failed, err: %d\n", rc); - kfree(optee_device); + put_device(&optee_device->dev); } return rc; diff -Nru linux-6.0.6/drivers/thunderbolt/tb.c linux-6.0.12/drivers/thunderbolt/tb.c --- linux-6.0.6/drivers/thunderbolt/tb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/thunderbolt/tb.c 2023-01-18 18:27:39.000000000 +0000 @@ -105,6 +105,32 @@ } } +static void tb_discover_dp_resource(struct tb *tb, struct tb_port *port) +{ + struct tb_cm *tcm = tb_priv(tb); + struct tb_port *p; + + list_for_each_entry(p, &tcm->dp_resources, list) { + if (p == port) + return; + } + + tb_port_dbg(port, "DP %s resource available discovered\n", + tb_port_is_dpin(port) ? "IN" : "OUT"); + list_add_tail(&port->list, &tcm->dp_resources); +} + +static void tb_discover_dp_resources(struct tb *tb) +{ + struct tb_cm *tcm = tb_priv(tb); + struct tb_tunnel *tunnel; + + list_for_each_entry(tunnel, &tcm->tunnel_list, list) { + if (tb_tunnel_is_dp(tunnel)) + tb_discover_dp_resource(tb, tunnel->dst_port); + } +} + static void tb_switch_discover_tunnels(struct tb_switch *sw, struct list_head *list, bool alloc_hopids) @@ -1446,6 +1472,8 @@ tb_scan_switch(tb->root_switch); /* Find out tunnels created by the boot firmware */ tb_discover_tunnels(tb); + /* Add DP resources from the DP tunnels created by the boot firmware */ + tb_discover_dp_resources(tb); /* * If the boot firmware did not create USB 3.x tunnels create them * now for the whole topology. diff -Nru linux-6.0.6/drivers/tty/n_gsm.c linux-6.0.12/drivers/tty/n_gsm.c --- linux-6.0.6/drivers/tty/n_gsm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/tty/n_gsm.c 2023-01-18 18:27:39.000000000 +0000 @@ -248,7 +248,7 @@ bool constipated; /* Asked by remote to shut up */ bool has_devices; /* Devices were registered */ - struct mutex tx_mutex; + spinlock_t tx_lock; unsigned int tx_bytes; /* TX data outstanding */ #define TX_THRESH_HI 8192 #define TX_THRESH_LO 2048 @@ -256,7 +256,7 @@ struct list_head tx_data_list; /* Pending data packets */ /* Control messages */ - struct delayed_work kick_timeout; /* Kick TX queuing on timeout */ + struct timer_list kick_timer; /* Kick TX queuing on timeout */ struct timer_list t2_timer; /* Retransmit timer for commands */ int cretries; /* Command retry counter */ struct gsm_control *pending_cmd;/* Our current pending command */ @@ -680,6 +680,7 @@ struct gsm_msg *msg; u8 *dp; int ocr; + unsigned long flags; msg = gsm_data_alloc(gsm, addr, 0, control); if (!msg) @@ -701,10 +702,10 @@ gsm_print_packet("Q->", addr, cr, control, NULL, 0); - mutex_lock(&gsm->tx_mutex); + spin_lock_irqsave(&gsm->tx_lock, flags); list_add_tail(&msg->list, &gsm->tx_ctrl_list); gsm->tx_bytes += msg->len; - mutex_unlock(&gsm->tx_mutex); + spin_unlock_irqrestore(&gsm->tx_lock, flags); gsmld_write_trigger(gsm); return 0; @@ -729,7 +730,7 @@ spin_unlock_irqrestore(&dlci->lock, flags); /* Clear data packets in MUX write queue */ - mutex_lock(&gsm->tx_mutex); + spin_lock_irqsave(&gsm->tx_lock, flags); list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) { if (msg->addr != addr) continue; @@ -737,7 +738,7 @@ list_del(&msg->list); kfree(msg); } - mutex_unlock(&gsm->tx_mutex); + spin_unlock_irqrestore(&gsm->tx_lock, flags); } /** @@ -1008,7 +1009,7 @@ gsm->tx_bytes += msg->len; gsmld_write_trigger(gsm); - schedule_delayed_work(&gsm->kick_timeout, 10 * gsm->t1 * HZ / 100); + mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100); } /** @@ -1023,9 +1024,10 @@ static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) { - mutex_lock(&dlci->gsm->tx_mutex); + unsigned long flags; + spin_lock_irqsave(&dlci->gsm->tx_lock, flags); __gsm_data_queue(dlci, msg); - mutex_unlock(&dlci->gsm->tx_mutex); + spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags); } /** @@ -1037,7 +1039,7 @@ * is data. Keep to the MRU of the mux. This path handles the usual tty * interface which is a byte stream with optional modem data. * - * Caller must hold the tx_mutex of the mux. + * Caller must hold the tx_lock of the mux. */ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci) @@ -1097,7 +1099,7 @@ * is data. Keep to the MRU of the mux. This path handles framed data * queued as skbuffs to the DLCI. * - * Caller must hold the tx_mutex of the mux. + * Caller must hold the tx_lock of the mux. */ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, @@ -1113,7 +1115,7 @@ if (dlci->adaption == 4) overhead = 1; - /* dlci->skb is locked by tx_mutex */ + /* dlci->skb is locked by tx_lock */ if (dlci->skb == NULL) { dlci->skb = skb_dequeue_tail(&dlci->skb_list); if (dlci->skb == NULL) @@ -1167,7 +1169,7 @@ * Push an empty frame in to the transmit queue to update the modem status * bits and to transmit an optional break. * - * Caller must hold the tx_mutex of the mux. + * Caller must hold the tx_lock of the mux. */ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci, @@ -1281,12 +1283,13 @@ static void gsm_dlci_data_kick(struct gsm_dlci *dlci) { + unsigned long flags; int sweep; if (dlci->constipated) return; - mutex_lock(&dlci->gsm->tx_mutex); + spin_lock_irqsave(&dlci->gsm->tx_lock, flags); /* If we have nothing running then we need to fire up */ sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO); if (dlci->gsm->tx_bytes == 0) { @@ -1297,7 +1300,7 @@ } if (sweep) gsm_dlci_data_sweep(dlci->gsm); - mutex_unlock(&dlci->gsm->tx_mutex); + spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags); } /* @@ -1670,7 +1673,7 @@ unsigned int command, u8 *data, int clen) { struct gsm_control *ctrl = kzalloc(sizeof(struct gsm_control), - GFP_KERNEL); + GFP_ATOMIC); unsigned long flags; if (ctrl == NULL) return NULL; @@ -1981,23 +1984,24 @@ } /** - * gsm_kick_timeout - transmit if possible - * @work: work contained in our gsm object + * gsm_kick_timer - transmit if possible + * @t: timer contained in our gsm object * * Transmit data from DLCIs if the queue is empty. We can't rely on * a tty wakeup except when we filled the pipe so we need to fire off * new data ourselves in other cases. */ -static void gsm_kick_timeout(struct work_struct *work) +static void gsm_kick_timer(struct timer_list *t) { - struct gsm_mux *gsm = container_of(work, struct gsm_mux, kick_timeout.work); + struct gsm_mux *gsm = from_timer(gsm, t, kick_timer); + unsigned long flags; int sent = 0; - mutex_lock(&gsm->tx_mutex); + spin_lock_irqsave(&gsm->tx_lock, flags); /* If we have nothing running then we need to fire up */ if (gsm->tx_bytes < TX_THRESH_LO) sent = gsm_dlci_data_sweep(gsm); - mutex_unlock(&gsm->tx_mutex); + spin_unlock_irqrestore(&gsm->tx_lock, flags); if (sent && debug & 4) pr_info("%s TX queue stalled\n", __func__); @@ -2454,7 +2458,7 @@ } /* Finish outstanding timers, making sure they are done */ - cancel_delayed_work_sync(&gsm->kick_timeout); + del_timer_sync(&gsm->kick_timer); del_timer_sync(&gsm->t2_timer); /* Finish writing to ldisc */ @@ -2527,7 +2531,6 @@ break; } } - mutex_destroy(&gsm->tx_mutex); mutex_destroy(&gsm->mutex); kfree(gsm->txframe); kfree(gsm->buf); @@ -2599,15 +2602,15 @@ } spin_lock_init(&gsm->lock); mutex_init(&gsm->mutex); - mutex_init(&gsm->tx_mutex); kref_init(&gsm->ref); INIT_LIST_HEAD(&gsm->tx_ctrl_list); INIT_LIST_HEAD(&gsm->tx_data_list); - INIT_DELAYED_WORK(&gsm->kick_timeout, gsm_kick_timeout); + timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); INIT_WORK(&gsm->tx_work, gsmld_write_task); init_waitqueue_head(&gsm->event); spin_lock_init(&gsm->control_lock); + spin_lock_init(&gsm->tx_lock); gsm->t1 = T1; gsm->t2 = T2; @@ -2632,7 +2635,6 @@ } spin_unlock(&gsm_mux_lock); if (i == MAX_MUX) { - mutex_destroy(&gsm->tx_mutex); mutex_destroy(&gsm->mutex); kfree(gsm->txframe); kfree(gsm->buf); @@ -2788,16 +2790,17 @@ static void gsmld_write_task(struct work_struct *work) { struct gsm_mux *gsm = container_of(work, struct gsm_mux, tx_work); + unsigned long flags; int i, ret; /* All outstanding control channel and control messages and one data * frame is sent. */ ret = -ENODEV; - mutex_lock(&gsm->tx_mutex); + spin_lock_irqsave(&gsm->tx_lock, flags); if (gsm->tty) ret = gsm_data_kick(gsm); - mutex_unlock(&gsm->tx_mutex); + spin_unlock_irqrestore(&gsm->tx_lock, flags); if (ret >= 0) for (i = 0; i < NUM_DLCI; i++) @@ -3005,6 +3008,7 @@ const unsigned char *buf, size_t nr) { struct gsm_mux *gsm = tty->disc_data; + unsigned long flags; int space; int ret; @@ -3012,13 +3016,13 @@ return -ENODEV; ret = -ENOBUFS; - mutex_lock(&gsm->tx_mutex); + spin_lock_irqsave(&gsm->tx_lock, flags); space = tty_write_room(tty); if (space >= nr) ret = tty->ops->write(tty, buf, nr); else set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - mutex_unlock(&gsm->tx_mutex); + spin_unlock_irqrestore(&gsm->tx_lock, flags); return ret; } @@ -3315,13 +3319,14 @@ static void gsm_modem_upd_via_data(struct gsm_dlci *dlci, u8 brk) { struct gsm_mux *gsm = dlci->gsm; + unsigned long flags; if (dlci->state != DLCI_OPEN || dlci->adaption != 2) return; - mutex_lock(&gsm->tx_mutex); + spin_lock_irqsave(&gsm->tx_lock, flags); gsm_dlci_modem_output(gsm, dlci, brk); - mutex_unlock(&gsm->tx_mutex); + spin_unlock_irqrestore(&gsm->tx_lock, flags); } /** diff -Nru linux-6.0.6/drivers/tty/serial/8250/8250_lpss.c linux-6.0.12/drivers/tty/serial/8250/8250_lpss.c --- linux-6.0.6/drivers/tty/serial/8250/8250_lpss.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/tty/serial/8250/8250_lpss.c 2023-01-18 18:27:39.000000000 +0000 @@ -174,6 +174,8 @@ */ up->dma = dma; + lpss->dma_maxburst = 16; + port->set_termios = dw8250_do_set_termios; return 0; @@ -277,8 +279,13 @@ struct dw_dma_slave *rx_param, *tx_param; struct device *dev = port->port.dev; - if (!lpss->dma_param.dma_dev) + if (!lpss->dma_param.dma_dev) { + dma = port->dma; + if (dma) + goto out_configuration_only; + return 0; + } rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL); if (!rx_param) @@ -289,16 +296,18 @@ return -ENOMEM; *rx_param = lpss->dma_param; - dma->rxconf.src_maxburst = lpss->dma_maxburst; - *tx_param = lpss->dma_param; - dma->txconf.dst_maxburst = lpss->dma_maxburst; dma->fn = lpss8250_dma_filter; dma->rx_param = rx_param; dma->tx_param = tx_param; port->dma = dma; + +out_configuration_only: + dma->rxconf.src_maxburst = lpss->dma_maxburst; + dma->txconf.dst_maxburst = lpss->dma_maxburst; + return 0; } diff -Nru linux-6.0.6/drivers/tty/serial/8250/8250_omap.c linux-6.0.12/drivers/tty/serial/8250/8250_omap.c --- linux-6.0.6/drivers/tty/serial/8250/8250_omap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/tty/serial/8250/8250_omap.c 2023-01-18 18:27:39.000000000 +0000 @@ -157,7 +157,11 @@ return readl(up->port.membase + (reg << up->port.regshift)); } -static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) +/* + * Called on runtime PM resume path from omap8250_restore_regs(), and + * omap8250_set_mctrl(). + */ +static void __omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct uart_8250_port *up = up_to_u8250p(port); struct omap8250_priv *priv = up->port.private_data; @@ -181,6 +185,20 @@ } } +static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + int err; + + err = pm_runtime_resume_and_get(port->dev); + if (err) + return; + + __omap8250_set_mctrl(port, mctrl); + + pm_runtime_mark_last_busy(port->dev); + pm_runtime_put_autosuspend(port->dev); +} + /* * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460) * The access to uart register after MDR1 Access @@ -193,27 +211,10 @@ static void omap_8250_mdr1_errataset(struct uart_8250_port *up, struct omap8250_priv *priv) { - u8 timeout = 255; - serial_out(up, UART_OMAP_MDR1, priv->mdr1); udelay(2); serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); - /* - * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and - * TX_FIFO_E bit is 1. - */ - while (UART_LSR_THRE != (serial_in(up, UART_LSR) & - (UART_LSR_THRE | UART_LSR_DR))) { - timeout--; - if (!timeout) { - /* Should *never* happen. we warn and carry on */ - dev_crit(up->port.dev, "Errata i202: timedout %x\n", - serial_in(up, UART_LSR)); - break; - } - udelay(1); - } } static void omap_8250_get_divisor(struct uart_port *port, unsigned int baud, @@ -292,6 +293,7 @@ { struct omap8250_priv *priv = up->port.private_data; struct uart_8250_dma *dma = up->dma; + u8 mcr = serial8250_in_MCR(up); if (dma && dma->tx_running) { /* @@ -308,7 +310,7 @@ serial_out(up, UART_EFR, UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); - serial8250_out_MCR(up, UART_MCR_TCRTLR); + serial8250_out_MCR(up, mcr | UART_MCR_TCRTLR); serial_out(up, UART_FCR, up->fcr); omap8250_update_scr(up, priv); @@ -324,7 +326,8 @@ serial_out(up, UART_LCR, 0); /* drop TCR + TLR access, we setup XON/XOFF later */ - serial8250_out_MCR(up, up->mcr); + serial8250_out_MCR(up, mcr); + serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); @@ -341,7 +344,7 @@ omap8250_update_mdr1(up, priv); - up->port.ops->set_mctrl(&up->port, up->port.mctrl); + __omap8250_set_mctrl(&up->port, up->port.mctrl); if (up->port.rs485.flags & SER_RS485_ENABLED) serial8250_em485_stop_tx(up); @@ -669,7 +672,6 @@ pm_runtime_get_sync(port->dev); - up->mcr = 0; serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); serial_out(up, UART_LCR, UART_LCR_WLEN8); @@ -1460,9 +1462,15 @@ static int omap8250_remove(struct platform_device *pdev) { struct omap8250_priv *priv = platform_get_drvdata(pdev); + int err; + + err = pm_runtime_resume_and_get(&pdev->dev); + if (err) + return err; pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); + flush_work(&priv->qos_work); pm_runtime_disable(&pdev->dev); serial8250_unregister_port(priv->line); cpu_latency_qos_remove_request(&priv->pm_qos_request); diff -Nru linux-6.0.6/drivers/tty/serial/8250/8250_port.c linux-6.0.12/drivers/tty/serial/8250/8250_port.c --- linux-6.0.6/drivers/tty/serial/8250/8250_port.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/tty/serial/8250/8250_port.c 2023-01-18 18:27:39.000000000 +0000 @@ -1892,10 +1892,13 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir) { switch (iir & 0x3f) { - case UART_IIR_RX_TIMEOUT: - serial8250_rx_dma_flush(up); + case UART_IIR_RDI: + if (!up->dma->rx_running) + break; fallthrough; case UART_IIR_RLSI: + case UART_IIR_RX_TIMEOUT: + serial8250_rx_dma_flush(up); return true; } return up->dma->rx_dma(up); diff -Nru linux-6.0.6/drivers/tty/serial/8250/Kconfig linux-6.0.12/drivers/tty/serial/8250/Kconfig --- linux-6.0.6/drivers/tty/serial/8250/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/tty/serial/8250/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -118,7 +118,7 @@ config SERIAL_8250_GSC tristate - depends on SERIAL_8250 && GSC + depends on SERIAL_8250 && PARISC default SERIAL_8250 config SERIAL_8250_DMA diff -Nru linux-6.0.6/drivers/tty/serial/fsl_lpuart.c linux-6.0.12/drivers/tty/serial/fsl_lpuart.c --- linux-6.0.6/drivers/tty/serial/fsl_lpuart.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/tty/serial/fsl_lpuart.c 2023-01-18 18:27:39.000000000 +0000 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -404,33 +405,6 @@ #define lpuart_enable_clks(x) __lpuart_enable_clks(x, true) #define lpuart_disable_clks(x) __lpuart_enable_clks(x, false) -static int lpuart_global_reset(struct lpuart_port *sport) -{ - struct uart_port *port = &sport->port; - void __iomem *global_addr; - int ret; - - if (uart_console(port)) - return 0; - - ret = clk_prepare_enable(sport->ipg_clk); - if (ret) { - dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret); - return ret; - } - - if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) { - global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF; - writel(UART_GLOBAL_RST, global_addr); - usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); - writel(0, global_addr); - usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); - } - - clk_disable_unprepare(sport->ipg_clk); - return 0; -} - static void lpuart_stop_tx(struct uart_port *port) { unsigned char temp; @@ -2641,6 +2615,54 @@ /* delay_rts_* and RX_DURING_TX are not supported */ }; +static int lpuart_global_reset(struct lpuart_port *sport) +{ + struct uart_port *port = &sport->port; + void __iomem *global_addr; + unsigned long ctrl, bd; + unsigned int val = 0; + int ret; + + ret = clk_prepare_enable(sport->ipg_clk); + if (ret) { + dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret); + return ret; + } + + if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) { + /* + * If the transmitter is used by earlycon, wait for transmit engine to + * complete and then reset. + */ + ctrl = lpuart32_read(port, UARTCTRL); + if (ctrl & UARTCTRL_TE) { + bd = lpuart32_read(&sport->port, UARTBAUD); + if (read_poll_timeout(lpuart32_tx_empty, val, val, 1, 100000, false, + port)) { + dev_warn(sport->port.dev, + "timeout waiting for transmit engine to complete\n"); + clk_disable_unprepare(sport->ipg_clk); + return 0; + } + } + + global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF; + writel(UART_GLOBAL_RST, global_addr); + usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); + writel(0, global_addr); + usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); + + /* Recover the transmitter for earlycon. */ + if (ctrl & UARTCTRL_TE) { + lpuart32_write(port, bd, UARTBAUD); + lpuart32_write(port, ctrl, UARTCTRL); + } + } + + clk_disable_unprepare(sport->ipg_clk); + return 0; +} + static int lpuart_probe(struct platform_device *pdev) { const struct lpuart_soc_data *sdata = of_device_get_match_data(&pdev->dev); diff -Nru linux-6.0.6/drivers/tty/serial/imx.c linux-6.0.12/drivers/tty/serial/imx.c --- linux-6.0.6/drivers/tty/serial/imx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/tty/serial/imx.c 2023-01-18 18:27:39.000000000 +0000 @@ -2594,6 +2594,7 @@ .suspend_noirq = imx_uart_suspend_noirq, .resume_noirq = imx_uart_resume_noirq, .freeze_noirq = imx_uart_suspend_noirq, + .thaw_noirq = imx_uart_resume_noirq, .restore_noirq = imx_uart_resume_noirq, .suspend = imx_uart_suspend, .resume = imx_uart_resume, diff -Nru linux-6.0.6/drivers/usb/cdns3/cdnsp-gadget.c linux-6.0.12/drivers/usb/cdns3/cdnsp-gadget.c --- linux-6.0.6/drivers/usb/cdns3/cdnsp-gadget.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/cdns3/cdnsp-gadget.c 2023-01-18 18:27:39.000000000 +0000 @@ -600,11 +600,11 @@ trace_cdnsp_ep_halt(value ? "Set" : "Clear"); - if (value) { - ret = cdnsp_cmd_stop_ep(pdev, pep); - if (ret) - return ret; + ret = cdnsp_cmd_stop_ep(pdev, pep); + if (ret) + return ret; + if (value) { if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_STOPPED) { cdnsp_queue_halt_endpoint(pdev, pep->idx); cdnsp_ring_cmd_db(pdev); @@ -613,10 +613,6 @@ pep->ep_state |= EP_HALTED; } else { - /* - * In device mode driver can call reset endpoint command - * from any endpoint state. - */ cdnsp_queue_reset_ep(pdev, pep->idx); cdnsp_ring_cmd_db(pdev); ret = cdnsp_wait_for_cmd_compl(pdev); diff -Nru linux-6.0.6/drivers/usb/cdns3/cdnsp-ring.c linux-6.0.12/drivers/usb/cdns3/cdnsp-ring.c --- linux-6.0.6/drivers/usb/cdns3/cdnsp-ring.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/cdns3/cdnsp-ring.c 2023-01-18 18:27:39.000000000 +0000 @@ -1763,10 +1763,15 @@ int trb_buff_len, unsigned int td_total_len, struct cdnsp_request *preq, - bool more_trbs_coming) + bool more_trbs_coming, + bool zlp) { u32 maxp, total_packet_count; + /* Before ZLP driver needs set TD_SIZE = 1. */ + if (zlp) + return 1; + /* One TRB with a zero-length data packet. */ if (!more_trbs_coming || (transferred == 0 && trb_buff_len == 0) || trb_buff_len == td_total_len) @@ -1960,7 +1965,8 @@ /* Set the TRB length, TD size, and interrupter fields. */ remainder = cdnsp_td_remainder(pdev, enqd_len, trb_buff_len, full_len, preq, - more_trbs_coming); + more_trbs_coming, + zero_len_trb); length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0); @@ -2025,7 +2031,7 @@ if (preq->request.length > 0) { remainder = cdnsp_td_remainder(pdev, 0, preq->request.length, - preq->request.length, preq, 1); + preq->request.length, preq, 1, 0); length_field = TRB_LEN(preq->request.length) | TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0); @@ -2076,7 +2082,8 @@ u32 ep_state = GET_EP_CTX_STATE(pep->out_ctx); int ret = 0; - if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED) { + if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED || + ep_state == EP_STATE_HALTED) { trace_cdnsp_ep_stopped_or_disabled(pep->out_ctx); goto ep_stopped; } @@ -2225,7 +2232,7 @@ /* Set the TRB length, TD size, & interrupter fields. */ remainder = cdnsp_td_remainder(pdev, running_total, trb_buff_len, td_len, preq, - more_trbs_coming); + more_trbs_coming, 0); length_field = TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0); diff -Nru linux-6.0.6/drivers/usb/cdns3/host.c linux-6.0.12/drivers/usb/cdns3/host.c --- linux-6.0.6/drivers/usb/cdns3/host.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/cdns3/host.c 2023-01-18 18:27:39.000000000 +0000 @@ -24,11 +24,37 @@ #define CFG_RXDET_P3_EN BIT(15) #define LPM_2_STB_SWITCH_EN BIT(25) -static int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd); +static void xhci_cdns3_plat_start(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + u32 value; + + /* set usbcmd.EU3S */ + value = readl(&xhci->op_regs->command); + value |= CMD_PM_INDEX; + writel(value, &xhci->op_regs->command); + + if (hcd->regs) { + value = readl(hcd->regs + XECP_AUX_CTRL_REG1); + value |= CFG_RXDET_P3_EN; + writel(value, hcd->regs + XECP_AUX_CTRL_REG1); + + value = readl(hcd->regs + XECP_PORT_CAP_REG); + value |= LPM_2_STB_SWITCH_EN; + writel(value, hcd->regs + XECP_PORT_CAP_REG); + } +} + +static int xhci_cdns3_resume_quirk(struct usb_hcd *hcd) +{ + xhci_cdns3_plat_start(hcd); + return 0; +} static const struct xhci_plat_priv xhci_plat_cdns3_xhci = { .quirks = XHCI_SKIP_PHY_INIT | XHCI_AVOID_BEI, - .suspend_quirk = xhci_cdns3_suspend_quirk, + .plat_start = xhci_cdns3_plat_start, + .resume_quirk = xhci_cdns3_resume_quirk, }; static int __cdns_host_init(struct cdns *cdns) @@ -90,32 +116,6 @@ return ret; } -static int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - u32 value; - - if (pm_runtime_status_suspended(hcd->self.controller)) - return 0; - - /* set usbcmd.EU3S */ - value = readl(&xhci->op_regs->command); - value |= CMD_PM_INDEX; - writel(value, &xhci->op_regs->command); - - if (hcd->regs) { - value = readl(hcd->regs + XECP_AUX_CTRL_REG1); - value |= CFG_RXDET_P3_EN; - writel(value, hcd->regs + XECP_AUX_CTRL_REG1); - - value = readl(hcd->regs + XECP_PORT_CAP_REG); - value |= LPM_2_STB_SWITCH_EN; - writel(value, hcd->regs + XECP_PORT_CAP_REG); - } - - return 0; -} - static void cdns_host_exit(struct cdns *cdns) { kfree(cdns->xhci_plat_data); diff -Nru linux-6.0.6/drivers/usb/chipidea/otg_fsm.c linux-6.0.12/drivers/usb/chipidea/otg_fsm.c --- linux-6.0.6/drivers/usb/chipidea/otg_fsm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/chipidea/otg_fsm.c 2023-01-18 18:27:39.000000000 +0000 @@ -256,8 +256,10 @@ ci->enabled_otg_timer_bits &= ~(1 << t); if (ci->next_otg_timer == t) { if (ci->enabled_otg_timer_bits == 0) { + spin_unlock_irqrestore(&ci->lock, flags); /* No enabled timers after delete it */ hrtimer_cancel(&ci->otg_fsm_hrtimer); + spin_lock_irqsave(&ci->lock, flags); ci->next_otg_timer = NUM_OTG_FSM_TIMERS; } else { /* Find the next timer */ diff -Nru linux-6.0.6/drivers/usb/core/quirks.c linux-6.0.12/drivers/usb/core/quirks.c --- linux-6.0.6/drivers/usb/core/quirks.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/core/quirks.c 2023-01-18 18:27:39.000000000 +0000 @@ -362,6 +362,9 @@ { USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM }, { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, + /* Realforce 87U Keyboard */ + { USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM }, + /* M-Systems Flash Disk Pioneers */ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, @@ -388,6 +391,15 @@ /* Kingston DataTraveler 3.0 */ { USB_DEVICE(0x0951, 0x1666), .driver_info = USB_QUIRK_NO_LPM }, + /* NVIDIA Jetson devices in Force Recovery mode */ + { USB_DEVICE(0x0955, 0x7018), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x0955, 0x7019), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x0955, 0x7418), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x0955, 0x7721), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x0955, 0x7c18), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x0955, 0x7e19), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x0955, 0x7f21), .driver_info = USB_QUIRK_RESET_RESUME }, + /* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */ { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF }, diff -Nru linux-6.0.6/drivers/usb/dwc3/core.c linux-6.0.12/drivers/usb/dwc3/core.c --- linux-6.0.6/drivers/usb/dwc3/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/dwc3/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -85,7 +86,7 @@ * mode. If the controller supports DRD but the dr_mode is not * specified or set to OTG, then set the mode to peripheral. */ - if (mode == USB_DR_MODE_OTG && + if (mode == USB_DR_MODE_OTG && !dwc->edev && (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) || !device_property_read_bool(dwc->dev, "usb-role-switch")) && !DWC3_VER_IS_PRIOR(DWC3, 330A)) @@ -1690,6 +1691,56 @@ } } +static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc) +{ + struct device *dev = dwc->dev; + struct device_node *np_phy; + struct extcon_dev *edev = NULL; + const char *name; + + if (device_property_read_bool(dev, "extcon")) + return extcon_get_edev_by_phandle(dev, 0); + + /* + * Device tree platforms should get extcon via phandle. + * On ACPI platforms, we get the name from a device property. + * This device property is for kernel internal use only and + * is expected to be set by the glue code. + */ + if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) + return extcon_get_extcon_dev(name); + + /* + * Check explicitly if "usb-role-switch" is used since + * extcon_find_edev_by_node() can not be used to check the absence of + * an extcon device. In the absence of an device it will always return + * EPROBE_DEFER. + */ + if (IS_ENABLED(CONFIG_USB_ROLE_SWITCH) && + device_property_read_bool(dev, "usb-role-switch")) + return NULL; + + /* + * Try to get an extcon device from the USB PHY controller's "port" + * node. Check if it has the "port" node first, to avoid printing the + * error message from underlying code, as it's a valid case: extcon + * device (and "port" node) may be missing in case of "usb-role-switch" + * or OTG mode. + */ + np_phy = of_parse_phandle(dev->of_node, "phys", 0); + if (of_graph_is_present(np_phy)) { + struct device_node *np_conn; + + np_conn = of_graph_get_remote_node(np_phy, -1, -1); + if (np_conn) + edev = extcon_find_edev_by_node(np_conn); + of_node_put(np_conn); + } + of_node_put(np_phy); + + return edev; +} + static int dwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1840,6 +1891,12 @@ goto err2; } + dwc->edev = dwc3_get_extcon(dwc); + if (IS_ERR(dwc->edev)) { + ret = dev_err_probe(dwc->dev, PTR_ERR(dwc->edev), "failed to get extcon\n"); + goto err3; + } + ret = dwc3_get_dr_mode(dwc); if (ret) goto err3; diff -Nru linux-6.0.6/drivers/usb/dwc3/drd.c linux-6.0.12/drivers/usb/dwc3/drd.c --- linux-6.0.6/drivers/usb/dwc3/drd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/dwc3/drd.c 2023-01-18 18:27:39.000000000 +0000 @@ -8,7 +8,6 @@ */ #include -#include #include #include #include @@ -439,51 +438,6 @@ return NOTIFY_DONE; } -static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc) -{ - struct device *dev = dwc->dev; - struct device_node *np_phy; - struct extcon_dev *edev = NULL; - const char *name; - - if (device_property_read_bool(dev, "extcon")) - return extcon_get_edev_by_phandle(dev, 0); - - /* - * Device tree platforms should get extcon via phandle. - * On ACPI platforms, we get the name from a device property. - * This device property is for kernel internal use only and - * is expected to be set by the glue code. - */ - if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) { - edev = extcon_get_extcon_dev(name); - if (!edev) - return ERR_PTR(-EPROBE_DEFER); - - return edev; - } - - /* - * Try to get an extcon device from the USB PHY controller's "port" - * node. Check if it has the "port" node first, to avoid printing the - * error message from underlying code, as it's a valid case: extcon - * device (and "port" node) may be missing in case of "usb-role-switch" - * or OTG mode. - */ - np_phy = of_parse_phandle(dev->of_node, "phys", 0); - if (of_graph_is_present(np_phy)) { - struct device_node *np_conn; - - np_conn = of_graph_get_remote_node(np_phy, -1, -1); - if (np_conn) - edev = extcon_find_edev_by_node(np_conn); - of_node_put(np_conn); - } - of_node_put(np_phy); - - return edev; -} - #if IS_ENABLED(CONFIG_USB_ROLE_SWITCH) #define ROLE_SWITCH 1 static int dwc3_usb_role_switch_set(struct usb_role_switch *sw, @@ -588,10 +542,6 @@ device_property_read_bool(dwc->dev, "usb-role-switch")) return dwc3_setup_role_switch(dwc); - dwc->edev = dwc3_get_extcon(dwc); - if (IS_ERR(dwc->edev)) - return PTR_ERR(dwc->edev); - if (dwc->edev) { dwc->edev_nb.notifier_call = dwc3_drd_notifier; ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST, diff -Nru linux-6.0.6/drivers/usb/dwc3/dwc3-exynos.c linux-6.0.12/drivers/usb/dwc3/dwc3-exynos.c --- linux-6.0.6/drivers/usb/dwc3/dwc3-exynos.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/dwc3/dwc3-exynos.c 2023-01-18 18:27:39.000000000 +0000 @@ -37,15 +37,6 @@ struct regulator *vdd10; }; -static int dwc3_exynos_remove_child(struct device *dev, void *unused) -{ - struct platform_device *pdev = to_platform_device(dev); - - platform_device_unregister(pdev); - - return 0; -} - static int dwc3_exynos_probe(struct platform_device *pdev) { struct dwc3_exynos *exynos; @@ -142,7 +133,7 @@ struct dwc3_exynos *exynos = platform_get_drvdata(pdev); int i; - device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child); + of_platform_depopulate(&pdev->dev); for (i = exynos->num_clks - 1; i >= 0; i--) clk_disable_unprepare(exynos->clks[i]); diff -Nru linux-6.0.6/drivers/usb/dwc3/dwc3-st.c linux-6.0.12/drivers/usb/dwc3/dwc3-st.c --- linux-6.0.6/drivers/usb/dwc3/dwc3-st.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/dwc3/dwc3-st.c 2023-01-18 18:27:39.000000000 +0000 @@ -251,7 +251,7 @@ /* Manage SoftReset */ reset_control_deassert(dwc3_data->rstc_rst); - child = of_get_child_by_name(node, "usb"); + child = of_get_compatible_child(node, "snps,dwc3"); if (!child) { dev_err(&pdev->dev, "failed to find dwc3 core node\n"); ret = -ENODEV; diff -Nru linux-6.0.6/drivers/usb/dwc3/gadget.c linux-6.0.12/drivers/usb/dwc3/gadget.c --- linux-6.0.6/drivers/usb/dwc3/gadget.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/dwc3/gadget.c 2023-01-18 18:27:39.000000000 +0000 @@ -965,7 +965,7 @@ return 0; } -static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) +static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status) { struct dwc3_request *req; @@ -975,19 +975,19 @@ while (!list_empty(&dep->started_list)) { req = next_request(&dep->started_list); - dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + dwc3_gadget_giveback(dep, req, status); } while (!list_empty(&dep->pending_list)) { req = next_request(&dep->pending_list); - dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + dwc3_gadget_giveback(dep, req, status); } while (!list_empty(&dep->cancelled_list)) { req = next_request(&dep->cancelled_list); - dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + dwc3_gadget_giveback(dep, req, status); } } @@ -1016,18 +1016,18 @@ reg &= ~DWC3_DALEPENA_EP(dep->number); dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); + dwc3_remove_requests(dwc, dep, -ESHUTDOWN); + + dep->stream_capable = false; + dep->type = 0; + dep->flags &= DWC3_EP_TXFIFO_RESIZED; + /* Clear out the ep descriptors for non-ep0 */ if (dep->number > 1) { dep->endpoint.comp_desc = NULL; dep->endpoint.desc = NULL; } - dwc3_remove_requests(dwc, dep); - - dep->stream_capable = false; - dep->type = 0; - dep->flags &= DWC3_EP_TXFIFO_RESIZED; - return 0; } @@ -1277,8 +1277,8 @@ trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; } - /* always enable Interrupt on Missed ISOC */ - trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; + if (!no_interrupt && !chain) + trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; break; case USB_ENDPOINT_XFER_BULK: @@ -1683,6 +1683,16 @@ cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); memset(¶ms, 0, sizeof(params)); ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); + /* + * If the End Transfer command was timed out while the device is + * not in SETUP phase, it's possible that an incoming Setup packet + * may prevent the command's completion. Let's retry when the + * ep0state returns to EP0_SETUP_PHASE. + */ + if (ret == -ETIMEDOUT && dep->dwc->ep0state != EP0_SETUP_PHASE) { + dep->flags |= DWC3_EP_DELAY_STOP; + return 0; + } WARN_ON_ONCE(ret); dep->resource_index = 0; @@ -2340,7 +2350,7 @@ if (!dep) continue; - dwc3_remove_requests(dwc, dep); + dwc3_remove_requests(dwc, dep, -ESHUTDOWN); } } @@ -2501,6 +2511,9 @@ if (dwc->ep0state != EP0_SETUP_PHASE) { int ret; + if (dwc->delayed_status) + dwc3_ep0_send_delayed_status(dwc); + reinit_completion(&dwc->ep0_in_setup); spin_unlock_irqrestore(&dwc->lock, flags); @@ -3215,6 +3228,10 @@ if (event->status & DEPEVT_STATUS_SHORT && !chain) return 1; + if ((trb->ctrl & DWC3_TRB_CTRL_ISP_IMI) && + DWC3_TRB_SIZE_TRBSTS(trb->size) == DWC3_TRBSTS_MISSED_ISOC) + return 1; + if ((trb->ctrl & DWC3_TRB_CTRL_IOC) || (trb->ctrl & DWC3_TRB_CTRL_LST)) return 1; diff -Nru linux-6.0.6/drivers/usb/dwc3/host.c linux-6.0.12/drivers/usb/dwc3/host.c --- linux-6.0.6/drivers/usb/dwc3/host.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/dwc3/host.c 2023-01-18 18:27:39.000000000 +0000 @@ -11,13 +11,8 @@ #include #include -#include "../host/xhci-plat.h" #include "core.h" -static const struct xhci_plat_priv dwc3_xhci_plat_priv = { - .quirks = XHCI_SKIP_PHY_INIT, -}; - static void dwc3_host_fill_xhci_irq_res(struct dwc3 *dwc, int irq, char *name) { @@ -97,11 +92,6 @@ goto err; } - ret = platform_device_add_data(xhci, &dwc3_xhci_plat_priv, - sizeof(dwc3_xhci_plat_priv)); - if (ret) - goto err; - memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); if (dwc->usb3_lpm_capable) diff -Nru linux-6.0.6/drivers/usb/gadget/function/uvc_queue.c linux-6.0.12/drivers/usb/gadget/function/uvc_queue.c --- linux-6.0.6/drivers/usb/gadget/function/uvc_queue.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/gadget/function/uvc_queue.c 2023-01-18 18:27:39.000000000 +0000 @@ -304,6 +304,7 @@ queue->sequence = 0; queue->buf_used = 0; + queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE; } else { ret = vb2_streamoff(&queue->queue, queue->queue.type); if (ret < 0) @@ -329,10 +330,11 @@ void uvcg_complete_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { - if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && - buf->length != buf->bytesused) { - buf->state = UVC_BUF_STATE_QUEUED; + if (queue->flags & UVC_QUEUE_DROP_INCOMPLETE) { + queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE; + buf->state = UVC_BUF_STATE_ERROR; vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0); + vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR); return; } diff -Nru linux-6.0.6/drivers/usb/gadget/function/uvc_video.c linux-6.0.12/drivers/usb/gadget/function/uvc_video.c --- linux-6.0.6/drivers/usb/gadget/function/uvc_video.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/gadget/function/uvc_video.c 2023-01-18 18:27:39.000000000 +0000 @@ -88,6 +88,7 @@ struct uvc_buffer *buf) { void *mem = req->buf; + struct uvc_request *ureq = req->context; int len = video->req_size; int ret; @@ -113,13 +114,14 @@ video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; list_del(&buf->queue); - uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; + ureq->last_buf = buf; video->payload_size = 0; } if (video->payload_size == video->max_payload_size || + video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE || buf->bytesused == video->queue.buf_used) video->payload_size = 0; } @@ -155,10 +157,10 @@ sg = sg_next(sg); for_each_sg(sg, iter, ureq->sgt.nents - 1, i) { - if (!len || !buf->sg || !sg_dma_len(buf->sg)) + if (!len || !buf->sg || !buf->sg->length) break; - sg_left = sg_dma_len(buf->sg) - buf->offset; + sg_left = buf->sg->length - buf->offset; part = min_t(unsigned int, len, sg_left); sg_set_page(iter, sg_page(buf->sg), part, buf->offset); @@ -180,7 +182,8 @@ req->length -= len; video->queue.buf_used += req->length - header_len; - if (buf->bytesused == video->queue.buf_used || !buf->sg) { + if (buf->bytesused == video->queue.buf_used || !buf->sg || + video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) { video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; buf->offset = 0; @@ -195,6 +198,7 @@ struct uvc_buffer *buf) { void *mem = req->buf; + struct uvc_request *ureq = req->context; int len = video->req_size; int ret; @@ -209,12 +213,13 @@ req->length = video->req_size - len; - if (buf->bytesused == video->queue.buf_used) { + if (buf->bytesused == video->queue.buf_used || + video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) { video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; list_del(&buf->queue); - uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; + ureq->last_buf = buf; } } @@ -255,6 +260,11 @@ case 0: break; + case -EXDEV: + uvcg_dbg(&video->uvc->func, "VS request missed xfer.\n"); + queue->flags |= UVC_QUEUE_DROP_INCOMPLETE; + break; + case -ESHUTDOWN: /* disconnect from host. */ uvcg_dbg(&video->uvc->func, "VS request cancelled.\n"); uvcg_queue_cancel(queue, 1); @@ -431,7 +441,8 @@ /* Endpoint now owns the request */ req = NULL; - video->req_int_count++; + if (buf->state != UVC_BUF_STATE_DONE) + video->req_int_count++; } if (!req) diff -Nru linux-6.0.6/drivers/usb/gadget/udc/aspeed-vhub/dev.c linux-6.0.12/drivers/usb/gadget/udc/aspeed-vhub/dev.c --- linux-6.0.6/drivers/usb/gadget/udc/aspeed-vhub/dev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/gadget/udc/aspeed-vhub/dev.c 2023-01-18 18:27:39.000000000 +0000 @@ -591,6 +591,7 @@ d->gadget.max_speed = USB_SPEED_HIGH; d->gadget.speed = USB_SPEED_UNKNOWN; d->gadget.dev.of_node = vhub->pdev->dev.of_node; + d->gadget.dev.of_node_reused = true; rc = usb_add_gadget_udc(d->port_dev, &d->gadget); if (rc != 0) diff -Nru linux-6.0.6/drivers/usb/gadget/udc/bdc/bdc_udc.c linux-6.0.12/drivers/usb/gadget/udc/bdc/bdc_udc.c --- linux-6.0.6/drivers/usb/gadget/udc/bdc/bdc_udc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/gadget/udc/bdc/bdc_udc.c 2023-01-18 18:27:39.000000000 +0000 @@ -151,6 +151,7 @@ bdc->delayed_status = false; bdc->reinit = reinit; bdc->test_mode = false; + usb_gadget_set_state(&bdc->gadget, USB_STATE_NOTATTACHED); } /* TNotify wkaeup timer */ diff -Nru linux-6.0.6/drivers/usb/host/bcma-hcd.c linux-6.0.12/drivers/usb/host/bcma-hcd.c --- linux-6.0.6/drivers/usb/host/bcma-hcd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/host/bcma-hcd.c 2023-01-18 18:27:39.000000000 +0000 @@ -285,7 +285,7 @@ { struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev); - if (IS_ERR_OR_NULL(usb_dev->gpio_desc)) + if (!usb_dev->gpio_desc) return; gpiod_set_value(usb_dev->gpio_desc, val); @@ -406,9 +406,11 @@ return -ENOMEM; usb_dev->core = core; - if (core->dev.of_node) - usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc", - GPIOD_OUT_HIGH); + usb_dev->gpio_desc = devm_gpiod_get_optional(&core->dev, "vcc", + GPIOD_OUT_HIGH); + if (IS_ERR(usb_dev->gpio_desc)) + return dev_err_probe(&core->dev, PTR_ERR(usb_dev->gpio_desc), + "error obtaining VCC GPIO"); switch (core->id.id) { case BCMA_CORE_USB20_HOST: diff -Nru linux-6.0.6/drivers/usb/host/xhci.c linux-6.0.12/drivers/usb/host/xhci.c --- linux-6.0.6/drivers/usb/host/xhci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/host/xhci.c 2023-01-18 18:27:39.000000000 +0000 @@ -810,9 +810,15 @@ spin_lock_irq(&xhci->lock); xhci_halt(xhci); - /* Workaround for spurious wakeups at shutdown with HSW */ - if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + + /* + * Workaround for spurious wakeps at shutdown with HSW, and for boot + * firmware delay in ADL-P PCH if port are left in U3 at shutdown + */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP || + xhci->quirks & XHCI_RESET_TO_DEFAULT) xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + spin_unlock_irq(&xhci->lock); xhci_cleanup_msix(xhci); diff -Nru linux-6.0.6/drivers/usb/host/xhci.h linux-6.0.12/drivers/usb/host/xhci.h --- linux-6.0.6/drivers/usb/host/xhci.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/host/xhci.h 2023-01-18 18:27:39.000000000 +0000 @@ -1900,6 +1900,7 @@ #define XHCI_BROKEN_D3COLD BIT_ULL(41) #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42) #define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43) +#define XHCI_RESET_TO_DEFAULT BIT_ULL(44) unsigned int num_active_eps; unsigned int limit_active_eps; diff -Nru linux-6.0.6/drivers/usb/host/xhci-mem.c linux-6.0.12/drivers/usb/host/xhci-mem.c --- linux-6.0.6/drivers/usb/host/xhci-mem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/host/xhci-mem.c 2023-01-18 18:27:39.000000000 +0000 @@ -889,15 +889,19 @@ if (dev->eps[i].stream_info) xhci_free_stream_info(xhci, dev->eps[i].stream_info); - /* Endpoints on the TT/root port lists should have been removed - * when usb_disable_device() was called for the device. - * We can't drop them anyway, because the udev might have gone - * away by this point, and we can't tell what speed it was. + /* + * Endpoints are normally deleted from the bandwidth list when + * endpoints are dropped, before device is freed. + * If host is dying or being removed then endpoints aren't + * dropped cleanly, so delete the endpoint from list here. + * Only applicable for hosts with software bandwidth checking. */ - if (!list_empty(&dev->eps[i].bw_endpoint_list)) - xhci_warn(xhci, "Slot %u endpoint %u " - "not removed from BW list!\n", - slot_id, i); + + if (!list_empty(&dev->eps[i].bw_endpoint_list)) { + list_del_init(&dev->eps[i].bw_endpoint_list); + xhci_dbg(xhci, "Slot %u endpoint %u not removed from BW list!\n", + slot_id, i); + } } /* If this is a hub, free the TT(s) from the TT list */ xhci_free_tt_info(xhci, dev, slot_id); diff -Nru linux-6.0.6/drivers/usb/host/xhci-pci.c linux-6.0.12/drivers/usb/host/xhci-pci.c --- linux-6.0.6/drivers/usb/host/xhci-pci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/host/xhci-pci.c 2023-01-18 18:27:39.000000000 +0000 @@ -58,25 +58,13 @@ #define PCI_DEVICE_ID_INTEL_CML_XHCI 0xa3af #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13 #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138 -#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e -#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI 0x464e -#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed -#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI 0xa71e -#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI 0x7ec0 +#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc -#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_1 0x161a -#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_2 0x161b -#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3 0x161d -#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 0x161e -#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 0x15d6 -#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 0x15d7 -#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_7 0x161c -#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_8 0x161f #define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042 #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 @@ -258,6 +246,10 @@ xhci->quirks |= XHCI_MISSING_CAS; if (pdev->vendor == PCI_VENDOR_ID_INTEL && + pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI) + xhci->quirks |= XHCI_RESET_TO_DEFAULT; + + if (pdev->vendor == PCI_VENDOR_ID_INTEL && (pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_XHCI || @@ -268,12 +260,7 @@ pdev->device == PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI)) + pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI)) xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; if (pdev->vendor == PCI_VENDOR_ID_ETRON && @@ -306,8 +293,14 @@ } if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && - pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) + pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) { + /* + * try to tame the ASMedia 1042 controller which reports 0.96 + * but appears to behave more like 1.0 + */ + xhci->quirks |= XHCI_SPURIOUS_SUCCESS; xhci->quirks |= XHCI_BROKEN_STREAMS; + } if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) { xhci->quirks |= XHCI_TRUST_TX_LENGTH; @@ -336,15 +329,8 @@ pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4)) xhci->quirks |= XHCI_NO_SOFT_RETRY; - if (pdev->vendor == PCI_VENDOR_ID_AMD && - (pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_1 || - pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_2 || - pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3 || - pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 || - pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 || - pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 || - pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_7 || - pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_8)) + /* xHC spec requires PCI devices to support D3hot and D3cold */ + if (xhci->hci_version >= 0x120) xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; if (xhci->quirks & XHCI_RESET_ON_RESUME) diff -Nru linux-6.0.6/drivers/usb/serial/option.c linux-6.0.12/drivers/usb/serial/option.c --- linux-6.0.6/drivers/usb/serial/option.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/serial/option.c 2023-01-18 18:27:39.000000000 +0000 @@ -162,6 +162,8 @@ #define NOVATELWIRELESS_PRODUCT_G2 0xA010 #define NOVATELWIRELESS_PRODUCT_MC551 0xB001 +#define UBLOX_VENDOR_ID 0x1546 + /* AMOI PRODUCTS */ #define AMOI_VENDOR_ID 0x1614 #define AMOI_PRODUCT_H01 0x0800 @@ -240,7 +242,6 @@ #define QUECTEL_PRODUCT_UC15 0x9090 /* These u-blox products use Qualcomm's vendor ID */ #define UBLOX_PRODUCT_R410M 0x90b2 -#define UBLOX_PRODUCT_R6XX 0x90fa /* These Yuga products use Qualcomm's vendor ID */ #define YUGA_PRODUCT_CLM920_NC5 0x9625 @@ -581,6 +582,9 @@ #define OPPO_VENDOR_ID 0x22d9 #define OPPO_PRODUCT_R11 0x276c +/* Sierra Wireless products */ +#define SIERRA_VENDOR_ID 0x1199 +#define SIERRA_PRODUCT_EM9191 0x90d3 /* Device flags */ @@ -1124,8 +1128,16 @@ /* u-blox products using Qualcomm vendor ID */ { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), .driver_info = RSVD(1) | RSVD(3) }, - { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R6XX), + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x908b), /* u-blox LARA-R6 00B */ + .driver_info = RSVD(4) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x90fa), .driver_info = RSVD(3) }, + /* u-blox products */ + { USB_DEVICE(UBLOX_VENDOR_ID, 0x1341) }, /* u-blox LARA-L6 */ + { USB_DEVICE(UBLOX_VENDOR_ID, 0x1342), /* u-blox LARA-L6 (RMNET) */ + .driver_info = RSVD(4) }, + { USB_DEVICE(UBLOX_VENDOR_ID, 0x1343), /* u-blox LARA-L6 (ECM) */ + .driver_info = RSVD(4) }, /* Quectel products using Quectel vendor ID */ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21, 0xff, 0xff, 0xff), .driver_info = NUMEP2 }, @@ -2167,6 +2179,7 @@ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x010a, 0xff) }, /* Fibocom MA510 (ECM mode) */ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0111, 0xff) }, /* Fibocom FM160 (MBIM mode) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a2, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */ @@ -2176,6 +2189,8 @@ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff -Nru linux-6.0.6/drivers/usb/typec/mux/intel_pmc_mux.c linux-6.0.12/drivers/usb/typec/mux/intel_pmc_mux.c --- linux-6.0.6/drivers/usb/typec/mux/intel_pmc_mux.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/typec/mux/intel_pmc_mux.c 2023-01-18 18:27:39.000000000 +0000 @@ -369,13 +369,24 @@ return pmc_usb_command(port, (void *)&req, sizeof(req)); } -static int pmc_usb_mux_safe_state(struct pmc_usb_port *port) +static int pmc_usb_mux_safe_state(struct pmc_usb_port *port, + struct typec_mux_state *state) { u8 msg; if (IOM_PORT_ACTIVITY_IS(port->iom_status, SAFE_MODE)) return 0; + if ((IOM_PORT_ACTIVITY_IS(port->iom_status, DP) || + IOM_PORT_ACTIVITY_IS(port->iom_status, DP_MFD)) && + state->alt && state->alt->svid == USB_TYPEC_DP_SID) + return 0; + + if ((IOM_PORT_ACTIVITY_IS(port->iom_status, TBT) || + IOM_PORT_ACTIVITY_IS(port->iom_status, ALT_MODE_TBT_USB)) && + state->alt && state->alt->svid == USB_TYPEC_TBT_SID) + return 0; + msg = PMC_USB_SAFE_MODE; msg |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT; @@ -443,7 +454,7 @@ return 0; if (state->mode == TYPEC_STATE_SAFE) - return pmc_usb_mux_safe_state(port); + return pmc_usb_mux_safe_state(port, state); if (state->mode == TYPEC_STATE_USB) return pmc_usb_connect(port, port->role); diff -Nru linux-6.0.6/drivers/usb/typec/tipd/core.c linux-6.0.12/drivers/usb/typec/tipd/core.c --- linux-6.0.6/drivers/usb/typec/tipd/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/typec/tipd/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -474,7 +474,7 @@ static irqreturn_t cd321x_interrupt(int irq, void *data) { struct tps6598x *tps = data; - u64 event; + u64 event = 0; u32 status; int ret; @@ -519,8 +519,8 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) { struct tps6598x *tps = data; - u64 event1; - u64 event2; + u64 event1 = 0; + u64 event2 = 0; u32 status; int ret; diff -Nru linux-6.0.6/drivers/usb/typec/ucsi/ucsi_acpi.c linux-6.0.12/drivers/usb/typec/ucsi/ucsi_acpi.c --- linux-6.0.6/drivers/usb/typec/ucsi/ucsi_acpi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/typec/ucsi/ucsi_acpi.c 2023-01-18 18:27:39.000000000 +0000 @@ -185,6 +185,15 @@ return 0; } +static int ucsi_acpi_resume(struct device *dev) +{ + struct ucsi_acpi *ua = dev_get_drvdata(dev); + + return ucsi_resume(ua->ucsi); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(ucsi_acpi_pm_ops, NULL, ucsi_acpi_resume); + static const struct acpi_device_id ucsi_acpi_match[] = { { "PNP0CA0", 0 }, { }, @@ -194,6 +203,7 @@ static struct platform_driver ucsi_acpi_platform_driver = { .driver = { .name = "ucsi_acpi", + .pm = pm_ptr(&ucsi_acpi_pm_ops), .acpi_match_table = ACPI_PTR(ucsi_acpi_match), }, .probe = ucsi_acpi_probe, diff -Nru linux-6.0.6/drivers/usb/typec/ucsi/ucsi.c linux-6.0.12/drivers/usb/typec/ucsi/ucsi.c --- linux-6.0.6/drivers/usb/typec/ucsi/ucsi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/usb/typec/ucsi/ucsi.c 2023-01-18 18:27:39.000000000 +0000 @@ -183,16 +183,6 @@ } EXPORT_SYMBOL_GPL(ucsi_send_command); -int ucsi_resume(struct ucsi *ucsi) -{ - u64 command; - - /* Restore UCSI notification enable mask after system resume */ - command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy; - - return ucsi_send_command(ucsi, command, NULL, 0); -} -EXPORT_SYMBOL_GPL(ucsi_resume); /* -------------------------------------------------------------------------- */ struct ucsi_work { @@ -744,6 +734,7 @@ static int ucsi_check_connection(struct ucsi_connector *con) { + u8 prev_flags = con->status.flags; u64 command; int ret; @@ -754,10 +745,13 @@ return ret; } + if (con->status.flags == prev_flags) + return 0; + if (con->status.flags & UCSI_CONSTAT_CONNECTED) { - if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) == - UCSI_CONSTAT_PWR_OPMODE_PD) - ucsi_partner_task(con, ucsi_check_altmodes, 30, 0); + ucsi_register_partner(con); + ucsi_pwr_opmode_change(con); + ucsi_partner_change(con); } else { ucsi_partner_change(con); ucsi_port_psy_changed(con); @@ -1276,6 +1270,28 @@ return ret; } +int ucsi_resume(struct ucsi *ucsi) +{ + struct ucsi_connector *con; + u64 command; + int ret; + + /* Restore UCSI notification enable mask after system resume */ + command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy; + ret = ucsi_send_command(ucsi, command, NULL, 0); + if (ret < 0) + return ret; + + for (con = ucsi->connector; con->port; con++) { + mutex_lock(&con->lock); + ucsi_check_connection(con); + mutex_unlock(&con->lock); + } + + return 0; +} +EXPORT_SYMBOL_GPL(ucsi_resume); + static void ucsi_init_work(struct work_struct *work) { struct ucsi *ucsi = container_of(work, struct ucsi, work.work); diff -Nru linux-6.0.6/drivers/vfio/vfio_main.c linux-6.0.12/drivers/vfio/vfio_main.c --- linux-6.0.6/drivers/vfio/vfio_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/vfio/vfio_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -710,8 +710,9 @@ /* * VFIO base fd, /dev/vfio/vfio */ -static long vfio_ioctl_check_extension(struct vfio_container *container, - unsigned long arg) +static long +vfio_container_ioctl_check_extension(struct vfio_container *container, + unsigned long arg) { struct vfio_iommu_driver *driver; long ret = 0; @@ -868,7 +869,7 @@ ret = VFIO_API_VERSION; break; case VFIO_CHECK_EXTENSION: - ret = vfio_ioctl_check_extension(container, arg); + ret = vfio_container_ioctl_check_extension(container, arg); break; case VFIO_SET_IOMMU: ret = vfio_ioctl_set_iommu(container, arg); @@ -1085,9 +1086,28 @@ up_write(&device->group->group_rwsem); } +static void vfio_device_container_register(struct vfio_device *device) +{ + struct vfio_iommu_driver *iommu_driver = + device->group->container->iommu_driver; + + if (iommu_driver && iommu_driver->ops->register_device) + iommu_driver->ops->register_device( + device->group->container->iommu_data, device); +} + +static void vfio_device_container_unregister(struct vfio_device *device) +{ + struct vfio_iommu_driver *iommu_driver = + device->group->container->iommu_driver; + + if (iommu_driver && iommu_driver->ops->unregister_device) + iommu_driver->ops->unregister_device( + device->group->container->iommu_data, device); +} + static struct file *vfio_device_open(struct vfio_device *device) { - struct vfio_iommu_driver *iommu_driver; struct file *filep; int ret; @@ -1118,12 +1138,7 @@ if (ret) goto err_undo_count; } - - iommu_driver = device->group->container->iommu_driver; - if (iommu_driver && iommu_driver->ops->register_device) - iommu_driver->ops->register_device( - device->group->container->iommu_data, device); - + vfio_device_container_register(device); up_read(&device->group->group_rwsem); } mutex_unlock(&device->dev_set->lock); @@ -1161,10 +1176,7 @@ if (device->open_count == 1 && device->ops->close_device) { device->ops->close_device(device); - iommu_driver = device->group->container->iommu_driver; - if (iommu_driver && iommu_driver->ops->unregister_device) - iommu_driver->ops->unregister_device( - device->group->container->iommu_data, device); + vfio_device_container_unregister(device); } err_undo_count: up_read(&device->group->group_rwsem); @@ -1360,7 +1372,6 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep) { struct vfio_device *device = filep->private_data; - struct vfio_iommu_driver *iommu_driver; mutex_lock(&device->dev_set->lock); vfio_assert_device_open(device); @@ -1368,10 +1379,7 @@ if (device->open_count == 1 && device->ops->close_device) device->ops->close_device(device); - iommu_driver = device->group->container->iommu_driver; - if (iommu_driver && iommu_driver->ops->unregister_device) - iommu_driver->ops->unregister_device( - device->group->container->iommu_data, device); + vfio_device_container_unregister(device); up_read(&device->group->group_rwsem); device->open_count--; if (device->open_count == 0) @@ -1763,8 +1771,8 @@ down_read(&group->group_rwsem); if (group->container) { - ret = vfio_ioctl_check_extension(group->container, - VFIO_DMA_CC_IOMMU); + ret = vfio_container_ioctl_check_extension(group->container, + VFIO_DMA_CC_IOMMU); } else { /* * Since the coherency state is determined only once a container diff -Nru linux-6.0.6/drivers/video/fbdev/smscufx.c linux-6.0.12/drivers/video/fbdev/smscufx.c --- linux-6.0.6/drivers/video/fbdev/smscufx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/video/fbdev/smscufx.c 2023-01-18 18:27:39.000000000 +0000 @@ -97,7 +97,6 @@ struct kref kref; int fb_count; bool virtualized; /* true when physical usb device not present */ - struct delayed_work free_framebuffer_work; atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */ atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ u8 *edid; /* null until we read edid from hw or get from sysfs */ @@ -1117,15 +1116,24 @@ { struct ufx_data *dev = container_of(kref, struct ufx_data, kref); - /* this function will wait for all in-flight urbs to complete */ - if (dev->urbs.count > 0) - ufx_free_urb_list(dev); + kfree(dev); +} - pr_debug("freeing ufx_data %p", dev); +static void ufx_ops_destory(struct fb_info *info) +{ + struct ufx_data *dev = info->par; + int node = info->node; - kfree(dev); + /* Assume info structure is freed after this point */ + framebuffer_release(info); + + pr_debug("fb_info for /dev/fb%d has been freed", node); + + /* release reference taken by kref_init in probe() */ + kref_put(&dev->kref, ufx_free); } + static void ufx_release_urb_work(struct work_struct *work) { struct urb_node *unode = container_of(work, struct urb_node, @@ -1134,14 +1142,9 @@ up(&unode->dev->urbs.limit_sem); } -static void ufx_free_framebuffer_work(struct work_struct *work) +static void ufx_free_framebuffer(struct ufx_data *dev) { - struct ufx_data *dev = container_of(work, struct ufx_data, - free_framebuffer_work.work); struct fb_info *info = dev->info; - int node = info->node; - - unregister_framebuffer(info); if (info->cmap.len != 0) fb_dealloc_cmap(&info->cmap); @@ -1153,11 +1156,6 @@ dev->info = NULL; - /* Assume info structure is freed after this point */ - framebuffer_release(info); - - pr_debug("fb_info for /dev/fb%d has been freed", node); - /* ref taken in probe() as part of registering framebfufer */ kref_put(&dev->kref, ufx_free); } @@ -1169,11 +1167,13 @@ { struct ufx_data *dev = info->par; + mutex_lock(&disconnect_mutex); + dev->fb_count--; /* We can't free fb_info here - fbmem will touch it when we return */ if (dev->virtualized && (dev->fb_count == 0)) - schedule_delayed_work(&dev->free_framebuffer_work, HZ); + ufx_free_framebuffer(dev); if ((dev->fb_count == 0) && (info->fbdefio)) { fb_deferred_io_cleanup(info); @@ -1186,6 +1186,8 @@ kref_put(&dev->kref, ufx_free); + mutex_unlock(&disconnect_mutex); + return 0; } @@ -1292,6 +1294,7 @@ .fb_blank = ufx_ops_blank, .fb_check_var = ufx_ops_check_var, .fb_set_par = ufx_ops_set_par, + .fb_destroy = ufx_ops_destory, }; /* Assumes &info->lock held by caller @@ -1673,9 +1676,6 @@ goto destroy_modedb; } - INIT_DELAYED_WORK(&dev->free_framebuffer_work, - ufx_free_framebuffer_work); - retval = ufx_reg_read(dev, 0x3000, &id_rev); check_warn_goto_error(retval, "error %d reading 0x3000 register from device", retval); dev_dbg(dev->gdev, "ID_REV register value 0x%08x", id_rev); @@ -1748,10 +1748,12 @@ static void ufx_usb_disconnect(struct usb_interface *interface) { struct ufx_data *dev; + struct fb_info *info; mutex_lock(&disconnect_mutex); dev = usb_get_intfdata(interface); + info = dev->info; pr_debug("USB disconnect starting\n"); @@ -1765,12 +1767,15 @@ /* if clients still have us open, will be freed on last close */ if (dev->fb_count == 0) - schedule_delayed_work(&dev->free_framebuffer_work, 0); + ufx_free_framebuffer(dev); - /* release reference taken by kref_init in probe() */ - kref_put(&dev->kref, ufx_free); + /* this function will wait for all in-flight urbs to complete */ + if (dev->urbs.count > 0) + ufx_free_urb_list(dev); - /* consider ufx_data freed */ + pr_debug("freeing ufx_data %p", dev); + + unregister_framebuffer(info); mutex_unlock(&disconnect_mutex); } diff -Nru linux-6.0.6/drivers/video/fbdev/stifb.c linux-6.0.12/drivers/video/fbdev/stifb.c --- linux-6.0.6/drivers/video/fbdev/stifb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/video/fbdev/stifb.c 2023-01-18 18:27:39.000000000 +0000 @@ -1055,7 +1055,8 @@ { struct stifb_info *fb = container_of(info, struct stifb_info, info); - if (rect->rop != ROP_COPY) + if (rect->rop != ROP_COPY || + (fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32)) return cfb_fillrect(info, rect); SETUP_HW(fb); diff -Nru linux-6.0.6/drivers/virt/coco/sev-guest/sev-guest.c linux-6.0.12/drivers/virt/coco/sev-guest/sev-guest.c --- linux-6.0.6/drivers/virt/coco/sev-guest/sev-guest.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/virt/coco/sev-guest/sev-guest.c 2023-01-18 18:27:39.000000000 +0000 @@ -67,8 +67,27 @@ return true; } +/* + * If an error is received from the host or AMD Secure Processor (ASP) there + * are two options. Either retry the exact same encrypted request or discontinue + * using the VMPCK. + * + * This is because in the current encryption scheme GHCB v2 uses AES-GCM to + * encrypt the requests. The IV for this scheme is the sequence number. GCM + * cannot tolerate IV reuse. + * + * The ASP FW v1.51 only increments the sequence numbers on a successful + * guest<->ASP back and forth and only accepts messages at its exact sequence + * number. + * + * So if the sequence number were to be reused the encryption scheme is + * vulnerable. If the sequence number were incremented for a fresh IV the ASP + * will reject the request. + */ static void snp_disable_vmpck(struct snp_guest_dev *snp_dev) { + dev_alert(snp_dev->dev, "Disabling vmpck_id %d to prevent IV reuse.\n", + vmpck_id); memzero_explicit(snp_dev->vmpck, VMPCK_KEY_LEN); snp_dev->vmpck = NULL; } @@ -321,34 +340,71 @@ if (rc) return rc; - /* Call firmware to process the request */ + /* + * Call firmware to process the request. In this function the encrypted + * message enters shared memory with the host. So after this call the + * sequence number must be incremented or the VMPCK must be deleted to + * prevent reuse of the IV. + */ rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err); + + /* + * If the extended guest request fails due to having too small of a + * certificate data buffer, retry the same guest request without the + * extended data request in order to increment the sequence number + * and thus avoid IV reuse. + */ + if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST && + err == SNP_GUEST_REQ_INVALID_LEN) { + const unsigned int certs_npages = snp_dev->input.data_npages; + + exit_code = SVM_VMGEXIT_GUEST_REQUEST; + + /* + * If this call to the firmware succeeds, the sequence number can + * be incremented allowing for continued use of the VMPCK. If + * there is an error reflected in the return value, this value + * is checked further down and the result will be the deletion + * of the VMPCK and the error code being propagated back to the + * user as an ioctl() return code. + */ + rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err); + + /* + * Override the error to inform callers the given extended + * request buffer size was too small and give the caller the + * required buffer size. + */ + err = SNP_GUEST_REQ_INVALID_LEN; + snp_dev->input.data_npages = certs_npages; + } + if (fw_err) *fw_err = err; - if (rc) - return rc; + if (rc) { + dev_alert(snp_dev->dev, + "Detected error from ASP request. rc: %d, fw_err: %llu\n", + rc, *fw_err); + goto disable_vmpck; + } - /* - * The verify_and_dec_payload() will fail only if the hypervisor is - * actively modifying the message header or corrupting the encrypted payload. - * This hints that hypervisor is acting in a bad faith. Disable the VMPCK so that - * the key cannot be used for any communication. The key is disabled to ensure - * that AES-GCM does not use the same IV while encrypting the request payload. - */ rc = verify_and_dec_payload(snp_dev, resp_buf, resp_sz); if (rc) { dev_alert(snp_dev->dev, - "Detected unexpected decode failure, disabling the vmpck_id %d\n", - vmpck_id); - snp_disable_vmpck(snp_dev); - return rc; + "Detected unexpected decode failure from ASP. rc: %d\n", + rc); + goto disable_vmpck; } /* Increment to new message sequence after payload decryption was successful. */ snp_inc_msg_seqno(snp_dev); return 0; + +disable_vmpck: + snp_disable_vmpck(snp_dev); + return rc; } static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) diff -Nru linux-6.0.6/drivers/xen/pcpu.c linux-6.0.12/drivers/xen/pcpu.c --- linux-6.0.6/drivers/xen/pcpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/xen/pcpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -228,7 +228,7 @@ err = device_register(dev); if (err) { - pcpu_release(dev); + put_device(dev); return err; } diff -Nru linux-6.0.6/drivers/xen/platform-pci.c linux-6.0.12/drivers/xen/platform-pci.c --- linux-6.0.6/drivers/xen/platform-pci.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/xen/platform-pci.c 2023-01-18 18:27:39.000000000 +0000 @@ -144,7 +144,7 @@ if (ret) { dev_warn(&pdev->dev, "Unable to set the evtchn callback " "err=%d\n", ret); - goto out; + goto irq_out; } } @@ -152,13 +152,16 @@ grant_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes); ret = gnttab_setup_auto_xlat_frames(grant_frames); if (ret) - goto out; + goto irq_out; ret = gnttab_init(); if (ret) goto grant_out; return 0; grant_out: gnttab_free_auto_xlat_frames(); +irq_out: + if (!xen_have_vector_callback) + free_irq(pdev->irq, pdev); out: pci_release_region(pdev, 0); mem_out: diff -Nru linux-6.0.6/drivers/xen/xen-pciback/conf_space_capability.c linux-6.0.12/drivers/xen/xen-pciback/conf_space_capability.c --- linux-6.0.6/drivers/xen/xen-pciback/conf_space_capability.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/drivers/xen/xen-pciback/conf_space_capability.c 2023-01-18 18:27:39.000000000 +0000 @@ -190,13 +190,16 @@ }; static struct msi_msix_field_config { - u16 enable_bit; /* bit for enabling MSI/MSI-X */ - unsigned int int_type; /* interrupt type for exclusiveness check */ + u16 enable_bit; /* bit for enabling MSI/MSI-X */ + u16 allowed_bits; /* bits allowed to be changed */ + unsigned int int_type; /* interrupt type for exclusiveness check */ } msi_field_config = { .enable_bit = PCI_MSI_FLAGS_ENABLE, + .allowed_bits = PCI_MSI_FLAGS_ENABLE, .int_type = INTERRUPT_TYPE_MSI, }, msix_field_config = { .enable_bit = PCI_MSIX_FLAGS_ENABLE, + .allowed_bits = PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL, .int_type = INTERRUPT_TYPE_MSIX, }; @@ -229,7 +232,7 @@ return 0; if (!dev_data->allow_interrupt_control || - (new_value ^ old_value) & ~field_config->enable_bit) + (new_value ^ old_value) & ~field_config->allowed_bits) return PCIBIOS_SET_FAILED; if (new_value & field_config->enable_bit) { diff -Nru linux-6.0.6/fs/afs/fs_probe.c linux-6.0.12/fs/afs/fs_probe.c --- linux-6.0.6/fs/afs/fs_probe.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/afs/fs_probe.c 2023-01-18 18:27:39.000000000 +0000 @@ -167,8 +167,8 @@ clear_bit(AFS_SERVER_FL_HAS_FS64, &server->flags); } - if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) && - rtt_us < server->probe.rtt) { + rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us); + if (rtt_us < server->probe.rtt) { server->probe.rtt = rtt_us; server->rtt = rtt_us; alist->preferred = index; diff -Nru linux-6.0.6/fs/afs/server.c linux-6.0.12/fs/afs/server.c --- linux-6.0.6/fs/afs/server.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/afs/server.c 2023-01-18 18:27:39.000000000 +0000 @@ -406,7 +406,7 @@ if (!server) return; - a = atomic_inc_return(&server->active); + a = atomic_read(&server->active); zero = __refcount_dec_and_test(&server->ref, &r); trace_afs_server(debug_id, r - 1, a, reason); if (unlikely(zero)) diff -Nru linux-6.0.6/fs/binfmt_elf.c linux-6.0.12/fs/binfmt_elf.c --- linux-6.0.6/fs/binfmt_elf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/binfmt_elf.c 2023-01-18 18:27:39.000000000 +0000 @@ -911,7 +911,7 @@ interp_elf_ex = kmalloc(sizeof(*interp_elf_ex), GFP_KERNEL); if (!interp_elf_ex) { retval = -ENOMEM; - goto out_free_ph; + goto out_free_file; } /* Get the exec headers */ @@ -1354,6 +1354,7 @@ out_free_dentry: kfree(interp_elf_ex); kfree(interp_elf_phdata); +out_free_file: allow_write_access(interpreter); if (interpreter) fput(interpreter); diff -Nru linux-6.0.6/fs/btrfs/backref.c linux-6.0.12/fs/btrfs/backref.c --- linux-6.0.6/fs/btrfs/backref.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/backref.c 2023-01-18 18:27:39.000000000 +0000 @@ -289,8 +289,10 @@ struct prelim_ref *ref, *next_ref; rbtree_postorder_for_each_entry_safe(ref, next_ref, - &preftree->root.rb_root, rbnode) + &preftree->root.rb_root, rbnode) { + free_inode_elem_list(ref->inode_list); free_pref(ref); + } preftree->root = RB_ROOT_CACHED; preftree->count = 0; @@ -648,6 +650,18 @@ return (struct extent_inode_elem *)(uintptr_t)node->aux; } +static void free_leaf_list(struct ulist *ulist) +{ + struct ulist_node *node; + struct ulist_iterator uiter; + + ULIST_ITER_INIT(&uiter); + while ((node = ulist_next(ulist, &uiter))) + free_inode_elem_list(unode_aux_to_inode_list(node)); + + ulist_free(ulist); +} + /* * We maintain three separate rbtrees: one for direct refs, one for * indirect refs which have a key, and one for indirect refs which do not @@ -762,7 +776,11 @@ cond_resched(); } out: - ulist_free(parents); + /* + * We may have inode lists attached to refs in the parents ulist, so we + * must free them before freeing the ulist and its refs. + */ + free_leaf_list(parents); return ret; } @@ -1368,6 +1386,12 @@ if (ret < 0) goto out; ref->inode_list = eie; + /* + * We transferred the list ownership to the ref, + * so set to NULL to avoid a double free in case + * an error happens after this. + */ + eie = NULL; } ret = ulist_add_merge_ptr(refs, ref->parent, ref->inode_list, @@ -1393,6 +1417,14 @@ eie->next = ref->inode_list; } eie = NULL; + /* + * We have transferred the inode list ownership from + * this ref to the ref we added to the 'refs' ulist. + * So set this ref's inode list to NULL to avoid + * use-after-free when our caller uses it or double + * frees in case an error happens before we return. + */ + ref->inode_list = NULL; } cond_resched(); } @@ -1409,24 +1441,6 @@ return ret; } -static void free_leaf_list(struct ulist *blocks) -{ - struct ulist_node *node = NULL; - struct extent_inode_elem *eie; - struct ulist_iterator uiter; - - ULIST_ITER_INIT(&uiter); - while ((node = ulist_next(blocks, &uiter))) { - if (!node->aux) - continue; - eie = unode_aux_to_inode_list(node); - free_inode_elem_list(eie); - node->aux = 0; - } - - ulist_free(blocks); -} - /* * Finds all leafs with a reference to the specified combination of bytenr and * offset. key_list_head will point to a list of corresponding keys (caller must diff -Nru linux-6.0.6/fs/btrfs/ctree.h linux-6.0.12/fs/btrfs/ctree.h --- linux-6.0.6/fs/btrfs/ctree.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/ctree.h 2023-01-18 18:27:39.000000000 +0000 @@ -3407,7 +3407,10 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, const struct btrfs_ioctl_encoded_io_args *encoded); -ssize_t btrfs_dio_rw(struct kiocb *iocb, struct iov_iter *iter, size_t done_before); +ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter, + size_t done_before); +struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter, + size_t done_before); extern const struct dentry_operations btrfs_dentry_operations; diff -Nru linux-6.0.6/fs/btrfs/disk-io.c linux-6.0.12/fs/btrfs/disk-io.c --- linux-6.0.6/fs/btrfs/disk-io.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/disk-io.c 2023-01-18 18:27:39.000000000 +0000 @@ -2544,7 +2544,9 @@ fs_info->dev_root = root; } /* Initialize fs_info for all devices in any case */ - btrfs_init_devices_late(fs_info); + ret = btrfs_init_devices_late(fs_info); + if (ret) + goto out; /* * This tree can share blocks with some other fs tree during relocation diff -Nru linux-6.0.6/fs/btrfs/export.c linux-6.0.12/fs/btrfs/export.c --- linux-6.0.6/fs/btrfs/export.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/export.c 2023-01-18 18:27:39.000000000 +0000 @@ -58,7 +58,7 @@ } struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, - u64 root_objectid, u32 generation, + u64 root_objectid, u64 generation, int check_generation) { struct btrfs_fs_info *fs_info = btrfs_sb(sb); diff -Nru linux-6.0.6/fs/btrfs/export.h linux-6.0.12/fs/btrfs/export.h --- linux-6.0.6/fs/btrfs/export.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/export.h 2023-01-18 18:27:39.000000000 +0000 @@ -19,7 +19,7 @@ } __attribute__ ((packed)); struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, - u64 root_objectid, u32 generation, + u64 root_objectid, u64 generation, int check_generation); struct dentry *btrfs_get_parent(struct dentry *child); diff -Nru linux-6.0.6/fs/btrfs/extent-tree.c linux-6.0.12/fs/btrfs/extent-tree.c --- linux-6.0.6/fs/btrfs/extent-tree.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/extent-tree.c 2023-01-18 18:27:39.000000000 +0000 @@ -3294,21 +3294,22 @@ } /* - * If this is a leaf and there are tree mod log users, we may - * have recorded mod log operations that point to this leaf. - * So we must make sure no one reuses this leaf's extent before - * mod log operations are applied to a node, otherwise after - * rewinding a node using the mod log operations we get an - * inconsistent btree, as the leaf's extent may now be used as - * a node or leaf for another different btree. + * If there are tree mod log users we may have recorded mod log + * operations for this node. If we re-allocate this node we + * could replay operations on this node that happened when it + * existed in a completely different root. For example if it + * was part of root A, then was reallocated to root B, and we + * are doing a btrfs_old_search_slot(root b), we could replay + * operations that happened when the block was part of root A, + * giving us an inconsistent view of the btree. + * * We are safe from races here because at this point no other * node or root points to this extent buffer, so if after this - * check a new tree mod log user joins, it will not be able to - * find a node pointing to this leaf and record operations that - * point to this leaf. + * check a new tree mod log user joins we will not have an + * existing log of operations on this node that we have to + * contend with. */ - if (btrfs_header_level(buf) == 0 && - test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags)) + if (test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags)) must_pin = true; if (must_pin || btrfs_is_zoned(fs_info)) { diff -Nru linux-6.0.6/fs/btrfs/file.c linux-6.0.12/fs/btrfs/file.c --- linux-6.0.6/fs/btrfs/file.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/file.c 2023-01-18 18:27:39.000000000 +0000 @@ -1889,6 +1889,7 @@ loff_t endbyte; ssize_t err; unsigned int ilock_flags = 0; + struct iomap_dio *dio; if (iocb->ki_flags & IOCB_NOWAIT) ilock_flags |= BTRFS_ILOCK_TRY; @@ -1949,11 +1950,22 @@ * So here we disable page faults in the iov_iter and then retry if we * got -EFAULT, faulting in the pages before the retry. */ -again: from->nofault = true; - err = btrfs_dio_rw(iocb, from, written); + dio = btrfs_dio_write(iocb, from, written); from->nofault = false; + /* + * iomap_dio_complete() will call btrfs_sync_file() if we have a dsync + * iocb, and that needs to lock the inode. So unlock it before calling + * iomap_dio_complete() to avoid a deadlock. + */ + btrfs_inode_unlock(inode, ilock_flags); + + if (IS_ERR_OR_NULL(dio)) + err = PTR_ERR_OR_ZERO(dio); + else + err = iomap_dio_complete(dio); + /* No increment (+=) because iomap returns a cumulative value. */ if (err > 0) written = err; @@ -1979,12 +1991,10 @@ } else { fault_in_iov_iter_readable(from, left); prev_left = left; - goto again; + goto relock; } } - btrfs_inode_unlock(inode, ilock_flags); - /* * If 'err' is -ENOTBLK or we have not written all data, then it means * we must fallback to buffered IO. @@ -3787,7 +3797,7 @@ */ pagefault_disable(); to->nofault = true; - ret = btrfs_dio_rw(iocb, to, read); + ret = btrfs_dio_read(iocb, to, read); to->nofault = false; pagefault_enable(); diff -Nru linux-6.0.6/fs/btrfs/inode.c linux-6.0.12/fs/btrfs/inode.c --- linux-6.0.6/fs/btrfs/inode.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/inode.c 2023-01-18 18:27:39.000000000 +0000 @@ -8142,7 +8142,7 @@ */ status = BLK_STS_RESOURCE; dip->csums = kcalloc(nr_sectors, fs_info->csum_size, GFP_NOFS); - if (!dip) + if (!dip->csums) goto out_err; status = btrfs_lookup_bio_sums(inode, dio_bio, dip->csums); @@ -8241,13 +8241,21 @@ .bio_set = &btrfs_dio_bioset, }; -ssize_t btrfs_dio_rw(struct kiocb *iocb, struct iov_iter *iter, size_t done_before) +ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter, size_t done_before) { struct btrfs_dio_data data; return iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops, - IOMAP_DIO_PARTIAL | IOMAP_DIO_NOSYNC, - &data, done_before); + IOMAP_DIO_PARTIAL, &data, done_before); +} + +struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter, + size_t done_before) +{ + struct btrfs_dio_data data; + + return __iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops, + IOMAP_DIO_PARTIAL, &data, done_before); } static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, diff -Nru linux-6.0.6/fs/btrfs/ioctl.c linux-6.0.12/fs/btrfs/ioctl.c --- linux-6.0.6/fs/btrfs/ioctl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/ioctl.c 2023-01-18 18:27:39.000000000 +0000 @@ -3105,6 +3105,8 @@ } } + btrfs_free_path(path); + path = NULL; if (copy_to_user(argp, subvol_info, sizeof(*subvol_info))) ret = -EFAULT; @@ -3194,6 +3196,8 @@ } out: + btrfs_free_path(path); + if (!ret || ret == -EOVERFLOW) { rootrefs->num_items = found; /* update min_treeid for next search */ @@ -3205,7 +3209,6 @@ } kfree(rootrefs); - btrfs_free_path(path); return ret; } @@ -4231,6 +4234,8 @@ ipath->fspath->val[i] = rel_ptr; } + btrfs_free_path(path); + path = NULL; ret = copy_to_user((void __user *)(unsigned long)ipa->fspath, ipath->fspath, size); if (ret) { @@ -4281,21 +4286,20 @@ size = min_t(u32, loi->size, SZ_16M); } - path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto out; - } - inodes = init_data_container(size); if (IS_ERR(inodes)) { ret = PTR_ERR(inodes); - inodes = NULL; - goto out; + goto out_loi; } + path = btrfs_alloc_path(); + if (!path) { + ret = -ENOMEM; + goto out; + } ret = iterate_inodes_from_logical(loi->logical, fs_info, path, inodes, ignore_offset); + btrfs_free_path(path); if (ret == -EINVAL) ret = -ENOENT; if (ret < 0) @@ -4307,7 +4311,6 @@ ret = -EFAULT; out: - btrfs_free_path(path); kvfree(inodes); out_loi: kfree(loi); diff -Nru linux-6.0.6/fs/btrfs/qgroup.c linux-6.0.12/fs/btrfs/qgroup.c --- linux-6.0.6/fs/btrfs/qgroup.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/qgroup.c 2023-01-18 18:27:39.000000000 +0000 @@ -2920,14 +2920,7 @@ dstgroup->rsv_rfer = inherit->lim.rsv_rfer; dstgroup->rsv_excl = inherit->lim.rsv_excl; - ret = update_qgroup_limit_item(trans, dstgroup); - if (ret) { - fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT; - btrfs_info(fs_info, - "unable to update quota limit for %llu", - dstgroup->qgroupid); - goto unlock; - } + qgroup_dirty(fs_info, dstgroup); } if (srcid) { diff -Nru linux-6.0.6/fs/btrfs/raid56.c linux-6.0.12/fs/btrfs/raid56.c --- linux-6.0.6/fs/btrfs/raid56.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/raid56.c 2023-01-18 18:27:39.000000000 +0000 @@ -2767,8 +2767,10 @@ rbio->faila = find_logical_bio_stripe(rbio, bio); if (rbio->faila == -1) { - BUG(); - kfree(rbio); + btrfs_warn_rl(fs_info, + "can not determine the failed stripe number for full stripe %llu", + bioc->raid_map[0]); + __free_raid_bio(rbio); return NULL; } diff -Nru linux-6.0.6/fs/btrfs/sysfs.c linux-6.0.12/fs/btrfs/sysfs.c --- linux-6.0.6/fs/btrfs/sysfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/sysfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -2251,8 +2251,11 @@ #ifdef CONFIG_BTRFS_DEBUG ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_debug_feature_attr_group); - if (ret) - goto out2; + if (ret) { + sysfs_unmerge_group(&btrfs_kset->kobj, + &btrfs_static_feature_attr_group); + goto out_remove_group; + } #endif return 0; diff -Nru linux-6.0.6/fs/btrfs/tests/btrfs-tests.c linux-6.0.12/fs/btrfs/tests/btrfs-tests.c --- linux-6.0.6/fs/btrfs/tests/btrfs-tests.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/tests/btrfs-tests.c 2023-01-18 18:27:39.000000000 +0000 @@ -200,7 +200,7 @@ void btrfs_free_dummy_root(struct btrfs_root *root) { - if (!root) + if (IS_ERR_OR_NULL(root)) return; /* Will be freed by btrfs_free_fs_roots */ if (WARN_ON(test_bit(BTRFS_ROOT_IN_RADIX, &root->state))) diff -Nru linux-6.0.6/fs/btrfs/tests/qgroup-tests.c linux-6.0.12/fs/btrfs/tests/qgroup-tests.c --- linux-6.0.6/fs/btrfs/tests/qgroup-tests.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/tests/qgroup-tests.c 2023-01-18 18:27:39.000000000 +0000 @@ -225,20 +225,20 @@ */ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false); if (ret) { - ulist_free(old_roots); test_err("couldn't find old roots: %d", ret); return ret; } ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, BTRFS_FS_TREE_OBJECTID); - if (ret) + if (ret) { + ulist_free(old_roots); return ret; + } ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); if (ret) { ulist_free(old_roots); - ulist_free(new_roots); test_err("couldn't find old roots: %d", ret); return ret; } @@ -250,29 +250,31 @@ return ret; } + /* btrfs_qgroup_account_extent() always frees the ulists passed to it. */ + old_roots = NULL; + new_roots = NULL; + if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, nodesize, nodesize)) { test_err("qgroup counts didn't match expected values"); return -EINVAL; } - old_roots = NULL; - new_roots = NULL; ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false); if (ret) { - ulist_free(old_roots); test_err("couldn't find old roots: %d", ret); return ret; } ret = remove_extent_item(root, nodesize, nodesize); - if (ret) + if (ret) { + ulist_free(old_roots); return -EINVAL; + } ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); if (ret) { ulist_free(old_roots); - ulist_free(new_roots); test_err("couldn't find old roots: %d", ret); return ret; } @@ -322,20 +324,20 @@ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false); if (ret) { - ulist_free(old_roots); test_err("couldn't find old roots: %d", ret); return ret; } ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, BTRFS_FS_TREE_OBJECTID); - if (ret) + if (ret) { + ulist_free(old_roots); return ret; + } ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); if (ret) { ulist_free(old_roots); - ulist_free(new_roots); test_err("couldn't find old roots: %d", ret); return ret; } @@ -355,20 +357,20 @@ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false); if (ret) { - ulist_free(old_roots); test_err("couldn't find old roots: %d", ret); return ret; } ret = add_tree_ref(root, nodesize, nodesize, 0, BTRFS_FIRST_FREE_OBJECTID); - if (ret) + if (ret) { + ulist_free(old_roots); return ret; + } ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); if (ret) { ulist_free(old_roots); - ulist_free(new_roots); test_err("couldn't find old roots: %d", ret); return ret; } @@ -394,20 +396,20 @@ ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false); if (ret) { - ulist_free(old_roots); test_err("couldn't find old roots: %d", ret); return ret; } ret = remove_extent_ref(root, nodesize, nodesize, 0, BTRFS_FIRST_FREE_OBJECTID); - if (ret) + if (ret) { + ulist_free(old_roots); return ret; + } ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); if (ret) { ulist_free(old_roots); - ulist_free(new_roots); test_err("couldn't find old roots: %d", ret); return ret; } diff -Nru linux-6.0.6/fs/btrfs/tree-log.c linux-6.0.12/fs/btrfs/tree-log.c --- linux-6.0.6/fs/btrfs/tree-log.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/tree-log.c 2023-01-18 18:27:39.000000000 +0000 @@ -3834,15 +3834,29 @@ u64 *last_old_dentry_offset) { struct btrfs_root *log = inode->root->log_root; - struct extent_buffer *src = path->nodes[0]; - const int nritems = btrfs_header_nritems(src); + struct extent_buffer *src; + const int nritems = btrfs_header_nritems(path->nodes[0]); const u64 ino = btrfs_ino(inode); bool last_found = false; int batch_start = 0; int batch_size = 0; int i; - for (i = path->slots[0]; i < nritems; i++) { + /* + * We need to clone the leaf, release the read lock on it, and use the + * clone before modifying the log tree. See the comment at copy_items() + * about why we need to do this. + */ + src = btrfs_clone_extent_buffer(path->nodes[0]); + if (!src) + return -ENOMEM; + + i = path->slots[0]; + btrfs_release_path(path); + path->nodes[0] = src; + path->slots[0] = i; + + for (; i < nritems; i++) { struct btrfs_dir_item *di; struct btrfs_key key; int ret; @@ -4414,7 +4428,7 @@ { struct btrfs_root *log = inode->root->log_root; struct btrfs_file_extent_item *extent; - struct extent_buffer *src = src_path->nodes[0]; + struct extent_buffer *src; int ret = 0; struct btrfs_key *ins_keys; u32 *ins_sizes; @@ -4425,6 +4439,43 @@ const bool skip_csum = (inode->flags & BTRFS_INODE_NODATASUM); const u64 i_size = i_size_read(&inode->vfs_inode); + /* + * To keep lockdep happy and avoid deadlocks, clone the source leaf and + * use the clone. This is because otherwise we would be changing the log + * tree, to insert items from the subvolume tree or insert csum items, + * while holding a read lock on a leaf from the subvolume tree, which + * creates a nasty lock dependency when COWing log tree nodes/leaves: + * + * 1) Modifying the log tree triggers an extent buffer allocation while + * holding a write lock on a parent extent buffer from the log tree. + * Allocating the pages for an extent buffer, or the extent buffer + * struct, can trigger inode eviction and finally the inode eviction + * will trigger a release/remove of a delayed node, which requires + * taking the delayed node's mutex; + * + * 2) Allocating a metadata extent for a log tree can trigger the async + * reclaim thread and make us wait for it to release enough space and + * unblock our reservation ticket. The reclaim thread can start + * flushing delayed items, and that in turn results in the need to + * lock delayed node mutexes and in the need to write lock extent + * buffers of a subvolume tree - all this while holding a write lock + * on the parent extent buffer in the log tree. + * + * So one task in scenario 1) running in parallel with another task in + * scenario 2) could lead to a deadlock, one wanting to lock a delayed + * node mutex while having a read lock on a leaf from the subvolume, + * while the other is holding the delayed node's mutex and wants to + * write lock the same subvolume leaf for flushing delayed items. + */ + src = btrfs_clone_extent_buffer(src_path->nodes[0]); + if (!src) + return -ENOMEM; + + i = src_path->slots[0]; + btrfs_release_path(src_path); + src_path->nodes[0] = src; + src_path->slots[0] = i; + ins_data = kmalloc(nr * sizeof(struct btrfs_key) + nr * sizeof(u32), GFP_NOFS); if (!ins_data) diff -Nru linux-6.0.6/fs/btrfs/volumes.c linux-6.0.12/fs/btrfs/volumes.c --- linux-6.0.6/fs/btrfs/volumes.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/volumes.c 2023-01-18 18:27:39.000000000 +0000 @@ -1009,6 +1009,18 @@ rcu_assign_pointer(device->name, name); } + if (orig_dev->zone_info) { + struct btrfs_zoned_device_info *zone_info; + + zone_info = btrfs_clone_dev_zone_info(orig_dev); + if (!zone_info) { + btrfs_free_device(device); + ret = -ENOMEM; + goto error; + } + device->zone_info = zone_info; + } + list_add(&device->dev_list, &fs_devices->devices); device->fs_devices = fs_devices; fs_devices->num_devices++; @@ -6805,18 +6817,18 @@ static bool dev_args_match_device(const struct btrfs_dev_lookup_args *args, const struct btrfs_device *device) { - ASSERT((args->devid != (u64)-1) || args->missing); + if (args->missing) { + if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) && + !device->bdev) + return true; + return false; + } - if ((args->devid != (u64)-1) && device->devid != args->devid) + if (device->devid != args->devid) return false; if (args->uuid && memcmp(device->uuid, args->uuid, BTRFS_UUID_SIZE) != 0) return false; - if (!args->missing) - return true; - if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) && - !device->bdev) - return true; - return false; + return true; } /* @@ -7029,6 +7041,7 @@ u64 devid; u64 type; u8 uuid[BTRFS_UUID_SIZE]; + int index; int num_stripes; int ret; int i; @@ -7036,6 +7049,7 @@ logical = key->offset; length = btrfs_chunk_length(leaf, chunk); type = btrfs_chunk_type(leaf, chunk); + index = btrfs_bg_flags_to_raid_index(type); num_stripes = btrfs_chunk_num_stripes(leaf, chunk); #if BITS_PER_LONG == 32 @@ -7089,7 +7103,15 @@ map->io_align = btrfs_chunk_io_align(leaf, chunk); map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk); map->type = type; - map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk); + /* + * We can't use the sub_stripes value, as for profiles other than + * RAID10, they may have 0 as sub_stripes for filesystems created by + * older mkfs (sub_stripes = btrfs_raid_array[index].sub_stripes; map->verified_stripes = 0; em->orig_block_len = btrfs_calc_stripe_length(em); for (i = 0; i < num_stripes; i++) { @@ -7621,10 +7643,11 @@ return ret; } -void btrfs_init_devices_late(struct btrfs_fs_info *fs_info) +int btrfs_init_devices_late(struct btrfs_fs_info *fs_info) { struct btrfs_fs_devices *fs_devices = fs_info->fs_devices, *seed_devs; struct btrfs_device *device; + int ret = 0; fs_devices->fs_info = fs_info; @@ -7633,12 +7656,18 @@ device->fs_info = fs_info; list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) { - list_for_each_entry(device, &seed_devs->devices, dev_list) + list_for_each_entry(device, &seed_devs->devices, dev_list) { device->fs_info = fs_info; + ret = btrfs_get_dev_zone_info(device, false); + if (ret) + break; + } seed_devs->fs_info = fs_info; } mutex_unlock(&fs_devices->device_list_mutex); + + return ret; } static u64 btrfs_dev_stats_value(const struct extent_buffer *eb, diff -Nru linux-6.0.6/fs/btrfs/volumes.h linux-6.0.12/fs/btrfs/volumes.h --- linux-6.0.6/fs/btrfs/volumes.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/volumes.h 2023-01-18 18:27:39.000000000 +0000 @@ -629,7 +629,7 @@ void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index); int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info, struct btrfs_ioctl_get_dev_stats *stats); -void btrfs_init_devices_late(struct btrfs_fs_info *fs_info); +int btrfs_init_devices_late(struct btrfs_fs_info *fs_info); int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info); int btrfs_run_dev_stats(struct btrfs_trans_handle *trans); void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_device *srcdev); diff -Nru linux-6.0.6/fs/btrfs/zoned.c linux-6.0.12/fs/btrfs/zoned.c --- linux-6.0.6/fs/btrfs/zoned.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/zoned.c 2023-01-18 18:27:39.000000000 +0000 @@ -134,7 +134,8 @@ super[i] = page_address(page[i]); } - if (super[0]->generation > super[1]->generation) + if (btrfs_super_generation(super[0]) > + btrfs_super_generation(super[1])) sector = zones[1].start; else sector = zones[0].start; @@ -466,7 +467,7 @@ goto out; } - zones = kcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL); + zones = kvcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL); if (!zones) { ret = -ENOMEM; goto out; @@ -585,7 +586,7 @@ } - kfree(zones); + kvfree(zones); switch (bdev_zoned_model(bdev)) { case BLK_ZONED_HM: @@ -617,7 +618,7 @@ return 0; out: - kfree(zones); + kvfree(zones); out_free_zone_info: btrfs_destroy_dev_zone_info(device); @@ -639,6 +640,46 @@ device->zone_info = NULL; } +struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(struct btrfs_device *orig_dev) +{ + struct btrfs_zoned_device_info *zone_info; + + zone_info = kmemdup(orig_dev->zone_info, sizeof(*zone_info), GFP_KERNEL); + if (!zone_info) + return NULL; + + zone_info->seq_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL); + if (!zone_info->seq_zones) + goto out; + + bitmap_copy(zone_info->seq_zones, orig_dev->zone_info->seq_zones, + zone_info->nr_zones); + + zone_info->empty_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL); + if (!zone_info->empty_zones) + goto out; + + bitmap_copy(zone_info->empty_zones, orig_dev->zone_info->empty_zones, + zone_info->nr_zones); + + zone_info->active_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL); + if (!zone_info->active_zones) + goto out; + + bitmap_copy(zone_info->active_zones, orig_dev->zone_info->active_zones, + zone_info->nr_zones); + zone_info->zone_cache = NULL; + + return zone_info; + +out: + bitmap_free(zone_info->seq_zones); + bitmap_free(zone_info->empty_zones); + bitmap_free(zone_info->active_zones); + kfree(zone_info); + return NULL; +} + int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, struct blk_zone *zone) { diff -Nru linux-6.0.6/fs/btrfs/zoned.h linux-6.0.12/fs/btrfs/zoned.h --- linux-6.0.6/fs/btrfs/zoned.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/btrfs/zoned.h 2023-01-18 18:27:39.000000000 +0000 @@ -36,6 +36,7 @@ int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info); int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache); void btrfs_destroy_dev_zone_info(struct btrfs_device *device); +struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(struct btrfs_device *orig_dev); int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info); int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info); int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw, @@ -103,6 +104,16 @@ static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { } +/* + * In case the kernel is compiled without CONFIG_BLK_DEV_ZONED we'll never call + * into btrfs_clone_dev_zone_info() so it's safe to return NULL here. + */ +static inline struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info( + struct btrfs_device *orig_dev) +{ + return NULL; +} + static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info) { if (!btrfs_is_zoned(fs_info)) diff -Nru linux-6.0.6/fs/buffer.c linux-6.0.12/fs/buffer.c --- linux-6.0.6/fs/buffer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/buffer.c 2023-01-18 18:27:39.000000000 +0000 @@ -2352,7 +2352,7 @@ struct address_space *mapping = inode->i_mapping; const struct address_space_operations *aops = mapping->a_ops; struct page *page; - void *fsdata; + void *fsdata = NULL; int err; err = inode_newsize_ok(inode, size); @@ -2378,7 +2378,7 @@ const struct address_space_operations *aops = mapping->a_ops; unsigned int blocksize = i_blocksize(inode); struct page *page; - void *fsdata; + void *fsdata = NULL; pgoff_t index, curidx; loff_t curpos; unsigned zerofrom, offset, len; diff -Nru linux-6.0.6/fs/ceph/caps.c linux-6.0.12/fs/ceph/caps.c --- linux-6.0.6/fs/ceph/caps.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ceph/caps.c 2023-01-18 18:27:39.000000000 +0000 @@ -2247,7 +2247,6 @@ struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_mds_request *req1 = NULL, *req2 = NULL; - unsigned int max_sessions; int ret, err = 0; spin_lock(&ci->i_unsafe_lock); @@ -2266,27 +2265,23 @@ spin_unlock(&ci->i_unsafe_lock); /* - * The mdsc->max_sessions is unlikely to be changed - * mostly, here we will retry it by reallocating the - * sessions array memory to get rid of the mdsc->mutex - * lock. - */ -retry: - max_sessions = mdsc->max_sessions; - - /* * Trigger to flush the journal logs in all the relevant MDSes * manually, or in the worst case we must wait at most 5 seconds * to wait the journal logs to be flushed by the MDSes periodically. */ - if ((req1 || req2) && likely(max_sessions)) { - struct ceph_mds_session **sessions = NULL; - struct ceph_mds_session *s; + if (req1 || req2) { struct ceph_mds_request *req; + struct ceph_mds_session **sessions; + struct ceph_mds_session *s; + unsigned int max_sessions; int i; - sessions = kzalloc(max_sessions * sizeof(s), GFP_KERNEL); + mutex_lock(&mdsc->mutex); + max_sessions = mdsc->max_sessions; + + sessions = kcalloc(max_sessions, sizeof(s), GFP_KERNEL); if (!sessions) { + mutex_unlock(&mdsc->mutex); err = -ENOMEM; goto out; } @@ -2298,16 +2293,6 @@ s = req->r_session; if (!s) continue; - if (unlikely(s->s_mds >= max_sessions)) { - spin_unlock(&ci->i_unsafe_lock); - for (i = 0; i < max_sessions; i++) { - s = sessions[i]; - if (s) - ceph_put_mds_session(s); - } - kfree(sessions); - goto retry; - } if (!sessions[s->s_mds]) { s = ceph_get_mds_session(s); sessions[s->s_mds] = s; @@ -2320,16 +2305,6 @@ s = req->r_session; if (!s) continue; - if (unlikely(s->s_mds >= max_sessions)) { - spin_unlock(&ci->i_unsafe_lock); - for (i = 0; i < max_sessions; i++) { - s = sessions[i]; - if (s) - ceph_put_mds_session(s); - } - kfree(sessions); - goto retry; - } if (!sessions[s->s_mds]) { s = ceph_get_mds_session(s); sessions[s->s_mds] = s; @@ -2341,11 +2316,12 @@ /* the auth MDS */ spin_lock(&ci->i_ceph_lock); if (ci->i_auth_cap) { - s = ci->i_auth_cap->session; - if (!sessions[s->s_mds]) - sessions[s->s_mds] = ceph_get_mds_session(s); + s = ci->i_auth_cap->session; + if (!sessions[s->s_mds]) + sessions[s->s_mds] = ceph_get_mds_session(s); } spin_unlock(&ci->i_ceph_lock); + mutex_unlock(&mdsc->mutex); /* send flush mdlog request to MDSes */ for (i = 0; i < max_sessions; i++) { diff -Nru linux-6.0.6/fs/ceph/snap.c linux-6.0.12/fs/ceph/snap.c --- linux-6.0.6/fs/ceph/snap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ceph/snap.c 2023-01-18 18:27:39.000000000 +0000 @@ -763,7 +763,7 @@ struct ceph_mds_snap_realm *ri; /* encoded */ __le64 *snaps; /* encoded */ __le64 *prior_parent_snaps; /* encoded */ - struct ceph_snap_realm *realm = NULL; + struct ceph_snap_realm *realm; struct ceph_snap_realm *first_realm = NULL; struct ceph_snap_realm *realm_to_rebuild = NULL; int rebuild_snapcs; @@ -774,6 +774,7 @@ dout("%s deletion=%d\n", __func__, deletion); more: + realm = NULL; rebuild_snapcs = 0; ceph_decode_need(&p, e, sizeof(*ri), bad); ri = p; diff -Nru linux-6.0.6/fs/cifs/cifsfs.c linux-6.0.12/fs/cifs/cifsfs.c --- linux-6.0.6/fs/cifs/cifsfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/cifs/cifsfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -1252,7 +1252,7 @@ rc = filemap_write_and_wait_range(src_inode->i_mapping, off, off + len - 1); if (rc) - goto out; + goto unlock; /* should we flush first and last page first */ truncate_inode_pages(&target_inode->i_data, 0); @@ -1268,6 +1268,8 @@ * that target is updated on the server */ CIFS_I(target_inode)->time = 0; + +unlock: /* although unlocking in the reverse order from locking is not * strictly necessary here it is a little cleaner to be consistent */ diff -Nru linux-6.0.6/fs/cifs/connect.c linux-6.0.12/fs/cifs/connect.c --- linux-6.0.6/fs/cifs/connect.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/cifs/connect.c 2023-01-18 18:27:39.000000000 +0000 @@ -3846,9 +3846,13 @@ uuid_copy(&cifs_sb->dfs_mount_id, &mnt_ctx.mount_id); out: - free_xid(mnt_ctx.xid); cifs_try_adding_channels(cifs_sb, mnt_ctx.ses); - return mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon); + rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon); + if (rc) + goto error; + + free_xid(mnt_ctx.xid); + return rc; error: dfs_cache_put_refsrv_sessions(&mnt_ctx.mount_id); @@ -3875,8 +3879,12 @@ goto error; } + rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon); + if (rc) + goto error; + free_xid(mnt_ctx.xid); - return mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon); + return rc; error: mount_put_conns(&mnt_ctx); @@ -3921,12 +3929,11 @@ pSMB->AndXCommand = 0xFF; pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); bcc_ptr = &pSMB->Password[0]; - if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) { - pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ - *bcc_ptr = 0; /* password is null byte */ - bcc_ptr++; /* skip password */ - /* already aligned so no need to do it below */ - } + + pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ + *bcc_ptr = 0; /* password is null byte */ + bcc_ptr++; /* skip password */ + /* already aligned so no need to do it below */ if (ses->server->sign) smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; diff -Nru linux-6.0.6/fs/cifs/ioctl.c linux-6.0.12/fs/cifs/ioctl.c --- linux-6.0.6/fs/cifs/ioctl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/cifs/ioctl.c 2023-01-18 18:27:39.000000000 +0000 @@ -343,7 +343,7 @@ rc = put_user(ExtAttrBits & FS_FL_USER_VISIBLE, (int __user *)arg); - if (rc != EOPNOTSUPP) + if (rc != -EOPNOTSUPP) break; } #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ @@ -373,7 +373,7 @@ * pSMBFile->fid.netfid, * extAttrBits, * &ExtAttrMask); - * if (rc != EOPNOTSUPP) + * if (rc != -EOPNOTSUPP) * break; */ diff -Nru linux-6.0.6/fs/cifs/misc.c linux-6.0.12/fs/cifs/misc.c --- linux-6.0.6/fs/cifs/misc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/cifs/misc.c 2023-01-18 18:27:39.000000000 +0000 @@ -400,6 +400,7 @@ { struct smb_hdr *buf = (struct smb_hdr *)buffer; struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf; + struct TCP_Server_Info *pserver; struct cifs_ses *ses; struct cifs_tcon *tcon; struct cifsInodeInfo *pCifsInode; @@ -464,9 +465,12 @@ if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)) return false; + /* If server is a channel, select the primary channel */ + pserver = CIFS_SERVER_IS_CHAN(srv) ? srv->primary_server : srv; + /* look up tcon based on tid & uid */ spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry(ses, &srv->smb_ses_list, smb_ses_list) { + list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { if (tcon->tid != buf->Tid) continue; diff -Nru linux-6.0.6/fs/cifs/sess.c linux-6.0.12/fs/cifs/sess.c --- linux-6.0.6/fs/cifs/sess.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/cifs/sess.c 2023-01-18 18:27:39.000000000 +0000 @@ -302,14 +302,14 @@ /* now drop the ref to the current iface */ if (old_iface && iface) { - kref_put(&old_iface->refcount, release_iface); cifs_dbg(FYI, "replacing iface: %pIS with %pIS\n", &old_iface->sockaddr, &iface->sockaddr); - } else if (old_iface) { kref_put(&old_iface->refcount, release_iface); + } else if (old_iface) { cifs_dbg(FYI, "releasing ref to iface: %pIS\n", &old_iface->sockaddr); + kref_put(&old_iface->refcount, release_iface); } else { WARN_ON(!iface); cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr); diff -Nru linux-6.0.6/fs/cifs/smb2misc.c linux-6.0.12/fs/cifs/smb2misc.c --- linux-6.0.6/fs/cifs/smb2misc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/cifs/smb2misc.c 2023-01-18 18:27:39.000000000 +0000 @@ -135,6 +135,7 @@ int smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server) { + struct TCP_Server_Info *pserver; struct smb2_hdr *shdr = (struct smb2_hdr *)buf; struct smb2_pdu *pdu = (struct smb2_pdu *)shdr; int hdr_size = sizeof(struct smb2_hdr); @@ -143,6 +144,9 @@ __u32 calc_len; /* calculated length */ __u64 mid; + /* If server is a channel, select the primary channel */ + pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; + /* * Add function to do table lookup of StructureSize by command * ie Validate the wct via smb2_struct_sizes table above @@ -155,7 +159,7 @@ /* decrypt frame now that it is completely read in */ spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry(iter, &server->smb_ses_list, smb_ses_list) { + list_for_each_entry(iter, &pserver->smb_ses_list, smb_ses_list) { if (iter->Suid == le64_to_cpu(thdr->SessionId)) { ses = iter; break; @@ -671,6 +675,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) { struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer; + struct TCP_Server_Info *pserver; struct cifs_ses *ses; struct cifs_tcon *tcon; struct cifsInodeInfo *cinode; @@ -691,9 +696,12 @@ cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel); + /* If server is a channel, select the primary channel */ + pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; + /* look up tcon based on tid & uid */ spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { spin_lock(&tcon->open_file_lock); diff -Nru linux-6.0.6/fs/cifs/smb2ops.c linux-6.0.12/fs/cifs/smb2ops.c --- linux-6.0.6/fs/cifs/smb2ops.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/cifs/smb2ops.c 2023-01-18 18:27:39.000000000 +0000 @@ -1123,6 +1123,8 @@ COMPOUND_FID, current->tgid, FILE_FULL_EA_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); + if (rc) + goto sea_exit; smb2_set_next_command(tcon, &rqst[1]); smb2_set_related(&rqst[1]); @@ -1133,6 +1135,8 @@ rqst[2].rq_nvec = 1; rc = SMB2_close_init(tcon, server, &rqst[2], COMPOUND_FID, COMPOUND_FID, false); + if (rc) + goto sea_exit; smb2_set_related(&rqst[2]); rc = compound_send_recv(xid, ses, server, @@ -2288,14 +2292,18 @@ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server) { struct smb2_hdr *shdr = (struct smb2_hdr *)buf; + struct TCP_Server_Info *pserver; struct cifs_ses *ses; struct cifs_tcon *tcon; if (shdr->Status != STATUS_NETWORK_NAME_DELETED) return; + /* If server is a channel, select the primary channel */ + pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; + spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { if (tcon->tid == le32_to_cpu(shdr->Id.SyncId.TreeId)) { spin_lock(&tcon->tc_lock); diff -Nru linux-6.0.6/fs/cifs/smb2transport.c linux-6.0.12/fs/cifs/smb2transport.c --- linux-6.0.6/fs/cifs/smb2transport.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/cifs/smb2transport.c 2023-01-18 18:27:39.000000000 +0000 @@ -140,9 +140,13 @@ static struct cifs_ses * smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) { + struct TCP_Server_Info *pserver; struct cifs_ses *ses; - list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + /* If server is a channel, select the primary channel */ + pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; + + list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { if (ses->Suid != ses_id) continue; ++ses->ses_count; diff -Nru linux-6.0.6/fs/crypto/fscrypt_private.h linux-6.0.12/fs/crypto/fscrypt_private.h --- linux-6.0.6/fs/crypto/fscrypt_private.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/crypto/fscrypt_private.h 2023-01-18 18:27:39.000000000 +0000 @@ -225,7 +225,7 @@ * will be NULL if the master key was found in a process-subscribed * keyring rather than in the filesystem-level keyring. */ - struct key *ci_master_key; + struct fscrypt_master_key *ci_master_key; /* * Link in list of inodes that were unlocked with the master key. @@ -437,6 +437,40 @@ struct fscrypt_master_key { /* + * Back-pointer to the super_block of the filesystem to which this + * master key has been added. Only valid if ->mk_active_refs > 0. + */ + struct super_block *mk_sb; + + /* + * Link in ->mk_sb->s_master_keys->key_hashtable. + * Only valid if ->mk_active_refs > 0. + */ + struct hlist_node mk_node; + + /* Semaphore that protects ->mk_secret and ->mk_users */ + struct rw_semaphore mk_sem; + + /* + * Active and structural reference counts. An active ref guarantees + * that the struct continues to exist, continues to be in the keyring + * ->mk_sb->s_master_keys, and that any embedded subkeys (e.g. + * ->mk_direct_keys) that have been prepared continue to exist. + * A structural ref only guarantees that the struct continues to exist. + * + * There is one active ref associated with ->mk_secret being present, + * and one active ref for each inode in ->mk_decrypted_inodes. + * + * There is one structural ref associated with the active refcount being + * nonzero. Finding a key in the keyring also takes a structural ref, + * which is then held temporarily while the key is operated on. + */ + refcount_t mk_active_refs; + refcount_t mk_struct_refs; + + struct rcu_head mk_rcu_head; + + /* * The secret key material. After FS_IOC_REMOVE_ENCRYPTION_KEY is * executed, this is wiped and no new inodes can be unlocked with this * key; however, there may still be inodes in ->mk_decrypted_inodes @@ -444,7 +478,10 @@ * FS_IOC_REMOVE_ENCRYPTION_KEY can be retried, or * FS_IOC_ADD_ENCRYPTION_KEY can add the secret again. * - * Locking: protected by this master key's key->sem. + * While ->mk_secret is present, one ref in ->mk_active_refs is held. + * + * Locking: protected by ->mk_sem. The manipulation of ->mk_active_refs + * associated with this field is protected by ->mk_sem as well. */ struct fscrypt_master_key_secret mk_secret; @@ -465,23 +502,13 @@ * * This is NULL for v1 policy keys; those can only be added by root. * - * Locking: in addition to this keyring's own semaphore, this is - * protected by this master key's key->sem, so we can do atomic - * search+insert. It can also be searched without taking any locks, but - * in that case the returned key may have already been removed. + * Locking: protected by ->mk_sem. (We don't just rely on the keyrings + * subsystem semaphore ->mk_users->sem, as we need support for atomic + * search+insert along with proper synchronization with ->mk_secret.) */ struct key *mk_users; /* - * Length of ->mk_decrypted_inodes, plus one if mk_secret is present. - * Once this goes to 0, the master key is removed from ->s_master_keys. - * The 'struct fscrypt_master_key' will continue to live as long as the - * 'struct key' whose payload it is, but we won't let this reference - * count rise again. - */ - refcount_t mk_refcount; - - /* * List of inodes that were unlocked using this key. This allows the * inodes to be evicted efficiently if the key is removed. */ @@ -506,10 +533,10 @@ is_master_key_secret_present(const struct fscrypt_master_key_secret *secret) { /* - * The READ_ONCE() is only necessary for fscrypt_drop_inode() and - * fscrypt_key_describe(). These run in atomic context, so they can't - * take the key semaphore and thus 'secret' can change concurrently - * which would be a data race. But they only need to know whether the + * The READ_ONCE() is only necessary for fscrypt_drop_inode(). + * fscrypt_drop_inode() runs in atomic context, so it can't take the key + * semaphore and thus 'secret' can change concurrently which would be a + * data race. But fscrypt_drop_inode() only need to know whether the * secret *was* present at the time of check, so READ_ONCE() suffices. */ return READ_ONCE(secret->size) != 0; @@ -538,7 +565,11 @@ return 0; } -struct key * +void fscrypt_put_master_key(struct fscrypt_master_key *mk); + +void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk); + +struct fscrypt_master_key * fscrypt_find_master_key(struct super_block *sb, const struct fscrypt_key_specifier *mk_spec); diff -Nru linux-6.0.6/fs/crypto/hooks.c linux-6.0.12/fs/crypto/hooks.c --- linux-6.0.6/fs/crypto/hooks.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/crypto/hooks.c 2023-01-18 18:27:39.000000000 +0000 @@ -5,8 +5,6 @@ * Encryption hooks for higher-level filesystem operations. */ -#include - #include "fscrypt_private.h" /** @@ -142,7 +140,6 @@ unsigned int oldflags, unsigned int flags) { struct fscrypt_info *ci; - struct key *key; struct fscrypt_master_key *mk; int err; @@ -158,14 +155,13 @@ ci = inode->i_crypt_info; if (ci->ci_policy.version != FSCRYPT_POLICY_V2) return -EINVAL; - key = ci->ci_master_key; - mk = key->payload.data[0]; - down_read(&key->sem); + mk = ci->ci_master_key; + down_read(&mk->mk_sem); if (is_master_key_secret_present(&mk->mk_secret)) err = fscrypt_derive_dirhash_key(ci, mk); else err = -ENOKEY; - up_read(&key->sem); + up_read(&mk->mk_sem); return err; } return 0; diff -Nru linux-6.0.6/fs/crypto/keyring.c linux-6.0.12/fs/crypto/keyring.c --- linux-6.0.6/fs/crypto/keyring.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/crypto/keyring.c 2023-01-18 18:27:39.000000000 +0000 @@ -18,6 +18,7 @@ * information about these ioctls. */ +#include #include #include #include @@ -25,6 +26,18 @@ #include "fscrypt_private.h" +/* The master encryption keys for a filesystem (->s_master_keys) */ +struct fscrypt_keyring { + /* + * Lock that protects ->key_hashtable. It does *not* protect the + * fscrypt_master_key structs themselves. + */ + spinlock_t lock; + + /* Hash table that maps fscrypt_key_specifier to fscrypt_master_key */ + struct hlist_head key_hashtable[128]; +}; + static void wipe_master_key_secret(struct fscrypt_master_key_secret *secret) { fscrypt_destroy_hkdf(&secret->hkdf); @@ -38,20 +51,70 @@ memzero_explicit(src, sizeof(*src)); } -static void free_master_key(struct fscrypt_master_key *mk) +static void fscrypt_free_master_key(struct rcu_head *head) +{ + struct fscrypt_master_key *mk = + container_of(head, struct fscrypt_master_key, mk_rcu_head); + /* + * The master key secret and any embedded subkeys should have already + * been wiped when the last active reference to the fscrypt_master_key + * struct was dropped; doing it here would be unnecessarily late. + * Nevertheless, use kfree_sensitive() in case anything was missed. + */ + kfree_sensitive(mk); +} + +void fscrypt_put_master_key(struct fscrypt_master_key *mk) +{ + if (!refcount_dec_and_test(&mk->mk_struct_refs)) + return; + /* + * No structural references left, so free ->mk_users, and also free the + * fscrypt_master_key struct itself after an RCU grace period ensures + * that concurrent keyring lookups can no longer find it. + */ + WARN_ON(refcount_read(&mk->mk_active_refs) != 0); + key_put(mk->mk_users); + mk->mk_users = NULL; + call_rcu(&mk->mk_rcu_head, fscrypt_free_master_key); +} + +void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk) { + struct super_block *sb = mk->mk_sb; + struct fscrypt_keyring *keyring = sb->s_master_keys; size_t i; - wipe_master_key_secret(&mk->mk_secret); + if (!refcount_dec_and_test(&mk->mk_active_refs)) + return; + /* + * No active references left, so complete the full removal of this + * fscrypt_master_key struct by removing it from the keyring and + * destroying any subkeys embedded in it. + */ + + spin_lock(&keyring->lock); + hlist_del_rcu(&mk->mk_node); + spin_unlock(&keyring->lock); + + /* + * ->mk_active_refs == 0 implies that ->mk_secret is not present and + * that ->mk_decrypted_inodes is empty. + */ + WARN_ON(is_master_key_secret_present(&mk->mk_secret)); + WARN_ON(!list_empty(&mk->mk_decrypted_inodes)); for (i = 0; i <= FSCRYPT_MODE_MAX; i++) { fscrypt_destroy_prepared_key(&mk->mk_direct_keys[i]); fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_64_keys[i]); fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_32_keys[i]); } + memzero_explicit(&mk->mk_ino_hash_key, + sizeof(mk->mk_ino_hash_key)); + mk->mk_ino_hash_key_initialized = false; - key_put(mk->mk_users); - kfree_sensitive(mk); + /* Drop the structural ref associated with the active refs. */ + fscrypt_put_master_key(mk); } static inline bool valid_key_spec(const struct fscrypt_key_specifier *spec) @@ -61,44 +124,6 @@ return master_key_spec_len(spec) != 0; } -static int fscrypt_key_instantiate(struct key *key, - struct key_preparsed_payload *prep) -{ - key->payload.data[0] = (struct fscrypt_master_key *)prep->data; - return 0; -} - -static void fscrypt_key_destroy(struct key *key) -{ - free_master_key(key->payload.data[0]); -} - -static void fscrypt_key_describe(const struct key *key, struct seq_file *m) -{ - seq_puts(m, key->description); - - if (key_is_positive(key)) { - const struct fscrypt_master_key *mk = key->payload.data[0]; - - if (!is_master_key_secret_present(&mk->mk_secret)) - seq_puts(m, ": secret removed"); - } -} - -/* - * Type of key in ->s_master_keys. Each key of this type represents a master - * key which has been added to the filesystem. Its payload is a - * 'struct fscrypt_master_key'. The "." prefix in the key type name prevents - * users from adding keys of this type via the keyrings syscalls rather than via - * the intended method of FS_IOC_ADD_ENCRYPTION_KEY. - */ -static struct key_type key_type_fscrypt = { - .name = "._fscrypt", - .instantiate = fscrypt_key_instantiate, - .destroy = fscrypt_key_destroy, - .describe = fscrypt_key_describe, -}; - static int fscrypt_user_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { @@ -131,32 +156,6 @@ .describe = fscrypt_user_key_describe, }; -/* Search ->s_master_keys or ->mk_users */ -static struct key *search_fscrypt_keyring(struct key *keyring, - struct key_type *type, - const char *description) -{ - /* - * We need to mark the keyring reference as "possessed" so that we - * acquire permission to search it, via the KEY_POS_SEARCH permission. - */ - key_ref_t keyref = make_key_ref(keyring, true /* possessed */); - - keyref = keyring_search(keyref, type, description, false); - if (IS_ERR(keyref)) { - if (PTR_ERR(keyref) == -EAGAIN || /* not found */ - PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */ - keyref = ERR_PTR(-ENOKEY); - return ERR_CAST(keyref); - } - return key_ref_to_ptr(keyref); -} - -#define FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE \ - (CONST_STRLEN("fscrypt-") + sizeof_field(struct super_block, s_id)) - -#define FSCRYPT_MK_DESCRIPTION_SIZE (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1) - #define FSCRYPT_MK_USERS_DESCRIPTION_SIZE \ (CONST_STRLEN("fscrypt-") + 2 * FSCRYPT_KEY_IDENTIFIER_SIZE + \ CONST_STRLEN("-users") + 1) @@ -164,21 +163,6 @@ #define FSCRYPT_MK_USER_DESCRIPTION_SIZE \ (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + CONST_STRLEN(".uid.") + 10 + 1) -static void format_fs_keyring_description( - char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE], - const struct super_block *sb) -{ - sprintf(description, "fscrypt-%s", sb->s_id); -} - -static void format_mk_description( - char description[FSCRYPT_MK_DESCRIPTION_SIZE], - const struct fscrypt_key_specifier *mk_spec) -{ - sprintf(description, "%*phN", - master_key_spec_len(mk_spec), (u8 *)&mk_spec->u); -} - static void format_mk_users_keyring_description( char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE], const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) @@ -199,20 +183,15 @@ /* Create ->s_master_keys if needed. Synchronized by fscrypt_add_key_mutex. */ static int allocate_filesystem_keyring(struct super_block *sb) { - char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE]; - struct key *keyring; + struct fscrypt_keyring *keyring; if (sb->s_master_keys) return 0; - format_fs_keyring_description(description, sb); - keyring = keyring_alloc(description, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, - current_cred(), KEY_POS_SEARCH | - KEY_USR_SEARCH | KEY_USR_READ | KEY_USR_VIEW, - KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); - if (IS_ERR(keyring)) - return PTR_ERR(keyring); - + keyring = kzalloc(sizeof(*keyring), GFP_KERNEL); + if (!keyring) + return -ENOMEM; + spin_lock_init(&keyring->lock); /* * Pairs with the smp_load_acquire() in fscrypt_find_master_key(). * I.e., here we publish ->s_master_keys with a RELEASE barrier so that @@ -222,21 +201,80 @@ return 0; } -void fscrypt_sb_free(struct super_block *sb) +/* + * Release all encryption keys that have been added to the filesystem, along + * with the keyring that contains them. + * + * This is called at unmount time. The filesystem's underlying block device(s) + * are still available at this time; this is important because after user file + * accesses have been allowed, this function may need to evict keys from the + * keyslots of an inline crypto engine, which requires the block device(s). + * + * This is also called when the super_block is being freed. This is needed to + * avoid a memory leak if mounting fails after the "test_dummy_encryption" + * option was processed, as in that case the unmount-time call isn't made. + */ +void fscrypt_destroy_keyring(struct super_block *sb) { - key_put(sb->s_master_keys); + struct fscrypt_keyring *keyring = sb->s_master_keys; + size_t i; + + if (!keyring) + return; + + for (i = 0; i < ARRAY_SIZE(keyring->key_hashtable); i++) { + struct hlist_head *bucket = &keyring->key_hashtable[i]; + struct fscrypt_master_key *mk; + struct hlist_node *tmp; + + hlist_for_each_entry_safe(mk, tmp, bucket, mk_node) { + /* + * Since all inodes were already evicted, every key + * remaining in the keyring should have an empty inode + * list, and should only still be in the keyring due to + * the single active ref associated with ->mk_secret. + * There should be no structural refs beyond the one + * associated with the active ref. + */ + WARN_ON(refcount_read(&mk->mk_active_refs) != 1); + WARN_ON(refcount_read(&mk->mk_struct_refs) != 1); + WARN_ON(!is_master_key_secret_present(&mk->mk_secret)); + wipe_master_key_secret(&mk->mk_secret); + fscrypt_put_master_key_activeref(mk); + } + } + kfree_sensitive(keyring); sb->s_master_keys = NULL; } +static struct hlist_head * +fscrypt_mk_hash_bucket(struct fscrypt_keyring *keyring, + const struct fscrypt_key_specifier *mk_spec) +{ + /* + * Since key specifiers should be "random" values, it is sufficient to + * use a trivial hash function that just takes the first several bits of + * the key specifier. + */ + unsigned long i = get_unaligned((unsigned long *)&mk_spec->u); + + return &keyring->key_hashtable[i % ARRAY_SIZE(keyring->key_hashtable)]; +} + /* - * Find the specified master key in ->s_master_keys. - * Returns ERR_PTR(-ENOKEY) if not found. + * Find the specified master key struct in ->s_master_keys and take a structural + * ref to it. The structural ref guarantees that the key struct continues to + * exist, but it does *not* guarantee that ->s_master_keys continues to contain + * the key struct. The structural ref needs to be dropped by + * fscrypt_put_master_key(). Returns NULL if the key struct is not found. */ -struct key *fscrypt_find_master_key(struct super_block *sb, - const struct fscrypt_key_specifier *mk_spec) +struct fscrypt_master_key * +fscrypt_find_master_key(struct super_block *sb, + const struct fscrypt_key_specifier *mk_spec) { - struct key *keyring; - char description[FSCRYPT_MK_DESCRIPTION_SIZE]; + struct fscrypt_keyring *keyring; + struct hlist_head *bucket; + struct fscrypt_master_key *mk; /* * Pairs with the smp_store_release() in allocate_filesystem_keyring(). @@ -246,10 +284,38 @@ */ keyring = smp_load_acquire(&sb->s_master_keys); if (keyring == NULL) - return ERR_PTR(-ENOKEY); /* No keyring yet, so no keys yet. */ + return NULL; /* No keyring yet, so no keys yet. */ - format_mk_description(description, mk_spec); - return search_fscrypt_keyring(keyring, &key_type_fscrypt, description); + bucket = fscrypt_mk_hash_bucket(keyring, mk_spec); + rcu_read_lock(); + switch (mk_spec->type) { + case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR: + hlist_for_each_entry_rcu(mk, bucket, mk_node) { + if (mk->mk_spec.type == + FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR && + memcmp(mk->mk_spec.u.descriptor, + mk_spec->u.descriptor, + FSCRYPT_KEY_DESCRIPTOR_SIZE) == 0 && + refcount_inc_not_zero(&mk->mk_struct_refs)) + goto out; + } + break; + case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER: + hlist_for_each_entry_rcu(mk, bucket, mk_node) { + if (mk->mk_spec.type == + FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER && + memcmp(mk->mk_spec.u.identifier, + mk_spec->u.identifier, + FSCRYPT_KEY_IDENTIFIER_SIZE) == 0 && + refcount_inc_not_zero(&mk->mk_struct_refs)) + goto out; + } + break; + } + mk = NULL; +out: + rcu_read_unlock(); + return mk; } static int allocate_master_key_users_keyring(struct fscrypt_master_key *mk) @@ -277,17 +343,30 @@ static struct key *find_master_key_user(struct fscrypt_master_key *mk) { char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE]; + key_ref_t keyref; format_mk_user_description(description, mk->mk_spec.u.identifier); - return search_fscrypt_keyring(mk->mk_users, &key_type_fscrypt_user, - description); + + /* + * We need to mark the keyring reference as "possessed" so that we + * acquire permission to search it, via the KEY_POS_SEARCH permission. + */ + keyref = keyring_search(make_key_ref(mk->mk_users, true /*possessed*/), + &key_type_fscrypt_user, description, false); + if (IS_ERR(keyref)) { + if (PTR_ERR(keyref) == -EAGAIN || /* not found */ + PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */ + keyref = ERR_PTR(-ENOKEY); + return ERR_CAST(keyref); + } + return key_ref_to_ptr(keyref); } /* * Give the current user a "key" in ->mk_users. This charges the user's quota * and marks the master key as added by the current user, so that it cannot be - * removed by another user with the key. Either the master key's key->sem must - * be held for write, or the master key must be still undergoing initialization. + * removed by another user with the key. Either ->mk_sem must be held for + * write, or the master key must be still undergoing initialization. */ static int add_master_key_user(struct fscrypt_master_key *mk) { @@ -309,7 +388,7 @@ /* * Remove the current user's "key" from ->mk_users. - * The master key's key->sem must be held for write. + * ->mk_sem must be held for write. * * Returns 0 if removed, -ENOKEY if not found, or another -errno code. */ @@ -327,63 +406,49 @@ } /* - * Allocate a new fscrypt_master_key which contains the given secret, set it as - * the payload of a new 'struct key' of type fscrypt, and link the 'struct key' - * into the given keyring. Synchronized by fscrypt_add_key_mutex. + * Allocate a new fscrypt_master_key, transfer the given secret over to it, and + * insert it into sb->s_master_keys. */ -static int add_new_master_key(struct fscrypt_master_key_secret *secret, - const struct fscrypt_key_specifier *mk_spec, - struct key *keyring) +static int add_new_master_key(struct super_block *sb, + struct fscrypt_master_key_secret *secret, + const struct fscrypt_key_specifier *mk_spec) { + struct fscrypt_keyring *keyring = sb->s_master_keys; struct fscrypt_master_key *mk; - char description[FSCRYPT_MK_DESCRIPTION_SIZE]; - struct key *key; int err; mk = kzalloc(sizeof(*mk), GFP_KERNEL); if (!mk) return -ENOMEM; + mk->mk_sb = sb; + init_rwsem(&mk->mk_sem); + refcount_set(&mk->mk_struct_refs, 1); mk->mk_spec = *mk_spec; - move_master_key_secret(&mk->mk_secret, secret); - - refcount_set(&mk->mk_refcount, 1); /* secret is present */ INIT_LIST_HEAD(&mk->mk_decrypted_inodes); spin_lock_init(&mk->mk_decrypted_inodes_lock); if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) { err = allocate_master_key_users_keyring(mk); if (err) - goto out_free_mk; + goto out_put; err = add_master_key_user(mk); if (err) - goto out_free_mk; + goto out_put; } - /* - * Note that we don't charge this key to anyone's quota, since when - * ->mk_users is in use those keys are charged instead, and otherwise - * (when ->mk_users isn't in use) only root can add these keys. - */ - format_mk_description(description, mk_spec); - key = key_alloc(&key_type_fscrypt, description, - GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(), - KEY_POS_SEARCH | KEY_USR_SEARCH | KEY_USR_VIEW, - KEY_ALLOC_NOT_IN_QUOTA, NULL); - if (IS_ERR(key)) { - err = PTR_ERR(key); - goto out_free_mk; - } - err = key_instantiate_and_link(key, mk, sizeof(*mk), keyring, NULL); - key_put(key); - if (err) - goto out_free_mk; + move_master_key_secret(&mk->mk_secret, secret); + refcount_set(&mk->mk_active_refs, 1); /* ->mk_secret is present */ + spin_lock(&keyring->lock); + hlist_add_head_rcu(&mk->mk_node, + fscrypt_mk_hash_bucket(keyring, mk_spec)); + spin_unlock(&keyring->lock); return 0; -out_free_mk: - free_master_key(mk); +out_put: + fscrypt_put_master_key(mk); return err; } @@ -392,42 +457,34 @@ static int add_existing_master_key(struct fscrypt_master_key *mk, struct fscrypt_master_key_secret *secret) { - struct key *mk_user; - bool rekey; int err; /* * If the current user is already in ->mk_users, then there's nothing to - * do. (Not applicable for v1 policy keys, which have NULL ->mk_users.) + * do. Otherwise, we need to add the user to ->mk_users. (Neither is + * applicable for v1 policy keys, which have NULL ->mk_users.) */ if (mk->mk_users) { - mk_user = find_master_key_user(mk); + struct key *mk_user = find_master_key_user(mk); + if (mk_user != ERR_PTR(-ENOKEY)) { if (IS_ERR(mk_user)) return PTR_ERR(mk_user); key_put(mk_user); return 0; } - } - - /* If we'll be re-adding ->mk_secret, try to take the reference. */ - rekey = !is_master_key_secret_present(&mk->mk_secret); - if (rekey && !refcount_inc_not_zero(&mk->mk_refcount)) - return KEY_DEAD; - - /* Add the current user to ->mk_users, if applicable. */ - if (mk->mk_users) { err = add_master_key_user(mk); - if (err) { - if (rekey && refcount_dec_and_test(&mk->mk_refcount)) - return KEY_DEAD; + if (err) return err; - } } /* Re-add the secret if needed. */ - if (rekey) + if (!is_master_key_secret_present(&mk->mk_secret)) { + if (!refcount_inc_not_zero(&mk->mk_active_refs)) + return KEY_DEAD; move_master_key_secret(&mk->mk_secret, secret); + } + return 0; } @@ -436,38 +493,36 @@ const struct fscrypt_key_specifier *mk_spec) { static DEFINE_MUTEX(fscrypt_add_key_mutex); - struct key *key; + struct fscrypt_master_key *mk; int err; mutex_lock(&fscrypt_add_key_mutex); /* serialize find + link */ -retry: - key = fscrypt_find_master_key(sb, mk_spec); - if (IS_ERR(key)) { - err = PTR_ERR(key); - if (err != -ENOKEY) - goto out_unlock; + + mk = fscrypt_find_master_key(sb, mk_spec); + if (!mk) { /* Didn't find the key in ->s_master_keys. Add it. */ err = allocate_filesystem_keyring(sb); - if (err) - goto out_unlock; - err = add_new_master_key(secret, mk_spec, sb->s_master_keys); + if (!err) + err = add_new_master_key(sb, secret, mk_spec); } else { /* * Found the key in ->s_master_keys. Re-add the secret if * needed, and add the user to ->mk_users if needed. */ - down_write(&key->sem); - err = add_existing_master_key(key->payload.data[0], secret); - up_write(&key->sem); + down_write(&mk->mk_sem); + err = add_existing_master_key(mk, secret); + up_write(&mk->mk_sem); if (err == KEY_DEAD) { - /* Key being removed or needs to be removed */ - key_invalidate(key); - key_put(key); - goto retry; + /* + * We found a key struct, but it's already been fully + * removed. Ignore the old struct and add a new one. + * fscrypt_add_key_mutex means we don't need to worry + * about concurrent adds. + */ + err = add_new_master_key(sb, secret, mk_spec); } - key_put(key); + fscrypt_put_master_key(mk); } -out_unlock: mutex_unlock(&fscrypt_add_key_mutex); return err; } @@ -771,19 +826,19 @@ const u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) { struct fscrypt_key_specifier mk_spec; - struct key *key, *mk_user; struct fscrypt_master_key *mk; + struct key *mk_user; int err; mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER; memcpy(mk_spec.u.identifier, identifier, FSCRYPT_KEY_IDENTIFIER_SIZE); - key = fscrypt_find_master_key(sb, &mk_spec); - if (IS_ERR(key)) { - err = PTR_ERR(key); + mk = fscrypt_find_master_key(sb, &mk_spec); + if (!mk) { + err = -ENOKEY; goto out; } - mk = key->payload.data[0]; + down_read(&mk->mk_sem); mk_user = find_master_key_user(mk); if (IS_ERR(mk_user)) { err = PTR_ERR(mk_user); @@ -791,7 +846,8 @@ key_put(mk_user); err = 0; } - key_put(key); + up_read(&mk->mk_sem); + fscrypt_put_master_key(mk); out: if (err == -ENOKEY && capable(CAP_FOWNER)) err = 0; @@ -953,11 +1009,10 @@ struct super_block *sb = file_inode(filp)->i_sb; struct fscrypt_remove_key_arg __user *uarg = _uarg; struct fscrypt_remove_key_arg arg; - struct key *key; struct fscrypt_master_key *mk; u32 status_flags = 0; int err; - bool dead; + bool inodes_remain; if (copy_from_user(&arg, uarg, sizeof(arg))) return -EFAULT; @@ -977,12 +1032,10 @@ return -EACCES; /* Find the key being removed. */ - key = fscrypt_find_master_key(sb, &arg.key_spec); - if (IS_ERR(key)) - return PTR_ERR(key); - mk = key->payload.data[0]; - - down_write(&key->sem); + mk = fscrypt_find_master_key(sb, &arg.key_spec); + if (!mk) + return -ENOKEY; + down_write(&mk->mk_sem); /* If relevant, remove current user's (or all users) claim to the key */ if (mk->mk_users && mk->mk_users->keys.nr_leaves_on_tree != 0) { @@ -991,7 +1044,7 @@ else err = remove_master_key_user(mk); if (err) { - up_write(&key->sem); + up_write(&mk->mk_sem); goto out_put_key; } if (mk->mk_users->keys.nr_leaves_on_tree != 0) { @@ -1003,26 +1056,22 @@ status_flags |= FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS; err = 0; - up_write(&key->sem); + up_write(&mk->mk_sem); goto out_put_key; } } /* No user claims remaining. Go ahead and wipe the secret. */ - dead = false; + err = -ENOKEY; if (is_master_key_secret_present(&mk->mk_secret)) { wipe_master_key_secret(&mk->mk_secret); - dead = refcount_dec_and_test(&mk->mk_refcount); - } - up_write(&key->sem); - if (dead) { - /* - * No inodes reference the key, and we wiped the secret, so the - * key object is free to be removed from the keyring. - */ - key_invalidate(key); + fscrypt_put_master_key_activeref(mk); err = 0; - } else { + } + inodes_remain = refcount_read(&mk->mk_active_refs) > 0; + up_write(&mk->mk_sem); + + if (inodes_remain) { /* Some inodes still reference this key; try to evict them. */ err = try_to_lock_encrypted_files(sb, mk); if (err == -EBUSY) { @@ -1038,7 +1087,7 @@ * has been fully removed including all files locked. */ out_put_key: - key_put(key); + fscrypt_put_master_key(mk); if (err == 0) err = put_user(status_flags, &uarg->removal_status_flags); return err; @@ -1085,7 +1134,6 @@ { struct super_block *sb = file_inode(filp)->i_sb; struct fscrypt_get_key_status_arg arg; - struct key *key; struct fscrypt_master_key *mk; int err; @@ -1102,19 +1150,18 @@ arg.user_count = 0; memset(arg.__out_reserved, 0, sizeof(arg.__out_reserved)); - key = fscrypt_find_master_key(sb, &arg.key_spec); - if (IS_ERR(key)) { - if (key != ERR_PTR(-ENOKEY)) - return PTR_ERR(key); + mk = fscrypt_find_master_key(sb, &arg.key_spec); + if (!mk) { arg.status = FSCRYPT_KEY_STATUS_ABSENT; err = 0; goto out; } - mk = key->payload.data[0]; - down_read(&key->sem); + down_read(&mk->mk_sem); if (!is_master_key_secret_present(&mk->mk_secret)) { - arg.status = FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED; + arg.status = refcount_read(&mk->mk_active_refs) > 0 ? + FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED : + FSCRYPT_KEY_STATUS_ABSENT /* raced with full removal */; err = 0; goto out_release_key; } @@ -1136,8 +1183,8 @@ } err = 0; out_release_key: - up_read(&key->sem); - key_put(key); + up_read(&mk->mk_sem); + fscrypt_put_master_key(mk); out: if (!err && copy_to_user(uarg, &arg, sizeof(arg))) err = -EFAULT; @@ -1149,13 +1196,9 @@ { int err; - err = register_key_type(&key_type_fscrypt); - if (err) - return err; - err = register_key_type(&key_type_fscrypt_user); if (err) - goto err_unregister_fscrypt; + return err; err = register_key_type(&key_type_fscrypt_provisioning); if (err) @@ -1165,7 +1208,5 @@ err_unregister_fscrypt_user: unregister_key_type(&key_type_fscrypt_user); -err_unregister_fscrypt: - unregister_key_type(&key_type_fscrypt); return err; } diff -Nru linux-6.0.6/fs/crypto/keysetup.c linux-6.0.12/fs/crypto/keysetup.c --- linux-6.0.6/fs/crypto/keysetup.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/crypto/keysetup.c 2023-01-18 18:27:39.000000000 +0000 @@ -9,7 +9,6 @@ */ #include -#include #include #include "fscrypt_private.h" @@ -159,6 +158,7 @@ { crypto_free_skcipher(prep_key->tfm); fscrypt_destroy_inline_crypt_key(prep_key); + memzero_explicit(prep_key, sizeof(*prep_key)); } /* Given a per-file encryption key, set up the file's crypto transform object */ @@ -412,20 +412,18 @@ /* * Find the master key, then set up the inode's actual encryption key. * - * If the master key is found in the filesystem-level keyring, then the - * corresponding 'struct key' is returned in *master_key_ret with its semaphore - * read-locked. This is needed to ensure that only one task links the - * fscrypt_info into ->mk_decrypted_inodes (as multiple tasks may race to create - * an fscrypt_info for the same inode), and to synchronize the master key being - * removed with a new inode starting to use it. + * If the master key is found in the filesystem-level keyring, then it is + * returned in *mk_ret with its semaphore read-locked. This is needed to ensure + * that only one task links the fscrypt_info into ->mk_decrypted_inodes (as + * multiple tasks may race to create an fscrypt_info for the same inode), and to + * synchronize the master key being removed with a new inode starting to use it. */ static int setup_file_encryption_key(struct fscrypt_info *ci, bool need_dirhash_key, - struct key **master_key_ret) + struct fscrypt_master_key **mk_ret) { - struct key *key; - struct fscrypt_master_key *mk = NULL; struct fscrypt_key_specifier mk_spec; + struct fscrypt_master_key *mk; int err; err = fscrypt_select_encryption_impl(ci); @@ -436,11 +434,10 @@ if (err) return err; - key = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec); - if (IS_ERR(key)) { - if (key != ERR_PTR(-ENOKEY) || - ci->ci_policy.version != FSCRYPT_POLICY_V1) - return PTR_ERR(key); + mk = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec); + if (!mk) { + if (ci->ci_policy.version != FSCRYPT_POLICY_V1) + return -ENOKEY; /* * As a legacy fallback for v1 policies, search for the key in @@ -450,9 +447,7 @@ */ return fscrypt_setup_v1_file_key_via_subscribed_keyrings(ci); } - - mk = key->payload.data[0]; - down_read(&key->sem); + down_read(&mk->mk_sem); /* Has the secret been removed (via FS_IOC_REMOVE_ENCRYPTION_KEY)? */ if (!is_master_key_secret_present(&mk->mk_secret)) { @@ -480,18 +475,18 @@ if (err) goto out_release_key; - *master_key_ret = key; + *mk_ret = mk; return 0; out_release_key: - up_read(&key->sem); - key_put(key); + up_read(&mk->mk_sem); + fscrypt_put_master_key(mk); return err; } static void put_crypt_info(struct fscrypt_info *ci) { - struct key *key; + struct fscrypt_master_key *mk; if (!ci) return; @@ -501,24 +496,18 @@ else if (ci->ci_owns_key) fscrypt_destroy_prepared_key(&ci->ci_enc_key); - key = ci->ci_master_key; - if (key) { - struct fscrypt_master_key *mk = key->payload.data[0]; - + mk = ci->ci_master_key; + if (mk) { /* * Remove this inode from the list of inodes that were unlocked - * with the master key. - * - * In addition, if we're removing the last inode from a key that - * already had its secret removed, invalidate the key so that it - * gets removed from ->s_master_keys. + * with the master key. In addition, if we're removing the last + * inode from a master key struct that already had its secret + * removed, then complete the full removal of the struct. */ spin_lock(&mk->mk_decrypted_inodes_lock); list_del(&ci->ci_master_key_link); spin_unlock(&mk->mk_decrypted_inodes_lock); - if (refcount_dec_and_test(&mk->mk_refcount)) - key_invalidate(key); - key_put(key); + fscrypt_put_master_key_activeref(mk); } memzero_explicit(ci, sizeof(*ci)); kmem_cache_free(fscrypt_info_cachep, ci); @@ -532,7 +521,7 @@ { struct fscrypt_info *crypt_info; struct fscrypt_mode *mode; - struct key *master_key = NULL; + struct fscrypt_master_key *mk = NULL; int res; res = fscrypt_initialize(inode->i_sb->s_cop->flags); @@ -555,8 +544,7 @@ WARN_ON(mode->ivsize > FSCRYPT_MAX_IV_SIZE); crypt_info->ci_mode = mode; - res = setup_file_encryption_key(crypt_info, need_dirhash_key, - &master_key); + res = setup_file_encryption_key(crypt_info, need_dirhash_key, &mk); if (res) goto out; @@ -571,12 +559,9 @@ * We won the race and set ->i_crypt_info to our crypt_info. * Now link it into the master key's inode list. */ - if (master_key) { - struct fscrypt_master_key *mk = - master_key->payload.data[0]; - - refcount_inc(&mk->mk_refcount); - crypt_info->ci_master_key = key_get(master_key); + if (mk) { + crypt_info->ci_master_key = mk; + refcount_inc(&mk->mk_active_refs); spin_lock(&mk->mk_decrypted_inodes_lock); list_add(&crypt_info->ci_master_key_link, &mk->mk_decrypted_inodes); @@ -586,9 +571,9 @@ } res = 0; out: - if (master_key) { - up_read(&master_key->sem); - key_put(master_key); + if (mk) { + up_read(&mk->mk_sem); + fscrypt_put_master_key(mk); } put_crypt_info(crypt_info); return res; @@ -753,7 +738,6 @@ int fscrypt_drop_inode(struct inode *inode) { const struct fscrypt_info *ci = fscrypt_get_info(inode); - const struct fscrypt_master_key *mk; /* * If ci is NULL, then the inode doesn't have an encryption key set up @@ -763,7 +747,6 @@ */ if (!ci || !ci->ci_master_key) return 0; - mk = ci->ci_master_key->payload.data[0]; /* * With proper, non-racy use of FS_IOC_REMOVE_ENCRYPTION_KEY, all inodes @@ -782,6 +765,6 @@ * then the thread removing the key will either evict the inode itself * or will correctly detect that it wasn't evicted due to the race. */ - return !is_master_key_secret_present(&mk->mk_secret); + return !is_master_key_secret_present(&ci->ci_master_key->mk_secret); } EXPORT_SYMBOL_GPL(fscrypt_drop_inode); diff -Nru linux-6.0.6/fs/crypto/policy.c linux-6.0.12/fs/crypto/policy.c --- linux-6.0.6/fs/crypto/policy.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/crypto/policy.c 2023-01-18 18:27:39.000000000 +0000 @@ -744,12 +744,8 @@ * delayed key setup that requires the inode number. */ if (ci->ci_policy.version == FSCRYPT_POLICY_V2 && - (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) { - const struct fscrypt_master_key *mk = - ci->ci_master_key->payload.data[0]; - - fscrypt_hash_inode_number(ci, mk); - } + (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) + fscrypt_hash_inode_number(ci, ci->ci_master_key); return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, fs_data); } diff -Nru linux-6.0.6/fs/erofs/fscache.c linux-6.0.12/fs/erofs/fscache.c --- linux-6.0.6/fs/erofs/fscache.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/erofs/fscache.c 2023-01-18 18:27:39.000000000 +0000 @@ -69,11 +69,15 @@ rcu_read_lock(); xas_for_each(&xas, folio, last_page) { - unsigned int pgpos = - (folio_index(folio) - start_page) * PAGE_SIZE; - unsigned int pgend = pgpos + folio_size(folio); + unsigned int pgpos, pgend; bool pg_failed = false; + if (xas_retry(&xas, folio)) + continue; + + pgpos = (folio_index(folio) - start_page) * PAGE_SIZE; + pgend = pgpos + folio_size(folio); + for (;;) { if (!subreq) { pg_failed = true; @@ -234,113 +238,114 @@ return ret; } -static int erofs_fscache_read_folio_inline(struct folio *folio, - struct erofs_map_blocks *map) -{ - struct super_block *sb = folio_mapping(folio)->host->i_sb; - struct erofs_buf buf = __EROFS_BUF_INITIALIZER; - erofs_blk_t blknr; - size_t offset, len; - void *src, *dst; - - /* For tail packing layout, the offset may be non-zero. */ - offset = erofs_blkoff(map->m_pa); - blknr = erofs_blknr(map->m_pa); - len = map->m_llen; - - src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP); - if (IS_ERR(src)) - return PTR_ERR(src); - - dst = kmap_local_folio(folio, 0); - memcpy(dst, src + offset, len); - memset(dst + len, 0, PAGE_SIZE - len); - kunmap_local(dst); - - erofs_put_metabuf(&buf); - return 0; -} - -static int erofs_fscache_read_folio(struct file *file, struct folio *folio) +/* + * Read into page cache in the range described by (@pos, @len). + * + * On return, the caller is responsible for page unlocking if the output @unlock + * is true, or the callee will take this responsibility through netfs_io_request + * interface. + * + * The return value is the number of bytes successfully handled, or negative + * error code on failure. The only exception is that, the length of the range + * instead of the error code is returned on failure after netfs_io_request is + * allocated, so that .readahead() could advance rac accordingly. + */ +static int erofs_fscache_data_read(struct address_space *mapping, + loff_t pos, size_t len, bool *unlock) { - struct inode *inode = folio_mapping(folio)->host; + struct inode *inode = mapping->host; struct super_block *sb = inode->i_sb; + struct netfs_io_request *rreq; struct erofs_map_blocks map; struct erofs_map_dev mdev; - struct netfs_io_request *rreq; - erofs_off_t pos; - loff_t pstart; + struct iov_iter iter; + size_t count; int ret; - DBG_BUGON(folio_size(folio) != EROFS_BLKSIZ); + *unlock = true; - pos = folio_pos(folio); map.m_la = pos; - ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW); if (ret) - goto out_unlock; + return ret; - if (!(map.m_flags & EROFS_MAP_MAPPED)) { - folio_zero_range(folio, 0, folio_size(folio)); - goto out_uptodate; + if (map.m_flags & EROFS_MAP_META) { + struct erofs_buf buf = __EROFS_BUF_INITIALIZER; + erofs_blk_t blknr; + size_t offset, size; + void *src; + + /* For tail packing layout, the offset may be non-zero. */ + offset = erofs_blkoff(map.m_pa); + blknr = erofs_blknr(map.m_pa); + size = map.m_llen; + + src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP); + if (IS_ERR(src)) + return PTR_ERR(src); + + iov_iter_xarray(&iter, READ, &mapping->i_pages, pos, PAGE_SIZE); + if (copy_to_iter(src + offset, size, &iter) != size) { + erofs_put_metabuf(&buf); + return -EFAULT; + } + iov_iter_zero(PAGE_SIZE - size, &iter); + erofs_put_metabuf(&buf); + return PAGE_SIZE; } - if (map.m_flags & EROFS_MAP_META) { - ret = erofs_fscache_read_folio_inline(folio, &map); - goto out_uptodate; + if (!(map.m_flags & EROFS_MAP_MAPPED)) { + count = len; + iov_iter_xarray(&iter, READ, &mapping->i_pages, pos, count); + iov_iter_zero(count, &iter); + return count; } + count = min_t(size_t, map.m_llen - (pos - map.m_la), len); + DBG_BUGON(!count || count % PAGE_SIZE); + mdev = (struct erofs_map_dev) { .m_deviceid = map.m_deviceid, .m_pa = map.m_pa, }; - ret = erofs_map_dev(sb, &mdev); if (ret) - goto out_unlock; - - - rreq = erofs_fscache_alloc_request(folio_mapping(folio), - folio_pos(folio), folio_size(folio)); - if (IS_ERR(rreq)) { - ret = PTR_ERR(rreq); - goto out_unlock; - } - - pstart = mdev.m_pa + (pos - map.m_la); - return erofs_fscache_read_folios_async(mdev.m_fscache->cookie, - rreq, pstart); + return ret; -out_uptodate: - if (!ret) - folio_mark_uptodate(folio); -out_unlock: - folio_unlock(folio); - return ret; + rreq = erofs_fscache_alloc_request(mapping, pos, count); + if (IS_ERR(rreq)) + return PTR_ERR(rreq); + + *unlock = false; + erofs_fscache_read_folios_async(mdev.m_fscache->cookie, + rreq, mdev.m_pa + (pos - map.m_la)); + return count; } -static void erofs_fscache_advance_folios(struct readahead_control *rac, - size_t len, bool unlock) +static int erofs_fscache_read_folio(struct file *file, struct folio *folio) { - while (len) { - struct folio *folio = readahead_folio(rac); - len -= folio_size(folio); - if (unlock) { + bool unlock; + int ret; + + DBG_BUGON(folio_size(folio) != EROFS_BLKSIZ); + + ret = erofs_fscache_data_read(folio_mapping(folio), folio_pos(folio), + folio_size(folio), &unlock); + if (unlock) { + if (ret > 0) folio_mark_uptodate(folio); - folio_unlock(folio); - } + folio_unlock(folio); } + return ret < 0 ? ret : 0; } static void erofs_fscache_readahead(struct readahead_control *rac) { - struct inode *inode = rac->mapping->host; - struct super_block *sb = inode->i_sb; - size_t len, count, done = 0; - erofs_off_t pos; - loff_t start, offset; - int ret; + struct folio *folio; + size_t len, done = 0; + loff_t start, pos; + bool unlock; + int ret, size; if (!readahead_count(rac)) return; @@ -349,67 +354,22 @@ len = readahead_length(rac); do { - struct erofs_map_blocks map; - struct erofs_map_dev mdev; - struct netfs_io_request *rreq; - pos = start + done; - map.m_la = pos; - - ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW); - if (ret) + ret = erofs_fscache_data_read(rac->mapping, pos, + len - done, &unlock); + if (ret <= 0) return; - offset = start + done; - count = min_t(size_t, map.m_llen - (pos - map.m_la), - len - done); - - if (!(map.m_flags & EROFS_MAP_MAPPED)) { - struct iov_iter iter; - - iov_iter_xarray(&iter, READ, &rac->mapping->i_pages, - offset, count); - iov_iter_zero(count, &iter); - - erofs_fscache_advance_folios(rac, count, true); - ret = count; - continue; - } - - if (map.m_flags & EROFS_MAP_META) { - struct folio *folio = readahead_folio(rac); - - ret = erofs_fscache_read_folio_inline(folio, &map); - if (!ret) { + size = ret; + while (size) { + folio = readahead_folio(rac); + size -= folio_size(folio); + if (unlock) { folio_mark_uptodate(folio); - ret = folio_size(folio); + folio_unlock(folio); } - - folio_unlock(folio); - continue; } - - mdev = (struct erofs_map_dev) { - .m_deviceid = map.m_deviceid, - .m_pa = map.m_pa, - }; - ret = erofs_map_dev(sb, &mdev); - if (ret) - return; - - rreq = erofs_fscache_alloc_request(rac->mapping, offset, count); - if (IS_ERR(rreq)) - return; - /* - * Drop the ref of folios here. Unlock them in - * rreq_unlock_folios() when rreq complete. - */ - erofs_fscache_advance_folios(rac, count, false); - ret = erofs_fscache_read_folios_async(mdev.m_fscache->cookie, - rreq, mdev.m_pa + (pos - map.m_la)); - if (!ret) - ret = count; - } while (ret > 0 && ((done += ret) < len)); + } while ((done += ret) < len); } static const struct address_space_operations erofs_fscache_meta_aops = { diff -Nru linux-6.0.6/fs/erofs/zdata.c linux-6.0.12/fs/erofs/zdata.c --- linux-6.0.6/fs/erofs/zdata.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/erofs/zdata.c 2023-01-18 18:27:39.000000000 +0000 @@ -765,13 +765,13 @@ if (fe->pcl->pageofs_out != (map->m_la & ~PAGE_MASK)) fe->pcl->multibases = true; - if ((map->m_flags & EROFS_MAP_FULL_MAPPED) && - fe->pcl->length == map->m_llen) - fe->pcl->partial = false; if (fe->pcl->length < offset + end - map->m_la) { fe->pcl->length = offset + end - map->m_la; fe->pcl->pageofs_out = map->m_la & ~PAGE_MASK; } + if ((map->m_flags & EROFS_MAP_FULL_MAPPED) && + fe->pcl->length == map->m_llen) + fe->pcl->partial = false; next_part: /* shorten the remaining extent to update progress */ map->m_llen = offset + cur - map->m_la; diff -Nru linux-6.0.6/fs/erofs/zmap.c linux-6.0.12/fs/erofs/zmap.c --- linux-6.0.6/fs/erofs/zmap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/erofs/zmap.c 2023-01-18 18:27:39.000000000 +0000 @@ -61,8 +61,7 @@ pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + vi->xattr_isize, 8); - kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), - EROFS_KMAP_ATOMIC); + kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP); if (IS_ERR(kaddr)) { err = PTR_ERR(kaddr); goto out_unlock; @@ -79,7 +78,7 @@ erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel", headnr + 1, vi->z_algorithmtype[headnr], vi->nid); err = -EOPNOTSUPP; - goto unmap_done; + goto out_put_metabuf; } vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7); @@ -89,7 +88,7 @@ erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu", vi->nid); err = -EFSCORRUPTED; - goto unmap_done; + goto out_put_metabuf; } if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION && !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ @@ -97,12 +96,8 @@ erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu", vi->nid); err = -EFSCORRUPTED; - goto unmap_done; + goto out_put_metabuf; } -unmap_done: - erofs_put_metabuf(&buf); - if (err) - goto out_unlock; if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) { struct erofs_map_blocks map = { @@ -121,11 +116,13 @@ err = -EFSCORRUPTED; } if (err < 0) - goto out_unlock; + goto out_put_metabuf; } /* paired with smp_mb() at the beginning of the function */ smp_mb(); set_bit(EROFS_I_Z_INITED_BIT, &vi->flags); +out_put_metabuf: + erofs_put_metabuf(&buf); out_unlock: clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags); return err; diff -Nru linux-6.0.6/fs/exec.c linux-6.0.12/fs/exec.c --- linux-6.0.6/fs/exec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/exec.c 2023-01-18 18:27:39.000000000 +0000 @@ -1196,11 +1196,11 @@ return -ENOMEM; refcount_set(&newsighand->count, 1); - memcpy(newsighand->action, oldsighand->action, - sizeof(newsighand->action)); write_lock_irq(&tasklist_lock); spin_lock(&oldsighand->siglock); + memcpy(newsighand->action, oldsighand->action, + sizeof(newsighand->action)); rcu_assign_pointer(me->sighand, newsighand); spin_unlock(&oldsighand->siglock); write_unlock_irq(&tasklist_lock); diff -Nru linux-6.0.6/fs/ext4/extents.c linux-6.0.12/fs/ext4/extents.c --- linux-6.0.6/fs/ext4/extents.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ext4/extents.c 2023-01-18 18:27:39.000000000 +0000 @@ -5183,6 +5183,7 @@ * and it is decreased till we reach start. */ again: + ret = 0; if (SHIFT == SHIFT_LEFT) iterator = &start; else @@ -5226,14 +5227,21 @@ ext4_ext_get_actual_len(extent); } else { extent = EXT_FIRST_EXTENT(path[depth].p_hdr); - if (le32_to_cpu(extent->ee_block) > 0) + if (le32_to_cpu(extent->ee_block) > start) *iterator = le32_to_cpu(extent->ee_block) - 1; - else - /* Beginning is reached, end of the loop */ + else if (le32_to_cpu(extent->ee_block) == start) iterator = NULL; - /* Update path extent in case we need to stop */ - while (le32_to_cpu(extent->ee_block) < start) + else { + extent = EXT_LAST_EXTENT(path[depth].p_hdr); + while (le32_to_cpu(extent->ee_block) >= start) + extent--; + + if (extent == EXT_LAST_EXTENT(path[depth].p_hdr)) + break; + extent++; + iterator = NULL; + } path[depth].p_ext = extent; } ret = ext4_ext_shift_path_extents(path, shift, inode, diff -Nru linux-6.0.6/fs/ext4/ioctl.c linux-6.0.12/fs/ext4/ioctl.c --- linux-6.0.6/fs/ext4/ioctl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ext4/ioctl.c 2023-01-18 18:27:39.000000000 +0000 @@ -145,9 +145,8 @@ if (ext4_has_metadata_csum(sb) && es->s_checksum != ext4_superblock_csum(sb, es)) { ext4_msg(sb, KERN_ERR, "Invalid checksum for backup " - "superblock %llu\n", sb_block); + "superblock %llu", sb_block); unlock_buffer(bh); - err = -EFSBADCRC; goto out_bh; } func(es, arg); diff -Nru linux-6.0.6/fs/ext4/migrate.c linux-6.0.12/fs/ext4/migrate.c --- linux-6.0.6/fs/ext4/migrate.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ext4/migrate.c 2023-01-18 18:27:39.000000000 +0000 @@ -425,7 +425,8 @@ * already is extent-based, error out. */ if (!ext4_has_feature_extents(inode->i_sb) || - (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) + ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) || + ext4_has_inline_data(inode)) return -EINVAL; if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0) diff -Nru linux-6.0.6/fs/ext4/namei.c linux-6.0.12/fs/ext4/namei.c --- linux-6.0.6/fs/ext4/namei.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ext4/namei.c 2023-01-18 18:27:39.000000000 +0000 @@ -2259,8 +2259,16 @@ memset(de, 0, len); /* wipe old data */ de = (struct ext4_dir_entry_2 *) data2; top = data2 + len; - while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top) + while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top) { + if (ext4_check_dir_entry(dir, NULL, de, bh2, data2, len, + (data2 + (blocksize - csum_size) - + (char *) de))) { + brelse(bh2); + brelse(bh); + return -EFSCORRUPTED; + } de = de2; + } de->rec_len = ext4_rec_len_to_disk(data2 + (blocksize - csum_size) - (char *) de, blocksize); diff -Nru linux-6.0.6/fs/ext4/resize.c linux-6.0.12/fs/ext4/resize.c --- linux-6.0.6/fs/ext4/resize.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ext4/resize.c 2023-01-18 18:27:39.000000000 +0000 @@ -1158,6 +1158,7 @@ while (group < sbi->s_groups_count) { struct buffer_head *bh; ext4_fsblk_t backup_block; + struct ext4_super_block *es; /* Out of journal space, and can't get more - abort - so sad */ err = ext4_resize_ensure_credits_batch(handle, 1); @@ -1186,6 +1187,10 @@ memcpy(bh->b_data, data, size); if (rest) memset(bh->b_data + size, 0, rest); + es = (struct ext4_super_block *) bh->b_data; + es->s_block_group_nr = cpu_to_le16(group); + if (ext4_has_metadata_csum(sb)) + es->s_checksum = ext4_superblock_csum(sb, es); set_buffer_uptodate(bh); unlock_buffer(bh); err = ext4_handle_dirty_metadata(handle, NULL, bh); diff -Nru linux-6.0.6/fs/ext4/verity.c linux-6.0.12/fs/ext4/verity.c --- linux-6.0.6/fs/ext4/verity.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ext4/verity.c 2023-01-18 18:27:39.000000000 +0000 @@ -365,13 +365,14 @@ pgoff_t index, unsigned long num_ra_pages) { - DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index); struct page *page; index += ext4_verity_metadata_pos(inode) >> PAGE_SHIFT; page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED); if (!page || !PageUptodate(page)) { + DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index); + if (page) put_page(page); else if (num_ra_pages > 1) diff -Nru linux-6.0.6/fs/f2fs/verity.c linux-6.0.12/fs/f2fs/verity.c --- linux-6.0.6/fs/f2fs/verity.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/f2fs/verity.c 2023-01-18 18:27:39.000000000 +0000 @@ -262,13 +262,14 @@ pgoff_t index, unsigned long num_ra_pages) { - DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index); struct page *page; index += f2fs_verity_metadata_pos(inode) >> PAGE_SHIFT; page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED); if (!page || !PageUptodate(page)) { + DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index); + if (page) put_page(page); else if (num_ra_pages > 1) diff -Nru linux-6.0.6/fs/fscache/volume.c linux-6.0.12/fs/fscache/volume.c --- linux-6.0.6/fs/fscache/volume.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/fscache/volume.c 2023-01-18 18:27:39.000000000 +0000 @@ -203,7 +203,11 @@ struct fscache_volume *volume; struct fscache_cache *cache; size_t klen, hlen; - char *key; + u8 *key; + + klen = strlen(volume_key); + if (klen > NAME_MAX) + return NULL; if (!coherency_data) coherency_len = 0; @@ -229,7 +233,6 @@ /* Stick the length on the front of the key and pad it out to make * hashing easier. */ - klen = strlen(volume_key); hlen = round_up(1 + klen + 1, sizeof(__le32)); key = kzalloc(hlen, GFP_KERNEL); if (!key) diff -Nru linux-6.0.6/fs/fs-writeback.c linux-6.0.12/fs/fs-writeback.c --- linux-6.0.6/fs/fs-writeback.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/fs-writeback.c 2023-01-18 18:27:39.000000000 +0000 @@ -1712,18 +1712,26 @@ wb = inode_to_wb_and_lock_list(inode); spin_lock(&inode->i_lock); /* - * If the inode is now fully clean, then it can be safely removed from - * its writeback list (if any). Otherwise the flusher threads are - * responsible for the writeback lists. + * If the inode is freeing, its i_io_list shoudn't be updated + * as it can be finally deleted at this moment. */ - if (!(inode->i_state & I_DIRTY_ALL)) - inode_cgwb_move_to_attached(inode, wb); - else if (!(inode->i_state & I_SYNC_QUEUED)) { - if ((inode->i_state & I_DIRTY)) - redirty_tail_locked(inode, wb); - else if (inode->i_state & I_DIRTY_TIME) { - inode->dirtied_when = jiffies; - inode_io_list_move_locked(inode, wb, &wb->b_dirty_time); + if (!(inode->i_state & I_FREEING)) { + /* + * If the inode is now fully clean, then it can be safely + * removed from its writeback list (if any). Otherwise the + * flusher threads are responsible for the writeback lists. + */ + if (!(inode->i_state & I_DIRTY_ALL)) + inode_cgwb_move_to_attached(inode, wb); + else if (!(inode->i_state & I_SYNC_QUEUED)) { + if ((inode->i_state & I_DIRTY)) + redirty_tail_locked(inode, wb); + else if (inode->i_state & I_DIRTY_TIME) { + inode->dirtied_when = jiffies; + inode_io_list_move_locked(inode, + wb, + &wb->b_dirty_time); + } } } diff -Nru linux-6.0.6/fs/fuse/file.c linux-6.0.12/fs/fuse/file.c --- linux-6.0.6/fs/fuse/file.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/fuse/file.c 2023-01-18 18:27:39.000000000 +0000 @@ -2963,11 +2963,9 @@ .mode = mode }; int err; - bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || - (mode & (FALLOC_FL_PUNCH_HOLE | - FALLOC_FL_ZERO_RANGE)); - - bool block_faults = FUSE_IS_DAX(inode) && lock_inode; + bool block_faults = FUSE_IS_DAX(inode) && + (!(mode & FALLOC_FL_KEEP_SIZE) || + (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))); if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) @@ -2976,22 +2974,20 @@ if (fm->fc->no_fallocate) return -EOPNOTSUPP; - if (lock_inode) { - inode_lock(inode); - if (block_faults) { - filemap_invalidate_lock(inode->i_mapping); - err = fuse_dax_break_layouts(inode, 0, 0); - if (err) - goto out; - } - - if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) { - loff_t endbyte = offset + length - 1; - - err = fuse_writeback_range(inode, offset, endbyte); - if (err) - goto out; - } + inode_lock(inode); + if (block_faults) { + filemap_invalidate_lock(inode->i_mapping); + err = fuse_dax_break_layouts(inode, 0, 0); + if (err) + goto out; + } + + if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) { + loff_t endbyte = offset + length - 1; + + err = fuse_writeback_range(inode, offset, endbyte); + if (err) + goto out; } if (!(mode & FALLOC_FL_KEEP_SIZE) && @@ -3001,6 +2997,10 @@ goto out; } + err = file_modified(file); + if (err) + goto out; + if (!(mode & FALLOC_FL_KEEP_SIZE)) set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); @@ -3035,8 +3035,7 @@ if (block_faults) filemap_invalidate_unlock(inode->i_mapping); - if (lock_inode) - inode_unlock(inode); + inode_unlock(inode); fuse_flush_time_update(inode); diff -Nru linux-6.0.6/fs/fuse/readdir.c linux-6.0.12/fs/fuse/readdir.c --- linux-6.0.6/fs/fuse/readdir.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/fuse/readdir.c 2023-01-18 18:27:39.000000000 +0000 @@ -77,8 +77,10 @@ goto unlock; addr = kmap_local_page(page); - if (!offset) + if (!offset) { clear_page(addr); + SetPageUptodate(page); + } memcpy(addr + offset, dirent, reclen); kunmap_local(addr); fi->rdc.size = (index << PAGE_SHIFT) + offset + reclen; @@ -516,6 +518,12 @@ page = find_get_page_flags(file->f_mapping, index, FGP_ACCESSED | FGP_LOCK); + /* Page gone missing, then re-added to cache, but not initialized? */ + if (page && !PageUptodate(page)) { + unlock_page(page); + put_page(page); + page = NULL; + } spin_lock(&fi->rdc.lock); if (!page) { /* diff -Nru linux-6.0.6/fs/gfs2/ops_fstype.c linux-6.0.12/fs/gfs2/ops_fstype.c --- linux-6.0.6/fs/gfs2/ops_fstype.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/gfs2/ops_fstype.c 2023-01-18 18:27:39.000000000 +0000 @@ -178,7 +178,10 @@ pr_warn("Invalid block size\n"); return -EINVAL; } - + if (sb->sb_bsize_shift != ffs(sb->sb_bsize) - 1) { + pr_warn("Invalid block size shift\n"); + return -EINVAL; + } return 0; } @@ -381,8 +384,10 @@ if (!table[0]) table = sdp->sd_vfs->s_id; - strlcpy(sdp->sd_proto_name, proto, GFS2_FSNAME_LEN); - strlcpy(sdp->sd_table_name, table, GFS2_FSNAME_LEN); + BUILD_BUG_ON(GFS2_LOCKNAME_LEN > GFS2_FSNAME_LEN); + + strscpy(sdp->sd_proto_name, proto, GFS2_LOCKNAME_LEN); + strscpy(sdp->sd_table_name, table, GFS2_LOCKNAME_LEN); table = sdp->sd_table_name; while ((table = strchr(table, '/'))) @@ -1439,13 +1444,13 @@ switch (o) { case Opt_lockproto: - strlcpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN); + strscpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN); break; case Opt_locktable: - strlcpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN); + strscpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN); break; case Opt_hostdata: - strlcpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN); + strscpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN); break; case Opt_spectator: args->ar_spectator = 1; diff -Nru linux-6.0.6/fs/hugetlbfs/inode.c linux-6.0.12/fs/hugetlbfs/inode.c --- linux-6.0.6/fs/hugetlbfs/inode.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/hugetlbfs/inode.c 2023-01-18 18:27:39.000000000 +0000 @@ -328,6 +328,12 @@ } else { unlock_page(page); + if (PageHWPoison(page)) { + put_page(page); + retval = -EIO; + break; + } + /* * We have the page, copy it to user space buffer. */ @@ -364,7 +370,7 @@ return -EINVAL; } -static void remove_huge_page(struct page *page) +static void hugetlb_delete_from_page_cache(struct page *page) { ClearPageDirty(page); ClearPageUptodate(page); @@ -487,15 +493,14 @@ folio_lock(folio); /* * We must free the huge page and remove from page - * cache (remove_huge_page) BEFORE removing the - * region/reserve map (hugetlb_unreserve_pages). In - * rare out of memory conditions, removal of the - * region/reserve map could fail. Correspondingly, - * the subpool and global reserve usage count can need - * to be adjusted. + * cache BEFORE removing the region/reserve map + * (hugetlb_unreserve_pages). In rare out of memory + * conditions, removal of the region/reserve map could + * fail. Correspondingly, the subpool and global + * reserve usage count can need to be adjusted. */ VM_BUG_ON(HPageRestoreReserve(&folio->page)); - remove_huge_page(&folio->page); + hugetlb_delete_from_page_cache(&folio->page); freed++; if (!truncate_op) { if (unlikely(hugetlb_unreserve_pages(inode, @@ -737,7 +742,7 @@ } clear_huge_page(page, addr, pages_per_huge_page(h)); __SetPageUptodate(page); - error = huge_add_to_page_cache(page, mapping, index); + error = hugetlb_add_to_page_cache(page, mapping, index); if (unlikely(error)) { restore_reserve_on_error(h, &pseudo_vma, addr, page); put_page(page); @@ -749,7 +754,7 @@ SetHPageMigratable(page); /* - * unlock_page because locked by huge_add_to_page_cache() + * unlock_page because locked by hugetlb_add_to_page_cache() * put_page() due to reference from alloc_huge_page() */ unlock_page(page); @@ -991,13 +996,6 @@ static int hugetlbfs_error_remove_page(struct address_space *mapping, struct page *page) { - struct inode *inode = mapping->host; - pgoff_t index = page->index; - - remove_huge_page(page); - if (unlikely(hugetlb_unreserve_pages(inode, index, index + 1, 1))) - hugetlb_fix_reserve_counts(inode); - return 0; } diff -Nru linux-6.0.6/fs/kernfs/dir.c linux-6.0.12/fs/kernfs/dir.c --- linux-6.0.6/fs/kernfs/dir.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/kernfs/dir.c 2023-01-18 18:27:39.000000000 +0000 @@ -1585,8 +1585,11 @@ down_write(&root->kernfs_rwsem); kn = kernfs_find_ns(parent, name, ns); - if (kn) + if (kn) { + kernfs_get(kn); __kernfs_remove(kn); + kernfs_put(kn); + } up_write(&root->kernfs_rwsem); diff -Nru linux-6.0.6/fs/ksmbd/vfs.c linux-6.0.12/fs/ksmbd/vfs.c --- linux-6.0.6/fs/ksmbd/vfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ksmbd/vfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -1784,9 +1784,9 @@ ret = vfs_copy_file_range(src_fp->filp, src_off, dst_fp->filp, dst_off, len, 0); if (ret == -EOPNOTSUPP || ret == -EXDEV) - ret = generic_copy_file_range(src_fp->filp, src_off, - dst_fp->filp, dst_off, - len, 0); + ret = vfs_copy_file_range(src_fp->filp, src_off, + dst_fp->filp, dst_off, len, + COPY_FILE_SPLICE); if (ret < 0) return ret; diff -Nru linux-6.0.6/fs/namei.c linux-6.0.12/fs/namei.c --- linux-6.0.6/fs/namei.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/namei.c 2023-01-18 18:27:39.000000000 +0000 @@ -5088,7 +5088,7 @@ const struct address_space_operations *aops = mapping->a_ops; bool nofs = !mapping_gfp_constraint(mapping, __GFP_FS); struct page *page; - void *fsdata; + void *fsdata = NULL; int err; unsigned int flags; diff -Nru linux-6.0.6/fs/netfs/buffered_read.c linux-6.0.12/fs/netfs/buffered_read.c --- linux-6.0.6/fs/netfs/buffered_read.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/netfs/buffered_read.c 2023-01-18 18:27:39.000000000 +0000 @@ -17,9 +17,9 @@ { struct netfs_io_subrequest *subreq; struct folio *folio; - unsigned int iopos, account = 0; pgoff_t start_page = rreq->start / PAGE_SIZE; pgoff_t last_page = ((rreq->start + rreq->len) / PAGE_SIZE) - 1; + size_t account = 0; bool subreq_failed = false; XA_STATE(xas, &rreq->mapping->i_pages, start_page); @@ -39,18 +39,23 @@ */ subreq = list_first_entry(&rreq->subrequests, struct netfs_io_subrequest, rreq_link); - iopos = 0; subreq_failed = (subreq->error < 0); trace_netfs_rreq(rreq, netfs_rreq_trace_unlock); rcu_read_lock(); xas_for_each(&xas, folio, last_page) { - unsigned int pgpos = (folio_index(folio) - start_page) * PAGE_SIZE; - unsigned int pgend = pgpos + folio_size(folio); + loff_t pg_end; bool pg_failed = false; + if (xas_retry(&xas, folio)) + continue; + + pg_end = folio_pos(folio) + folio_size(folio) - 1; + for (;;) { + loff_t sreq_end; + if (!subreq) { pg_failed = true; break; @@ -58,11 +63,11 @@ if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) folio_start_fscache(folio); pg_failed |= subreq_failed; - if (pgend < iopos + subreq->len) + sreq_end = subreq->start + subreq->len - 1; + if (pg_end < sreq_end) break; account += subreq->transferred; - iopos += subreq->len; if (!list_is_last(&subreq->rreq_link, &rreq->subrequests)) { subreq = list_next_entry(subreq, rreq_link); subreq_failed = (subreq->error < 0); @@ -70,7 +75,8 @@ subreq = NULL; subreq_failed = false; } - if (pgend == iopos) + + if (pg_end == sreq_end) break; } diff -Nru linux-6.0.6/fs/netfs/io.c linux-6.0.12/fs/netfs/io.c --- linux-6.0.6/fs/netfs/io.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/netfs/io.c 2023-01-18 18:27:39.000000000 +0000 @@ -121,6 +121,9 @@ XA_STATE(xas, &rreq->mapping->i_pages, subreq->start / PAGE_SIZE); xas_for_each(&xas, folio, (subreq->start + subreq->len - 1) / PAGE_SIZE) { + if (xas_retry(&xas, folio)) + continue; + /* We might have multiple writes from the same huge * folio, but we mustn't unlock a folio more than once. */ diff -Nru linux-6.0.6/fs/nfs/delegation.c linux-6.0.12/fs/nfs/delegation.c --- linux-6.0.6/fs/nfs/delegation.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nfs/delegation.c 2023-01-18 18:27:39.000000000 +0000 @@ -228,8 +228,7 @@ * */ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred, - fmode_t type, - const nfs4_stateid *stateid, + fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit) { struct nfs_delegation *delegation; @@ -239,25 +238,24 @@ delegation = rcu_dereference(NFS_I(inode)->delegation); if (delegation != NULL) { spin_lock(&delegation->lock); - if (nfs4_is_valid_delegation(delegation, 0)) { - nfs4_stateid_copy(&delegation->stateid, stateid); - delegation->type = type; - delegation->pagemod_limit = pagemod_limit; - oldcred = delegation->cred; - delegation->cred = get_cred(cred); - clear_bit(NFS_DELEGATION_NEED_RECLAIM, - &delegation->flags); - spin_unlock(&delegation->lock); - rcu_read_unlock(); - put_cred(oldcred); - trace_nfs4_reclaim_delegation(inode, type); - return; - } - /* We appear to have raced with a delegation return. */ + nfs4_stateid_copy(&delegation->stateid, stateid); + delegation->type = type; + delegation->pagemod_limit = pagemod_limit; + oldcred = delegation->cred; + delegation->cred = get_cred(cred); + clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags); + if (test_and_clear_bit(NFS_DELEGATION_REVOKED, + &delegation->flags)) + atomic_long_inc(&nfs_active_delegations); spin_unlock(&delegation->lock); + rcu_read_unlock(); + put_cred(oldcred); + trace_nfs4_reclaim_delegation(inode, type); + } else { + rcu_read_unlock(); + nfs_inode_set_delegation(inode, cred, type, stateid, + pagemod_limit); } - rcu_read_unlock(); - nfs_inode_set_delegation(inode, cred, type, stateid, pagemod_limit); } static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync) diff -Nru linux-6.0.6/fs/nfs/nfs42proc.c linux-6.0.12/fs/nfs/nfs42proc.c --- linux-6.0.6/fs/nfs/nfs42proc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nfs/nfs42proc.c 2023-01-18 18:27:39.000000000 +0000 @@ -1093,6 +1093,9 @@ &args.seq_args, &res.seq_res, 0); trace_nfs4_clone(src_inode, dst_inode, &args, status); if (status == 0) { + /* a zero-length count means clone to EOF in src */ + if (count == 0 && res.dst_fattr->valid & NFS_ATTR_FATTR_SIZE) + count = nfs_size_to_loff_t(res.dst_fattr->size) - dst_offset; nfs42_copy_dest_done(dst_inode, dst_offset, count); status = nfs_post_op_update_inode(dst_inode, res.dst_fattr); } diff -Nru linux-6.0.6/fs/nfs/nfs4client.c linux-6.0.12/fs/nfs/nfs4client.c --- linux-6.0.6/fs/nfs/nfs4client.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nfs/nfs4client.c 2023-01-18 18:27:39.000000000 +0000 @@ -346,6 +346,7 @@ ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE, "NFSv4.0 transport Slot table"); if (ret) { + nfs4_shutdown_slot_table(tbl); kfree(tbl); return ret; } diff -Nru linux-6.0.6/fs/nfs/nfs4proc.c linux-6.0.12/fs/nfs/nfs4proc.c --- linux-6.0.6/fs/nfs/nfs4proc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nfs/nfs4proc.c 2023-01-18 18:27:39.000000000 +0000 @@ -7137,6 +7137,7 @@ { struct nfs4_lockdata *data = calldata; struct nfs4_lock_state *lsp = data->lsp; + struct nfs_server *server = NFS_SERVER(d_inode(data->ctx->dentry)); if (!nfs4_sequence_done(task, &data->res.seq_res)) return; @@ -7144,8 +7145,7 @@ data->rpc_status = task->tk_status; switch (task->tk_status) { case 0: - renew_lease(NFS_SERVER(d_inode(data->ctx->dentry)), - data->timestamp); + renew_lease(server, data->timestamp); if (data->arg.new_lock && !data->cancelled) { data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS); if (locks_lock_inode_wait(lsp->ls_state->inode, &data->fl) < 0) @@ -7166,6 +7166,8 @@ if (!nfs4_stateid_match(&data->arg.open_stateid, &lsp->ls_state->open_stateid)) goto out_restart; + else if (nfs4_async_handle_error(task, server, lsp->ls_state, NULL) == -EAGAIN) + goto out_restart; } else if (!nfs4_stateid_match(&data->arg.lock_stateid, &lsp->ls_stateid)) goto out_restart; diff -Nru linux-6.0.6/fs/nfs/nfs4state.c linux-6.0.12/fs/nfs/nfs4state.c --- linux-6.0.6/fs/nfs/nfs4state.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nfs/nfs4state.c 2023-01-18 18:27:39.000000000 +0000 @@ -1787,6 +1787,7 @@ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp) { + set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state); /* Mark all delegations for reclaim */ nfs_delegation_mark_reclaim(clp); nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot); @@ -2671,6 +2672,7 @@ if (status < 0) goto out_error; nfs4_state_end_reclaim_reboot(clp); + continue; } /* Detect expired delegations... */ diff -Nru linux-6.0.6/fs/nfsd/filecache.c linux-6.0.12/fs/nfsd/filecache.c --- linux-6.0.6/fs/nfsd/filecache.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nfsd/filecache.c 2023-01-18 18:27:39.000000000 +0000 @@ -405,22 +405,15 @@ return false; } -/* - * Return true if the file was unhashed. - */ -static bool +static void nfsd_file_unhash_and_dispose(struct nfsd_file *nf, struct list_head *dispose) { trace_nfsd_file_unhash_and_dispose(nf); - if (!nfsd_file_unhash(nf)) - return false; - /* keep final reference for nfsd_file_lru_dispose */ - if (refcount_dec_not_one(&nf->nf_ref)) - return true; - - nfsd_file_lru_remove(nf); - list_add(&nf->nf_lru, dispose); - return true; + if (nfsd_file_unhash(nf)) { + /* caller must call nfsd_file_dispose_list() later */ + nfsd_file_lru_remove(nf); + list_add(&nf->nf_lru, dispose); + } } static void @@ -562,8 +555,6 @@ * @lock: LRU list lock (unused) * @arg: dispose list * - * Note this can deadlock with nfsd_file_cache_purge. - * * Return values: * %LRU_REMOVED: @item was removed from the LRU * %LRU_ROTATE: @item is to be moved to the LRU tail @@ -748,8 +739,6 @@ * * Walk the LRU list and close any entries that have not been used since * the last scan. - * - * Note this can deadlock with nfsd_file_cache_purge. */ static void nfsd_file_delayed_close(struct work_struct *work) @@ -891,16 +880,12 @@ goto out; } -/* - * Note this can deadlock with nfsd_file_lru_cb. - */ static void __nfsd_file_cache_purge(struct net *net) { struct rhashtable_iter iter; struct nfsd_file *nf; LIST_HEAD(dispose); - bool del; rhashtable_walk_enter(&nfsd_file_rhash_tbl, &iter); do { @@ -908,16 +893,8 @@ nf = rhashtable_walk_next(&iter); while (!IS_ERR_OR_NULL(nf)) { - if (net && nf->nf_net != net) - continue; - del = nfsd_file_unhash_and_dispose(nf, &dispose); - - /* - * Deadlock detected! Something marked this entry as - * unhased, but hasn't removed it from the hash list. - */ - WARN_ON_ONCE(!del); - + if (!net || nf->nf_net == net) + nfsd_file_unhash_and_dispose(nf, &dispose); nf = rhashtable_walk_next(&iter); } diff -Nru linux-6.0.6/fs/nfsd/nfs4state.c linux-6.0.12/fs/nfsd/nfs4state.c --- linux-6.0.6/fs/nfsd/nfs4state.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nfsd/nfs4state.c 2023-01-18 18:27:39.000000000 +0000 @@ -5313,6 +5313,7 @@ if (err) return -EAGAIN; + exp_put(exp); dput(child); if (child != file_dentry(fp->fi_deleg_file->nf_file)) return -EAGAIN; diff -Nru linux-6.0.6/fs/nfsd/vfs.c linux-6.0.12/fs/nfsd/vfs.c --- linux-6.0.6/fs/nfsd/vfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nfsd/vfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -572,8 +572,8 @@ ret = vfs_copy_file_range(src, src_pos, dst, dst_pos, count, 0); if (ret == -EOPNOTSUPP || ret == -EXDEV) - ret = generic_copy_file_range(src, src_pos, dst, dst_pos, - count, 0); + ret = vfs_copy_file_range(src, src_pos, dst, dst_pos, count, + COPY_FILE_SPLICE); return ret; } @@ -847,10 +847,11 @@ struct svc_rqst *rqstp = sd->u.data; struct page *page = buf->page; // may be a compound one unsigned offset = buf->offset; + struct page *last_page; - page += offset / PAGE_SIZE; - for (int i = sd->len; i > 0; i -= PAGE_SIZE) - svc_rqst_replace_page(rqstp, page++); + last_page = page + (offset + sd->len - 1) / PAGE_SIZE; + for (page += offset / PAGE_SIZE; page <= last_page; page++) + svc_rqst_replace_page(rqstp, page); if (rqstp->rq_res.page_len == 0) // first call rqstp->rq_res.page_base = offset % PAGE_SIZE; rqstp->rq_res.page_len += sd->len; diff -Nru linux-6.0.6/fs/nilfs2/dat.c linux-6.0.12/fs/nilfs2/dat.c --- linux-6.0.6/fs/nilfs2/dat.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nilfs2/dat.c 2023-01-18 18:27:39.000000000 +0000 @@ -111,6 +111,13 @@ kunmap_atomic(kaddr); nilfs_dat_commit_entry(dat, req); + + if (unlikely(req->pr_desc_bh == NULL || req->pr_bitmap_bh == NULL)) { + nilfs_error(dat->i_sb, + "state inconsistency probably due to duplicate use of vblocknr = %llu", + (unsigned long long)req->pr_entry_nr); + return; + } nilfs_palloc_commit_free_entry(dat, req); } diff -Nru linux-6.0.6/fs/nilfs2/segment.c linux-6.0.12/fs/nilfs2/segment.c --- linux-6.0.6/fs/nilfs2/segment.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nilfs2/segment.c 2023-01-18 18:27:39.000000000 +0000 @@ -317,7 +317,7 @@ struct the_nilfs *nilfs = sb->s_fs_info; struct nilfs_sc_info *sci = nilfs->ns_writer; - if (!sci || !sci->sc_flush_request) + if (sb_rdonly(sb) || unlikely(!sci) || !sci->sc_flush_request) return; set_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags); @@ -2243,7 +2243,7 @@ struct nilfs_transaction_info *ti; int err; - if (!sci) + if (sb_rdonly(sb) || unlikely(!sci)) return -EROFS; /* A call inside transactions causes a deadlock. */ @@ -2282,7 +2282,7 @@ struct nilfs_transaction_info ti; int err = 0; - if (!sci) + if (sb_rdonly(sb) || unlikely(!sci)) return -EROFS; nilfs_transaction_lock(sb, &ti, 0); @@ -2778,11 +2778,12 @@ if (nilfs->ns_writer) { /* - * This happens if the filesystem was remounted - * read/write after nilfs_error degenerated it into a - * read-only mount. + * This happens if the filesystem is made read-only by + * __nilfs_error or nilfs_remount and then remounted + * read/write. In these cases, reuse the existing + * writer. */ - nilfs_detach_log_writer(sb); + return 0; } nilfs->ns_writer = nilfs_segctor_new(sb, root); diff -Nru linux-6.0.6/fs/nilfs2/sufile.c linux-6.0.12/fs/nilfs2/sufile.c --- linux-6.0.6/fs/nilfs2/sufile.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nilfs2/sufile.c 2023-01-18 18:27:39.000000000 +0000 @@ -495,14 +495,22 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum) { struct buffer_head *bh; + void *kaddr; + struct nilfs_segment_usage *su; int ret; + down_write(&NILFS_MDT(sufile)->mi_sem); ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh); if (!ret) { mark_buffer_dirty(bh); nilfs_mdt_mark_dirty(sufile); + kaddr = kmap_atomic(bh->b_page); + su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr); + nilfs_segment_usage_set_dirty(su); + kunmap_atomic(kaddr); brelse(bh); } + up_write(&NILFS_MDT(sufile)->mi_sem); return ret; } diff -Nru linux-6.0.6/fs/nilfs2/super.c linux-6.0.12/fs/nilfs2/super.c --- linux-6.0.6/fs/nilfs2/super.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nilfs2/super.c 2023-01-18 18:27:39.000000000 +0000 @@ -1133,8 +1133,6 @@ if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb)) goto out; if (*flags & SB_RDONLY) { - /* Shutting down log writer */ - nilfs_detach_log_writer(sb); sb->s_flags |= SB_RDONLY; /* diff -Nru linux-6.0.6/fs/nilfs2/the_nilfs.c linux-6.0.12/fs/nilfs2/the_nilfs.c --- linux-6.0.6/fs/nilfs2/the_nilfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/nilfs2/the_nilfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -690,9 +690,7 @@ { unsigned long ncleansegs; - down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile); - up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment; return 0; } diff -Nru linux-6.0.6/fs/ntfs/attrib.c linux-6.0.12/fs/ntfs/attrib.c --- linux-6.0.6/fs/ntfs/attrib.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ntfs/attrib.c 2023-01-18 18:27:39.000000000 +0000 @@ -594,17 +594,37 @@ for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) { u8 *mrec_end = (u8 *)ctx->mrec + le32_to_cpu(ctx->mrec->bytes_allocated); - u8 *name_end = (u8 *)a + le16_to_cpu(a->name_offset) + - a->name_length * sizeof(ntfschar); - if ((u8*)a < (u8*)ctx->mrec || (u8*)a > mrec_end || - name_end > mrec_end) + u8 *name_end; + + /* check whether ATTR_RECORD wrap */ + if ((u8 *)a < (u8 *)ctx->mrec) break; + + /* check whether Attribute Record Header is within bounds */ + if ((u8 *)a > mrec_end || + (u8 *)a + sizeof(ATTR_RECORD) > mrec_end) + break; + + /* check whether ATTR_RECORD's name is within bounds */ + name_end = (u8 *)a + le16_to_cpu(a->name_offset) + + a->name_length * sizeof(ntfschar); + if (name_end > mrec_end) + break; + ctx->attr = a; if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) || a->type == AT_END)) return -ENOENT; if (unlikely(!a->length)) break; + + /* check whether ATTR_RECORD's length wrap */ + if ((u8 *)a + le32_to_cpu(a->length) < (u8 *)a) + break; + /* check whether ATTR_RECORD's length is within bounds */ + if ((u8 *)a + le32_to_cpu(a->length) > mrec_end) + break; + if (a->type != type) continue; /* diff -Nru linux-6.0.6/fs/ntfs/inode.c linux-6.0.12/fs/ntfs/inode.c --- linux-6.0.6/fs/ntfs/inode.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/ntfs/inode.c 2023-01-18 18:27:39.000000000 +0000 @@ -1829,6 +1829,13 @@ goto err_out; } + /* Sanity check offset to the first attribute */ + if (le16_to_cpu(m->attrs_offset) >= le32_to_cpu(m->bytes_allocated)) { + ntfs_error(sb, "Incorrect mft offset to the first attribute %u in superblock.", + le16_to_cpu(m->attrs_offset)); + goto err_out; + } + /* Need this to sanity check attribute list references to $MFT. */ vi->i_generation = ni->seq_no = le16_to_cpu(m->sequence_number); diff -Nru linux-6.0.6/fs/read_write.c linux-6.0.12/fs/read_write.c --- linux-6.0.6/fs/read_write.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/read_write.c 2023-01-18 18:27:39.000000000 +0000 @@ -1388,6 +1388,8 @@ struct file *file_out, loff_t pos_out, size_t len, unsigned int flags) { + lockdep_assert(sb_write_started(file_inode(file_out)->i_sb)); + return do_splice_direct(file_in, &pos_in, file_out, &pos_out, len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0); } @@ -1424,7 +1426,9 @@ * and several different sets of file_operations, but they all end up * using the same ->copy_file_range() function pointer. */ - if (file_out->f_op->copy_file_range) { + if (flags & COPY_FILE_SPLICE) { + /* cross sb splice is allowed */ + } else if (file_out->f_op->copy_file_range) { if (file_in->f_op->copy_file_range != file_out->f_op->copy_file_range) return -EXDEV; @@ -1474,8 +1478,9 @@ size_t len, unsigned int flags) { ssize_t ret; + bool splice = flags & COPY_FILE_SPLICE; - if (flags != 0) + if (flags & ~COPY_FILE_SPLICE) return -EINVAL; ret = generic_copy_file_checks(file_in, pos_in, file_out, pos_out, &len, @@ -1501,14 +1506,14 @@ * same sb using clone, but for filesystems where both clone and copy * are supported (e.g. nfs,cifs), we only call the copy method. */ - if (file_out->f_op->copy_file_range) { + if (!splice && file_out->f_op->copy_file_range) { ret = file_out->f_op->copy_file_range(file_in, pos_in, file_out, pos_out, len, flags); goto done; } - if (file_in->f_op->remap_file_range && + if (!splice && file_in->f_op->remap_file_range && file_inode(file_in)->i_sb == file_inode(file_out)->i_sb) { ret = file_in->f_op->remap_file_range(file_in, pos_in, file_out, pos_out, @@ -1528,6 +1533,8 @@ * consistent story about which filesystems support copy_file_range() * and which filesystems do not, that will allow userspace tools to * make consistent desicions w.r.t using copy_file_range(). + * + * We also get here if caller (e.g. nfsd) requested COPY_FILE_SPLICE. */ ret = generic_copy_file_range(file_in, pos_in, file_out, pos_out, len, flags); @@ -1582,6 +1589,10 @@ pos_out = f_out.file->f_pos; } + ret = -EINVAL; + if (flags != 0) + goto out; + ret = vfs_copy_file_range(f_in.file, pos_in, f_out.file, pos_out, len, flags); if (ret > 0) { diff -Nru linux-6.0.6/fs/squashfs/file.c linux-6.0.12/fs/squashfs/file.c --- linux-6.0.6/fs/squashfs/file.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/squashfs/file.c 2023-01-18 18:27:39.000000000 +0000 @@ -506,8 +506,9 @@ squashfs_i(inode)->fragment_size); struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; unsigned int n, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; + int error = buffer->error; - if (buffer->error) + if (error) goto out; expected += squashfs_i(inode)->fragment_offset; @@ -529,7 +530,7 @@ out: squashfs_cache_put(buffer); - return buffer->error; + return error; } static void squashfs_readahead(struct readahead_control *ractl) @@ -557,6 +558,13 @@ int res, bsize; u64 block = 0; unsigned int expected; + struct page *last_page; + + expected = start >> msblk->block_log == file_end ? + (i_size_read(inode) & (msblk->block_size - 1)) : + msblk->block_size; + + max_pages = (expected + PAGE_SIZE - 1) >> PAGE_SHIFT; nr_pages = __readahead_batch(ractl, pages, max_pages); if (!nr_pages) @@ -566,13 +574,10 @@ goto skip_pages; index = pages[0]->index >> shift; + if ((pages[nr_pages - 1]->index >> shift) != index) goto skip_pages; - expected = index == file_end ? - (i_size_read(inode) & (msblk->block_size - 1)) : - msblk->block_size; - if (index == file_end && squashfs_i(inode)->fragment_block != SQUASHFS_INVALID_BLK) { res = squashfs_readahead_fragment(pages, nr_pages, @@ -593,15 +598,15 @@ res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor); - squashfs_page_actor_free(actor); + last_page = squashfs_page_actor_free(actor); if (res == expected) { int bytes; /* Last page (if present) may have trailing bytes not filled */ bytes = res % PAGE_SIZE; - if (pages[nr_pages - 1]->index == file_end && bytes) - memzero_page(pages[nr_pages - 1], bytes, + if (index == file_end && bytes && last_page) + memzero_page(last_page, bytes, PAGE_SIZE - bytes); for (i = 0; i < nr_pages; i++) { diff -Nru linux-6.0.6/fs/squashfs/page_actor.c linux-6.0.12/fs/squashfs/page_actor.c --- linux-6.0.6/fs/squashfs/page_actor.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/squashfs/page_actor.c 2023-01-18 18:27:39.000000000 +0000 @@ -71,11 +71,13 @@ (actor->next_index != actor->page[actor->next_page]->index)) { actor->next_index++; actor->returned_pages++; + actor->last_page = NULL; return actor->alloc_buffer ? actor->tmp_buffer : ERR_PTR(-ENOMEM); } actor->next_index++; actor->returned_pages++; + actor->last_page = actor->page[actor->next_page]; return actor->pageaddr = kmap_local_page(actor->page[actor->next_page++]); } @@ -125,6 +127,7 @@ actor->returned_pages = 0; actor->next_index = page[0]->index & ~((1 << (msblk->block_log - PAGE_SHIFT)) - 1); actor->pageaddr = NULL; + actor->last_page = NULL; actor->alloc_buffer = msblk->decompressor->alloc_buffer; actor->squashfs_first_page = direct_first_page; actor->squashfs_next_page = direct_next_page; diff -Nru linux-6.0.6/fs/squashfs/page_actor.h linux-6.0.12/fs/squashfs/page_actor.h --- linux-6.0.6/fs/squashfs/page_actor.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/squashfs/page_actor.h 2023-01-18 18:27:39.000000000 +0000 @@ -16,6 +16,7 @@ void *(*squashfs_first_page)(struct squashfs_page_actor *); void *(*squashfs_next_page)(struct squashfs_page_actor *); void (*squashfs_finish_page)(struct squashfs_page_actor *); + struct page *last_page; int pages; int length; int next_page; @@ -29,10 +30,13 @@ extern struct squashfs_page_actor *squashfs_page_actor_init_special( struct squashfs_sb_info *msblk, struct page **page, int pages, int length); -static inline void squashfs_page_actor_free(struct squashfs_page_actor *actor) +static inline struct page *squashfs_page_actor_free(struct squashfs_page_actor *actor) { + struct page *last_page = actor->last_page; + kfree(actor->tmp_buffer); kfree(actor); + return last_page; } static inline void *squashfs_first_page(struct squashfs_page_actor *actor) { diff -Nru linux-6.0.6/fs/super.c linux-6.0.12/fs/super.c --- linux-6.0.6/fs/super.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/super.c 2023-01-18 18:27:39.000000000 +0000 @@ -291,7 +291,7 @@ WARN_ON(s->s_inode_lru.node); WARN_ON(!list_empty(&s->s_mounts)); security_sb_free(s); - fscrypt_sb_free(s); + fscrypt_destroy_keyring(s); put_user_ns(s->s_user_ns); kfree(s->s_subtype); call_rcu(&s->rcu, destroy_super_rcu); @@ -480,6 +480,7 @@ evict_inodes(sb); /* only nonzero refcount inodes can have marks */ fsnotify_sb_delete(sb); + fscrypt_destroy_keyring(sb); security_sb_delete(sb); if (sb->s_dio_done_wq) { diff -Nru linux-6.0.6/fs/udf/namei.c linux-6.0.12/fs/udf/namei.c --- linux-6.0.6/fs/udf/namei.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/udf/namei.c 2023-01-18 18:27:39.000000000 +0000 @@ -240,7 +240,7 @@ poffset - lfi); else { if (!copy_name) { - copy_name = kmalloc(UDF_NAME_LEN, + copy_name = kmalloc(UDF_NAME_LEN_CS0, GFP_NOFS); if (!copy_name) { fi = ERR_PTR(-ENOMEM); diff -Nru linux-6.0.6/fs/zonefs/super.c linux-6.0.12/fs/zonefs/super.c --- linux-6.0.6/fs/zonefs/super.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/zonefs/super.c 2023-01-18 18:27:39.000000000 +0000 @@ -41,6 +41,13 @@ return; /* + * For zones that transitioned to the offline or readonly condition, + * we only need to clear the active state. + */ + if (zi->i_flags & (ZONEFS_ZONE_OFFLINE | ZONEFS_ZONE_READONLY)) + goto out; + + /* * If the zone is active, that is, if it is explicitly open or * partially written, check if it was already accounted as active. */ @@ -53,6 +60,7 @@ return; } +out: /* The zone is not active. If it was, update the active count */ if (zi->i_flags & ZONEFS_ZONE_ACTIVE) { zi->i_flags &= ~ZONEFS_ZONE_ACTIVE; @@ -324,6 +332,7 @@ inode->i_flags |= S_IMMUTABLE; inode->i_mode &= ~0777; zone->wp = zone->start; + zi->i_flags |= ZONEFS_ZONE_OFFLINE; return 0; case BLK_ZONE_COND_READONLY: /* @@ -342,8 +351,10 @@ zone->cond = BLK_ZONE_COND_OFFLINE; inode->i_mode &= ~0777; zone->wp = zone->start; + zi->i_flags |= ZONEFS_ZONE_OFFLINE; return 0; } + zi->i_flags |= ZONEFS_ZONE_READONLY; inode->i_mode &= ~0222; return i_size_read(inode); case BLK_ZONE_COND_FULL: @@ -478,8 +489,7 @@ struct super_block *sb = inode->i_sb; struct zonefs_sb_info *sbi = ZONEFS_SB(sb); unsigned int noio_flag; - unsigned int nr_zones = - zi->i_zone_size >> (sbi->s_zone_sectors_shift + SECTOR_SHIFT); + unsigned int nr_zones = 1; struct zonefs_ioerr_data err = { .inode = inode, .write = write, @@ -487,6 +497,15 @@ int ret; /* + * The only files that have more than one zone are conventional zone + * files with aggregated conventional zones, for which the inode zone + * size is always larger than the device zone size. + */ + if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev)) + nr_zones = zi->i_zone_size >> + (sbi->s_zone_sectors_shift + SECTOR_SHIFT); + + /* * Memory allocations in blkdev_report_zones() can trigger a memory * reclaim which may in turn cause a recursion into zonefs as well as * struct request allocations for the same device. The former case may @@ -1407,6 +1426,14 @@ zi->i_ztype = type; zi->i_zsector = zone->start; zi->i_zone_size = zone->len << SECTOR_SHIFT; + if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT && + !(sbi->s_features & ZONEFS_F_AGGRCNV)) { + zonefs_err(sb, + "zone size %llu doesn't match device's zone sectors %llu\n", + zi->i_zone_size, + bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT); + return -EINVAL; + } zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE, zone->capacity << SECTOR_SHIFT); @@ -1456,11 +1483,11 @@ struct inode *dir = d_inode(parent); struct dentry *dentry; struct inode *inode; - int ret; + int ret = -ENOMEM; dentry = d_alloc_name(parent, name); if (!dentry) - return NULL; + return ERR_PTR(ret); inode = new_inode(parent->d_sb); if (!inode) @@ -1485,7 +1512,7 @@ dput: dput(dentry); - return NULL; + return ERR_PTR(ret); } struct zonefs_zone_data { @@ -1505,7 +1532,7 @@ struct blk_zone *zone, *next, *end; const char *zgroup_name; char *file_name; - struct dentry *dir; + struct dentry *dir, *dent; unsigned int n = 0; int ret; @@ -1523,8 +1550,8 @@ zgroup_name = "seq"; dir = zonefs_create_inode(sb->s_root, zgroup_name, NULL, type); - if (!dir) { - ret = -ENOMEM; + if (IS_ERR(dir)) { + ret = PTR_ERR(dir); goto free; } @@ -1570,8 +1597,9 @@ * Use the file number within its group as file name. */ snprintf(file_name, ZONEFS_NAME_MAX - 1, "%u", n); - if (!zonefs_create_inode(dir, file_name, zone, type)) { - ret = -ENOMEM; + dent = zonefs_create_inode(dir, file_name, zone, type); + if (IS_ERR(dent)) { + ret = PTR_ERR(dent); goto free; } @@ -1905,18 +1933,18 @@ if (ret) return ret; - ret = register_filesystem(&zonefs_type); + ret = zonefs_sysfs_init(); if (ret) goto destroy_inodecache; - ret = zonefs_sysfs_init(); + ret = register_filesystem(&zonefs_type); if (ret) - goto unregister_fs; + goto sysfs_exit; return 0; -unregister_fs: - unregister_filesystem(&zonefs_type); +sysfs_exit: + zonefs_sysfs_exit(); destroy_inodecache: zonefs_destroy_inodecache(); @@ -1925,9 +1953,9 @@ static void __exit zonefs_exit(void) { + unregister_filesystem(&zonefs_type); zonefs_sysfs_exit(); zonefs_destroy_inodecache(); - unregister_filesystem(&zonefs_type); } MODULE_AUTHOR("Damien Le Moal"); diff -Nru linux-6.0.6/fs/zonefs/zonefs.h linux-6.0.12/fs/zonefs/zonefs.h --- linux-6.0.6/fs/zonefs/zonefs.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/fs/zonefs/zonefs.h 2023-01-18 18:27:39.000000000 +0000 @@ -39,8 +39,10 @@ return ZONEFS_ZTYPE_SEQ; } -#define ZONEFS_ZONE_OPEN (1 << 0) -#define ZONEFS_ZONE_ACTIVE (1 << 1) +#define ZONEFS_ZONE_OPEN (1U << 0) +#define ZONEFS_ZONE_ACTIVE (1U << 1) +#define ZONEFS_ZONE_OFFLINE (1U << 2) +#define ZONEFS_ZONE_READONLY (1U << 3) /* * In-memory inode data. diff -Nru linux-6.0.6/include/acpi/ghes.h linux-6.0.12/include/acpi/ghes.h --- linux-6.0.6/include/acpi/ghes.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/acpi/ghes.h 2023-01-18 18:27:39.000000000 +0000 @@ -71,7 +71,7 @@ void ghes_unregister_vendor_record_notifier(struct notifier_block *nb); #endif -int ghes_estatus_pool_init(int num_ghes); +int ghes_estatus_pool_init(unsigned int num_ghes); /* From drivers/edac/ghes_edac.c */ diff -Nru linux-6.0.6/include/asm-generic/vmlinux.lds.h linux-6.0.12/include/asm-generic/vmlinux.lds.h --- linux-6.0.6/include/asm-generic/vmlinux.lds.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/asm-generic/vmlinux.lds.h 2023-01-18 18:27:39.000000000 +0000 @@ -333,6 +333,7 @@ #define DATA_DATA \ *(.xiptext) \ *(DATA_MAIN) \ + *(.data..decrypted) \ *(.ref.data) \ *(.data..shared_aligned) /* percpu related */ \ MEM_KEEP(init.data*) \ @@ -975,7 +976,6 @@ #ifdef CONFIG_AMD_MEM_ENCRYPT #define PERCPU_DECRYPTED_SECTION \ . = ALIGN(PAGE_SIZE); \ - *(.data..decrypted) \ *(.data..percpu..decrypted) \ . = ALIGN(PAGE_SIZE); #else diff -Nru linux-6.0.6/include/linux/blkdev.h linux-6.0.12/include/linux/blkdev.h --- linux-6.0.6/include/linux/blkdev.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/blkdev.h 2023-01-18 18:27:39.000000000 +0000 @@ -311,6 +311,13 @@ unsigned char discard_misaligned; unsigned char raid_partial_stripes_expensive; enum blk_zoned_model zoned; + + /* + * Drivers that set dma_alignment to less than 511 must be prepared to + * handle individual bvec's that are not a multiple of a SECTOR_SIZE + * due to possible offsets. + */ + unsigned int dma_alignment; }; typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx, @@ -456,12 +463,6 @@ unsigned long nr_requests; /* Max # of requests */ unsigned int dma_pad_mask; - /* - * Drivers that set dma_alignment to less than 511 must be prepared to - * handle individual bvec's that are not a multiple of a SECTOR_SIZE - * due to possible offsets. - */ - unsigned int dma_alignment; #ifdef CONFIG_BLK_INLINE_ENCRYPTION struct blk_crypto_profile *crypto_profile; @@ -945,7 +946,6 @@ extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt); extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); extern void blk_set_queue_depth(struct request_queue *q, unsigned int depth); -extern void blk_set_default_limits(struct queue_limits *lim); extern void blk_set_stacking_limits(struct queue_limits *lim); extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, sector_t offset); @@ -1311,7 +1311,7 @@ static inline int queue_dma_alignment(const struct request_queue *q) { - return q ? q->dma_alignment : 511; + return q ? q->limits.dma_alignment : 511; } static inline unsigned int bdev_dma_alignment(struct block_device *bdev) diff -Nru linux-6.0.6/include/linux/bpf.h linux-6.0.12/include/linux/bpf.h --- linux-6.0.6/include/linux/bpf.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/bpf.h 2023-01-18 18:27:39.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include struct bpf_verifier_env; struct bpf_verifier_log; @@ -894,6 +895,10 @@ void *rw_image; u32 image_off; struct bpf_ksym ksym; +#ifdef CONFIG_HAVE_STATIC_CALL + struct static_call_key *sc_key; + void *sc_tramp; +#endif }; static __always_inline __nocfi unsigned int bpf_dispatcher_nop_func( @@ -911,6 +916,34 @@ struct bpf_attach_target_info *tgt_info); void bpf_trampoline_put(struct bpf_trampoline *tr); int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs); + +/* + * When the architecture supports STATIC_CALL replace the bpf_dispatcher_fn + * indirection with a direct call to the bpf program. If the architecture does + * not have STATIC_CALL, avoid a double-indirection. + */ +#ifdef CONFIG_HAVE_STATIC_CALL + +#define __BPF_DISPATCHER_SC_INIT(_name) \ + .sc_key = &STATIC_CALL_KEY(_name), \ + .sc_tramp = STATIC_CALL_TRAMP_ADDR(_name), + +#define __BPF_DISPATCHER_SC(name) \ + DEFINE_STATIC_CALL(bpf_dispatcher_##name##_call, bpf_dispatcher_nop_func) + +#define __BPF_DISPATCHER_CALL(name) \ + static_call(bpf_dispatcher_##name##_call)(ctx, insnsi, bpf_func) + +#define __BPF_DISPATCHER_UPDATE(_d, _new) \ + __static_call_update((_d)->sc_key, (_d)->sc_tramp, (_new)) + +#else +#define __BPF_DISPATCHER_SC_INIT(name) +#define __BPF_DISPATCHER_SC(name) +#define __BPF_DISPATCHER_CALL(name) bpf_func(ctx, insnsi) +#define __BPF_DISPATCHER_UPDATE(_d, _new) +#endif + #define BPF_DISPATCHER_INIT(_name) { \ .mutex = __MUTEX_INITIALIZER(_name.mutex), \ .func = &_name##_func, \ @@ -922,25 +955,29 @@ .name = #_name, \ .lnode = LIST_HEAD_INIT(_name.ksym.lnode), \ }, \ + __BPF_DISPATCHER_SC_INIT(_name##_call) \ } #define DEFINE_BPF_DISPATCHER(name) \ + __BPF_DISPATCHER_SC(name); \ noinline __nocfi unsigned int bpf_dispatcher_##name##_func( \ const void *ctx, \ const struct bpf_insn *insnsi, \ bpf_func_t bpf_func) \ { \ - return bpf_func(ctx, insnsi); \ + return __BPF_DISPATCHER_CALL(name); \ } \ EXPORT_SYMBOL(bpf_dispatcher_##name##_func); \ struct bpf_dispatcher bpf_dispatcher_##name = \ BPF_DISPATCHER_INIT(bpf_dispatcher_##name); + #define DECLARE_BPF_DISPATCHER(name) \ unsigned int bpf_dispatcher_##name##_func( \ const void *ctx, \ const struct bpf_insn *insnsi, \ bpf_func_t bpf_func); \ extern struct bpf_dispatcher bpf_dispatcher_##name; + #define BPF_DISPATCHER_FUNC(name) bpf_dispatcher_##name##_func #define BPF_DISPATCHER_PTR(name) (&bpf_dispatcher_##name) void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from, @@ -1967,6 +2004,7 @@ return !sysctl_unprivileged_bpf_disabled; } +void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog); #else /* !CONFIG_BPF_SYSCALL */ static inline struct bpf_prog *bpf_prog_get(u32 ufd) { @@ -2176,6 +2214,9 @@ return false; } +static inline void bpf_prog_inc_misses_counter(struct bpf_prog *prog) +{ +} #endif /* CONFIG_BPF_SYSCALL */ void __bpf_free_used_btfs(struct bpf_prog_aux *aux, diff -Nru linux-6.0.6/include/linux/bpf_verifier.h linux-6.0.12/include/linux/bpf_verifier.h --- linux-6.0.6/include/linux/bpf_verifier.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/bpf_verifier.h 2023-01-18 18:27:39.000000000 +0000 @@ -348,6 +348,27 @@ iter < frame->allocated_stack / BPF_REG_SIZE; \ iter++, reg = bpf_get_spilled_reg(iter, frame)) +/* Invoke __expr over regsiters in __vst, setting __state and __reg */ +#define bpf_for_each_reg_in_vstate(__vst, __state, __reg, __expr) \ + ({ \ + struct bpf_verifier_state *___vstate = __vst; \ + int ___i, ___j; \ + for (___i = 0; ___i <= ___vstate->curframe; ___i++) { \ + struct bpf_reg_state *___regs; \ + __state = ___vstate->frame[___i]; \ + ___regs = __state->regs; \ + for (___j = 0; ___j < MAX_BPF_REG; ___j++) { \ + __reg = &___regs[___j]; \ + (void)(__expr); \ + } \ + bpf_for_each_spilled_reg(___j, __state, __reg) { \ + if (!__reg) \ + continue; \ + (void)(__expr); \ + } \ + } \ + }) + /* linked list of verifier states used to prune search */ struct bpf_verifier_state_list { struct bpf_verifier_state state; diff -Nru linux-6.0.6/include/linux/can/dev.h linux-6.0.12/include/linux/can/dev.h --- linux-6.0.6/include/linux/can/dev.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/can/dev.h 2023-01-18 18:27:39.000000000 +0000 @@ -147,6 +147,22 @@ return priv->ctrlmode & ~priv->ctrlmode_supported; } +/* drop skb if it does not contain a valid CAN frame for sending */ +static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_buff *skb) +{ + struct can_priv *priv = netdev_priv(dev); + + if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) { + netdev_info_once(dev, + "interface in listen only mode, dropping skb\n"); + kfree_skb(skb); + dev->stats.tx_dropped++; + return true; + } + + return can_dropped_invalid_skb(dev, skb); +} + void can_setup(struct net_device *dev); struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, diff -Nru linux-6.0.6/include/linux/damon.h linux-6.0.12/include/linux/damon.h --- linux-6.0.6/include/linux/damon.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/damon.h 2023-01-18 18:27:39.000000000 +0000 @@ -216,13 +216,26 @@ }; /** - * struct damos - Represents a Data Access Monitoring-based Operation Scheme. + * struct damos_access_pattern - Target access pattern of the given scheme. * @min_sz_region: Minimum size of target regions. * @max_sz_region: Maximum size of target regions. * @min_nr_accesses: Minimum ``->nr_accesses`` of target regions. * @max_nr_accesses: Maximum ``->nr_accesses`` of target regions. * @min_age_region: Minimum age of target regions. * @max_age_region: Maximum age of target regions. + */ +struct damos_access_pattern { + unsigned long min_sz_region; + unsigned long max_sz_region; + unsigned int min_nr_accesses; + unsigned int max_nr_accesses; + unsigned int min_age_region; + unsigned int max_age_region; +}; + +/** + * struct damos - Represents a Data Access Monitoring-based Operation Scheme. + * @pattern: Access pattern of target regions. * @action: &damo_action to be applied to the target regions. * @quota: Control the aggressiveness of this scheme. * @wmarks: Watermarks for automated (in)activation of this scheme. @@ -230,10 +243,8 @@ * @list: List head for siblings. * * For each aggregation interval, DAMON finds regions which fit in the - * condition (&min_sz_region, &max_sz_region, &min_nr_accesses, - * &max_nr_accesses, &min_age_region, &max_age_region) and applies &action to - * those. To avoid consuming too much CPU time or IO resources for the - * &action, "a is used. + * &pattern and applies &action to those. To avoid consuming too much + * CPU time or IO resources for the &action, "a is used. * * To do the work only when needed, schemes can be activated for specific * system situations using &wmarks. If all schemes that registered to the @@ -248,12 +259,7 @@ * &action is applied. */ struct damos { - unsigned long min_sz_region; - unsigned long max_sz_region; - unsigned int min_nr_accesses; - unsigned int max_nr_accesses; - unsigned int min_age_region; - unsigned int max_age_region; + struct damos_access_pattern pattern; enum damos_action action; struct damos_quota quota; struct damos_watermarks wmarks; @@ -501,12 +507,9 @@ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges, unsigned int nr_ranges); -struct damos *damon_new_scheme( - unsigned long min_sz_region, unsigned long max_sz_region, - unsigned int min_nr_accesses, unsigned int max_nr_accesses, - unsigned int min_age_region, unsigned int max_age_region, - enum damos_action action, struct damos_quota *quota, - struct damos_watermarks *wmarks); +struct damos *damon_new_scheme(struct damos_access_pattern *pattern, + enum damos_action action, struct damos_quota *quota, + struct damos_watermarks *wmarks); void damon_add_scheme(struct damon_ctx *ctx, struct damos *s); void damon_destroy_scheme(struct damos *s); diff -Nru linux-6.0.6/include/linux/efi.h linux-6.0.12/include/linux/efi.h --- linux-6.0.6/include/linux/efi.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/efi.h 2023-01-18 18:27:39.000000000 +0000 @@ -1192,7 +1192,7 @@ arch_efi_call_virt_teardown(); \ }) -#define EFI_RANDOM_SEED_SIZE 64U +#define EFI_RANDOM_SEED_SIZE 32U // BLAKE2S_HASH_SIZE struct linux_efi_random_seed { u32 size; diff -Nru linux-6.0.6/include/linux/fault-inject.h linux-6.0.12/include/linux/fault-inject.h --- linux-6.0.6/include/linux/fault-inject.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/fault-inject.h 2023-01-18 18:27:39.000000000 +0000 @@ -20,7 +20,6 @@ atomic_t space; unsigned long verbose; bool task_filter; - bool no_warn; unsigned long stacktrace_depth; unsigned long require_start; unsigned long require_end; @@ -32,6 +31,10 @@ struct dentry *dname; }; +enum fault_flags { + FAULT_NOWARN = 1 << 0, +}; + #define FAULT_ATTR_INITIALIZER { \ .interval = 1, \ .times = ATOMIC_INIT(1), \ @@ -40,11 +43,11 @@ .ratelimit_state = RATELIMIT_STATE_INIT_DISABLED, \ .verbose = 2, \ .dname = NULL, \ - .no_warn = false, \ } #define DECLARE_FAULT_ATTR(name) struct fault_attr name = FAULT_ATTR_INITIALIZER int setup_fault_attr(struct fault_attr *attr, char *str); +bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags); bool should_fail(struct fault_attr *attr, ssize_t size); #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS diff -Nru linux-6.0.6/include/linux/fscache.h linux-6.0.12/include/linux/fscache.h --- linux-6.0.6/include/linux/fscache.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/fscache.h 2023-01-18 18:27:39.000000000 +0000 @@ -75,7 +75,7 @@ atomic_t n_accesses; /* Number of cache accesses in progress */ unsigned int debug_id; unsigned int key_hash; /* Hash of key string */ - char *key; /* Volume ID, eg. "afs@example.com@1234" */ + u8 *key; /* Volume ID, eg. "afs@example.com@1234" */ struct list_head proc_link; /* Link in /proc/fs/fscache/volumes */ struct hlist_bl_node hash_link; /* Link in hash table */ struct work_struct work; diff -Nru linux-6.0.6/include/linux/fscrypt.h linux-6.0.12/include/linux/fscrypt.h --- linux-6.0.6/include/linux/fscrypt.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/fscrypt.h 2023-01-18 18:27:39.000000000 +0000 @@ -312,7 +312,7 @@ } /* keyring.c */ -void fscrypt_sb_free(struct super_block *sb); +void fscrypt_destroy_keyring(struct super_block *sb); int fscrypt_ioctl_add_key(struct file *filp, void __user *arg); int fscrypt_add_test_dummy_key(struct super_block *sb, const struct fscrypt_dummy_policy *dummy_policy); @@ -526,7 +526,7 @@ } /* keyring.c */ -static inline void fscrypt_sb_free(struct super_block *sb) +static inline void fscrypt_destroy_keyring(struct super_block *sb) { } diff -Nru linux-6.0.6/include/linux/fs.h linux-6.0.12/include/linux/fs.h --- linux-6.0.6/include/linux/fs.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/fs.h 2023-01-18 18:27:39.000000000 +0000 @@ -1472,7 +1472,7 @@ const struct xattr_handler **s_xattr; #ifdef CONFIG_FS_ENCRYPTION const struct fscrypt_operations *s_cop; - struct key *s_master_keys; /* master crypto keys in use */ + struct fscrypt_keyring *s_master_keys; /* master crypto keys in use */ #endif #ifdef CONFIG_FS_VERITY const struct fsverity_operations *s_vop; @@ -2087,6 +2087,14 @@ */ #define REMAP_FILE_ADVISORY (REMAP_FILE_CAN_SHORTEN) +/* + * These flags control the behavior of vfs_copy_file_range(). + * They are not available to the user via syscall. + * + * COPY_FILE_SPLICE: call splice direct instead of fs clone/copy ops + */ +#define COPY_FILE_SPLICE (1 << 0) + struct iov_iter; struct io_uring_cmd; diff -Nru linux-6.0.6/include/linux/hugetlb.h linux-6.0.12/include/linux/hugetlb.h --- linux-6.0.6/include/linux/hugetlb.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/hugetlb.h 2023-01-18 18:27:39.000000000 +0000 @@ -665,7 +665,7 @@ nodemask_t *nmask, gfp_t gfp_mask); struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma, unsigned long address); -int huge_add_to_page_cache(struct page *page, struct address_space *mapping, +int hugetlb_add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t idx); void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma, unsigned long address, struct page *page); diff -Nru linux-6.0.6/include/linux/io_uring.h linux-6.0.12/include/linux/io_uring.h --- linux-6.0.6/include/linux/io_uring.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/io_uring.h 2023-01-18 18:27:39.000000000 +0000 @@ -15,6 +15,9 @@ IO_URING_F_SQE128 = 4, IO_URING_F_CQE32 = 8, IO_URING_F_IOPOLL = 16, + + /* the request is executed from poll, it should not be freed */ + IO_URING_F_MULTISHOT = 32, }; struct io_uring_cmd { diff -Nru linux-6.0.6/include/linux/kvm_host.h linux-6.0.12/include/linux/kvm_host.h --- linux-6.0.6/include/linux/kvm_host.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/kvm_host.h 2023-01-18 18:27:39.000000000 +0000 @@ -1241,8 +1241,18 @@ void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn); /** - * kvm_gfn_to_pfn_cache_init - prepare a cached kernel mapping and HPA for a - * given guest physical address. + * kvm_gpc_init - initialize gfn_to_pfn_cache. + * + * @gpc: struct gfn_to_pfn_cache object. + * + * This sets up a gfn_to_pfn_cache by initializing locks. Note, the cache must + * be zero-allocated (or zeroed by the caller before init). + */ +void kvm_gpc_init(struct gfn_to_pfn_cache *gpc); + +/** + * kvm_gpc_activate - prepare a cached kernel mapping and HPA for a given guest + * physical address. * * @kvm: pointer to kvm instance. * @gpc: struct gfn_to_pfn_cache object. @@ -1266,9 +1276,9 @@ * kvm_gfn_to_pfn_cache_check() to ensure that the cache is valid before * accessing the target page. */ -int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, - struct kvm_vcpu *vcpu, enum pfn_cache_usage usage, - gpa_t gpa, unsigned long len); +int kvm_gpc_activate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, + struct kvm_vcpu *vcpu, enum pfn_cache_usage usage, + gpa_t gpa, unsigned long len); /** * kvm_gfn_to_pfn_cache_check - check validity of a gfn_to_pfn_cache. @@ -1325,7 +1335,7 @@ void kvm_gfn_to_pfn_cache_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc); /** - * kvm_gfn_to_pfn_cache_destroy - destroy and unlink a gfn_to_pfn_cache. + * kvm_gpc_deactivate - deactivate and unlink a gfn_to_pfn_cache. * * @kvm: pointer to kvm instance. * @gpc: struct gfn_to_pfn_cache object. @@ -1333,7 +1343,7 @@ * This removes a cache from the @kvm's list to be processed on MMU notifier * invocation. */ -void kvm_gfn_to_pfn_cache_destroy(struct kvm *kvm, struct gfn_to_pfn_cache *gpc); +void kvm_gpc_deactivate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc); void kvm_sigset_activate(struct kvm_vcpu *vcpu); void kvm_sigset_deactivate(struct kvm_vcpu *vcpu); diff -Nru linux-6.0.6/include/linux/mlx5/driver.h linux-6.0.12/include/linux/mlx5/driver.h --- linux-6.0.6/include/linux/mlx5/driver.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/mlx5/driver.h 2023-01-18 18:27:39.000000000 +0000 @@ -973,7 +973,7 @@ struct mlx5_async_ctx { struct mlx5_core_dev *dev; atomic_t num_inflight; - struct wait_queue_head wait; + struct completion inflight_done; }; struct mlx5_async_work; @@ -984,6 +984,7 @@ struct mlx5_async_ctx *ctx; mlx5_async_cbk_t user_callback; u16 opcode; /* cmd opcode */ + u16 op_mod; /* cmd op_mod */ void *out; /* pointer to the cmd output buffer */ }; diff -Nru linux-6.0.6/include/linux/mmc/mmc.h linux-6.0.12/include/linux/mmc/mmc.h --- linux-6.0.6/include/linux/mmc/mmc.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/mmc/mmc.h 2023-01-18 18:27:39.000000000 +0000 @@ -451,7 +451,7 @@ #define MMC_SECURE_TRIM1_ARG 0x80000001 #define MMC_SECURE_TRIM2_ARG 0x80008000 #define MMC_SECURE_ARGS 0x80000000 -#define MMC_TRIM_ARGS 0x00008001 +#define MMC_TRIM_OR_DISCARD_ARGS 0x00008003 #define mmc_driver_type_mask(n) (1 << (n)) diff -Nru linux-6.0.6/include/linux/perf_event.h linux-6.0.12/include/linux/perf_event.h --- linux-6.0.6/include/linux/perf_event.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/perf_event.h 2023-01-18 18:27:39.000000000 +0000 @@ -736,11 +736,14 @@ struct fasync_struct *fasync; /* delayed work for NMIs and such */ - int pending_wakeup; - int pending_kill; - int pending_disable; + unsigned int pending_wakeup; + unsigned int pending_kill; + unsigned int pending_disable; + unsigned int pending_sigtrap; unsigned long pending_addr; /* SIGTRAP */ - struct irq_work pending; + struct irq_work pending_irq; + struct callback_head pending_task; + unsigned int pending_work; atomic_t event_limit; @@ -857,6 +860,14 @@ #endif void *task_ctx_data; /* pmu specific data */ struct rcu_head rcu_head; + + /* + * Sum (event->pending_sigtrap + event->pending_work) + * + * The SIGTRAP is targeted at ctx->task, as such it won't do changing + * that until the signal is delivered. + */ + local_t nr_pending; }; /* diff -Nru linux-6.0.6/include/linux/ring_buffer.h linux-6.0.12/include/linux/ring_buffer.h --- linux-6.0.6/include/linux/ring_buffer.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/ring_buffer.h 2023-01-18 18:27:39.000000000 +0000 @@ -100,7 +100,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full); __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu, - struct file *filp, poll_table *poll_table); + struct file *filp, poll_table *poll_table, int full); void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu); #define RING_BUFFER_ALL_CPUS -1 diff -Nru linux-6.0.6/include/linux/skmsg.h linux-6.0.12/include/linux/skmsg.h --- linux-6.0.6/include/linux/skmsg.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/skmsg.h 2023-01-18 18:27:39.000000000 +0000 @@ -376,7 +376,7 @@ } struct sk_psock *sk_psock_init(struct sock *sk, int node); -void sk_psock_stop(struct sk_psock *psock, bool wait); +void sk_psock_stop(struct sk_psock *psock); #if IS_ENABLED(CONFIG_BPF_STREAM_PARSER) int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock); diff -Nru linux-6.0.6/include/linux/trace.h linux-6.0.12/include/linux/trace.h --- linux-6.0.6/include/linux/trace.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/trace.h 2023-01-18 18:27:39.000000000 +0000 @@ -26,13 +26,13 @@ int flags; }; +struct trace_array; + #ifdef CONFIG_TRACING int register_ftrace_export(struct trace_export *export); int unregister_ftrace_export(struct trace_export *export); -struct trace_array; - void trace_printk_init_buffers(void); __printf(3, 4) int trace_array_printk(struct trace_array *tr, unsigned long ip, diff -Nru linux-6.0.6/include/linux/userfaultfd_k.h linux-6.0.12/include/linux/userfaultfd_k.h --- linux-6.0.6/include/linux/userfaultfd_k.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/userfaultfd_k.h 2023-01-18 18:27:39.000000000 +0000 @@ -146,9 +146,9 @@ static inline bool vma_can_userfault(struct vm_area_struct *vma, unsigned long vm_flags) { - if (vm_flags & VM_UFFD_MINOR) - return is_vm_hugetlb_page(vma) || vma_is_shmem(vma); - + if ((vm_flags & VM_UFFD_MINOR) && + (!is_vm_hugetlb_page(vma) && !vma_is_shmem(vma))) + return false; #ifndef CONFIG_PTE_MARKER_UFFD_WP /* * If user requested uffd-wp but not enabled pte markers for diff -Nru linux-6.0.6/include/linux/wireless.h linux-6.0.12/include/linux/wireless.h --- linux-6.0.6/include/linux/wireless.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/linux/wireless.h 2023-01-18 18:27:39.000000000 +0000 @@ -26,7 +26,15 @@ struct __compat_iw_event { __u16 len; /* Real length of this stuff */ __u16 cmd; /* Wireless IOCTL */ - compat_caddr_t pointer; + + union { + compat_caddr_t pointer; + + /* we need ptr_bytes to make memcpy() run-time destination + * buffer bounds checking happy, nothing special + */ + DECLARE_FLEX_ARRAY(__u8, ptr_bytes); + }; }; #define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer) #define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length) diff -Nru linux-6.0.6/include/media/v4l2-common.h linux-6.0.12/include/media/v4l2-common.h --- linux-6.0.6/include/media/v4l2-common.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/media/v4l2-common.h 2023-01-18 18:27:39.000000000 +0000 @@ -175,7 +175,8 @@ * * @sd: pointer to &struct v4l2_subdev * @client: pointer to struct i2c_client - * @devname: the name of the device; if NULL, the I²C device's name will be used + * @devname: the name of the device; if NULL, the I²C device drivers's name + * will be used * @postfix: sub-device specific string to put right after the I²C device name; * may be NULL */ diff -Nru linux-6.0.6/include/media/v4l2-subdev.h linux-6.0.12/include/media/v4l2-subdev.h --- linux-6.0.6/include/media/v4l2-subdev.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/media/v4l2-subdev.h 2023-01-18 18:27:39.000000000 +0000 @@ -1046,6 +1046,8 @@ struct v4l2_subdev_state *state, unsigned int pad) { + if (WARN_ON(!state)) + return NULL; if (WARN_ON(pad >= sd->entity.num_pads)) pad = 0; return &state->pads[pad].try_fmt; @@ -1064,6 +1066,8 @@ struct v4l2_subdev_state *state, unsigned int pad) { + if (WARN_ON(!state)) + return NULL; if (WARN_ON(pad >= sd->entity.num_pads)) pad = 0; return &state->pads[pad].try_crop; @@ -1082,6 +1086,8 @@ struct v4l2_subdev_state *state, unsigned int pad) { + if (WARN_ON(!state)) + return NULL; if (WARN_ON(pad >= sd->entity.num_pads)) pad = 0; return &state->pads[pad].try_compose; diff -Nru linux-6.0.6/include/net/ip.h linux-6.0.12/include/net/ip.h --- linux-6.0.6/include/net/ip.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/net/ip.h 2023-01-18 18:27:39.000000000 +0000 @@ -563,7 +563,7 @@ BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) != offsetof(typeof(flow->addrs), v4addrs.src) + sizeof(flow->addrs.v4addrs.src)); - memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs)); + memcpy(&flow->addrs.v4addrs, &iph->addrs, sizeof(flow->addrs.v4addrs)); flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; } diff -Nru linux-6.0.6/include/net/ipv6.h linux-6.0.12/include/net/ipv6.h --- linux-6.0.6/include/net/ipv6.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/net/ipv6.h 2023-01-18 18:27:39.000000000 +0000 @@ -897,7 +897,7 @@ BUILD_BUG_ON(offsetof(typeof(flow->addrs), v6addrs.dst) != offsetof(typeof(flow->addrs), v6addrs.src) + sizeof(flow->addrs.v6addrs.src)); - memcpy(&flow->addrs.v6addrs, &iph->saddr, sizeof(flow->addrs.v6addrs)); + memcpy(&flow->addrs.v6addrs, &iph->addrs, sizeof(flow->addrs.v6addrs)); flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; } diff -Nru linux-6.0.6/include/net/neighbour.h linux-6.0.12/include/net/neighbour.h --- linux-6.0.6/include/net/neighbour.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/net/neighbour.h 2023-01-18 18:27:39.000000000 +0000 @@ -83,7 +83,7 @@ struct rcu_head rcu_head; int reachable_time; - int qlen; + u32 qlen; int data[NEIGH_VAR_DATA_MAX]; DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX); }; diff -Nru linux-6.0.6/include/net/sctp/stream_sched.h linux-6.0.12/include/net/sctp/stream_sched.h --- linux-6.0.6/include/net/sctp/stream_sched.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/net/sctp/stream_sched.h 2023-01-18 18:27:39.000000000 +0000 @@ -26,6 +26,8 @@ int (*init)(struct sctp_stream *stream); /* Init a stream */ int (*init_sid)(struct sctp_stream *stream, __u16 sid, gfp_t gfp); + /* free a stream */ + void (*free_sid)(struct sctp_stream *stream, __u16 sid); /* Frees the entire thing */ void (*free)(struct sctp_stream *stream); diff -Nru linux-6.0.6/include/net/sock.h linux-6.0.12/include/net/sock.h --- linux-6.0.6/include/net/sock.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/net/sock.h 2023-01-18 18:27:39.000000000 +0000 @@ -1871,6 +1871,13 @@ void sock_kzfree_s(struct sock *sk, void *mem, int size); void sk_send_sigurg(struct sock *sk); +static inline void sock_replace_proto(struct sock *sk, struct proto *proto) +{ + if (sk->sk_socket) + clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags); + WRITE_ONCE(sk->sk_prot, proto); +} + struct sockcm_cookie { u64 transmit_time; u32 mark; @@ -2567,7 +2574,7 @@ static inline gfp_t gfp_memcg_charge(void) { - return in_softirq() ? GFP_NOWAIT : GFP_KERNEL; + return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; } static inline long sock_rcvtimeo(const struct sock *sk, bool noblock) diff -Nru linux-6.0.6/include/soc/at91/sama7-ddr.h linux-6.0.12/include/soc/at91/sama7-ddr.h --- linux-6.0.6/include/soc/at91/sama7-ddr.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/soc/at91/sama7-ddr.h 2023-01-18 18:27:39.000000000 +0000 @@ -26,7 +26,10 @@ #define DDR3PHY_PGSR (0x0C) /* DDR3PHY PHY General Status Register */ #define DDR3PHY_PGSR_IDONE (1 << 0) /* Initialization Done */ -#define DDR3PHY_ACIOCR (0x24) /* DDR3PHY AC I/O Configuration Register */ +#define DDR3PHY_ACDLLCR (0x14) /* DDR3PHY AC DLL Control Register */ +#define DDR3PHY_ACDLLCR_DLLSRST (1 << 30) /* DLL Soft Reset */ + +#define DDR3PHY_ACIOCR (0x24) /* DDR3PHY AC I/O Configuration Register */ #define DDR3PHY_ACIOCR_CSPDD_CS0 (1 << 18) /* CS#[0] Power Down Driver */ #define DDR3PHY_ACIOCR_CKPDD_CK0 (1 << 8) /* CK[0] Power Down Driver */ #define DDR3PHY_ACIORC_ACPDD (1 << 3) /* AC Power Down Driver */ diff -Nru linux-6.0.6/include/sound/control.h linux-6.0.12/include/sound/control.h --- linux-6.0.6/include/sound/control.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/sound/control.h 2023-01-18 18:27:39.000000000 +0000 @@ -138,6 +138,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace); int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id); int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id); +void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name); int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active); struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid); struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id); diff -Nru linux-6.0.6/include/sound/soc-acpi-intel-match.h linux-6.0.12/include/sound/soc-acpi-intel-match.h --- linux-6.0.6/include/sound/soc-acpi-intel-match.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/sound/soc-acpi-intel-match.h 2023-01-18 18:27:39.000000000 +0000 @@ -30,6 +30,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[]; @@ -38,6 +39,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[]; /* diff -Nru linux-6.0.6/include/sound/sof/info.h linux-6.0.12/include/sound/sof/info.h --- linux-6.0.6/include/sound/sof/info.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/sound/sof/info.h 2023-01-18 18:27:39.000000000 +0000 @@ -36,6 +36,10 @@ SOF_IPC_EXT_USER_ABI_INFO = 4, }; +/* Build u32 number in format MMmmmppp */ +#define SOF_FW_VER(MAJOR, MINOR, PATCH) ((uint32_t)( \ + ((MAJOR) << 24) | ((MINOR) << 12) | (PATCH))) + /* FW version - SOF_IPC_GLB_VERSION */ struct sof_ipc_fw_version { struct sof_ipc_hdr hdr; diff -Nru linux-6.0.6/include/uapi/linux/audit.h linux-6.0.12/include/uapi/linux/audit.h --- linux-6.0.6/include/uapi/linux/audit.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/uapi/linux/audit.h 2023-01-18 18:27:39.000000000 +0000 @@ -187,7 +187,7 @@ #define AUDIT_MAX_KEY_LEN 256 #define AUDIT_BITMASK_SIZE 64 #define AUDIT_WORD(nr) ((__u32)((nr)/32)) -#define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32)) +#define AUDIT_BIT(nr) (1U << ((nr) - AUDIT_WORD(nr)*32)) #define AUDIT_SYSCALL_CLASSES 16 #define AUDIT_CLASS_DIR_WRITE 0 diff -Nru linux-6.0.6/include/uapi/linux/capability.h linux-6.0.12/include/uapi/linux/capability.h --- linux-6.0.6/include/uapi/linux/capability.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/uapi/linux/capability.h 2023-01-18 18:27:39.000000000 +0000 @@ -426,7 +426,7 @@ */ #define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */ -#define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */ +#define CAP_TO_MASK(x) (1U << ((x) & 31)) /* mask for indexed __u32 */ #endif /* _UAPI_LINUX_CAPABILITY_H */ diff -Nru linux-6.0.6/include/uapi/linux/idxd.h linux-6.0.12/include/uapi/linux/idxd.h --- linux-6.0.6/include/uapi/linux/idxd.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/uapi/linux/idxd.h 2023-01-18 18:27:39.000000000 +0000 @@ -29,6 +29,7 @@ IDXD_SCMD_WQ_NO_SIZE = 0x800e0000, IDXD_SCMD_WQ_NO_PRIV = 0x800f0000, IDXD_SCMD_WQ_IRQ_ERR = 0x80100000, + IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000, }; #define IDXD_SCMD_SOFTERR_MASK 0x80000000 diff -Nru linux-6.0.6/include/uapi/linux/ip.h linux-6.0.12/include/uapi/linux/ip.h --- linux-6.0.6/include/uapi/linux/ip.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/uapi/linux/ip.h 2023-01-18 18:27:39.000000000 +0000 @@ -100,8 +100,10 @@ __u8 ttl; __u8 protocol; __sum16 check; - __be32 saddr; - __be32 daddr; + __struct_group(/* no tag */, addrs, /* no attrs */, + __be32 saddr; + __be32 daddr; + ); /*The options start here. */ }; diff -Nru linux-6.0.6/include/uapi/linux/ipv6.h linux-6.0.12/include/uapi/linux/ipv6.h --- linux-6.0.6/include/uapi/linux/ipv6.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/uapi/linux/ipv6.h 2023-01-18 18:27:39.000000000 +0000 @@ -130,8 +130,10 @@ __u8 nexthdr; __u8 hop_limit; - struct in6_addr saddr; - struct in6_addr daddr; + __struct_group(/* no tag */, addrs, /* no attrs */, + struct in6_addr saddr; + struct in6_addr daddr; + ); }; diff -Nru linux-6.0.6/include/uapi/linux/videodev2.h linux-6.0.12/include/uapi/linux/videodev2.h --- linux-6.0.6/include/uapi/linux/videodev2.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/include/uapi/linux/videodev2.h 2023-01-18 18:27:39.000000000 +0000 @@ -1602,7 +1602,8 @@ ((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt)) #define V4L2_DV_BT_BLANKING_HEIGHT(bt) \ ((bt)->vfrontporch + (bt)->vsync + (bt)->vbackporch + \ - (bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch) + ((bt)->interlaced ? \ + ((bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch) : 0)) #define V4L2_DV_BT_FRAME_HEIGHT(bt) \ ((bt)->height + V4L2_DV_BT_BLANKING_HEIGHT(bt)) diff -Nru linux-6.0.6/init/Kconfig linux-6.0.12/init/Kconfig --- linux-6.0.6/init/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/init/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -76,7 +76,7 @@ config CC_HAS_ASM_GOTO_TIED_OUTPUT depends on CC_HAS_ASM_GOTO_OUTPUT # Detect buggy gcc and clang, fixed in gcc-11 clang-14. - def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .\n": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null) + def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null) config TOOLS_SUPPORT_RELR def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh) diff -Nru linux-6.0.6/io_uring/filetable.c linux-6.0.12/io_uring/filetable.c --- linux-6.0.6/io_uring/filetable.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/io_uring/filetable.c 2023-01-18 18:27:39.000000000 +0000 @@ -101,8 +101,6 @@ err: if (needs_switch) io_rsrc_node_switch(ctx, ctx->file_data); - if (ret) - fput(file); return ret; } diff -Nru linux-6.0.6/io_uring/io_uring.c linux-6.0.12/io_uring/io_uring.c --- linux-6.0.6/io_uring/io_uring.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/io_uring/io_uring.c 2023-01-18 18:27:39.000000000 +0000 @@ -171,6 +171,11 @@ return ctx->cached_cq_tail - READ_ONCE(ctx->rings->cq.head); } +static inline unsigned int __io_cqring_events_user(struct io_ring_ctx *ctx) +{ + return READ_ONCE(ctx->rings->cq.tail) - READ_ONCE(ctx->rings->cq.head); +} + static bool io_match_linked(struct io_kiocb *head) { struct io_kiocb *req; @@ -1613,7 +1618,7 @@ io_tw_lock(req->ctx, locked); if (unlikely(req->task->flags & PF_EXITING)) return -EFAULT; - return io_issue_sqe(req, IO_URING_F_NONBLOCK); + return io_issue_sqe(req, IO_URING_F_NONBLOCK|IO_URING_F_MULTISHOT); } struct io_wq_work *io_wq_free_work(struct io_wq_work *work) @@ -2163,7 +2168,7 @@ static inline bool io_should_wake(struct io_wait_queue *iowq) { struct io_ring_ctx *ctx = iowq->ctx; - int dist = ctx->cached_cq_tail - (int) iowq->cq_tail; + int dist = READ_ONCE(ctx->rings->cq.tail) - (int) iowq->cq_tail; /* * Wake up if we have enough events, or if a timeout occurred since we @@ -2240,7 +2245,8 @@ do { io_cqring_overflow_flush(ctx); - if (io_cqring_events(ctx) >= min_events) + /* if user messes with these they will just get an early return */ + if (__io_cqring_events_user(ctx) >= min_events) return 0; if (!io_run_task_work()) break; @@ -2653,15 +2659,12 @@ io_poll_remove_all(ctx, NULL, true); mutex_unlock(&ctx->uring_lock); - /* failed during ring init, it couldn't have issued any requests */ - if (ctx->rings) { + /* + * If we failed setting up the ctx, we might not have any rings + * and therefore did not submit any requests + */ + if (ctx->rings) io_kill_timeouts(ctx, NULL, true); - /* if we failed setting up the ctx, we might not have any rings */ - io_iopoll_try_reap_events(ctx); - /* drop cached put refs after potentially doing completions */ - if (current->io_uring) - io_uring_drop_tctx_refs(current); - } INIT_WORK(&ctx->exit_work, io_ring_exit_work); /* diff -Nru linux-6.0.6/io_uring/io_uring.h linux-6.0.12/io_uring/io_uring.h --- linux-6.0.6/io_uring/io_uring.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/io_uring/io_uring.h 2023-01-18 18:27:39.000000000 +0000 @@ -17,8 +17,8 @@ IOU_ISSUE_SKIP_COMPLETE = -EIOCBQUEUED, /* - * Intended only when both REQ_F_POLLED and REQ_F_APOLL_MULTISHOT - * are set to indicate to the poll runner that multishot should be + * Intended only when both IO_URING_F_MULTISHOT is passed + * to indicate to the poll runner that multishot should be * removed and the result is set on req->cqe.res. */ IOU_STOP_MULTISHOT = -ECANCELED, @@ -229,9 +229,14 @@ static inline bool io_run_task_work(void) { + /* + * Always check-and-clear the task_work notification signal. With how + * signaling works for task_work, we can find it set with nothing to + * run. We need to clear it for that case, like get_signal() does. + */ + if (test_thread_flag(TIF_NOTIFY_SIGNAL)) + clear_notify_signal(); if (task_work_pending(current)) { - if (test_thread_flag(TIF_NOTIFY_SIGNAL)) - clear_notify_signal(); __set_current_state(TASK_RUNNING); task_work_run(); return 1; diff -Nru linux-6.0.6/io_uring/kbuf.c linux-6.0.12/io_uring/kbuf.c --- linux-6.0.6/io_uring/kbuf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/io_uring/kbuf.c 2023-01-18 18:27:39.000000000 +0000 @@ -346,6 +346,8 @@ tmp = READ_ONCE(sqe->off); if (tmp > USHRT_MAX) return -E2BIG; + if (tmp + p->nbufs >= USHRT_MAX) + return -EINVAL; p->bid = tmp; return 0; } diff -Nru linux-6.0.6/io_uring/net.c linux-6.0.12/io_uring/net.c --- linux-6.0.6/io_uring/net.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/io_uring/net.c 2023-01-18 18:27:39.000000000 +0000 @@ -66,8 +66,6 @@ struct io_kiocb *notif; }; -#define IO_APOLL_MULTI_POLLED (REQ_F_APOLL_MULTISHOT | REQ_F_POLLED) - int io_shutdown_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_shutdown *shutdown = io_kiocb_to_cmd(req, struct io_shutdown); @@ -558,7 +556,8 @@ * again (for multishot). */ static inline bool io_recv_finish(struct io_kiocb *req, int *ret, - unsigned int cflags, bool mshot_finished) + unsigned int cflags, bool mshot_finished, + unsigned issue_flags) { if (!(req->flags & REQ_F_APOLL_MULTISHOT)) { io_req_set_res(req, *ret, cflags); @@ -581,7 +580,7 @@ io_req_set_res(req, *ret, cflags); - if (req->flags & REQ_F_POLLED) + if (issue_flags & IO_URING_F_MULTISHOT) *ret = IOU_STOP_MULTISHOT; else *ret = IOU_OK; @@ -740,8 +739,7 @@ if (ret < min_ret) { if (ret == -EAGAIN && force_nonblock) { ret = io_setup_async_msg(req, kmsg, issue_flags); - if (ret == -EAGAIN && (req->flags & IO_APOLL_MULTI_POLLED) == - IO_APOLL_MULTI_POLLED) { + if (ret == -EAGAIN && (issue_flags & IO_URING_F_MULTISHOT)) { io_kbuf_recycle(req, issue_flags); return IOU_ISSUE_SKIP_COMPLETE; } @@ -770,7 +768,7 @@ if (kmsg->msg.msg_inq) cflags |= IORING_CQE_F_SOCK_NONEMPTY; - if (!io_recv_finish(req, &ret, cflags, mshot_finished)) + if (!io_recv_finish(req, &ret, cflags, mshot_finished, issue_flags)) goto retry_multishot; if (mshot_finished) { @@ -836,7 +834,7 @@ ret = sock_recvmsg(sock, &msg, flags); if (ret < min_ret) { if (ret == -EAGAIN && force_nonblock) { - if ((req->flags & IO_APOLL_MULTI_POLLED) == IO_APOLL_MULTI_POLLED) { + if (issue_flags & IO_URING_F_MULTISHOT) { io_kbuf_recycle(req, issue_flags); return IOU_ISSUE_SKIP_COMPLETE; } @@ -869,7 +867,7 @@ if (msg.msg_inq) cflags |= IORING_CQE_F_SOCK_NONEMPTY; - if (!io_recv_finish(req, &ret, cflags, ret <= 0)) + if (!io_recv_finish(req, &ret, cflags, ret <= 0, issue_flags)) goto retry_multishot; return ret; @@ -1168,8 +1166,7 @@ * return EAGAIN to arm the poll infra since it * has already been done */ - if ((req->flags & IO_APOLL_MULTI_POLLED) == - IO_APOLL_MULTI_POLLED) + if (issue_flags & IO_URING_F_MULTISHOT) ret = IOU_ISSUE_SKIP_COMPLETE; return ret; } @@ -1194,9 +1191,7 @@ goto retry; io_req_set_res(req, ret, 0); - if (req->flags & REQ_F_POLLED) - return IOU_STOP_MULTISHOT; - return IOU_OK; + return (issue_flags & IO_URING_F_MULTISHOT) ? IOU_STOP_MULTISHOT : IOU_OK; } int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) diff -Nru linux-6.0.6/io_uring/poll.c linux-6.0.12/io_uring/poll.c --- linux-6.0.6/io_uring/poll.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/io_uring/poll.c 2023-01-18 18:27:39.000000000 +0000 @@ -40,7 +40,14 @@ }; #define IO_POLL_CANCEL_FLAG BIT(31) -#define IO_POLL_REF_MASK GENMASK(30, 0) +#define IO_POLL_RETRY_FLAG BIT(30) +#define IO_POLL_REF_MASK GENMASK(29, 0) + +/* + * We usually have 1-2 refs taken, 128 is more than enough and we want to + * maximise the margin between this amount and the moment when it overflows. + */ +#define IO_POLL_REF_BIAS 128 #define IO_WQE_F_DOUBLE 1 @@ -58,6 +65,21 @@ return priv & IO_WQE_F_DOUBLE; } +static bool io_poll_get_ownership_slowpath(struct io_kiocb *req) +{ + int v; + + /* + * poll_refs are already elevated and we don't have much hope for + * grabbing the ownership. Instead of incrementing set a retry flag + * to notify the loop that there might have been some change. + */ + v = atomic_fetch_or(IO_POLL_RETRY_FLAG, &req->poll_refs); + if (v & IO_POLL_REF_MASK) + return false; + return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK); +} + /* * If refs part of ->poll_refs (see IO_POLL_REF_MASK) is 0, it's free. We can * bump it and acquire ownership. It's disallowed to modify requests while not @@ -66,6 +88,8 @@ */ static inline bool io_poll_get_ownership(struct io_kiocb *req) { + if (unlikely(atomic_read(&req->poll_refs) >= IO_POLL_REF_BIAS)) + return io_poll_get_ownership_slowpath(req); return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK); } @@ -116,6 +140,8 @@ struct io_hash_table *table = &req->ctx->cancel_table_locked; u32 index = hash_long(req->cqe.user_data, table->hash_bits); + lockdep_assert_held(&req->ctx->uring_lock); + hlist_add_head(&req->hash_node, &table->hbs[index].list); } @@ -226,6 +252,23 @@ return IOU_POLL_DONE; if (v & IO_POLL_CANCEL_FLAG) return -ECANCELED; + /* + * cqe.res contains only events of the first wake up + * and all others are be lost. Redo vfs_poll() to get + * up to date state. + */ + if ((v & IO_POLL_REF_MASK) != 1) + req->cqe.res = 0; + if (v & IO_POLL_RETRY_FLAG) { + req->cqe.res = 0; + /* + * We won't find new events that came in between + * vfs_poll and the ref put unless we clear the flag + * in advance. + */ + atomic_andnot(IO_POLL_RETRY_FLAG, &req->poll_refs); + v &= ~IO_POLL_RETRY_FLAG; + } /* the mask was stashed in __io_poll_execute */ if (!req->cqe.res) { @@ -237,6 +280,8 @@ continue; if (req->apoll_events & EPOLLONESHOT) return IOU_POLL_DONE; + if (io_is_uring_fops(req->file)) + return IOU_POLL_DONE; /* multishot, just fill a CQE and proceed */ if (!(req->flags & REQ_F_APOLL_MULTISHOT)) { @@ -256,11 +301,15 @@ return ret; } + /* force the next iteration to vfs_poll() */ + req->cqe.res = 0; + /* * Release all references, retry if someone tried to restart * task_work while we were executing it. */ - } while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs)); + } while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs) & + IO_POLL_REF_MASK); return IOU_POLL_NO_ACTION; } @@ -394,7 +443,8 @@ return 1; } -static void io_poll_double_prepare(struct io_kiocb *req) +/* fails only when polling is already completing by the first entry */ +static bool io_poll_double_prepare(struct io_kiocb *req) { struct wait_queue_head *head; struct io_poll *poll = io_poll_get_single(req); @@ -403,20 +453,20 @@ rcu_read_lock(); head = smp_load_acquire(&poll->head); /* - * poll arm may not hold ownership and so race with - * io_poll_wake() by modifying req->flags. There is only one - * poll entry queued, serialise with it by taking its head lock. + * poll arm might not hold ownership and so race for req->flags with + * io_poll_wake(). There is only one poll entry queued, serialise with + * it by taking its head lock. As we're still arming the tw hanlder + * is not going to be run, so there are no races with it. */ - if (head) + if (head) { spin_lock_irq(&head->lock); - - req->flags |= REQ_F_DOUBLE_POLL; - if (req->opcode == IORING_OP_POLL_ADD) - req->flags |= REQ_F_ASYNC_DATA; - - if (head) + req->flags |= REQ_F_DOUBLE_POLL; + if (req->opcode == IORING_OP_POLL_ADD) + req->flags |= REQ_F_ASYNC_DATA; spin_unlock_irq(&head->lock); + } rcu_read_unlock(); + return !!head; } static void __io_queue_proc(struct io_poll *poll, struct io_poll_table *pt, @@ -454,7 +504,11 @@ /* mark as double wq entry */ wqe_private |= IO_WQE_F_DOUBLE; io_init_poll_iocb(poll, first->events, first->wait.func); - io_poll_double_prepare(req); + if (!io_poll_double_prepare(req)) { + /* the request is completing, just back off */ + kfree(poll); + return; + } *poll_ptr = poll; } else { /* fine to modify, there is no poll queued to race with us */ @@ -499,7 +553,6 @@ unsigned issue_flags) { struct io_ring_ctx *ctx = req->ctx; - int v; INIT_HLIST_NODE(&req->hash_node); req->work.cancel_seq = atomic_read(&ctx->cancel_seq); @@ -567,11 +620,10 @@ if (ipt->owning) { /* - * Release ownership. If someone tried to queue a tw while it was - * locked, kick it off for them. + * Try to release ownership. If we see a change of state, e.g. + * poll was waken up, queue up a tw, it'll deal with it. */ - v = atomic_dec_return(&req->poll_refs); - if (unlikely(v & IO_POLL_REF_MASK)) + if (atomic_cmpxchg(&req->poll_refs, 1, 0) != 1) __io_poll_execute(req, 0); } return 0; diff -Nru linux-6.0.6/ipc/sem.c linux-6.0.12/ipc/sem.c --- linux-6.0.6/ipc/sem.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/ipc/sem.c 2023-01-18 18:27:39.000000000 +0000 @@ -2179,14 +2179,15 @@ * scenarios where we were awakened externally, during the * window between wake_q_add() and wake_up_q(). */ + rcu_read_lock(); error = READ_ONCE(queue.status); if (error != -EINTR) { /* see SEM_BARRIER_2 for purpose/pairing */ smp_acquire__after_ctrl_dep(); + rcu_read_unlock(); goto out; } - rcu_read_lock(); locknum = sem_lock(sma, sops, nsops); if (!ipc_valid_object(&sma->sem_perm)) diff -Nru linux-6.0.6/kernel/bpf/bpf_local_storage.c linux-6.0.12/kernel/bpf/bpf_local_storage.c --- linux-6.0.6/kernel/bpf/bpf_local_storage.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/bpf/bpf_local_storage.c 2023-01-18 18:27:39.000000000 +0000 @@ -74,7 +74,7 @@ gfp_flags | __GFP_NOWARN); if (selem) { if (value) - memcpy(SDATA(selem)->data, value, smap->map.value_size); + copy_map_value(&smap->map, SDATA(selem)->data, value); return selem; } diff -Nru linux-6.0.6/kernel/bpf/btf.c linux-6.0.12/kernel/bpf/btf.c --- linux-6.0.6/kernel/bpf/btf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/bpf/btf.c 2023-01-18 18:27:39.000000000 +0000 @@ -4436,6 +4436,11 @@ return -EINVAL; } + if (btf_type_is_resolve_source_only(ret_type)) { + btf_verifier_log_type(env, t, "Invalid return type"); + return -EINVAL; + } + if (btf_type_needs_resolve(ret_type) && !env_type_is_resolved(env, ret_type_id)) { err = btf_resolve(env, ret_type, ret_type_id); diff -Nru linux-6.0.6/kernel/bpf/dispatcher.c linux-6.0.12/kernel/bpf/dispatcher.c --- linux-6.0.6/kernel/bpf/dispatcher.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/bpf/dispatcher.c 2023-01-18 18:27:39.000000000 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include /* The BPF dispatcher is a multiway branch code generator. The * dispatcher is a mechanism to avoid the performance penalty of an @@ -104,17 +105,11 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs) { - void *old, *new, *tmp; - u32 noff; - int err; - - if (!prev_num_progs) { - old = NULL; - noff = 0; - } else { - old = d->image + d->image_off; + void *new, *tmp; + u32 noff = 0; + + if (prev_num_progs) noff = d->image_off ^ (PAGE_SIZE / 2); - } new = d->num_progs ? d->image + noff : NULL; tmp = d->num_progs ? d->rw_image + noff : NULL; @@ -128,11 +123,10 @@ return; } - err = bpf_arch_text_poke(d->func, BPF_MOD_JUMP, old, new); - if (err || !new) - return; + __BPF_DISPATCHER_UPDATE(d, new ?: (void *)&bpf_dispatcher_nop_func); - d->image_off = noff; + if (new) + d->image_off = noff; } void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from, diff -Nru linux-6.0.6/kernel/bpf/percpu_freelist.c linux-6.0.12/kernel/bpf/percpu_freelist.c --- linux-6.0.6/kernel/bpf/percpu_freelist.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/bpf/percpu_freelist.c 2023-01-18 18:27:39.000000000 +0000 @@ -102,22 +102,21 @@ u32 nr_elems) { struct pcpu_freelist_head *head; - int i, cpu, pcpu_entries; + unsigned int cpu, cpu_idx, i, j, n, m; - pcpu_entries = nr_elems / num_possible_cpus() + 1; - i = 0; + n = nr_elems / num_possible_cpus(); + m = nr_elems % num_possible_cpus(); + cpu_idx = 0; for_each_possible_cpu(cpu) { -again: head = per_cpu_ptr(s->freelist, cpu); - /* No locking required as this is not visible yet. */ - pcpu_freelist_push_node(head, buf); - i++; - buf += elem_size; - if (i == nr_elems) - break; - if (i % pcpu_entries) - goto again; + j = n + (cpu_idx < m ? 1 : 0); + for (i = 0; i < j; i++) { + /* No locking required as this is not visible yet. */ + pcpu_freelist_push_node(head, buf); + buf += elem_size; + } + cpu_idx++; } } diff -Nru linux-6.0.6/kernel/bpf/syscall.c linux-6.0.12/kernel/bpf/syscall.c --- linux-6.0.6/kernel/bpf/syscall.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/bpf/syscall.c 2023-01-18 18:27:39.000000000 +0000 @@ -2094,6 +2094,17 @@ u64 misses; }; +void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog) +{ + struct bpf_prog_stats *stats; + unsigned int flags; + + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->misses); + u64_stats_update_end_irqrestore(&stats->syncp, flags); +} + static void bpf_prog_get_stats(const struct bpf_prog *prog, struct bpf_prog_kstats *stats) { diff -Nru linux-6.0.6/kernel/bpf/trampoline.c linux-6.0.12/kernel/bpf/trampoline.c --- linux-6.0.6/kernel/bpf/trampoline.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/bpf/trampoline.c 2023-01-18 18:27:39.000000000 +0000 @@ -863,17 +863,6 @@ return start; } -static void notrace inc_misses_counter(struct bpf_prog *prog) -{ - struct bpf_prog_stats *stats; - unsigned int flags; - - stats = this_cpu_ptr(prog->stats); - flags = u64_stats_update_begin_irqsave(&stats->syncp); - u64_stats_inc(&stats->misses); - u64_stats_update_end_irqrestore(&stats->syncp, flags); -} - /* The logic is similar to bpf_prog_run(), but with an explicit * rcu_read_lock() and migrate_disable() which are required * for the trampoline. The macro is split into @@ -896,7 +885,7 @@ run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx); if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) { - inc_misses_counter(prog); + bpf_prog_inc_misses_counter(prog); return 0; } return bpf_prog_start_time(); @@ -967,7 +956,7 @@ might_fault(); if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) { - inc_misses_counter(prog); + bpf_prog_inc_misses_counter(prog); return 0; } diff -Nru linux-6.0.6/kernel/bpf/verifier.c linux-6.0.12/kernel/bpf/verifier.c --- linux-6.0.6/kernel/bpf/verifier.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/bpf/verifier.c 2023-01-18 18:27:39.000000000 +0000 @@ -1011,12 +1011,17 @@ */ static void *realloc_array(void *arr, size_t old_n, size_t new_n, size_t size) { + void *new_arr; + if (!new_n || old_n == new_n) goto out; - arr = krealloc_array(arr, new_n, size, GFP_KERNEL); - if (!arr) + new_arr = krealloc_array(arr, new_n, size, GFP_KERNEL); + if (!new_arr) { + kfree(arr); return NULL; + } + arr = new_arr; if (new_n > old_n) memset(arr + old_n * size, 0, (new_n - old_n) * size); @@ -6495,31 +6500,15 @@ /* Packet data might have moved, any old PTR_TO_PACKET[_META,_END] * are now invalid, so turn them into unknown SCALAR_VALUE. */ -static void __clear_all_pkt_pointers(struct bpf_verifier_env *env, - struct bpf_func_state *state) +static void clear_all_pkt_pointers(struct bpf_verifier_env *env) { - struct bpf_reg_state *regs = state->regs, *reg; - int i; - - for (i = 0; i < MAX_BPF_REG; i++) - if (reg_is_pkt_pointer_any(®s[i])) - mark_reg_unknown(env, regs, i); + struct bpf_func_state *state; + struct bpf_reg_state *reg; - bpf_for_each_spilled_reg(i, state, reg) { - if (!reg) - continue; + bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({ if (reg_is_pkt_pointer_any(reg)) __mark_reg_unknown(env, reg); - } -} - -static void clear_all_pkt_pointers(struct bpf_verifier_env *env) -{ - struct bpf_verifier_state *vstate = env->cur_state; - int i; - - for (i = 0; i <= vstate->curframe; i++) - __clear_all_pkt_pointers(env, vstate->frame[i]); + })); } enum { @@ -6548,41 +6537,28 @@ reg->range = AT_PKT_END; } -static void release_reg_references(struct bpf_verifier_env *env, - struct bpf_func_state *state, - int ref_obj_id) -{ - struct bpf_reg_state *regs = state->regs, *reg; - int i; - - for (i = 0; i < MAX_BPF_REG; i++) - if (regs[i].ref_obj_id == ref_obj_id) - mark_reg_unknown(env, regs, i); - - bpf_for_each_spilled_reg(i, state, reg) { - if (!reg) - continue; - if (reg->ref_obj_id == ref_obj_id) - __mark_reg_unknown(env, reg); - } -} - /* The pointer with the specified id has released its reference to kernel * resources. Identify all copies of the same pointer and clear the reference. */ static int release_reference(struct bpf_verifier_env *env, int ref_obj_id) { - struct bpf_verifier_state *vstate = env->cur_state; + struct bpf_func_state *state; + struct bpf_reg_state *reg; int err; - int i; err = release_reference_state(cur_func(env), ref_obj_id); if (err) return err; - for (i = 0; i <= vstate->curframe; i++) - release_reg_references(env, vstate->frame[i], ref_obj_id); + bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({ + if (reg->ref_obj_id == ref_obj_id) { + if (!env->allow_ptr_leaks) + __mark_reg_not_init(env, reg); + else + __mark_reg_unknown(env, reg); + } + })); return 0; } @@ -6698,11 +6674,11 @@ /* Transfer references to the callee */ err = copy_reference_state(callee, caller); if (err) - return err; + goto err_out; err = set_callee_state_cb(env, caller, callee, *insn_idx); if (err) - return err; + goto err_out; clear_caller_saved_regs(env, caller->regs); @@ -6719,6 +6695,11 @@ print_verifier_state(env, callee, true); } return 0; + +err_out: + free_func_state(callee); + state->frame[state->curframe + 1] = NULL; + return err; } int map_set_for_each_callback_args(struct bpf_verifier_env *env, @@ -6904,8 +6885,7 @@ return -EINVAL; } - state->curframe--; - caller = state->frame[state->curframe]; + caller = state->frame[state->curframe - 1]; if (callee->in_callback_fn) { /* enforce R0 return value range [0, 1]. */ struct tnum range = tnum_range(0, 1); @@ -6944,7 +6924,7 @@ } /* clear everything in the callee */ free_func_state(callee); - state->frame[state->curframe + 1] = NULL; + state->frame[state->curframe--] = NULL; return 0; } @@ -9278,34 +9258,14 @@ return 0; } -static void __find_good_pkt_pointers(struct bpf_func_state *state, - struct bpf_reg_state *dst_reg, - enum bpf_reg_type type, int new_range) -{ - struct bpf_reg_state *reg; - int i; - - for (i = 0; i < MAX_BPF_REG; i++) { - reg = &state->regs[i]; - if (reg->type == type && reg->id == dst_reg->id) - /* keep the maximum range already checked */ - reg->range = max(reg->range, new_range); - } - - bpf_for_each_spilled_reg(i, state, reg) { - if (!reg) - continue; - if (reg->type == type && reg->id == dst_reg->id) - reg->range = max(reg->range, new_range); - } -} - static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, struct bpf_reg_state *dst_reg, enum bpf_reg_type type, bool range_right_open) { - int new_range, i; + struct bpf_func_state *state; + struct bpf_reg_state *reg; + int new_range; if (dst_reg->off < 0 || (dst_reg->off == 0 && range_right_open)) @@ -9370,9 +9330,11 @@ * the range won't allow anything. * dst_reg->off is known < MAX_PACKET_OFF, therefore it fits in a u16. */ - for (i = 0; i <= vstate->curframe; i++) - __find_good_pkt_pointers(vstate->frame[i], dst_reg, type, - new_range); + bpf_for_each_reg_in_vstate(vstate, state, reg, ({ + if (reg->type == type && reg->id == dst_reg->id) + /* keep the maximum range already checked */ + reg->range = max(reg->range, new_range); + })); } static int is_branch32_taken(struct bpf_reg_state *reg, u32 val, u8 opcode) @@ -9861,7 +9823,7 @@ if (!reg_may_point_to_spin_lock(reg)) { /* For not-NULL ptr, reg->ref_obj_id will be reset - * in release_reg_references(). + * in release_reference(). * * reg->id is still used by spin_lock ptr. Other * than spin_lock ptr type, reg->id can be reset. @@ -9871,22 +9833,6 @@ } } -static void __mark_ptr_or_null_regs(struct bpf_func_state *state, u32 id, - bool is_null) -{ - struct bpf_reg_state *reg; - int i; - - for (i = 0; i < MAX_BPF_REG; i++) - mark_ptr_or_null_reg(state, &state->regs[i], id, is_null); - - bpf_for_each_spilled_reg(i, state, reg) { - if (!reg) - continue; - mark_ptr_or_null_reg(state, reg, id, is_null); - } -} - /* The logic is similar to find_good_pkt_pointers(), both could eventually * be folded together at some point. */ @@ -9894,10 +9840,9 @@ bool is_null) { struct bpf_func_state *state = vstate->frame[vstate->curframe]; - struct bpf_reg_state *regs = state->regs; + struct bpf_reg_state *regs = state->regs, *reg; u32 ref_obj_id = regs[regno].ref_obj_id; u32 id = regs[regno].id; - int i; if (ref_obj_id && ref_obj_id == id && is_null) /* regs[regno] is in the " == NULL" branch. @@ -9906,8 +9851,9 @@ */ WARN_ON_ONCE(release_reference_state(state, id)); - for (i = 0; i <= vstate->curframe; i++) - __mark_ptr_or_null_regs(vstate->frame[i], id, is_null); + bpf_for_each_reg_in_vstate(vstate, state, reg, ({ + mark_ptr_or_null_reg(state, reg, id, is_null); + })); } static bool try_match_pkt_pointers(const struct bpf_insn *insn, @@ -10020,23 +9966,11 @@ { struct bpf_func_state *state; struct bpf_reg_state *reg; - int i, j; - for (i = 0; i <= vstate->curframe; i++) { - state = vstate->frame[i]; - for (j = 0; j < MAX_BPF_REG; j++) { - reg = &state->regs[j]; - if (reg->type == SCALAR_VALUE && reg->id == known_reg->id) - *reg = *known_reg; - } - - bpf_for_each_spilled_reg(j, state, reg) { - if (!reg) - continue; - if (reg->type == SCALAR_VALUE && reg->id == known_reg->id) - *reg = *known_reg; - } - } + bpf_for_each_reg_in_vstate(vstate, state, reg, ({ + if (reg->type == SCALAR_VALUE && reg->id == known_reg->id) + *reg = *known_reg; + })); } static int check_cond_jmp_op(struct bpf_verifier_env *env, diff -Nru linux-6.0.6/kernel/events/core.c linux-6.0.12/kernel/events/core.c --- linux-6.0.6/kernel/events/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/events/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -54,6 +54,7 @@ #include #include #include +#include #include "internal.h" @@ -2268,11 +2269,26 @@ event->pmu->del(event, 0); event->oncpu = -1; - if (READ_ONCE(event->pending_disable) >= 0) { - WRITE_ONCE(event->pending_disable, -1); + if (event->pending_disable) { + event->pending_disable = 0; perf_cgroup_event_disable(event, ctx); state = PERF_EVENT_STATE_OFF; } + + if (event->pending_sigtrap) { + bool dec = true; + + event->pending_sigtrap = 0; + if (state != PERF_EVENT_STATE_OFF && + !event->pending_work) { + event->pending_work = 1; + dec = false; + task_work_add(current, &event->pending_task, TWA_RESUME); + } + if (dec) + local_dec(&event->ctx->nr_pending); + } + perf_event_set_state(event, state); if (!is_software_event(event)) @@ -2424,7 +2440,7 @@ * hold the top-level event's child_mutex, so any descendant that * goes to exit will block in perf_event_exit_event(). * - * When called from perf_pending_event it's OK because event->ctx + * When called from perf_pending_irq it's OK because event->ctx * is the current context on this CPU and preemption is disabled, * hence we can't get into perf_event_task_sched_out for this context. */ @@ -2463,9 +2479,8 @@ void perf_event_disable_inatomic(struct perf_event *event) { - WRITE_ONCE(event->pending_disable, smp_processor_id()); - /* can fail, see perf_pending_event_disable() */ - irq_work_queue(&event->pending); + event->pending_disable = 1; + irq_work_queue(&event->pending_irq); } #define MAX_INTERRUPTS (~0ULL) @@ -3420,11 +3435,23 @@ raw_spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING); if (context_equiv(ctx, next_ctx)) { + perf_pmu_disable(pmu); + + /* PMIs are disabled; ctx->nr_pending is stable. */ + if (local_read(&ctx->nr_pending) || + local_read(&next_ctx->nr_pending)) { + /* + * Must not swap out ctx when there's pending + * events that rely on the ctx->task relation. + */ + raw_spin_unlock(&next_ctx->lock); + rcu_read_unlock(); + goto inside_switch; + } + WRITE_ONCE(ctx->task, next); WRITE_ONCE(next_ctx->task, task); - perf_pmu_disable(pmu); - if (cpuctx->sched_cb_usage && pmu->sched_task) pmu->sched_task(ctx, false); @@ -3465,6 +3492,7 @@ raw_spin_lock(&ctx->lock); perf_pmu_disable(pmu); +inside_switch: if (cpuctx->sched_cb_usage && pmu->sched_task) pmu->sched_task(ctx, false); task_ctx_sched_out(cpuctx, ctx, EVENT_ALL); @@ -4931,7 +4959,7 @@ static void _free_event(struct perf_event *event) { - irq_work_sync(&event->pending); + irq_work_sync(&event->pending_irq); unaccount_event(event); @@ -6431,7 +6459,8 @@ return; /* - * perf_pending_event() can race with the task exiting. + * Both perf_pending_task() and perf_pending_irq() can race with the + * task exiting. */ if (current->flags & PF_EXITING) return; @@ -6440,23 +6469,33 @@ event->attr.type, event->attr.sig_data); } -static void perf_pending_event_disable(struct perf_event *event) +/* + * Deliver the pending work in-event-context or follow the context. + */ +static void __perf_pending_irq(struct perf_event *event) { - int cpu = READ_ONCE(event->pending_disable); + int cpu = READ_ONCE(event->oncpu); + /* + * If the event isn't running; we done. event_sched_out() will have + * taken care of things. + */ if (cpu < 0) return; + /* + * Yay, we hit home and are in the context of the event. + */ if (cpu == smp_processor_id()) { - WRITE_ONCE(event->pending_disable, -1); - - if (event->attr.sigtrap) { + if (event->pending_sigtrap) { + event->pending_sigtrap = 0; perf_sigtrap(event); - atomic_set_release(&event->event_limit, 1); /* rearm event */ - return; + local_dec(&event->ctx->nr_pending); + } + if (event->pending_disable) { + event->pending_disable = 0; + perf_event_disable_local(event); } - - perf_event_disable_local(event); return; } @@ -6476,33 +6515,60 @@ * irq_work_queue(); // FAILS * * irq_work_run() - * perf_pending_event() + * perf_pending_irq() * * But the event runs on CPU-B and wants disabling there. */ - irq_work_queue_on(&event->pending, cpu); + irq_work_queue_on(&event->pending_irq, cpu); } -static void perf_pending_event(struct irq_work *entry) +static void perf_pending_irq(struct irq_work *entry) { - struct perf_event *event = container_of(entry, struct perf_event, pending); + struct perf_event *event = container_of(entry, struct perf_event, pending_irq); int rctx; - rctx = perf_swevent_get_recursion_context(); /* * If we 'fail' here, that's OK, it means recursion is already disabled * and we won't recurse 'further'. */ + rctx = perf_swevent_get_recursion_context(); - perf_pending_event_disable(event); - + /* + * The wakeup isn't bound to the context of the event -- it can happen + * irrespective of where the event is. + */ if (event->pending_wakeup) { event->pending_wakeup = 0; perf_event_wakeup(event); } + __perf_pending_irq(event); + + if (rctx >= 0) + perf_swevent_put_recursion_context(rctx); +} + +static void perf_pending_task(struct callback_head *head) +{ + struct perf_event *event = container_of(head, struct perf_event, pending_task); + int rctx; + + /* + * If we 'fail' here, that's OK, it means recursion is already disabled + * and we won't recurse 'further'. + */ + preempt_disable_notrace(); + rctx = perf_swevent_get_recursion_context(); + + if (event->pending_work) { + event->pending_work = 0; + perf_sigtrap(event); + local_dec(&event->ctx->nr_pending); + } + if (rctx >= 0) perf_swevent_put_recursion_context(rctx); + preempt_enable_notrace(); } #ifdef CONFIG_GUEST_PERF_EVENTS @@ -8940,7 +9006,7 @@ PERF_RECORD_KSYMBOL_TYPE_BPF, (u64)(unsigned long)subprog->bpf_func, subprog->jited_len, unregister, - prog->aux->ksym.name); + subprog->aux->ksym.name); } } } @@ -9188,8 +9254,8 @@ */ static int __perf_event_overflow(struct perf_event *event, - int throttle, struct perf_sample_data *data, - struct pt_regs *regs) + int throttle, struct perf_sample_data *data, + struct pt_regs *regs) { int events = atomic_read(&event->event_limit); int ret = 0; @@ -9212,24 +9278,49 @@ if (events && atomic_dec_and_test(&event->event_limit)) { ret = 1; event->pending_kill = POLL_HUP; - event->pending_addr = data->addr; - perf_event_disable_inatomic(event); } + if (event->attr.sigtrap) { + unsigned int pending_id = 1; + + if (regs) + pending_id = hash32_ptr((void *)instruction_pointer(regs)) ?: 1; + if (!event->pending_sigtrap) { + event->pending_sigtrap = pending_id; + local_inc(&event->ctx->nr_pending); + } else if (event->attr.exclude_kernel) { + /* + * Should not be able to return to user space without + * consuming pending_sigtrap; with exceptions: + * + * 1. Where !exclude_kernel, events can overflow again + * in the kernel without returning to user space. + * + * 2. Events that can overflow again before the IRQ- + * work without user space progress (e.g. hrtimer). + * To approximate progress (with false negatives), + * check 32-bit hash of the current IP. + */ + WARN_ON_ONCE(event->pending_sigtrap != pending_id); + } + event->pending_addr = data->addr; + irq_work_queue(&event->pending_irq); + } + READ_ONCE(event->overflow_handler)(event, data, regs); if (*perf_event_fasync(event) && event->pending_kill) { event->pending_wakeup = 1; - irq_work_queue(&event->pending); + irq_work_queue(&event->pending_irq); } return ret; } int perf_event_overflow(struct perf_event *event, - struct perf_sample_data *data, - struct pt_regs *regs) + struct perf_sample_data *data, + struct pt_regs *regs) { return __perf_event_overflow(event, 1, data, regs); } @@ -11537,8 +11628,8 @@ init_waitqueue_head(&event->waitq); - event->pending_disable = -1; - init_irq_work(&event->pending, perf_pending_event); + init_irq_work(&event->pending_irq, perf_pending_irq); + init_task_work(&event->pending_task, perf_pending_task); mutex_init(&event->mmap_mutex); raw_spin_lock_init(&event->addr_filters.lock); @@ -11560,9 +11651,6 @@ if (parent_event) event->event_caps = parent_event->event_caps; - if (event->attr.sigtrap) - atomic_set(&event->event_limit, 1); - if (task) { event->attach_state = PERF_ATTACH_TASK; /* diff -Nru linux-6.0.6/kernel/events/ring_buffer.c linux-6.0.12/kernel/events/ring_buffer.c --- linux-6.0.6/kernel/events/ring_buffer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/events/ring_buffer.c 2023-01-18 18:27:39.000000000 +0000 @@ -22,7 +22,7 @@ atomic_set(&handle->rb->poll, EPOLLIN); handle->event->pending_wakeup = 1; - irq_work_queue(&handle->event->pending); + irq_work_queue(&handle->event->pending_irq); } /* diff -Nru linux-6.0.6/kernel/gcov/clang.c linux-6.0.12/kernel/gcov/clang.c --- linux-6.0.6/kernel/gcov/clang.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/gcov/clang.c 2023-01-18 18:27:39.000000000 +0000 @@ -280,6 +280,8 @@ for (i = 0; i < sfn_ptr->num_counters; i++) dfn_ptr->counters[i] += sfn_ptr->counters[i]; + + sfn_ptr = list_next_entry(sfn_ptr, head); } } diff -Nru linux-6.0.6/kernel/kprobes.c linux-6.0.12/kernel/kprobes.c --- linux-6.0.6/kernel/kprobes.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/kprobes.c 2023-01-18 18:27:39.000000000 +0000 @@ -1762,7 +1762,13 @@ if ((list_p != p) && (list_p->post_handler)) goto noclean; } - ap->post_handler = NULL; + /* + * For the kprobe-on-ftrace case, we keep the + * post_handler setting to identify this aggrprobe + * armed with kprobe_ipmodify_ops. + */ + if (!kprobe_ftrace(ap)) + ap->post_handler = NULL; } noclean: /* @@ -2425,8 +2431,11 @@ if (!kprobes_all_disarmed && kprobe_disabled(p)) { p->flags &= ~KPROBE_FLAG_DISABLED; ret = arm_kprobe(p); - if (ret) + if (ret) { p->flags |= KPROBE_FLAG_DISABLED; + if (p != kp) + kp->flags |= KPROBE_FLAG_DISABLED; + } } out: mutex_unlock(&kprobe_mutex); diff -Nru linux-6.0.6/kernel/power/hibernate.c linux-6.0.12/kernel/power/hibernate.c --- linux-6.0.6/kernel/power/hibernate.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/power/hibernate.c 2023-01-18 18:27:39.000000000 +0000 @@ -641,7 +641,7 @@ int error; if (hibernation_mode == HIBERNATION_SUSPEND) { - error = suspend_devices_and_enter(PM_SUSPEND_MEM); + error = suspend_devices_and_enter(mem_sleep_current); if (error) { hibernation_mode = hibernation_ops ? HIBERNATION_PLATFORM : diff -Nru linux-6.0.6/kernel/rcu/tree.c linux-6.0.12/kernel/rcu/tree.c --- linux-6.0.6/kernel/rcu/tree.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/rcu/tree.c 2023-01-18 18:27:39.000000000 +0000 @@ -1402,30 +1402,32 @@ // where caller does not hold the root rcu_node structure's lock. static void rcu_poll_gp_seq_start_unlocked(unsigned long *snap) { + unsigned long flags; struct rcu_node *rnp = rcu_get_root(); if (rcu_init_invoked()) { lockdep_assert_irqs_enabled(); - raw_spin_lock_irq_rcu_node(rnp); + raw_spin_lock_irqsave_rcu_node(rnp, flags); } rcu_poll_gp_seq_start(snap); if (rcu_init_invoked()) - raw_spin_unlock_irq_rcu_node(rnp); + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); } // Make the polled API aware of the end of a grace period, but where // caller does not hold the root rcu_node structure's lock. static void rcu_poll_gp_seq_end_unlocked(unsigned long *snap) { + unsigned long flags; struct rcu_node *rnp = rcu_get_root(); if (rcu_init_invoked()) { lockdep_assert_irqs_enabled(); - raw_spin_lock_irq_rcu_node(rnp); + raw_spin_lock_irqsave_rcu_node(rnp, flags); } rcu_poll_gp_seq_end(snap); if (rcu_init_invoked()) - raw_spin_unlock_irq_rcu_node(rnp); + raw_spin_unlock_irqrestore_rcu_node(rnp, flags); } /* diff -Nru linux-6.0.6/kernel/rseq.c linux-6.0.12/kernel/rseq.c --- linux-6.0.6/kernel/rseq.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/rseq.c 2023-01-18 18:27:39.000000000 +0000 @@ -171,12 +171,27 @@ return 0; } +static bool rseq_warn_flags(const char *str, u32 flags) +{ + u32 test_flags; + + if (!flags) + return false; + test_flags = flags & RSEQ_CS_NO_RESTART_FLAGS; + if (test_flags) + pr_warn_once("Deprecated flags (%u) in %s ABI structure", test_flags, str); + test_flags = flags & ~RSEQ_CS_NO_RESTART_FLAGS; + if (test_flags) + pr_warn_once("Unknown flags (%u) in %s ABI structure", test_flags, str); + return true; +} + static int rseq_need_restart(struct task_struct *t, u32 cs_flags) { u32 flags, event_mask; int ret; - if (WARN_ON_ONCE(cs_flags & RSEQ_CS_NO_RESTART_FLAGS) || cs_flags) + if (rseq_warn_flags("rseq_cs", cs_flags)) return -EINVAL; /* Get thread flags. */ @@ -184,7 +199,7 @@ if (ret) return ret; - if (WARN_ON_ONCE(flags & RSEQ_CS_NO_RESTART_FLAGS) || flags) + if (rseq_warn_flags("rseq", flags)) return -EINVAL; /* diff -Nru linux-6.0.6/kernel/sched/sched.h linux-6.0.12/kernel/sched/sched.h --- linux-6.0.6/kernel/sched/sched.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/sched/sched.h 2023-01-18 18:27:39.000000000 +0000 @@ -1197,6 +1197,14 @@ #endif } +DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); + +#define cpu_rq(cpu) (&per_cpu(runqueues, (cpu))) +#define this_rq() this_cpu_ptr(&runqueues) +#define task_rq(p) cpu_rq(task_cpu(p)) +#define cpu_curr(cpu) (cpu_rq(cpu)->curr) +#define raw_rq() raw_cpu_ptr(&runqueues) + struct sched_group; #ifdef CONFIG_SCHED_CORE static inline struct cpumask *sched_group_span(struct sched_group *sg); @@ -1284,7 +1292,7 @@ return true; for_each_cpu_and(cpu, sched_group_span(group), p->cpus_ptr) { - if (sched_core_cookie_match(rq, p)) + if (sched_core_cookie_match(cpu_rq(cpu), p)) return true; } return false; @@ -1399,14 +1407,6 @@ static inline void update_idle_core(struct rq *rq) { } #endif -DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); - -#define cpu_rq(cpu) (&per_cpu(runqueues, (cpu))) -#define this_rq() this_cpu_ptr(&runqueues) -#define task_rq(p) cpu_rq(task_cpu(p)) -#define cpu_curr(cpu) (cpu_rq(cpu)->curr) -#define raw_rq() raw_cpu_ptr(&runqueues) - #ifdef CONFIG_FAIR_GROUP_SCHED static inline struct task_struct *task_of(struct sched_entity *se) { diff -Nru linux-6.0.6/kernel/sysctl.c linux-6.0.12/kernel/sysctl.c --- linux-6.0.6/kernel/sysctl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/sysctl.c 2023-01-18 18:27:39.000000000 +0000 @@ -265,13 +265,14 @@ ppos); } -static size_t proc_skip_spaces(char **buf) +static void proc_skip_spaces(char **buf, size_t *size) { - size_t ret; - char *tmp = skip_spaces(*buf); - ret = tmp - *buf; - *buf = tmp; - return ret; + while (*size) { + if (!isspace(**buf)) + break; + (*size)--; + (*buf)++; + } } static void proc_skip_char(char **buf, size_t *size, const char v) @@ -340,13 +341,12 @@ unsigned long *val, bool *neg, const char *perm_tr, unsigned perm_tr_len, char *tr) { - int len; char *p, tmp[TMPBUFLEN]; + ssize_t len = *size; - if (!*size) + if (len <= 0) return -EINVAL; - len = *size; if (len > TMPBUFLEN - 1) len = TMPBUFLEN - 1; @@ -519,7 +519,7 @@ bool neg; if (write) { - left -= proc_skip_spaces(&p); + proc_skip_spaces(&p, &left); if (!left) break; @@ -546,7 +546,7 @@ if (!write && !first && left && !err) proc_put_char(&buffer, &left, '\n'); if (write && !err && left) - left -= proc_skip_spaces(&p); + proc_skip_spaces(&p, &left); if (write && first) return err ? : -EINVAL; *lenp -= left; @@ -588,7 +588,7 @@ if (left > PAGE_SIZE - 1) left = PAGE_SIZE - 1; - left -= proc_skip_spaces(&p); + proc_skip_spaces(&p, &left); if (!left) { err = -EINVAL; goto out_free; @@ -608,7 +608,7 @@ } if (!err && left) - left -= proc_skip_spaces(&p); + proc_skip_spaces(&p, &left); out_free: if (err) @@ -1073,7 +1073,7 @@ if (write) { bool neg; - left -= proc_skip_spaces(&p); + proc_skip_spaces(&p, &left); if (!left) break; @@ -1102,7 +1102,7 @@ if (!write && !first && left && !err) proc_put_char(&buffer, &left, '\n'); if (write && !err) - left -= proc_skip_spaces(&p); + proc_skip_spaces(&p, &left); if (write && first) return err ? : -EINVAL; *lenp -= left; diff -Nru linux-6.0.6/kernel/trace/bpf_trace.c linux-6.0.12/kernel/trace/bpf_trace.c --- linux-6.0.6/kernel/trace/bpf_trace.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/bpf_trace.c 2023-01-18 18:27:39.000000000 +0000 @@ -2058,9 +2058,15 @@ void __bpf_trace_run(struct bpf_prog *prog, u64 *args) { cant_sleep(); + if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) { + bpf_prog_inc_misses_counter(prog); + goto out; + } rcu_read_lock(); (void) bpf_prog_run(prog, args); rcu_read_unlock(); +out: + this_cpu_dec(*(prog->active)); } #define UNPACK(...) __VA_ARGS__ diff -Nru linux-6.0.6/kernel/trace/fprobe.c linux-6.0.12/kernel/trace/fprobe.c --- linux-6.0.6/kernel/trace/fprobe.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/fprobe.c 2023-01-18 18:27:39.000000000 +0000 @@ -141,6 +141,8 @@ return -E2BIG; fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler); + if (!fp->rethook) + return -ENOMEM; for (i = 0; i < size; i++) { struct fprobe_rethook_node *node; @@ -301,7 +303,8 @@ { int ret; - if (!fp || fp->ops.func != fprobe_handler) + if (!fp || (fp->ops.saved_func != fprobe_handler && + fp->ops.saved_func != fprobe_kprobe_handler)) return -EINVAL; /* diff -Nru linux-6.0.6/kernel/trace/ftrace.c linux-6.0.12/kernel/trace/ftrace.c --- linux-6.0.6/kernel/trace/ftrace.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/ftrace.c 2023-01-18 18:27:39.000000000 +0000 @@ -1289,6 +1289,7 @@ if (!ftrace_mod) return -ENOMEM; + INIT_LIST_HEAD(&ftrace_mod->list); ftrace_mod->func = kstrdup(func, GFP_KERNEL); ftrace_mod->module = kstrdup(module, GFP_KERNEL); ftrace_mod->enable = enable; @@ -3031,18 +3032,8 @@ command |= FTRACE_UPDATE_TRACE_FUNC; } - if (!command || !ftrace_enabled) { - /* - * If these are dynamic or per_cpu ops, they still - * need their data freed. Since, function tracing is - * not currently active, we can just free them - * without synchronizing all CPUs. - */ - if (ops->flags & FTRACE_OPS_FL_DYNAMIC) - goto free_ops; - - return 0; - } + if (!command || !ftrace_enabled) + goto out; /* * If the ops uses a trampoline, then it needs to be @@ -3079,6 +3070,7 @@ removed_ops = NULL; ops->flags &= ~FTRACE_OPS_FL_REMOVING; +out: /* * Dynamic ops may be freed, we must make sure that all * callers are done before leaving this function. @@ -3106,7 +3098,6 @@ if (IS_ENABLED(CONFIG_PREEMPTION)) synchronize_rcu_tasks(); - free_ops: ftrace_trampoline_free(ops); } @@ -3203,7 +3194,7 @@ /* if we can't allocate this size, try something smaller */ if (!order) return -ENOMEM; - order >>= 1; + order--; goto again; } @@ -7404,7 +7395,7 @@ } pr_info("ftrace: allocating %ld entries in %ld pages\n", - count, count / ENTRIES_PER_PAGE + 1); + count, DIV_ROUND_UP(count, ENTRIES_PER_PAGE)); ret = ftrace_process_locs(NULL, __start_mcount_loc, diff -Nru linux-6.0.6/kernel/trace/kprobe_event_gen_test.c linux-6.0.12/kernel/trace/kprobe_event_gen_test.c --- linux-6.0.6/kernel/trace/kprobe_event_gen_test.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/kprobe_event_gen_test.c 2023-01-18 18:27:39.000000000 +0000 @@ -73,6 +73,10 @@ #define KPROBE_GEN_TEST_ARG3 NULL #endif +static bool trace_event_file_is_valid(struct trace_event_file *input) +{ + return input && !IS_ERR(input); +} /* * Test to make sure we can create a kprobe event, then add more @@ -100,20 +104,20 @@ KPROBE_GEN_TEST_FUNC, KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1); if (ret) - goto free; + goto out; /* Use kprobe_event_add_fields to add the rest of the fields */ ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3); if (ret) - goto free; + goto out; /* * This actually creates the event. */ ret = kprobe_event_gen_cmd_end(&cmd); if (ret) - goto free; + goto out; /* * Now get the gen_kprobe_test event file. We need to prevent @@ -136,13 +140,13 @@ goto delete; } out: + kfree(buf); return ret; delete: + if (trace_event_file_is_valid(gen_kprobe_test)) + gen_kprobe_test = NULL; /* We got an error after creating the event, delete it */ ret = kprobe_event_delete("gen_kprobe_test"); - free: - kfree(buf); - goto out; } @@ -170,14 +174,14 @@ KPROBE_GEN_TEST_FUNC, "$retval"); if (ret) - goto free; + goto out; /* * This actually creates the event. */ ret = kretprobe_event_gen_cmd_end(&cmd); if (ret) - goto free; + goto out; /* * Now get the gen_kretprobe_test event file. We need to @@ -201,13 +205,13 @@ goto delete; } out: + kfree(buf); return ret; delete: + if (trace_event_file_is_valid(gen_kretprobe_test)) + gen_kretprobe_test = NULL; /* We got an error after creating the event, delete it */ ret = kprobe_event_delete("gen_kretprobe_test"); - free: - kfree(buf); - goto out; } @@ -221,10 +225,12 @@ ret = test_gen_kretprobe_cmd(); if (ret) { - WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr, - "kprobes", - "gen_kretprobe_test", false)); - trace_put_event_file(gen_kretprobe_test); + if (trace_event_file_is_valid(gen_kretprobe_test)) { + WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr, + "kprobes", + "gen_kretprobe_test", false)); + trace_put_event_file(gen_kretprobe_test); + } WARN_ON(kprobe_event_delete("gen_kretprobe_test")); } @@ -233,24 +239,30 @@ static void __exit kprobe_event_gen_test_exit(void) { - /* Disable the event or you can't remove it */ - WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr, - "kprobes", - "gen_kprobe_test", false)); + if (trace_event_file_is_valid(gen_kprobe_test)) { + /* Disable the event or you can't remove it */ + WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr, + "kprobes", + "gen_kprobe_test", false)); + + /* Now give the file and instance back */ + trace_put_event_file(gen_kprobe_test); + } - /* Now give the file and instance back */ - trace_put_event_file(gen_kprobe_test); /* Now unregister and free the event */ WARN_ON(kprobe_event_delete("gen_kprobe_test")); - /* Disable the event or you can't remove it */ - WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr, - "kprobes", - "gen_kretprobe_test", false)); + if (trace_event_file_is_valid(gen_kretprobe_test)) { + /* Disable the event or you can't remove it */ + WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr, + "kprobes", + "gen_kretprobe_test", false)); + + /* Now give the file and instance back */ + trace_put_event_file(gen_kretprobe_test); + } - /* Now give the file and instance back */ - trace_put_event_file(gen_kretprobe_test); /* Now unregister and free the event */ WARN_ON(kprobe_event_delete("gen_kretprobe_test")); diff -Nru linux-6.0.6/kernel/trace/rethook.c linux-6.0.12/kernel/trace/rethook.c --- linux-6.0.6/kernel/trace/rethook.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/rethook.c 2023-01-18 18:27:39.000000000 +0000 @@ -83,8 +83,10 @@ { struct rethook *rh = kzalloc(sizeof(struct rethook), GFP_KERNEL); - if (!rh || !handler) + if (!rh || !handler) { + kfree(rh); return NULL; + } rh->data = data; rh->handler = handler; diff -Nru linux-6.0.6/kernel/trace/ring_buffer.c linux-6.0.12/kernel/trace/ring_buffer.c --- linux-6.0.6/kernel/trace/ring_buffer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/ring_buffer.c 2023-01-18 18:27:39.000000000 +0000 @@ -519,6 +519,7 @@ local_t committing; local_t commits; local_t pages_touched; + local_t pages_lost; local_t pages_read; long last_pages_touch; size_t shortest_full; @@ -894,10 +895,18 @@ size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu) { size_t read; + size_t lost; size_t cnt; read = local_read(&buffer->buffers[cpu]->pages_read); + lost = local_read(&buffer->buffers[cpu]->pages_lost); cnt = local_read(&buffer->buffers[cpu]->pages_touched); + + if (WARN_ON_ONCE(cnt < lost)) + return 0; + + cnt -= lost; + /* The reader can read an empty page, but not more than that */ if (cnt < read) { WARN_ON_ONCE(read > cnt + 1); @@ -907,6 +916,21 @@ return cnt - read; } +static __always_inline bool full_hit(struct trace_buffer *buffer, int cpu, int full) +{ + struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; + size_t nr_pages; + size_t dirty; + + nr_pages = cpu_buffer->nr_pages; + if (!nr_pages || !full) + return true; + + dirty = ring_buffer_nr_dirty_pages(buffer, cpu); + + return (dirty * 100) > (full * nr_pages); +} + /* * rb_wake_up_waiters - wake up tasks waiting for ring buffer input * @@ -937,6 +961,9 @@ struct ring_buffer_per_cpu *cpu_buffer; struct rb_irq_work *rbwork; + if (!buffer) + return; + if (cpu == RING_BUFFER_ALL_CPUS) { /* Wake up individual ones too. One level recursion */ @@ -945,7 +972,15 @@ rbwork = &buffer->irq_work; } else { + if (WARN_ON_ONCE(!buffer->buffers)) + return; + if (WARN_ON_ONCE(cpu >= nr_cpu_ids)) + return; + cpu_buffer = buffer->buffers[cpu]; + /* The CPU buffer may not have been initialized yet */ + if (!cpu_buffer) + return; rbwork = &cpu_buffer->irq_work; } @@ -1035,22 +1070,20 @@ !ring_buffer_empty_cpu(buffer, cpu)) { unsigned long flags; bool pagebusy; - size_t nr_pages; - size_t dirty; + bool done; if (!full) break; raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page; - nr_pages = cpu_buffer->nr_pages; - dirty = ring_buffer_nr_dirty_pages(buffer, cpu); + done = !pagebusy && full_hit(buffer, cpu, full); + if (!cpu_buffer->shortest_full || cpu_buffer->shortest_full > full) cpu_buffer->shortest_full = full; raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); - if (!pagebusy && - (!nr_pages || (dirty * 100) > full * nr_pages)) + if (done) break; } @@ -1076,6 +1109,7 @@ * @cpu: the cpu buffer to wait on * @filp: the file descriptor * @poll_table: The poll descriptor + * @full: wait until the percentage of pages are available, if @cpu != RING_BUFFER_ALL_CPUS * * If @cpu == RING_BUFFER_ALL_CPUS then the task will wake up as soon * as data is added to any of the @buffer's cpu buffers. Otherwise @@ -1085,14 +1119,15 @@ * zero otherwise. */ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu, - struct file *filp, poll_table *poll_table) + struct file *filp, poll_table *poll_table, int full) { struct ring_buffer_per_cpu *cpu_buffer; struct rb_irq_work *work; - if (cpu == RING_BUFFER_ALL_CPUS) + if (cpu == RING_BUFFER_ALL_CPUS) { work = &buffer->irq_work; - else { + full = 0; + } else { if (!cpumask_test_cpu(cpu, buffer->cpumask)) return -EINVAL; @@ -1100,8 +1135,14 @@ work = &cpu_buffer->irq_work; } - poll_wait(filp, &work->waiters, poll_table); - work->waiters_pending = true; + if (full) { + poll_wait(filp, &work->full_waiters, poll_table); + work->full_waiters_pending = true; + } else { + poll_wait(filp, &work->waiters, poll_table); + work->waiters_pending = true; + } + /* * There's a tight race between setting the waiters_pending and * checking if the ring buffer is empty. Once the waiters_pending bit @@ -1117,6 +1158,9 @@ */ smp_mb(); + if (full) + return full_hit(buffer, cpu, full) ? EPOLLIN | EPOLLRDNORM : 0; + if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) || (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu))) return EPOLLIN | EPOLLRDNORM; @@ -1758,9 +1802,9 @@ free_buffer_page(cpu_buffer->reader_page); - rb_head_page_deactivate(cpu_buffer); - if (head) { + rb_head_page_deactivate(cpu_buffer); + list_for_each_entry_safe(bpage, tmp, head, list) { list_del_init(&bpage->list); free_buffer_page(bpage); @@ -1996,6 +2040,7 @@ */ local_add(page_entries, &cpu_buffer->overrun); local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); + local_inc(&cpu_buffer->pages_lost); } /* @@ -2480,6 +2525,7 @@ */ local_add(entries, &cpu_buffer->overrun); local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); + local_inc(&cpu_buffer->pages_lost); /* * The entries will be zeroed out when we move the @@ -3144,10 +3190,6 @@ static __always_inline void rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) { - size_t nr_pages; - size_t dirty; - size_t full; - if (buffer->irq_work.waiters_pending) { buffer->irq_work.waiters_pending = false; /* irq_work_queue() supplies it's own memory barriers */ @@ -3171,10 +3213,7 @@ cpu_buffer->last_pages_touch = local_read(&cpu_buffer->pages_touched); - full = cpu_buffer->shortest_full; - nr_pages = cpu_buffer->nr_pages; - dirty = ring_buffer_nr_dirty_pages(buffer, cpu_buffer->cpu); - if (full && nr_pages && (dirty * 100) <= full * nr_pages) + if (!full_hit(buffer, cpu_buffer->cpu, cpu_buffer->shortest_full)) return; cpu_buffer->irq_work.wakeup_full = true; @@ -5237,6 +5276,7 @@ local_set(&cpu_buffer->committing, 0); local_set(&cpu_buffer->commits, 0); local_set(&cpu_buffer->pages_touched, 0); + local_set(&cpu_buffer->pages_lost, 0); local_set(&cpu_buffer->pages_read, 0); cpu_buffer->last_pages_touch = 0; cpu_buffer->shortest_full = 0; diff -Nru linux-6.0.6/kernel/trace/synth_event_gen_test.c linux-6.0.12/kernel/trace/synth_event_gen_test.c --- linux-6.0.6/kernel/trace/synth_event_gen_test.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/synth_event_gen_test.c 2023-01-18 18:27:39.000000000 +0000 @@ -120,15 +120,13 @@ /* Now generate a gen_synth_test event */ ret = synth_event_trace_array(gen_synth_test, vals, ARRAY_SIZE(vals)); - out: + free: + kfree(buf); return ret; delete: /* We got an error after creating the event, delete it */ synth_event_delete("gen_synth_test"); - free: - kfree(buf); - - goto out; + goto free; } /* @@ -227,15 +225,13 @@ /* Now trace an empty_synth_test event */ ret = synth_event_trace_array(empty_synth_test, vals, ARRAY_SIZE(vals)); - out: + free: + kfree(buf); return ret; delete: /* We got an error after creating the event, delete it */ synth_event_delete("empty_synth_test"); - free: - kfree(buf); - - goto out; + goto free; } static struct synth_field_desc create_synth_test_fields[] = { diff -Nru linux-6.0.6/kernel/trace/trace.c linux-6.0.12/kernel/trace/trace.c --- linux-6.0.6/kernel/trace/trace.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/trace.c 2023-01-18 18:27:39.000000000 +0000 @@ -6657,6 +6657,7 @@ mutex_unlock(&trace_types_lock); free_cpumask_var(iter->started); + kfree(iter->fmt); mutex_destroy(&iter->mutex); kfree(iter); @@ -6681,7 +6682,7 @@ return EPOLLIN | EPOLLRDNORM; else return ring_buffer_poll_wait(iter->array_buffer->buffer, iter->cpu_file, - filp, poll_table); + filp, poll_table, iter->tr->buffer_percent); } static __poll_t @@ -7802,6 +7803,7 @@ int len) { struct tracing_log_err *err; + char *cmd; if (tr->n_err_log_entries < TRACING_LOG_ERRS_MAX) { err = alloc_tracing_log_err(len); @@ -7810,12 +7812,12 @@ return err; } - + cmd = kzalloc(len, GFP_KERNEL); + if (!cmd) + return ERR_PTR(-ENOMEM); err = list_first_entry(&tr->err_log, struct tracing_log_err, list); kfree(err->cmd); - err->cmd = kzalloc(len, GFP_KERNEL); - if (!err->cmd) - return ERR_PTR(-ENOMEM); + err->cmd = cmd; list_del(&err->list); return err; diff -Nru linux-6.0.6/kernel/trace/trace_dynevent.c linux-6.0.12/kernel/trace/trace_dynevent.c --- linux-6.0.6/kernel/trace/trace_dynevent.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/trace_dynevent.c 2023-01-18 18:27:39.000000000 +0000 @@ -118,6 +118,7 @@ if (ret) break; } + tracing_reset_all_online_cpus(); mutex_unlock(&event_mutex); out: argv_free(argv); @@ -214,6 +215,7 @@ break; } out: + tracing_reset_all_online_cpus(); mutex_unlock(&event_mutex); return ret; diff -Nru linux-6.0.6/kernel/trace/trace_eprobe.c linux-6.0.12/kernel/trace/trace_eprobe.c --- linux-6.0.6/kernel/trace/trace_eprobe.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/trace_eprobe.c 2023-01-18 18:27:39.000000000 +0000 @@ -560,6 +560,9 @@ { struct eprobe_data *edata = data->private_data; + if (unlikely(!rec)) + return; + __eprobe_trace_func(edata, rec); } diff -Nru linux-6.0.6/kernel/trace/trace_events.c linux-6.0.12/kernel/trace/trace_events.c --- linux-6.0.6/kernel/trace/trace_events.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/trace_events.c 2023-01-18 18:27:39.000000000 +0000 @@ -2880,7 +2880,10 @@ * TRACE_REG_UNREGISTER. */ if (file->flags & EVENT_FILE_FL_ENABLED) - return -EBUSY; + goto busy; + + if (file->flags & EVENT_FILE_FL_WAS_ENABLED) + tr->clear_trace = true; /* * The do_for_each_event_file_safe() is * a double loop. After finding the call for this @@ -2893,6 +2896,12 @@ __trace_remove_event_call(call); return 0; + busy: + /* No need to clear the trace now */ + list_for_each_entry(tr, &ftrace_trace_arrays, list) { + tr->clear_trace = false; + } + return -EBUSY; } /* Remove an event_call */ diff -Nru linux-6.0.6/kernel/trace/trace_events_hist.c linux-6.0.12/kernel/trace/trace_events_hist.c --- linux-6.0.6/kernel/trace/trace_events_hist.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/trace_events_hist.c 2023-01-18 18:27:39.000000000 +0000 @@ -5051,6 +5051,9 @@ void *key = NULL; unsigned int i; + if (unlikely(!rbe)) + return; + memset(compound_key, 0, hist_data->key_size); for_each_hist_key_field(i, hist_data) { diff -Nru linux-6.0.6/kernel/trace/trace_events_synth.c linux-6.0.12/kernel/trace/trace_events_synth.c --- linux-6.0.6/kernel/trace/trace_events_synth.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/trace_events_synth.c 2023-01-18 18:27:39.000000000 +0000 @@ -828,10 +828,9 @@ } ret = set_synth_event_print_fmt(call); - if (ret < 0) { + /* unregister_trace_event() will be called inside */ + if (ret < 0) trace_remove_event_call(call); - goto err; - } out: return ret; err: diff -Nru linux-6.0.6/kernel/trace/trace_osnoise.c linux-6.0.12/kernel/trace/trace_osnoise.c --- linux-6.0.6/kernel/trace/trace_osnoise.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/kernel/trace/trace_osnoise.c 2023-01-18 18:27:39.000000000 +0000 @@ -917,7 +917,7 @@ void osnoise_trace_irq_exit(int id, const char *desc) { struct osnoise_variables *osn_var = this_cpu_osn_var(); - int duration; + s64 duration; if (!osn_var->sampling) return; @@ -1048,7 +1048,7 @@ static void trace_softirq_exit_callback(void *data, unsigned int vec_nr) { struct osnoise_variables *osn_var = this_cpu_osn_var(); - int duration; + s64 duration; if (!osn_var->sampling) return; @@ -1144,7 +1144,7 @@ static void thread_exit(struct osnoise_variables *osn_var, struct task_struct *t) { - int duration; + s64 duration; if (!osn_var->sampling) return; diff -Nru linux-6.0.6/lib/fault-inject.c linux-6.0.12/lib/fault-inject.c --- linux-6.0.6/lib/fault-inject.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/lib/fault-inject.c 2023-01-18 18:27:39.000000000 +0000 @@ -41,9 +41,6 @@ static void fail_dump(struct fault_attr *attr) { - if (attr->no_warn) - return; - if (attr->verbose > 0 && __ratelimit(&attr->ratelimit_state)) { printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure.\n" "name %pd, interval %lu, probability %lu, " @@ -103,7 +100,7 @@ * http://www.nongnu.org/failmalloc/ */ -bool should_fail(struct fault_attr *attr, ssize_t size) +bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags) { if (in_task()) { unsigned int fail_nth = READ_ONCE(current->fail_nth); @@ -146,13 +143,19 @@ return false; fail: - fail_dump(attr); + if (!(flags & FAULT_NOWARN)) + fail_dump(attr); if (atomic_read(&attr->times) != -1) atomic_dec_not_zero(&attr->times); return true; } + +bool should_fail(struct fault_attr *attr, ssize_t size) +{ + return should_fail_ex(attr, size, 0); +} EXPORT_SYMBOL_GPL(should_fail); #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS diff -Nru linux-6.0.6/lib/Kconfig.debug linux-6.0.12/lib/Kconfig.debug --- linux-6.0.6/lib/Kconfig.debug 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/lib/Kconfig.debug 2023-01-18 18:27:39.000000000 +0000 @@ -398,6 +398,7 @@ default 2048 if GCC_PLUGIN_LATENT_ENTROPY default 2048 if PARISC default 1536 if (!64BIT && XTENSA) + default 1280 if KASAN && !64BIT default 1024 if !64BIT default 2048 if 64BIT help @@ -1862,8 +1863,14 @@ If unsure, say N. config FUNCTION_ERROR_INJECTION - def_bool y + bool "Fault-injections of functions" depends on HAVE_FUNCTION_ERROR_INJECTION && KPROBES + help + Add fault injections into various functions that are annotated with + ALLOW_ERROR_INJECTION() in the kernel. BPF may also modify the return + value of theses functions. This is useful to test error paths of code. + + If unsure, say N config FAULT_INJECTION bool "Fault-injection framework" @@ -2095,6 +2102,7 @@ depends on DEBUG_KERNEL depends on KPROBES depends on KUNIT + select STACKTRACE if ARCH_CORRECT_STACKTRACE_ON_KRETPROBE default KUNIT_ALL_TESTS help This option provides for testing basic kprobes functionality on diff -Nru linux-6.0.6/lib/vdso/Makefile linux-6.0.12/lib/vdso/Makefile --- linux-6.0.6/lib/vdso/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/lib/vdso/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -17,6 +17,6 @@ endif quiet_cmd_vdso_check = VDSOCHK $@ - cmd_vdso_check = if $(OBJDUMP) -R $@ | egrep -h "$(ARCH_REL_TYPE_ABS)"; \ + cmd_vdso_check = if $(OBJDUMP) -R $@ | grep -E -h "$(ARCH_REL_TYPE_ABS)"; \ then (echo >&2 "$@: dynamic relocations are not supported"; \ rm -f $@; /bin/false); fi diff -Nru linux-6.0.6/Makefile linux-6.0.12/Makefile --- linux-6.0.6/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 0 -SUBLEVEL = 6 +SUBLEVEL = 12 EXTRAVERSION = NAME = Hurr durr I'ma ninja sloth @@ -899,12 +899,6 @@ KBUILD_LDFLAGS += --thinlto-cache-dir=$(extmod_prefix).thinlto-cache else CC_FLAGS_LTO := -flto -# ensure -fcf-protection is disabled when using retpoline as it is -# incompatible with -mindirect-branch=thunk-extern -ifdef CONFIG_RETPOLINE -KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none,) -endif - endif CC_FLAGS_LTO += -fvisibility=hidden diff -Nru linux-6.0.6/mm/compaction.c linux-6.0.12/mm/compaction.c --- linux-6.0.6/mm/compaction.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/compaction.c 2023-01-18 18:27:39.000000000 +0000 @@ -987,28 +987,28 @@ } /* + * Be careful not to clear PageLRU until after we're + * sure the page is not being freed elsewhere -- the + * page release code relies on it. + */ + if (unlikely(!get_page_unless_zero(page))) + goto isolate_fail; + + /* * Migration will fail if an anonymous page is pinned in memory, * so avoid taking lru_lock and isolating it unnecessarily in an * admittedly racy check. */ mapping = page_mapping(page); - if (!mapping && page_count(page) > page_mapcount(page)) - goto isolate_fail; + if (!mapping && (page_count(page) - 1) > total_mapcount(page)) + goto isolate_fail_put; /* * Only allow to migrate anonymous pages in GFP_NOFS context * because those do not depend on fs locks. */ if (!(cc->gfp_mask & __GFP_FS) && mapping) - goto isolate_fail; - - /* - * Be careful not to clear PageLRU until after we're - * sure the page is not being freed elsewhere -- the - * page release code relies on it. - */ - if (unlikely(!get_page_unless_zero(page))) - goto isolate_fail; + goto isolate_fail_put; /* Only take pages on LRU: a check now makes later tests safe */ if (!PageLRU(page)) diff -Nru linux-6.0.6/mm/damon/core.c linux-6.0.12/mm/damon/core.c --- linux-6.0.6/mm/damon/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/damon/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -230,24 +230,21 @@ return 0; } -struct damos *damon_new_scheme( - unsigned long min_sz_region, unsigned long max_sz_region, - unsigned int min_nr_accesses, unsigned int max_nr_accesses, - unsigned int min_age_region, unsigned int max_age_region, - enum damos_action action, struct damos_quota *quota, - struct damos_watermarks *wmarks) +struct damos *damon_new_scheme(struct damos_access_pattern *pattern, + enum damos_action action, struct damos_quota *quota, + struct damos_watermarks *wmarks) { struct damos *scheme; scheme = kmalloc(sizeof(*scheme), GFP_KERNEL); if (!scheme) return NULL; - scheme->min_sz_region = min_sz_region; - scheme->max_sz_region = max_sz_region; - scheme->min_nr_accesses = min_nr_accesses; - scheme->max_nr_accesses = max_nr_accesses; - scheme->min_age_region = min_age_region; - scheme->max_age_region = max_age_region; + scheme->pattern.min_sz_region = pattern->min_sz_region; + scheme->pattern.max_sz_region = pattern->max_sz_region; + scheme->pattern.min_nr_accesses = pattern->min_nr_accesses; + scheme->pattern.max_nr_accesses = pattern->max_nr_accesses; + scheme->pattern.min_age_region = pattern->min_age_region; + scheme->pattern.max_age_region = pattern->max_age_region; scheme->action = action; scheme->stat = (struct damos_stat){}; INIT_LIST_HEAD(&scheme->list); @@ -667,10 +664,12 @@ unsigned long sz; sz = r->ar.end - r->ar.start; - return s->min_sz_region <= sz && sz <= s->max_sz_region && - s->min_nr_accesses <= r->nr_accesses && - r->nr_accesses <= s->max_nr_accesses && - s->min_age_region <= r->age && r->age <= s->max_age_region; + return s->pattern.min_sz_region <= sz && + sz <= s->pattern.max_sz_region && + s->pattern.min_nr_accesses <= r->nr_accesses && + r->nr_accesses <= s->pattern.max_nr_accesses && + s->pattern.min_age_region <= r->age && + r->age <= s->pattern.max_age_region; } static bool damos_valid_target(struct damon_ctx *c, struct damon_target *t, diff -Nru linux-6.0.6/mm/damon/dbgfs.c linux-6.0.12/mm/damon/dbgfs.c --- linux-6.0.6/mm/damon/dbgfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/damon/dbgfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -131,9 +131,12 @@ damon_for_each_scheme(s, c) { rc = scnprintf(&buf[written], len - written, "%lu %lu %u %u %u %u %d %lu %lu %lu %u %u %u %d %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", - s->min_sz_region, s->max_sz_region, - s->min_nr_accesses, s->max_nr_accesses, - s->min_age_region, s->max_age_region, + s->pattern.min_sz_region, + s->pattern.max_sz_region, + s->pattern.min_nr_accesses, + s->pattern.max_nr_accesses, + s->pattern.min_age_region, + s->pattern.max_age_region, damos_action_to_dbgfs_scheme_action(s->action), s->quota.ms, s->quota.sz, s->quota.reset_interval, @@ -221,8 +224,6 @@ struct damos *scheme, **schemes; const int max_nr_schemes = 256; int pos = 0, parsed, ret; - unsigned long min_sz, max_sz; - unsigned int min_nr_a, max_nr_a, min_age, max_age; unsigned int action_input; enum damos_action action; @@ -233,13 +234,18 @@ *nr_schemes = 0; while (pos < len && *nr_schemes < max_nr_schemes) { + struct damos_access_pattern pattern = {}; struct damos_quota quota = {}; struct damos_watermarks wmarks; ret = sscanf(&str[pos], "%lu %lu %u %u %u %u %u %lu %lu %lu %u %u %u %u %lu %lu %lu %lu%n", - &min_sz, &max_sz, &min_nr_a, &max_nr_a, - &min_age, &max_age, &action_input, "a.ms, + &pattern.min_sz_region, &pattern.max_sz_region, + &pattern.min_nr_accesses, + &pattern.max_nr_accesses, + &pattern.min_age_region, + &pattern.max_age_region, + &action_input, "a.ms, "a.sz, "a.reset_interval, "a.weight_sz, "a.weight_nr_accesses, "a.weight_age, &wmarks.metric, @@ -251,7 +257,9 @@ if ((int)action < 0) goto fail; - if (min_sz > max_sz || min_nr_a > max_nr_a || min_age > max_age) + if (pattern.min_sz_region > pattern.max_sz_region || + pattern.min_nr_accesses > pattern.max_nr_accesses || + pattern.min_age_region > pattern.max_age_region) goto fail; if (wmarks.high < wmarks.mid || wmarks.high < wmarks.low || @@ -259,8 +267,7 @@ goto fail; pos += parsed; - scheme = damon_new_scheme(min_sz, max_sz, min_nr_a, max_nr_a, - min_age, max_age, action, "a, &wmarks); + scheme = damon_new_scheme(&pattern, action, "a, &wmarks); if (!scheme) goto fail; @@ -882,6 +889,7 @@ static int dbgfs_rm_context(char *name) { struct dentry *root, *dir, **new_dirs; + struct inode *inode; struct damon_ctx **new_ctxs; int i, j; int ret = 0; @@ -897,6 +905,12 @@ if (!dir) return -ENOENT; + inode = d_inode(dir); + if (!S_ISDIR(inode->i_mode)) { + ret = -EINVAL; + goto out_dput; + } + new_dirs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_dirs), GFP_KERNEL); if (!new_dirs) { diff -Nru linux-6.0.6/mm/damon/lru_sort.c linux-6.0.12/mm/damon/lru_sort.c --- linux-6.0.6/mm/damon/lru_sort.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/damon/lru_sort.c 2023-01-18 18:27:39.000000000 +0000 @@ -293,6 +293,17 @@ /* Create a DAMON-based operation scheme for hot memory regions */ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres) { + struct damos_access_pattern pattern = { + /* Find regions having PAGE_SIZE or larger size */ + .min_sz_region = PAGE_SIZE, + .max_sz_region = ULONG_MAX, + /* and accessed for more than the threshold */ + .min_nr_accesses = hot_thres, + .max_nr_accesses = UINT_MAX, + /* no matter its age */ + .min_age_region = 0, + .max_age_region = UINT_MAX, + }; struct damos_watermarks wmarks = { .metric = DAMOS_WMARK_FREE_MEM_RATE, .interval = wmarks_interval, @@ -313,26 +324,31 @@ .weight_nr_accesses = 1, .weight_age = 0, }; - struct damos *scheme = damon_new_scheme( - /* Find regions having PAGE_SIZE or larger size */ - PAGE_SIZE, ULONG_MAX, - /* and accessed for more than the threshold */ - hot_thres, UINT_MAX, - /* no matter its age */ - 0, UINT_MAX, + + return damon_new_scheme( + &pattern, /* prioritize those on LRU lists, as soon as found */ DAMOS_LRU_PRIO, /* under the quota. */ "a, /* (De)activate this according to the watermarks. */ &wmarks); - - return scheme; } /* Create a DAMON-based operation scheme for cold memory regions */ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres) { + struct damos_access_pattern pattern = { + /* Find regions having PAGE_SIZE or larger size */ + .min_sz_region = PAGE_SIZE, + .max_sz_region = ULONG_MAX, + /* and not accessed at all */ + .min_nr_accesses = 0, + .max_nr_accesses = 0, + /* for min_age or more micro-seconds */ + .min_age_region = cold_thres, + .max_age_region = UINT_MAX, + }; struct damos_watermarks wmarks = { .metric = DAMOS_WMARK_FREE_MEM_RATE, .interval = wmarks_interval, @@ -354,21 +370,15 @@ .weight_nr_accesses = 0, .weight_age = 1, }; - struct damos *scheme = damon_new_scheme( - /* Find regions having PAGE_SIZE or larger size */ - PAGE_SIZE, ULONG_MAX, - /* and not accessed at all */ - 0, 0, - /* for cold_thres or more micro-seconds, and */ - cold_thres, UINT_MAX, + + return damon_new_scheme( + &pattern, /* mark those as not accessed, as soon as found */ DAMOS_LRU_DEPRIO, /* under the quota. */ "a, /* (De)activate this according to the watermarks. */ &wmarks); - - return scheme; } static int damon_lru_sort_apply_parameters(void) diff -Nru linux-6.0.6/mm/damon/reclaim.c linux-6.0.12/mm/damon/reclaim.c --- linux-6.0.6/mm/damon/reclaim.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/damon/reclaim.c 2023-01-18 18:27:39.000000000 +0000 @@ -264,6 +264,17 @@ static struct damos *damon_reclaim_new_scheme(void) { + struct damos_access_pattern pattern = { + /* Find regions having PAGE_SIZE or larger size */ + .min_sz_region = PAGE_SIZE, + .max_sz_region = ULONG_MAX, + /* and not accessed at all */ + .min_nr_accesses = 0, + .max_nr_accesses = 0, + /* for min_age or more micro-seconds */ + .min_age_region = min_age / aggr_interval, + .max_age_region = UINT_MAX, + }; struct damos_watermarks wmarks = { .metric = DAMOS_WMARK_FREE_MEM_RATE, .interval = wmarks_interval, @@ -284,21 +295,15 @@ .weight_nr_accesses = 0, .weight_age = 1 }; - struct damos *scheme = damon_new_scheme( - /* Find regions having PAGE_SIZE or larger size */ - PAGE_SIZE, ULONG_MAX, - /* and not accessed at all */ - 0, 0, - /* for min_age or more micro-seconds, and */ - min_age / aggr_interval, UINT_MAX, + + return damon_new_scheme( + &pattern, /* page out those, as soon as found */ DAMOS_PAGEOUT, /* under the quota. */ "a, /* (De)activate this according to the watermarks. */ &wmarks); - - return scheme; } static int damon_reclaim_apply_parameters(void) diff -Nru linux-6.0.6/mm/damon/sysfs.c linux-6.0.12/mm/damon/sysfs.c --- linux-6.0.6/mm/damon/sysfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/damon/sysfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -2259,11 +2259,20 @@ static struct damos *damon_sysfs_mk_scheme( struct damon_sysfs_scheme *sysfs_scheme) { - struct damon_sysfs_access_pattern *pattern = + struct damon_sysfs_access_pattern *access_pattern = sysfs_scheme->access_pattern; struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas; struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights; struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks; + + struct damos_access_pattern pattern = { + .min_sz_region = access_pattern->sz->min, + .max_sz_region = access_pattern->sz->max, + .min_nr_accesses = access_pattern->nr_accesses->min, + .max_nr_accesses = access_pattern->nr_accesses->max, + .min_age_region = access_pattern->age->min, + .max_age_region = access_pattern->age->max, + }; struct damos_quota quota = { .ms = sysfs_quotas->ms, .sz = sysfs_quotas->sz, @@ -2280,18 +2289,58 @@ .low = sysfs_wmarks->low, }; - return damon_new_scheme(pattern->sz->min, pattern->sz->max, - pattern->nr_accesses->min, pattern->nr_accesses->max, - pattern->age->min, pattern->age->max, - sysfs_scheme->action, "a, &wmarks); + return damon_new_scheme(&pattern, sysfs_scheme->action, "a, + &wmarks); +} + +static void damon_sysfs_update_scheme(struct damos *scheme, + struct damon_sysfs_scheme *sysfs_scheme) +{ + struct damon_sysfs_access_pattern *access_pattern = + sysfs_scheme->access_pattern; + struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas; + struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights; + struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks; + + scheme->pattern.min_sz_region = access_pattern->sz->min; + scheme->pattern.max_sz_region = access_pattern->sz->max; + scheme->pattern.min_nr_accesses = access_pattern->nr_accesses->min; + scheme->pattern.max_nr_accesses = access_pattern->nr_accesses->max; + scheme->pattern.min_age_region = access_pattern->age->min; + scheme->pattern.max_age_region = access_pattern->age->max; + + scheme->action = sysfs_scheme->action; + + scheme->quota.ms = sysfs_quotas->ms; + scheme->quota.sz = sysfs_quotas->sz; + scheme->quota.reset_interval = sysfs_quotas->reset_interval_ms; + scheme->quota.weight_sz = sysfs_weights->sz; + scheme->quota.weight_nr_accesses = sysfs_weights->nr_accesses; + scheme->quota.weight_age = sysfs_weights->age; + + scheme->wmarks.metric = sysfs_wmarks->metric; + scheme->wmarks.interval = sysfs_wmarks->interval_us; + scheme->wmarks.high = sysfs_wmarks->high; + scheme->wmarks.mid = sysfs_wmarks->mid; + scheme->wmarks.low = sysfs_wmarks->low; } static int damon_sysfs_set_schemes(struct damon_ctx *ctx, struct damon_sysfs_schemes *sysfs_schemes) { - int i; + struct damos *scheme, *next; + int i = 0; - for (i = 0; i < sysfs_schemes->nr; i++) { + damon_for_each_scheme_safe(scheme, next, ctx) { + if (i < sysfs_schemes->nr) + damon_sysfs_update_scheme(scheme, + sysfs_schemes->schemes_arr[i]); + else + damon_destroy_scheme(scheme); + i++; + } + + for (; i < sysfs_schemes->nr; i++) { struct damos *scheme, *next; scheme = damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]); @@ -2342,6 +2391,10 @@ damon_for_each_scheme(scheme, ctx) { struct damon_sysfs_stats *sysfs_stats; + /* user could have removed the scheme sysfs dir */ + if (schemes_idx >= sysfs_schemes->nr) + break; + sysfs_stats = sysfs_schemes->schemes_arr[schemes_idx++]->stats; sysfs_stats->nr_tried = scheme->stat.nr_tried; sysfs_stats->sz_tried = scheme->stat.sz_tried; diff -Nru linux-6.0.6/mm/failslab.c linux-6.0.12/mm/failslab.c --- linux-6.0.6/mm/failslab.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/failslab.c 2023-01-18 18:27:39.000000000 +0000 @@ -16,6 +16,8 @@ bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags) { + int flags = 0; + /* No fault-injection for bootstrap cache */ if (unlikely(s == kmem_cache)) return false; @@ -30,10 +32,16 @@ if (failslab.cache_filter && !(s->flags & SLAB_FAILSLAB)) return false; + /* + * In some cases, it expects to specify __GFP_NOWARN + * to avoid printing any information(not just a warning), + * thus avoiding deadlocks. See commit 6b9dbedbe349 for + * details. + */ if (gfpflags & __GFP_NOWARN) - failslab.attr.no_warn = true; + flags |= FAULT_NOWARN; - return should_fail(&failslab.attr, s->object_size); + return should_fail_ex(&failslab.attr, s->object_size, flags); } static int __init setup_failslab(char *str) diff -Nru linux-6.0.6/mm/filemap.c linux-6.0.12/mm/filemap.c --- linux-6.0.6/mm/filemap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/filemap.c 2023-01-18 18:27:39.000000000 +0000 @@ -3712,7 +3712,7 @@ unsigned long offset; /* Offset into pagecache page */ unsigned long bytes; /* Bytes to write to page */ size_t copied; /* Bytes copied from user */ - void *fsdata; + void *fsdata = NULL; offset = (pos & (PAGE_SIZE - 1)); bytes = min_t(unsigned long, PAGE_SIZE - offset, diff -Nru linux-6.0.6/mm/huge_memory.c linux-6.0.12/mm/huge_memory.c --- linux-6.0.6/mm/huge_memory.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/huge_memory.c 2023-01-18 18:27:39.000000000 +0000 @@ -2445,7 +2445,16 @@ page_tail); page_tail->mapping = head->mapping; page_tail->index = head->index + tail; - page_tail->private = 0; + + /* + * page->private should not be set in tail pages with the exception + * of swap cache pages that store the swp_entry_t in tail pages. + * Fix up and warn once if private is unexpectedly set. + */ + if (!folio_test_swapcache(page_folio(head))) { + VM_WARN_ON_ONCE_PAGE(page_tail->private != 0, page_tail); + page_tail->private = 0; + } /* Page flags must be visible before we make the page non-compound. */ smp_wmb(); diff -Nru linux-6.0.6/mm/hugetlb.c linux-6.0.12/mm/hugetlb.c --- linux-6.0.6/mm/hugetlb.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/hugetlb.c 2023-01-18 18:27:39.000000000 +0000 @@ -5445,7 +5445,7 @@ return page != NULL; } -int huge_add_to_page_cache(struct page *page, struct address_space *mapping, +int hugetlb_add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t idx) { struct folio *folio = page_folio(page); @@ -5583,7 +5583,7 @@ new_page = true; if (vma->vm_flags & VM_MAYSHARE) { - int err = huge_add_to_page_cache(page, mapping, idx); + int err = hugetlb_add_to_page_cache(page, mapping, idx); if (err) { put_page(page); if (err == -EEXIST) @@ -6008,11 +6008,11 @@ /* * Serialization between remove_inode_hugepages() and - * huge_add_to_page_cache() below happens through the + * hugetlb_add_to_page_cache() below happens through the * hugetlb_fault_mutex_table that here must be hold by * the caller. */ - ret = huge_add_to_page_cache(page, mapping, idx); + ret = hugetlb_add_to_page_cache(page, mapping, idx); if (ret) goto out_release_nounlock; page_in_pagecache = true; @@ -6021,6 +6021,10 @@ ptl = huge_pte_lockptr(h, dst_mm, dst_pte); spin_lock(ptl); + ret = -EIO; + if (PageHWPoison(page)) + goto out_release_unlock; + /* * Recheck the i_size after holding PT lock to make sure not * to leave any page mapped (as page_mapped()) beyond the end diff -Nru linux-6.0.6/mm/hugetlb_vmemmap.c linux-6.0.12/mm/hugetlb_vmemmap.c --- linux-6.0.6/mm/hugetlb_vmemmap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/hugetlb_vmemmap.c 2023-01-18 18:27:39.000000000 +0000 @@ -11,6 +11,7 @@ #define pr_fmt(fmt) "HugeTLB: " fmt #include +#include #include #include #include diff -Nru linux-6.0.6/mm/kmemleak.c linux-6.0.12/mm/kmemleak.c --- linux-6.0.6/mm/kmemleak.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/kmemleak.c 2023-01-18 18:27:39.000000000 +0000 @@ -1464,6 +1464,27 @@ } /* + * Conditionally call resched() in a object iteration loop while making sure + * that the given object won't go away without RCU read lock by performing a + * get_object() if !pinned. + * + * Return: false if can't do a cond_resched() due to get_object() failure + * true otherwise + */ +static bool kmemleak_cond_resched(struct kmemleak_object *object, bool pinned) +{ + if (!pinned && !get_object(object)) + return false; + + rcu_read_unlock(); + cond_resched(); + rcu_read_lock(); + if (!pinned) + put_object(object); + return true; +} + +/* * Scan data sections and all the referenced memory blocks allocated via the * kernel's standard allocators. This function must be called with the * scan_mutex held. @@ -1474,7 +1495,7 @@ struct zone *zone; int __maybe_unused i; int new_leaks = 0; - int loop1_cnt = 0; + int loop_cnt = 0; jiffies_last_scan = jiffies; @@ -1483,7 +1504,6 @@ list_for_each_entry_rcu(object, &object_list, object_list) { bool obj_pinned = false; - loop1_cnt++; raw_spin_lock_irq(&object->lock); #ifdef DEBUG /* @@ -1517,24 +1537,11 @@ raw_spin_unlock_irq(&object->lock); /* - * Do a cond_resched() to avoid soft lockup every 64k objects. - * Make sure a reference has been taken so that the object - * won't go away without RCU read lock. + * Do a cond_resched() every 64k objects to avoid soft lockup. */ - if (!(loop1_cnt & 0xffff)) { - if (!obj_pinned && !get_object(object)) { - /* Try the next object instead */ - loop1_cnt--; - continue; - } - - rcu_read_unlock(); - cond_resched(); - rcu_read_lock(); - - if (!obj_pinned) - put_object(object); - } + if (!(++loop_cnt & 0xffff) && + !kmemleak_cond_resched(object, obj_pinned)) + loop_cnt--; /* Try again on next object */ } rcu_read_unlock(); @@ -1601,8 +1608,16 @@ * scan and color them gray until the next scan. */ rcu_read_lock(); + loop_cnt = 0; list_for_each_entry_rcu(object, &object_list, object_list) { /* + * Do a cond_resched() every 64k objects to avoid soft lockup. + */ + if (!(++loop_cnt & 0xffff) && + !kmemleak_cond_resched(object, false)) + loop_cnt--; /* Try again on next object */ + + /* * This is racy but we can save the overhead of lock/unlock * calls. The missed objects, if any, should be caught in * the next scan. @@ -1635,8 +1650,16 @@ * Scanning result reporting. */ rcu_read_lock(); + loop_cnt = 0; list_for_each_entry_rcu(object, &object_list, object_list) { /* + * Do a cond_resched() every 64k objects to avoid soft lockup. + */ + if (!(++loop_cnt & 0xffff) && + !kmemleak_cond_resched(object, false)) + loop_cnt--; /* Try again on next object */ + + /* * This is racy but we can save the overhead of lock/unlock * calls. The missed objects, if any, should be caught in * the next scan. diff -Nru linux-6.0.6/mm/maccess.c linux-6.0.12/mm/maccess.c --- linux-6.0.6/mm/maccess.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/maccess.c 2023-01-18 18:27:39.000000000 +0000 @@ -97,7 +97,7 @@ return src - unsafe_addr; Efault: pagefault_enable(); - dst[-1] = '\0'; + dst[0] = '\0'; return -EFAULT; } diff -Nru linux-6.0.6/mm/madvise.c linux-6.0.12/mm/madvise.c --- linux-6.0.6/mm/madvise.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/madvise.c 2023-01-18 18:27:39.000000000 +0000 @@ -811,7 +811,14 @@ if (start & ~huge_page_mask(hstate_vma(vma))) return false; - *end = ALIGN(*end, huge_page_size(hstate_vma(vma))); + /* + * Madvise callers expect the length to be rounded up to PAGE_SIZE + * boundaries, and may be unaware that this VMA uses huge pages. + * Avoid unexpected data loss by rounding down the number of + * huge pages freed. + */ + *end = ALIGN_DOWN(*end, huge_page_size(hstate_vma(vma))); + return true; } @@ -826,6 +833,9 @@ if (!madvise_dontneed_free_valid_vma(vma, start, &end, behavior)) return -EINVAL; + if (start == end) + return 0; + if (!userfaultfd_remove(vma, start, end)) { *prev = NULL; /* mmap_lock has been dropped, prev is stale */ diff -Nru linux-6.0.6/mm/memcontrol.c linux-6.0.12/mm/memcontrol.c --- linux-6.0.6/mm/memcontrol.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/memcontrol.c 2023-01-18 18:27:39.000000000 +0000 @@ -2971,7 +2971,7 @@ { struct obj_cgroup *objcg; - if (!memcg_kmem_enabled() || memcg_kmem_bypass()) + if (!memcg_kmem_enabled()) return NULL; if (PageMemcgKmem(page)) { diff -Nru linux-6.0.6/mm/memory-failure.c linux-6.0.12/mm/memory-failure.c --- linux-6.0.6/mm/memory-failure.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/memory-failure.c 2023-01-18 18:27:39.000000000 +0000 @@ -1079,6 +1079,7 @@ int res; struct page *hpage = compound_head(p); struct address_space *mapping; + bool extra_pins = false; if (!PageHuge(hpage)) return MF_DELAYED; @@ -1086,6 +1087,8 @@ mapping = page_mapping(hpage); if (mapping) { res = truncate_error_page(hpage, page_to_pfn(p), mapping); + /* The page is kept in page cache. */ + extra_pins = true; unlock_page(hpage); } else { unlock_page(hpage); @@ -1103,7 +1106,7 @@ } } - if (has_extra_refcount(ps, p, false)) + if (has_extra_refcount(ps, p, extra_pins)) res = MF_FAILED; return res; diff -Nru linux-6.0.6/mm/memremap.c linux-6.0.12/mm/memremap.c --- linux-6.0.6/mm/memremap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/memremap.c 2023-01-18 18:27:39.000000000 +0000 @@ -330,6 +330,7 @@ WARN(1, "File system DAX not supported\n"); return ERR_PTR(-EINVAL); } + params.pgprot = pgprot_decrypted(params.pgprot); break; case MEMORY_DEVICE_GENERIC: break; diff -Nru linux-6.0.6/mm/migrate.c linux-6.0.12/mm/migrate.c --- linux-6.0.6/mm/migrate.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/migrate.c 2023-01-18 18:27:39.000000000 +0000 @@ -1558,6 +1558,13 @@ */ list_splice(&ret_pages, from); + /* + * Return 0 in case all subpages of fail-to-migrate THPs are + * migrated successfully. + */ + if (list_empty(from)) + rc = 0; + count_vm_events(PGMIGRATE_SUCCESS, nr_succeeded); count_vm_events(PGMIGRATE_FAIL, nr_failed_pages); count_vm_events(THP_MIGRATION_SUCCESS, nr_thp_succeeded); diff -Nru linux-6.0.6/mm/page_alloc.c linux-6.0.12/mm/page_alloc.c --- linux-6.0.6/mm/page_alloc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/page_alloc.c 2023-01-18 18:27:39.000000000 +0000 @@ -804,6 +804,7 @@ p->mapping = TAIL_MAPPING; set_compound_head(p, head); + set_page_private(p, 0); } void prep_compound_page(struct page *page, unsigned int order) @@ -3882,6 +3883,8 @@ static bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) { + int flags = 0; + if (order < fail_page_alloc.min_order) return false; if (gfp_mask & __GFP_NOFAIL) @@ -3892,10 +3895,11 @@ (gfp_mask & __GFP_DIRECT_RECLAIM)) return false; + /* See comment in __should_failslab() */ if (gfp_mask & __GFP_NOWARN) - fail_page_alloc.attr.no_warn = true; + flags |= FAULT_NOWARN; - return should_fail(&fail_page_alloc.attr, 1 << order); + return should_fail_ex(&fail_page_alloc.attr, 1 << order, flags); } #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS diff -Nru linux-6.0.6/mm/userfaultfd.c linux-6.0.12/mm/userfaultfd.c --- linux-6.0.6/mm/userfaultfd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/userfaultfd.c 2023-01-18 18:27:39.000000000 +0000 @@ -64,7 +64,7 @@ pte_t _dst_pte, *dst_pte; bool writable = dst_vma->vm_flags & VM_WRITE; bool vm_shared = dst_vma->vm_flags & VM_SHARED; - bool page_in_cache = page->mapping; + bool page_in_cache = page_mapping(page); spinlock_t *ptl; struct inode *inode; pgoff_t offset, max_off; diff -Nru linux-6.0.6/mm/vmscan.c linux-6.0.12/mm/vmscan.c --- linux-6.0.6/mm/vmscan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/mm/vmscan.c 2023-01-18 18:27:39.000000000 +0000 @@ -2472,8 +2472,20 @@ * the flushers simply cannot keep up with the allocation * rate. Nudge the flusher threads in case they are asleep. */ - if (stat.nr_unqueued_dirty == nr_taken) + if (stat.nr_unqueued_dirty == nr_taken) { wakeup_flusher_threads(WB_REASON_VMSCAN); + /* + * For cgroupv1 dirty throttling is achieved by waking up + * the kernel flusher here and later waiting on folios + * which are in writeback to finish (see shrink_folio_list()). + * + * Flusher may not be able to issue writeback quickly + * enough for cgroupv1 writeback throttling to work + * on a large system. + */ + if (!writeback_throttling_sane(sc)) + reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK); + } sc->nr.dirty += stat.nr_dirty; sc->nr.congested += stat.nr_congested; @@ -2955,8 +2967,8 @@ enum lru_list lru; unsigned long nr_reclaimed = 0; unsigned long nr_to_reclaim = sc->nr_to_reclaim; + bool proportional_reclaim; struct blk_plug plug; - bool scan_adjusted; get_scan_count(lruvec, sc, nr); @@ -2974,8 +2986,8 @@ * abort proportional reclaim if either the file or anon lru has already * dropped to zero at the first pass. */ - scan_adjusted = (!cgroup_reclaim(sc) && !current_is_kswapd() && - sc->priority == DEF_PRIORITY); + proportional_reclaim = (!cgroup_reclaim(sc) && !current_is_kswapd() && + sc->priority == DEF_PRIORITY); blk_start_plug(&plug); while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || @@ -2995,7 +3007,7 @@ cond_resched(); - if (nr_reclaimed < nr_to_reclaim || scan_adjusted) + if (nr_reclaimed < nr_to_reclaim || proportional_reclaim) continue; /* @@ -3046,8 +3058,6 @@ nr_scanned = targets[lru] - nr[lru]; nr[lru] = targets[lru] * (100 - percentage) / 100; nr[lru] -= min(nr[lru], nr_scanned); - - scan_adjusted = true; } blk_finish_plug(&plug); sc->nr_reclaimed += nr_reclaimed; diff -Nru linux-6.0.6/net/9p/trans_fd.c linux-6.0.12/net/9p/trans_fd.c --- linux-6.0.6/net/9p/trans_fd.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/9p/trans_fd.c 2023-01-18 18:27:39.000000000 +0000 @@ -91,6 +91,7 @@ * @mux_list: list link for mux to manage multiple connections (?) * @client: reference to client instance for this connection * @err: error state + * @req_lock: lock protecting req_list and requests statuses * @req_list: accounting for requests which have been sent * @unsent_req_list: accounting for requests that haven't been sent * @rreq: read request @@ -114,6 +115,7 @@ struct list_head mux_list; struct p9_client *client; int err; + spinlock_t req_lock; struct list_head req_list; struct list_head unsent_req_list; struct p9_req_t *rreq; @@ -189,10 +191,10 @@ p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err); - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (m->err) { - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); return; } @@ -200,11 +202,15 @@ list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { list_move(&req->req_list, &cancel_list); + req->status = REQ_STATUS_ERROR; } list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) { list_move(&req->req_list, &cancel_list); + req->status = REQ_STATUS_ERROR; } + spin_unlock(&m->req_lock); + list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); list_del(&req->req_list); @@ -212,7 +218,6 @@ req->t_err = err; p9_client_cb(m->client, req, REQ_STATUS_ERROR); } - spin_unlock(&m->client->lock); } static __poll_t @@ -359,7 +364,7 @@ if ((m->rreq) && (m->rc.offset == m->rc.capacity)) { p9_debug(P9_DEBUG_TRANS, "got new packet\n"); m->rreq->rc.size = m->rc.offset; - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (m->rreq->status == REQ_STATUS_SENT) { list_del(&m->rreq->req_list); p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD); @@ -368,14 +373,14 @@ p9_debug(P9_DEBUG_TRANS, "Ignore replies associated with a cancelled request\n"); } else { - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); p9_debug(P9_DEBUG_ERROR, "Request tag %d errored out while we were reading the reply\n", m->rc.tag); err = -EIO; goto error; } - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); m->rc.sdata = NULL; m->rc.offset = 0; m->rc.capacity = 0; @@ -453,10 +458,10 @@ } if (!m->wsize) { - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (list_empty(&m->unsent_req_list)) { clear_bit(Wworksched, &m->wsched); - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); return; } @@ -471,7 +476,7 @@ m->wpos = 0; p9_req_get(req); m->wreq = req; - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); } p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n", @@ -588,6 +593,7 @@ INIT_LIST_HEAD(&m->mux_list); m->client = client; + spin_lock_init(&m->req_lock); INIT_LIST_HEAD(&m->req_list); INIT_LIST_HEAD(&m->unsent_req_list); INIT_WORK(&m->rq, p9_read_work); @@ -669,10 +675,10 @@ if (m->err < 0) return m->err; - spin_lock(&client->lock); + spin_lock(&m->req_lock); req->status = REQ_STATUS_UNSENT; list_add_tail(&req->req_list, &m->unsent_req_list); - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); if (test_and_clear_bit(Wpending, &m->wsched)) n = EPOLLOUT; @@ -687,11 +693,13 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) { + struct p9_trans_fd *ts = client->trans; + struct p9_conn *m = &ts->conn; int ret = 1; p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); - spin_lock(&client->lock); + spin_lock(&m->req_lock); if (req->status == REQ_STATUS_UNSENT) { list_del(&req->req_list); @@ -699,21 +707,24 @@ p9_req_put(client, req); ret = 0; } - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); return ret; } static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) { + struct p9_trans_fd *ts = client->trans; + struct p9_conn *m = &ts->conn; + p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); - spin_lock(&client->lock); + spin_lock(&m->req_lock); /* Ignore cancelled request if message has been received * before lock. */ if (req->status == REQ_STATUS_RCVD) { - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); return 0; } @@ -722,7 +733,8 @@ */ list_del(&req->req_list); req->status = REQ_STATUS_FLSHD; - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); + p9_req_put(client, req); return 0; @@ -821,11 +833,14 @@ goto out_free_ts; if (!(ts->rd->f_mode & FMODE_READ)) goto out_put_rd; + /* prevent workers from hanging on IO when fd is a pipe */ + ts->rd->f_flags |= O_NONBLOCK; ts->wr = fget(wfd); if (!ts->wr) goto out_put_rd; if (!(ts->wr->f_mode & FMODE_WRITE)) goto out_put_wr; + ts->wr->f_flags |= O_NONBLOCK; client->trans = ts; client->status = Connected; @@ -847,8 +862,10 @@ struct file *file; p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); - if (!p) + if (!p) { + sock_release(csocket); return -ENOMEM; + } csocket->sk->sk_allocation = GFP_NOIO; file = sock_alloc_file(csocket, 0, NULL); diff -Nru linux-6.0.6/net/bluetooth/hci_conn.c linux-6.0.12/net/bluetooth/hci_conn.c --- linux-6.0.6/net/bluetooth/hci_conn.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/bluetooth/hci_conn.c 2023-01-18 18:27:39.000000000 +0000 @@ -1003,10 +1003,21 @@ hdev->acl_cnt += conn->sent; } else { struct hci_conn *acl = conn->link; + if (acl) { acl->link = NULL; hci_conn_drop(acl); } + + /* Unacked ISO frames */ + if (conn->type == ISO_LINK) { + if (hdev->iso_pkts) + hdev->iso_cnt += conn->sent; + else if (hdev->le_pkts) + hdev->le_cnt += conn->sent; + else + hdev->acl_cnt += conn->sent; + } } if (conn->amp_mgr) @@ -1697,6 +1708,7 @@ if (!cis) return ERR_PTR(-ENOMEM); cis->cleanup = cis_cleanup; + cis->dst_type = dst_type; } if (cis->state == BT_CONNECTED) @@ -2076,12 +2088,6 @@ struct hci_conn *le; struct hci_conn *cis; - /* Convert from ISO socket address type to HCI address type */ - if (dst_type == BDADDR_LE_PUBLIC) - dst_type = ADDR_LE_DEV_PUBLIC; - else - dst_type = ADDR_LE_DEV_RANDOM; - if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) le = hci_connect_le(hdev, dst, dst_type, false, BT_SECURITY_LOW, diff -Nru linux-6.0.6/net/bluetooth/iso.c linux-6.0.12/net/bluetooth/iso.c --- linux-6.0.6/net/bluetooth/iso.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/bluetooth/iso.c 2023-01-18 18:27:39.000000000 +0000 @@ -235,6 +235,14 @@ return err; } +static inline u8 le_addr_type(u8 bdaddr_type) +{ + if (bdaddr_type == BDADDR_LE_PUBLIC) + return ADDR_LE_DEV_PUBLIC; + else + return ADDR_LE_DEV_RANDOM; +} + static int iso_connect_bis(struct sock *sk) { struct iso_conn *conn; @@ -328,14 +336,16 @@ /* Just bind if DEFER_SETUP has been set */ if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst, - iso_pi(sk)->dst_type, &iso_pi(sk)->qos); + le_addr_type(iso_pi(sk)->dst_type), + &iso_pi(sk)->qos); if (IS_ERR(hcon)) { err = PTR_ERR(hcon); goto done; } } else { hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst, - iso_pi(sk)->dst_type, &iso_pi(sk)->qos); + le_addr_type(iso_pi(sk)->dst_type), + &iso_pi(sk)->qos); if (IS_ERR(hcon)) { err = PTR_ERR(hcon); goto done; diff -Nru linux-6.0.6/net/bluetooth/l2cap_core.c linux-6.0.12/net/bluetooth/l2cap_core.c --- linux-6.0.6/net/bluetooth/l2cap_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/bluetooth/l2cap_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -1990,7 +1990,7 @@ if (link_type == LE_LINK && c->src_type == BDADDR_BREDR) continue; - if (c->psm == psm) { + if (c->chan_type != L2CAP_CHAN_FIXED && c->psm == psm) { int src_match, dst_match; int src_any, dst_any; @@ -3764,7 +3764,8 @@ l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), (unsigned long) &rfc, endptr - ptr); - if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { + if (remote_efs && + test_bit(FLAG_EFS_ENABLE, &chan->flags)) { chan->remote_id = efs.id; chan->remote_stype = efs.stype; chan->remote_msdu = le16_to_cpu(efs.msdu); @@ -5813,6 +5814,19 @@ BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm), scid, mtu, mps); + /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A + * page 1059: + * + * Valid range: 0x0001-0x00ff + * + * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges + */ + if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) { + result = L2CAP_CR_LE_BAD_PSM; + chan = NULL; + goto response; + } + /* Check if we have socket listening on psm */ pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src, &conn->hcon->dst, LE_LINK); @@ -6001,6 +6015,18 @@ psm = req->psm; + /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A + * page 1059: + * + * Valid range: 0x0001-0x00ff + * + * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges + */ + if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) { + result = L2CAP_CR_LE_BAD_PSM; + goto response; + } + BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps); memset(&pdu, 0, sizeof(pdu)); @@ -6885,6 +6911,7 @@ struct l2cap_ctrl *control, struct sk_buff *skb, u8 event) { + struct l2cap_ctrl local_control; int err = 0; bool skb_in_use = false; @@ -6909,15 +6936,32 @@ chan->buffer_seq = chan->expected_tx_seq; skb_in_use = true; + /* l2cap_reassemble_sdu may free skb, hence invalidate + * control, so make a copy in advance to use it after + * l2cap_reassemble_sdu returns and to avoid the race + * condition, for example: + * + * The current thread calls: + * l2cap_reassemble_sdu + * chan->ops->recv == l2cap_sock_recv_cb + * __sock_queue_rcv_skb + * Another thread calls: + * bt_sock_recvmsg + * skb_recv_datagram + * skb_free_datagram + * Then the current thread tries to access control, but + * it was freed by skb_free_datagram. + */ + local_control = *control; err = l2cap_reassemble_sdu(chan, skb, control); if (err) break; - if (control->final) { + if (local_control.final) { if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) { - control->final = 0; - l2cap_retransmit_all(chan, control); + local_control.final = 0; + l2cap_retransmit_all(chan, &local_control); l2cap_ertm_send(chan); } } @@ -7297,11 +7341,27 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff *skb) { + /* l2cap_reassemble_sdu may free skb, hence invalidate control, so store + * the txseq field in advance to use it after l2cap_reassemble_sdu + * returns and to avoid the race condition, for example: + * + * The current thread calls: + * l2cap_reassemble_sdu + * chan->ops->recv == l2cap_sock_recv_cb + * __sock_queue_rcv_skb + * Another thread calls: + * bt_sock_recvmsg + * skb_recv_datagram + * skb_free_datagram + * Then the current thread tries to access control, but it was freed by + * skb_free_datagram. + */ + u16 txseq = control->txseq; + BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb, chan->rx_state); - if (l2cap_classify_txseq(chan, control->txseq) == - L2CAP_TXSEQ_EXPECTED) { + if (l2cap_classify_txseq(chan, txseq) == L2CAP_TXSEQ_EXPECTED) { l2cap_pass_to_tx(chan, control); BT_DBG("buffer_seq %u->%u", chan->buffer_seq, @@ -7324,8 +7384,8 @@ } } - chan->last_acked_seq = control->txseq; - chan->expected_tx_seq = __next_seq(chan, control->txseq); + chan->last_acked_seq = txseq; + chan->expected_tx_seq = __next_seq(chan, txseq); return 0; } @@ -7581,6 +7641,7 @@ return; } + l2cap_chan_hold(chan); l2cap_chan_lock(chan); } else { BT_DBG("unknown cid 0x%4.4x", cid); @@ -8426,9 +8487,8 @@ * expected length. */ if (skb->len < L2CAP_LEN_SIZE) { - if (l2cap_recv_frag(conn, skb, conn->mtu) < 0) - goto drop; - return; + l2cap_recv_frag(conn, skb, conn->mtu); + break; } len = get_unaligned_le16(skb->data) + L2CAP_HDR_SIZE; @@ -8472,7 +8532,7 @@ /* Header still could not be read just continue */ if (conn->rx_skb->len < L2CAP_LEN_SIZE) - return; + break; } if (skb->len > conn->rx_len) { diff -Nru linux-6.0.6/net/bpf/test_run.c linux-6.0.12/net/bpf/test_run.c --- linux-6.0.6/net/bpf/test_run.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/bpf/test_run.c 2023-01-18 18:27:39.000000000 +0000 @@ -733,6 +733,7 @@ if (user_size > size) return ERR_PTR(-EMSGSIZE); + size = SKB_DATA_ALIGN(size); data = kzalloc(size + headroom + tailroom, GFP_USER); if (!data) return ERR_PTR(-ENOMEM); diff -Nru linux-6.0.6/net/bridge/br_netlink.c linux-6.0.12/net/bridge/br_netlink.c --- linux-6.0.6/net/bridge/br_netlink.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/bridge/br_netlink.c 2023-01-18 18:27:39.000000000 +0000 @@ -1332,7 +1332,7 @@ if (data[IFLA_BR_FDB_FLUSH]) { struct net_bridge_fdb_flush_desc desc = { - .flags_mask = BR_FDB_STATIC + .flags_mask = BIT(BR_FDB_STATIC) }; br_fdb_flush(br, &desc); diff -Nru linux-6.0.6/net/bridge/br_sysfs_br.c linux-6.0.12/net/bridge/br_sysfs_br.c --- linux-6.0.6/net/bridge/br_sysfs_br.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/bridge/br_sysfs_br.c 2023-01-18 18:27:39.000000000 +0000 @@ -345,7 +345,7 @@ struct netlink_ext_ack *extack) { struct net_bridge_fdb_flush_desc desc = { - .flags_mask = BR_FDB_STATIC + .flags_mask = BIT(BR_FDB_STATIC) }; br_fdb_flush(br, &desc); diff -Nru linux-6.0.6/net/bridge/br_vlan.c linux-6.0.12/net/bridge/br_vlan.c --- linux-6.0.6/net/bridge/br_vlan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/bridge/br_vlan.c 2023-01-18 18:27:39.000000000 +0000 @@ -959,6 +959,8 @@ list_for_each_entry(p, &br->port_list, list) { vg = nbp_vlan_group(p); list_for_each_entry(vlan, &vg->vlan_list, vlist) { + if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) + continue; err = vlan_vid_add(p->dev, proto, vlan->vid); if (err) goto err_filt; @@ -973,8 +975,11 @@ /* Delete VLANs for the old proto from the device filter. */ list_for_each_entry(p, &br->port_list, list) { vg = nbp_vlan_group(p); - list_for_each_entry(vlan, &vg->vlan_list, vlist) + list_for_each_entry(vlan, &vg->vlan_list, vlist) { + if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) + continue; vlan_vid_del(p->dev, oldproto, vlan->vid); + } } return 0; @@ -983,13 +988,19 @@ attr.u.vlan_protocol = ntohs(oldproto); switchdev_port_attr_set(br->dev, &attr, NULL); - list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist) + list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist) { + if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) + continue; vlan_vid_del(p->dev, proto, vlan->vid); + } list_for_each_entry_continue_reverse(p, &br->port_list, list) { vg = nbp_vlan_group(p); - list_for_each_entry(vlan, &vg->vlan_list, vlist) + list_for_each_entry(vlan, &vg->vlan_list, vlist) { + if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) + continue; vlan_vid_del(p->dev, proto, vlan->vid); + } } return err; diff -Nru linux-6.0.6/net/caif/chnl_net.c linux-6.0.12/net/caif/chnl_net.c --- linux-6.0.6/net/caif/chnl_net.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/caif/chnl_net.c 2023-01-18 18:27:39.000000000 +0000 @@ -310,9 +310,6 @@ if (result == 0) { pr_debug("connect timeout\n"); - caif_disconnect_client(dev_net(dev), &priv->chnl); - priv->state = CAIF_DISCONNECTED; - pr_debug("state disconnected\n"); result = -ETIMEDOUT; goto error; } diff -Nru linux-6.0.6/net/can/af_can.c linux-6.0.12/net/can/af_can.c --- linux-6.0.6/net/can/af_can.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/can/af_can.c 2023-01-18 18:27:39.000000000 +0000 @@ -451,7 +451,7 @@ /* insert new receiver (dev,canid,mask) -> (func,data) */ - if (dev && dev->type != ARPHRD_CAN) + if (dev && (dev->type != ARPHRD_CAN || !can_get_ml_priv(dev))) return -ENODEV; if (dev && !net_eq(net, dev_net(dev))) diff -Nru linux-6.0.6/net/can/isotp.c linux-6.0.12/net/can/isotp.c --- linux-6.0.6/net/can/isotp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/can/isotp.c 2023-01-18 18:27:39.000000000 +0000 @@ -111,6 +111,9 @@ #define ISOTP_FC_WT 1 /* wait */ #define ISOTP_FC_OVFLW 2 /* overflow */ +#define ISOTP_FC_TIMEOUT 1 /* 1 sec */ +#define ISOTP_ECHO_TIMEOUT 2 /* 2 secs */ + enum { ISOTP_IDLE = 0, ISOTP_WAIT_FIRST_FC, @@ -258,7 +261,8 @@ so->lastrxcf_tstamp = ktime_set(0, 0); /* start rx timeout watchdog */ - hrtimer_start(&so->rxtimer, ktime_set(1, 0), HRTIMER_MODE_REL_SOFT); + hrtimer_start(&so->rxtimer, ktime_set(ISOTP_FC_TIMEOUT, 0), + HRTIMER_MODE_REL_SOFT); return 0; } @@ -344,6 +348,8 @@ return 0; } +static void isotp_send_cframe(struct isotp_sock *so); + static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae) { struct sock *sk = &so->sk; @@ -398,14 +404,15 @@ case ISOTP_FC_CTS: so->tx.bs = 0; so->tx.state = ISOTP_SENDING; - /* start cyclic timer for sending CF frame */ - hrtimer_start(&so->txtimer, so->tx_gap, + /* send CF frame and enable echo timeout handling */ + hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0), HRTIMER_MODE_REL_SOFT); + isotp_send_cframe(so); break; case ISOTP_FC_WT: /* start timer to wait for next FC frame */ - hrtimer_start(&so->txtimer, ktime_set(1, 0), + hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0), HRTIMER_MODE_REL_SOFT); break; @@ -600,7 +607,7 @@ /* perform blocksize handling, if enabled */ if (!so->rxfc.bs || ++so->rx.bs < so->rxfc.bs) { /* start rx timeout watchdog */ - hrtimer_start(&so->rxtimer, ktime_set(1, 0), + hrtimer_start(&so->rxtimer, ktime_set(ISOTP_FC_TIMEOUT, 0), HRTIMER_MODE_REL_SOFT); return 0; } @@ -829,7 +836,7 @@ struct isotp_sock *so = isotp_sk(sk); struct canfd_frame *cf = (struct canfd_frame *)skb->data; - /* only handle my own local echo skb's */ + /* only handle my own local echo CF/SF skb's (no FF!) */ if (skb->sk != sk || so->cfecho != *(u32 *)cf->data) return; @@ -849,13 +856,16 @@ if (so->txfc.bs && so->tx.bs >= so->txfc.bs) { /* stop and wait for FC with timeout */ so->tx.state = ISOTP_WAIT_FC; - hrtimer_start(&so->txtimer, ktime_set(1, 0), + hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0), HRTIMER_MODE_REL_SOFT); return; } /* no gap between data frames needed => use burst mode */ if (!so->tx_gap) { + /* enable echo timeout handling */ + hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0), + HRTIMER_MODE_REL_SOFT); isotp_send_cframe(so); return; } @@ -879,7 +889,7 @@ /* start timeout for unlikely lost echo skb */ hrtimer_set_expires(&so->txtimer, ktime_add(ktime_get(), - ktime_set(2, 0))); + ktime_set(ISOTP_ECHO_TIMEOUT, 0))); restart = HRTIMER_RESTART; /* push out the next consecutive frame */ @@ -907,7 +917,8 @@ break; default: - WARN_ON_ONCE(1); + WARN_ONCE(1, "can-isotp: tx timer state %08X cfecho %08X\n", + so->tx.state, so->cfecho); } return restart; @@ -923,7 +934,7 @@ struct canfd_frame *cf; int ae = (so->opt.flags & CAN_ISOTP_EXTEND_ADDR) ? 1 : 0; int wait_tx_done = (so->opt.flags & CAN_ISOTP_WAIT_TX_DONE) ? 1 : 0; - s64 hrtimer_sec = 0; + s64 hrtimer_sec = ISOTP_ECHO_TIMEOUT; int off; int err; @@ -942,6 +953,8 @@ err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); if (err) goto err_out; + + so->tx.state = ISOTP_SENDING; } if (!size || size > MAX_MSG_LENGTH) { @@ -986,6 +999,10 @@ cf = (struct canfd_frame *)skb->data; skb_put_zero(skb, so->ll.mtu); + /* cfecho should have been zero'ed by init / former isotp_rcv_echo() */ + if (so->cfecho) + pr_notice_once("can-isotp: uninit cfecho %08X\n", so->cfecho); + /* check for single frame transmission depending on TX_DL */ if (size <= so->tx.ll_dl - SF_PCI_SZ4 - ae - off) { /* The message size generally fits into a SingleFrame - good. @@ -1011,11 +1028,8 @@ else cf->data[ae] |= size; - so->tx.state = ISOTP_IDLE; - wake_up_interruptible(&so->wait); - - /* don't enable wait queue for a single frame transmission */ - wait_tx_done = 0; + /* set CF echo tag for isotp_rcv_echo() (SF-mode) */ + so->cfecho = *(u32 *)cf->data; } else { /* send first frame */ @@ -1031,31 +1045,23 @@ /* disable wait for FCs due to activated block size */ so->txfc.bs = 0; - /* cfecho should have been zero'ed by init */ - if (so->cfecho) - pr_notice_once("can-isotp: no fc cfecho %08X\n", - so->cfecho); - - /* set consecutive frame echo tag */ + /* set CF echo tag for isotp_rcv_echo() (CF-mode) */ so->cfecho = *(u32 *)cf->data; - - /* switch directly to ISOTP_SENDING state */ - so->tx.state = ISOTP_SENDING; - - /* start timeout for unlikely lost echo skb */ - hrtimer_sec = 2; } else { /* standard flow control check */ so->tx.state = ISOTP_WAIT_FIRST_FC; /* start timeout for FC */ - hrtimer_sec = 1; - } + hrtimer_sec = ISOTP_FC_TIMEOUT; - hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0), - HRTIMER_MODE_REL_SOFT); + /* no CF echo tag for isotp_rcv_echo() (FF-mode) */ + so->cfecho = 0; + } } + hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0), + HRTIMER_MODE_REL_SOFT); + /* send the first or only CAN frame */ cf->flags = so->ll.tx_flags; @@ -1068,8 +1074,7 @@ __func__, ERR_PTR(err)); /* no transmission -> no timeout monitoring */ - if (hrtimer_sec) - hrtimer_cancel(&so->txtimer); + hrtimer_cancel(&so->txtimer); /* reset consecutive frame echo tag */ so->cfecho = 0; diff -Nru linux-6.0.6/net/can/j1939/main.c linux-6.0.12/net/can/j1939/main.c --- linux-6.0.6/net/can/j1939/main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/can/j1939/main.c 2023-01-18 18:27:39.000000000 +0000 @@ -332,6 +332,9 @@ /* re-claim the CAN_HDR from the SKB */ cf = skb_push(skb, J1939_CAN_HDR); + /* initialize header structure */ + memset(cf, 0, J1939_CAN_HDR); + /* make it a full can frame again */ skb_put(skb, J1939_CAN_FTR + (8 - dlc)); diff -Nru linux-6.0.6/net/can/j1939/transport.c linux-6.0.12/net/can/j1939/transport.c --- linux-6.0.6/net/can/j1939/transport.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/can/j1939/transport.c 2023-01-18 18:27:39.000000000 +0000 @@ -342,10 +342,12 @@ __skb_unlink(do_skb, &session->skb_queue); /* drop ref taken in j1939_session_skb_queue() */ skb_unref(do_skb); + spin_unlock_irqrestore(&session->skb_queue.lock, flags); kfree_skb(do_skb); + } else { + spin_unlock_irqrestore(&session->skb_queue.lock, flags); } - spin_unlock_irqrestore(&session->skb_queue.lock, flags); } void j1939_session_skb_queue(struct j1939_session *session, diff -Nru linux-6.0.6/net/core/flow_dissector.c linux-6.0.12/net/core/flow_dissector.c --- linux-6.0.6/net/core/flow_dissector.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/core/flow_dissector.c 2023-01-18 18:27:39.000000000 +0000 @@ -272,7 +272,7 @@ key->ct_zone = ct->zone.id; #endif #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) - key->ct_mark = ct->mark; + key->ct_mark = READ_ONCE(ct->mark); #endif cl = nf_ct_labels_find(ct); diff -Nru linux-6.0.6/net/core/neighbour.c linux-6.0.12/net/core/neighbour.c --- linux-6.0.6/net/core/neighbour.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/core/neighbour.c 2023-01-18 18:27:39.000000000 +0000 @@ -307,7 +307,31 @@ return 0; } -static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net) +static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev, + int family) +{ + switch (family) { + case AF_INET: + return __in_dev_arp_parms_get_rcu(dev); + case AF_INET6: + return __in6_dev_nd_parms_get_rcu(dev); + } + return NULL; +} + +static void neigh_parms_qlen_dec(struct net_device *dev, int family) +{ + struct neigh_parms *p; + + rcu_read_lock(); + p = neigh_get_dev_parms_rcu(dev, family); + if (p) + p->qlen--; + rcu_read_unlock(); +} + +static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net, + int family) { struct sk_buff_head tmp; unsigned long flags; @@ -321,13 +345,7 @@ struct net_device *dev = skb->dev; if (net == NULL || net_eq(dev_net(dev), net)) { - struct in_device *in_dev; - - rcu_read_lock(); - in_dev = __in_dev_get_rcu(dev); - if (in_dev) - in_dev->arp_parms->qlen--; - rcu_read_unlock(); + neigh_parms_qlen_dec(dev, family); __skb_unlink(skb, list); __skb_queue_tail(&tmp, skb); } @@ -409,7 +427,8 @@ write_lock_bh(&tbl->lock); neigh_flush_dev(tbl, dev, skip_perm); pneigh_ifdown_and_unlock(tbl, dev); - pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev)); + pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL, + tbl->family); if (skb_queue_empty_lockless(&tbl->proxy_queue)) del_timer_sync(&tbl->proxy_timer); return 0; @@ -1621,13 +1640,8 @@ if (tdif <= 0) { struct net_device *dev = skb->dev; - struct in_device *in_dev; - rcu_read_lock(); - in_dev = __in_dev_get_rcu(dev); - if (in_dev) - in_dev->arp_parms->qlen--; - rcu_read_unlock(); + neigh_parms_qlen_dec(dev, tbl->family); __skb_unlink(skb, &tbl->proxy_queue); if (tbl->proxy_redo && netif_running(dev)) { @@ -1821,7 +1835,7 @@ cancel_delayed_work_sync(&tbl->managed_work); cancel_delayed_work_sync(&tbl->gc_work); del_timer_sync(&tbl->proxy_timer); - pneigh_queue_purge(&tbl->proxy_queue, NULL); + pneigh_queue_purge(&tbl->proxy_queue, NULL, tbl->family); neigh_ifdown(tbl, NULL); if (atomic_read(&tbl->entries)) pr_crit("neighbour leakage\n"); @@ -3542,18 +3556,6 @@ return ret; } -static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev, - int family) -{ - switch (family) { - case AF_INET: - return __in_dev_arp_parms_get_rcu(dev); - case AF_INET6: - return __in6_dev_nd_parms_get_rcu(dev); - } - return NULL; -} - static void neigh_copy_dflt_parms(struct net *net, struct neigh_parms *p, int index) { diff -Nru linux-6.0.6/net/core/net_namespace.c linux-6.0.12/net/core/net_namespace.c --- linux-6.0.6/net/core/net_namespace.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/core/net_namespace.c 2023-01-18 18:27:39.000000000 +0000 @@ -117,6 +117,7 @@ static int ops_init(const struct pernet_operations *ops, struct net *net) { + struct net_generic *ng; int err = -ENOMEM; void *data = NULL; @@ -135,7 +136,13 @@ if (!err) return 0; + if (ops->id && ops->size) { cleanup: + ng = rcu_dereference_protected(net->gen, + lockdep_is_held(&pernet_ops_rwsem)); + ng->ptr[*ops->id] = NULL; + } + kfree(data); out: diff -Nru linux-6.0.6/net/core/skbuff.c linux-6.0.12/net/core/skbuff.c --- linux-6.0.6/net/core/skbuff.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/core/skbuff.c 2023-01-18 18:27:39.000000000 +0000 @@ -3868,7 +3868,7 @@ } else if (i < MAX_SKB_FRAGS) { skb_zcopy_downgrade_managed(skb); get_page(page); - skb_fill_page_desc(skb, i, page, offset, size); + skb_fill_page_desc_noacc(skb, i, page, offset, size); } else { return -EMSGSIZE; } @@ -4031,23 +4031,25 @@ int i = 0; int pos; - if (list_skb && !list_skb->head_frag && skb_headlen(list_skb) && - (skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY)) { - /* gso_size is untrusted, and we have a frag_list with a linear - * non head_frag head. - * - * (we assume checking the first list_skb member suffices; - * i.e if either of the list_skb members have non head_frag - * head, then the first one has too). - * - * If head_skb's headlen does not fit requested gso_size, it - * means that the frag_list members do NOT terminate on exact - * gso_size boundaries. Hence we cannot perform skb_frag_t page - * sharing. Therefore we must fallback to copying the frag_list - * skbs; we do so by disabling SG. - */ - if (mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) - features &= ~NETIF_F_SG; + if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) && + mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) { + struct sk_buff *check_skb; + + for (check_skb = list_skb; check_skb; check_skb = check_skb->next) { + if (skb_headlen(check_skb) && !check_skb->head_frag) { + /* gso_size is untrusted, and we have a frag_list with + * a linear non head_frag item. + * + * If head_skb's headlen does not fit requested gso_size, + * it means that the frag_list members do NOT terminate + * on exact gso_size boundaries. Hence we cannot perform + * skb_frag_t page sharing. Therefore we must fallback to + * copying the frag_list skbs; we do so by disabling SG. + */ + features &= ~NETIF_F_SG; + break; + } + } } __skb_push(head_skb, doffset); diff -Nru linux-6.0.6/net/core/skmsg.c linux-6.0.12/net/core/skmsg.c --- linux-6.0.6/net/core/skmsg.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/core/skmsg.c 2023-01-18 18:27:39.000000000 +0000 @@ -803,16 +803,13 @@ } } -void sk_psock_stop(struct sk_psock *psock, bool wait) +void sk_psock_stop(struct sk_psock *psock) { spin_lock_bh(&psock->ingress_lock); sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED); sk_psock_cork_free(psock); __sk_psock_zap_ingress(psock); spin_unlock_bh(&psock->ingress_lock); - - if (wait) - cancel_work_sync(&psock->work); } static void sk_psock_done_strp(struct sk_psock *psock); @@ -850,7 +847,7 @@ sk_psock_stop_verdict(sk, psock); write_unlock_bh(&sk->sk_callback_lock); - sk_psock_stop(psock, false); + sk_psock_stop(psock); INIT_RCU_WORK(&psock->rwork, sk_psock_destroy); queue_rcu_work(system_wq, &psock->rwork); diff -Nru linux-6.0.6/net/core/sock_map.c linux-6.0.12/net/core/sock_map.c --- linux-6.0.6/net/core/sock_map.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/core/sock_map.c 2023-01-18 18:27:39.000000000 +0000 @@ -1596,7 +1596,7 @@ saved_destroy = psock->saved_destroy; sock_map_remove_links(sk, psock); rcu_read_unlock(); - sk_psock_stop(psock, false); + sk_psock_stop(psock); sk_psock_put(sk, psock); saved_destroy(sk); } @@ -1619,9 +1619,10 @@ saved_close = psock->saved_close; sock_map_remove_links(sk, psock); rcu_read_unlock(); - sk_psock_stop(psock, true); - sk_psock_put(sk, psock); + sk_psock_stop(psock); release_sock(sk); + cancel_work_sync(&psock->work); + sk_psock_put(sk, psock); saved_close(sk, timeout); } EXPORT_SYMBOL_GPL(sock_map_close); diff -Nru linux-6.0.6/net/dccp/ipv4.c linux-6.0.12/net/dccp/ipv4.c --- linux-6.0.6/net/dccp/ipv4.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/dccp/ipv4.c 2023-01-18 18:27:39.000000000 +0000 @@ -136,6 +136,8 @@ * This unhashes the socket and releases the local port, if necessary. */ dccp_set_state(sk, DCCP_CLOSED); + if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) + inet_reset_saddr(sk); ip_rt_put(rt); sk->sk_route_caps = 0; inet->inet_dport = 0; diff -Nru linux-6.0.6/net/dccp/ipv6.c linux-6.0.12/net/dccp/ipv6.c --- linux-6.0.6/net/dccp/ipv6.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/dccp/ipv6.c 2023-01-18 18:27:39.000000000 +0000 @@ -967,6 +967,8 @@ late_failure: dccp_set_state(sk, DCCP_CLOSED); + if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) + inet_reset_saddr(sk); __sk_dst_reset(sk); failure: inet->inet_dport = 0; diff -Nru linux-6.0.6/net/dsa/dsa2.c linux-6.0.12/net/dsa/dsa2.c --- linux-6.0.6/net/dsa/dsa2.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/dsa/dsa2.c 2023-01-18 18:27:39.000000000 +0000 @@ -850,6 +850,14 @@ return err; } +static void dsa_switch_teardown_tag_protocol(struct dsa_switch *ds) +{ + const struct dsa_device_ops *tag_ops = ds->dst->tag_ops; + + if (tag_ops->disconnect) + tag_ops->disconnect(ds); +} + static int dsa_switch_setup(struct dsa_switch *ds) { struct dsa_devlink_priv *dl_priv; @@ -953,6 +961,8 @@ ds->slave_mii_bus = NULL; } + dsa_switch_teardown_tag_protocol(ds); + if (ds->ops->teardown) ds->ops->teardown(ds); @@ -1407,9 +1417,9 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master, const char *user_protocol) { + const struct dsa_device_ops *tag_ops = NULL; struct dsa_switch *ds = dp->ds; struct dsa_switch_tree *dst = ds->dst; - const struct dsa_device_ops *tag_ops; enum dsa_tag_protocol default_proto; /* Find out which protocol the switch would prefer. */ @@ -1432,10 +1442,17 @@ } tag_ops = dsa_find_tagger_by_name(user_protocol); - } else { - tag_ops = dsa_tag_driver_get(default_proto); + if (IS_ERR(tag_ops)) { + dev_warn(ds->dev, + "Failed to find a tagging driver for protocol %s, using default\n", + user_protocol); + tag_ops = NULL; + } } + if (!tag_ops) + tag_ops = dsa_tag_driver_get(default_proto); + if (IS_ERR(tag_ops)) { if (PTR_ERR(tag_ops) == -ENOPROTOOPT) return -EPROBE_DEFER; diff -Nru linux-6.0.6/net/dsa/dsa_priv.h linux-6.0.12/net/dsa/dsa_priv.h --- linux-6.0.6/net/dsa/dsa_priv.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/dsa/dsa_priv.h 2023-01-18 18:27:39.000000000 +0000 @@ -201,6 +201,7 @@ } /* port.c */ +bool dsa_port_supports_hwtstamp(struct dsa_port *dp, struct ifreq *ifr); void dsa_port_set_tag_protocol(struct dsa_port *cpu_dp, const struct dsa_device_ops *tag_ops); int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age); diff -Nru linux-6.0.6/net/dsa/master.c linux-6.0.12/net/dsa/master.c --- linux-6.0.6/net/dsa/master.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/dsa/master.c 2023-01-18 18:27:39.000000000 +0000 @@ -204,8 +204,7 @@ * switch in the tree that is PTP capable. */ list_for_each_entry(dp, &dst->ports, list) - if (dp->ds->ops->port_hwtstamp_get || - dp->ds->ops->port_hwtstamp_set) + if (dsa_port_supports_hwtstamp(dp, ifr)) return -EBUSY; break; } diff -Nru linux-6.0.6/net/dsa/port.c linux-6.0.12/net/dsa/port.c --- linux-6.0.6/net/dsa/port.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/dsa/port.c 2023-01-18 18:27:39.000000000 +0000 @@ -109,6 +109,22 @@ return !err; } +bool dsa_port_supports_hwtstamp(struct dsa_port *dp, struct ifreq *ifr) +{ + struct dsa_switch *ds = dp->ds; + int err; + + if (!ds->ops->port_hwtstamp_get || !ds->ops->port_hwtstamp_set) + return false; + + /* "See through" shim implementations of the "get" method. + * This will clobber the ifreq structure, but we will either return an + * error, or the master will overwrite it with proper values. + */ + err = ds->ops->port_hwtstamp_get(ds, dp->index, ifr); + return err != -EOPNOTSUPP; +} + int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age) { struct dsa_switch *ds = dp->ds; diff -Nru linux-6.0.6/net/ethtool/eeprom.c linux-6.0.12/net/ethtool/eeprom.c --- linux-6.0.6/net/ethtool/eeprom.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ethtool/eeprom.c 2023-01-18 18:27:39.000000000 +0000 @@ -124,7 +124,7 @@ if (ret) goto err_free; - ret = get_module_eeprom_by_page(dev, &page_data, info->extack); + ret = get_module_eeprom_by_page(dev, &page_data, info ? info->extack : NULL); if (ret < 0) goto err_ops; diff -Nru linux-6.0.6/net/hsr/hsr_forward.c linux-6.0.12/net/hsr/hsr_forward.c --- linux-6.0.6/net/hsr/hsr_forward.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/hsr/hsr_forward.c 2023-01-18 18:27:39.000000000 +0000 @@ -351,17 +351,18 @@ struct hsr_node *node_src) { bool was_multicast_frame; - int res; + int res, recv_len; was_multicast_frame = (skb->pkt_type == PACKET_MULTICAST); hsr_addr_subst_source(node_src, skb); skb_pull(skb, ETH_HLEN); + recv_len = skb->len; res = netif_rx(skb); if (res == NET_RX_DROP) { dev->stats.rx_dropped++; } else { dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; + dev->stats.rx_bytes += recv_len; if (was_multicast_frame) dev->stats.multicast++; } diff -Nru linux-6.0.6/net/ieee802154/socket.c linux-6.0.12/net/ieee802154/socket.c --- linux-6.0.6/net/ieee802154/socket.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ieee802154/socket.c 2023-01-18 18:27:39.000000000 +0000 @@ -502,8 +502,10 @@ if (err < 0) goto out; - if (addr->family != AF_IEEE802154) + if (addr->family != AF_IEEE802154) { + err = -EINVAL; goto out; + } ieee802154_addr_from_sa(&haddr, &addr->addr); dev = ieee802154_get_dev(sock_net(sk), &haddr); diff -Nru linux-6.0.6/net/ipv4/af_inet.c linux-6.0.12/net/ipv4/af_inet.c --- linux-6.0.6/net/ipv4/af_inet.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/af_inet.c 2023-01-18 18:27:39.000000000 +0000 @@ -748,6 +748,8 @@ (TCPF_ESTABLISHED | TCPF_SYN_RECV | TCPF_CLOSE_WAIT | TCPF_CLOSE))); + if (test_bit(SOCK_SUPPORT_ZC, &sock->flags)) + set_bit(SOCK_SUPPORT_ZC, &newsock->flags); sock_graft(sk2, newsock); newsock->state = SS_CONNECTED; diff -Nru linux-6.0.6/net/ipv4/esp4_offload.c linux-6.0.12/net/ipv4/esp4_offload.c --- linux-6.0.6/net/ipv4/esp4_offload.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/esp4_offload.c 2023-01-18 18:27:39.000000000 +0000 @@ -314,6 +314,9 @@ xo->seq.low += skb_shinfo(skb)->gso_segs; } + if (xo->seq.low < seq) + xo->seq.hi++; + esp.seqno = cpu_to_be64(seq + ((u64)xo->seq.hi << 32)); ip_hdr(skb)->tot_len = htons(skb->len); diff -Nru linux-6.0.6/net/ipv4/fib_semantics.c linux-6.0.12/net/ipv4/fib_semantics.c --- linux-6.0.6/net/ipv4/fib_semantics.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/fib_semantics.c 2023-01-18 18:27:39.000000000 +0000 @@ -888,13 +888,15 @@ return 1; } + if (fi->nh) { + if (cfg->fc_oif || cfg->fc_gw_family || cfg->fc_mp) + return 1; + return 0; + } + if (cfg->fc_oif || cfg->fc_gw_family) { struct fib_nh *nh; - /* cannot match on nexthop object attributes */ - if (fi->nh) - return 1; - nh = fib_info_nh(fi, 0); if (cfg->fc_encap) { if (fib_encap_match(net, cfg->fc_encap_type, diff -Nru linux-6.0.6/net/ipv4/fib_trie.c linux-6.0.12/net/ipv4/fib_trie.c --- linux-6.0.6/net/ipv4/fib_trie.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/fib_trie.c 2023-01-18 18:27:39.000000000 +0000 @@ -1381,8 +1381,10 @@ /* The alias was already inserted, so the node must exist. */ l = l ? l : fib_find_node(t, &tp, key); - if (WARN_ON_ONCE(!l)) + if (WARN_ON_ONCE(!l)) { + err = -ENOENT; goto out_free_new_fa; + } if (fib_find_alias(&l->leaf, new_fa->fa_slen, 0, 0, tb->tb_id, true) == new_fa) { diff -Nru linux-6.0.6/net/ipv4/inet_hashtables.c linux-6.0.12/net/ipv4/inet_hashtables.c --- linux-6.0.6/net/ipv4/inet_hashtables.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/inet_hashtables.c 2023-01-18 18:27:39.000000000 +0000 @@ -679,13 +679,13 @@ * Note that we use 32bit integers (vs RFC 'short integers') * because 2^16 is not a multiple of num_ephemeral and this * property might be used by clever attacker. + * * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, though - * attacks were since demonstrated, thus we use 65536 instead to really - * give more isolation and privacy, at the expense of 256kB of kernel - * memory. + * attacks were since demonstrated, thus we use 65536 by default instead + * to really give more isolation and privacy, at the expense of 256kB + * of kernel memory. */ -#define INET_TABLE_PERTURB_SHIFT 16 -#define INET_TABLE_PERTURB_SIZE (1 << INET_TABLE_PERTURB_SHIFT) +#define INET_TABLE_PERTURB_SIZE (1 << CONFIG_INET_TABLE_PERTURB_ORDER) static u32 *table_perturb; int __inet_hash_connect(struct inet_timewait_death_row *death_row, diff -Nru linux-6.0.6/net/ipv4/ip_input.c linux-6.0.12/net/ipv4/ip_input.c --- linux-6.0.6/net/ipv4/ip_input.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/ip_input.c 2023-01-18 18:27:39.000000000 +0000 @@ -366,6 +366,11 @@ iph->tos, dev); if (unlikely(err)) goto drop_error; + } else { + struct in_device *in_dev = __in_dev_get_rcu(dev); + + if (in_dev && IN_DEV_ORCONF(in_dev, NOPOLICY)) + IPCB(skb)->flags |= IPSKB_NOPOLICY; } #ifdef CONFIG_IP_ROUTE_CLASSID diff -Nru linux-6.0.6/net/ipv4/Kconfig linux-6.0.12/net/ipv4/Kconfig --- linux-6.0.6/net/ipv4/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -402,6 +402,16 @@ If unsure, say Y. +config INET_TABLE_PERTURB_ORDER + int "INET: Source port perturbation table size (as power of 2)" if EXPERT + default 16 + help + Source port perturbation table size (as power of 2) for + RFC 6056 3.3.4. Algorithm 4: Double-Hash Port Selection Algorithm. + + The default is almost always what you want. + Only change this if you know what you are doing. + config INET_XFRM_TUNNEL tristate select INET_TUNNEL diff -Nru linux-6.0.6/net/ipv4/netfilter/ipt_CLUSTERIP.c linux-6.0.12/net/ipv4/netfilter/ipt_CLUSTERIP.c --- linux-6.0.6/net/ipv4/netfilter/ipt_CLUSTERIP.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/netfilter/ipt_CLUSTERIP.c 2023-01-18 18:27:39.000000000 +0000 @@ -435,7 +435,7 @@ switch (ctinfo) { case IP_CT_NEW: - ct->mark = hash; + WRITE_ONCE(ct->mark, hash); break; case IP_CT_RELATED: case IP_CT_RELATED_REPLY: @@ -452,7 +452,7 @@ #ifdef DEBUG nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); #endif - pr_debug("hash=%u ct_hash=%u ", hash, ct->mark); + pr_debug("hash=%u ct_hash=%u ", hash, READ_ONCE(ct->mark)); if (!clusterip_responsible(cipinfo->config, hash)) { pr_debug("not responsible\n"); return NF_DROP; diff -Nru linux-6.0.6/net/ipv4/nexthop.c linux-6.0.12/net/ipv4/nexthop.c --- linux-6.0.6/net/ipv4/nexthop.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/nexthop.c 2023-01-18 18:27:39.000000000 +0000 @@ -2534,7 +2534,7 @@ if (!err) { nh->nh_flags = fib_nh->fib_nh_flags; fib_info_update_nhc_saddr(net, &fib_nh->nh_common, - fib_nh->fib_nh_scope); + !fib_nh->fib_nh_scope ? 0 : fib_nh->fib_nh_scope - 1); } else { fib_nh_release(net, fib_nh); } diff -Nru linux-6.0.6/net/ipv4/tcp_bpf.c linux-6.0.12/net/ipv4/tcp_bpf.c --- linux-6.0.6/net/ipv4/tcp_bpf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/tcp_bpf.c 2023-01-18 18:27:39.000000000 +0000 @@ -278,7 +278,7 @@ { bool cork = false, enospc = sk_msg_full(msg); struct sock *sk_redir; - u32 tosend, delta = 0; + u32 tosend, origsize, sent, delta = 0; u32 eval = __SK_NONE; int ret; @@ -333,10 +333,12 @@ cork = true; psock->cork = NULL; } - sk_msg_return(sk, msg, msg->sg.size); + sk_msg_return(sk, msg, tosend); release_sock(sk); + origsize = msg->sg.size; ret = tcp_bpf_sendmsg_redir(sk_redir, msg, tosend, flags); + sent = origsize - msg->sg.size; if (eval == __SK_REDIRECT) sock_put(sk_redir); @@ -375,7 +377,7 @@ msg->sg.data[msg->sg.start].page_link && msg->sg.data[msg->sg.start].length) { if (eval == __SK_REDIRECT) - sk_mem_charge(sk, msg->sg.size); + sk_mem_charge(sk, tosend - sent); goto more_data; } } @@ -607,7 +609,7 @@ } else { sk->sk_write_space = psock->saved_write_space; /* Pairs with lockless read in sk_clone_lock() */ - WRITE_ONCE(sk->sk_prot, psock->sk_proto); + sock_replace_proto(sk, psock->sk_proto); } return 0; } @@ -620,7 +622,7 @@ } /* Pairs with lockless read in sk_clone_lock() */ - WRITE_ONCE(sk->sk_prot, &tcp_bpf_prots[family][config]); + sock_replace_proto(sk, &tcp_bpf_prots[family][config]); return 0; } EXPORT_SYMBOL_GPL(tcp_bpf_update_proto); diff -Nru linux-6.0.6/net/ipv4/tcp.c linux-6.0.12/net/ipv4/tcp.c --- linux-6.0.6/net/ipv4/tcp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/tcp.c 2023-01-18 18:27:39.000000000 +0000 @@ -3648,7 +3648,7 @@ case TCP_REPAIR_OPTIONS: if (!tp->repair) err = -EINVAL; - else if (sk->sk_state == TCP_ESTABLISHED) + else if (sk->sk_state == TCP_ESTABLISHED && !tp->bytes_sent) err = tcp_repair_options_est(sk, optval, optlen); else err = -EPERM; diff -Nru linux-6.0.6/net/ipv4/tcp_cdg.c linux-6.0.12/net/ipv4/tcp_cdg.c --- linux-6.0.6/net/ipv4/tcp_cdg.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/tcp_cdg.c 2023-01-18 18:27:39.000000000 +0000 @@ -375,6 +375,7 @@ struct cdg *ca = inet_csk_ca(sk); struct tcp_sock *tp = tcp_sk(sk); + ca->gradients = NULL; /* We silently fall back to window = 1 if allocation fails. */ if (window > 1) ca->gradients = kcalloc(window, sizeof(ca->gradients[0]), @@ -388,6 +389,7 @@ struct cdg *ca = inet_csk_ca(sk); kfree(ca->gradients); + ca->gradients = NULL; } static struct tcp_congestion_ops tcp_cdg __read_mostly = { diff -Nru linux-6.0.6/net/ipv4/tcp_input.c linux-6.0.12/net/ipv4/tcp_input.c --- linux-6.0.6/net/ipv4/tcp_input.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/tcp_input.c 2023-01-18 18:27:39.000000000 +0000 @@ -2192,7 +2192,8 @@ */ static bool tcp_check_sack_reneging(struct sock *sk, int flag) { - if (flag & FLAG_SACK_RENEGING) { + if (flag & FLAG_SACK_RENEGING && + flag & FLAG_SND_UNA_ADVANCED) { struct tcp_sock *tp = tcp_sk(sk); unsigned long delay = max(usecs_to_jiffies(tp->srtt_us >> 4), msecs_to_jiffies(10)); diff -Nru linux-6.0.6/net/ipv4/tcp_ipv4.c linux-6.0.12/net/ipv4/tcp_ipv4.c --- linux-6.0.6/net/ipv4/tcp_ipv4.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/tcp_ipv4.c 2023-01-18 18:27:39.000000000 +0000 @@ -323,6 +323,8 @@ * if necessary. */ tcp_set_state(sk, TCP_CLOSE); + if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) + inet_reset_saddr(sk); ip_rt_put(rt); sk->sk_route_caps = 0; inet->inet_dport = 0; @@ -1853,11 +1855,13 @@ __skb_push(skb, hdrlen); no_coalesce: + limit = (u32)READ_ONCE(sk->sk_rcvbuf) + (u32)(READ_ONCE(sk->sk_sndbuf) >> 1); + /* Only socket owner can try to collapse/prune rx queues * to reduce memory overhead, so add a little headroom here. * Few sockets backlog are possibly concurrently non empty. */ - limit = READ_ONCE(sk->sk_rcvbuf) + READ_ONCE(sk->sk_sndbuf) + 64*1024; + limit += 64 * 1024; if (unlikely(sk_add_backlog(sk, skb, limit))) { bh_unlock_sock(sk); diff -Nru linux-6.0.6/net/ipv4/tcp_ulp.c linux-6.0.12/net/ipv4/tcp_ulp.c --- linux-6.0.6/net/ipv4/tcp_ulp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/tcp_ulp.c 2023-01-18 18:27:39.000000000 +0000 @@ -136,6 +136,9 @@ if (icsk->icsk_ulp_ops) goto out_err; + if (sk->sk_socket) + clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags); + err = ulp_ops->init(sk); if (err) goto out_err; diff -Nru linux-6.0.6/net/ipv4/udp_bpf.c linux-6.0.12/net/ipv4/udp_bpf.c --- linux-6.0.6/net/ipv4/udp_bpf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv4/udp_bpf.c 2023-01-18 18:27:39.000000000 +0000 @@ -141,14 +141,14 @@ if (restore) { sk->sk_write_space = psock->saved_write_space; - WRITE_ONCE(sk->sk_prot, psock->sk_proto); + sock_replace_proto(sk, psock->sk_proto); return 0; } if (sk->sk_family == AF_INET6) udp_bpf_check_v6_needs_rebuild(psock->sk_proto); - WRITE_ONCE(sk->sk_prot, &udp_bpf_prots[family]); + sock_replace_proto(sk, &udp_bpf_prots[family]); return 0; } EXPORT_SYMBOL_GPL(udp_bpf_update_proto); diff -Nru linux-6.0.6/net/ipv6/addrlabel.c linux-6.0.12/net/ipv6/addrlabel.c --- linux-6.0.6/net/ipv6/addrlabel.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/addrlabel.c 2023-01-18 18:27:39.000000000 +0000 @@ -437,6 +437,7 @@ { struct ifaddrlblmsg *ifal = nlmsg_data(nlh); ifal->ifal_family = AF_INET6; + ifal->__ifal_reserved = 0; ifal->ifal_prefixlen = prefixlen; ifal->ifal_flags = 0; ifal->ifal_index = ifindex; diff -Nru linux-6.0.6/net/ipv6/esp6_offload.c linux-6.0.12/net/ipv6/esp6_offload.c --- linux-6.0.6/net/ipv6/esp6_offload.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/esp6_offload.c 2023-01-18 18:27:39.000000000 +0000 @@ -346,6 +346,9 @@ xo->seq.low += skb_shinfo(skb)->gso_segs; } + if (xo->seq.low < seq) + xo->seq.hi++; + esp.seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32)); len = skb->len - sizeof(struct ipv6hdr); diff -Nru linux-6.0.6/net/ipv6/ip6_gre.c linux-6.0.12/net/ipv6/ip6_gre.c --- linux-6.0.6/net/ipv6/ip6_gre.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/ip6_gre.c 2023-01-18 18:27:39.000000000 +0000 @@ -1175,14 +1175,16 @@ dev->needed_headroom = dst_len; if (set_mtu) { - dev->mtu = rt->dst.dev->mtu - t_hlen; + int mtu = rt->dst.dev->mtu - t_hlen; + if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) - dev->mtu -= 8; + mtu -= 8; if (dev->type == ARPHRD_ETHER) - dev->mtu -= ETH_HLEN; + mtu -= ETH_HLEN; - if (dev->mtu < IPV6_MIN_MTU) - dev->mtu = IPV6_MIN_MTU; + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + WRITE_ONCE(dev->mtu, mtu); } } ip6_rt_put(rt); diff -Nru linux-6.0.6/net/ipv6/ip6_tunnel.c linux-6.0.12/net/ipv6/ip6_tunnel.c --- linux-6.0.6/net/ipv6/ip6_tunnel.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/ip6_tunnel.c 2023-01-18 18:27:39.000000000 +0000 @@ -1450,8 +1450,8 @@ struct net_device *tdev = NULL; struct __ip6_tnl_parm *p = &t->parms; struct flowi6 *fl6 = &t->fl.u.ip6; - unsigned int mtu; int t_hlen; + int mtu; __dev_addr_set(dev, &p->laddr, sizeof(struct in6_addr)); memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr)); @@ -1498,12 +1498,13 @@ dev->hard_header_len = tdev->hard_header_len + t_hlen; mtu = min_t(unsigned int, tdev->mtu, IP6_MAX_MTU); - dev->mtu = mtu - t_hlen; + mtu = mtu - t_hlen; if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) - dev->mtu -= 8; + mtu -= 8; - if (dev->mtu < IPV6_MIN_MTU) - dev->mtu = IPV6_MIN_MTU; + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + WRITE_ONCE(dev->mtu, mtu); } } } diff -Nru linux-6.0.6/net/ipv6/ipv6_sockglue.c linux-6.0.12/net/ipv6/ipv6_sockglue.c --- linux-6.0.6/net/ipv6/ipv6_sockglue.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/ipv6_sockglue.c 2023-01-18 18:27:39.000000000 +0000 @@ -419,6 +419,12 @@ rtnl_lock(); lock_sock(sk); + /* Another thread has converted the socket into IPv4 with + * IPV6_ADDRFORM concurrently. + */ + if (unlikely(sk->sk_family != AF_INET6)) + goto unlock; + switch (optname) { case IPV6_ADDRFORM: @@ -994,6 +1000,7 @@ break; } +unlock: release_sock(sk); if (needs_rtnl) rtnl_unlock(); diff -Nru linux-6.0.6/net/ipv6/route.c linux-6.0.12/net/ipv6/route.c --- linux-6.0.6/net/ipv6/route.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/route.c 2023-01-18 18:27:39.000000000 +0000 @@ -6555,10 +6555,16 @@ static int __net_init ip6_route_net_init_late(struct net *net) { #ifdef CONFIG_PROC_FS - proc_create_net("ipv6_route", 0, net->proc_net, &ipv6_route_seq_ops, - sizeof(struct ipv6_route_iter)); - proc_create_net_single("rt6_stats", 0444, net->proc_net, - rt6_stats_seq_show, NULL); + if (!proc_create_net("ipv6_route", 0, net->proc_net, + &ipv6_route_seq_ops, + sizeof(struct ipv6_route_iter))) + return -ENOMEM; + + if (!proc_create_net_single("rt6_stats", 0444, net->proc_net, + rt6_stats_seq_show, NULL)) { + remove_proc_entry("ipv6_route", net->proc_net); + return -ENOMEM; + } #endif return 0; } diff -Nru linux-6.0.6/net/ipv6/sit.c linux-6.0.12/net/ipv6/sit.c --- linux-6.0.6/net/ipv6/sit.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/sit.c 2023-01-18 18:27:39.000000000 +0000 @@ -1124,10 +1124,12 @@ if (tdev && !netif_is_l3_master(tdev)) { int t_hlen = tunnel->hlen + sizeof(struct iphdr); + int mtu; - dev->mtu = tdev->mtu - t_hlen; - if (dev->mtu < IPV6_MIN_MTU) - dev->mtu = IPV6_MIN_MTU; + mtu = tdev->mtu - t_hlen; + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + WRITE_ONCE(dev->mtu, mtu); } } diff -Nru linux-6.0.6/net/ipv6/tcp_ipv6.c linux-6.0.12/net/ipv6/tcp_ipv6.c --- linux-6.0.6/net/ipv6/tcp_ipv6.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/tcp_ipv6.c 2023-01-18 18:27:39.000000000 +0000 @@ -340,6 +340,8 @@ late_failure: tcp_set_state(sk, TCP_CLOSE); + if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) + inet_reset_saddr(sk); failure: inet->inet_dport = 0; sk->sk_route_caps = 0; diff -Nru linux-6.0.6/net/ipv6/xfrm6_policy.c linux-6.0.12/net/ipv6/xfrm6_policy.c --- linux-6.0.6/net/ipv6/xfrm6_policy.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/ipv6/xfrm6_policy.c 2023-01-18 18:27:39.000000000 +0000 @@ -287,9 +287,13 @@ if (ret) goto out_state; - register_pernet_subsys(&xfrm6_net_ops); + ret = register_pernet_subsys(&xfrm6_net_ops); + if (ret) + goto out_protocol; out: return ret; +out_protocol: + xfrm6_protocol_fini(); out_state: xfrm6_state_fini(); out_policy: diff -Nru linux-6.0.6/net/kcm/kcmsock.c linux-6.0.12/net/kcm/kcmsock.c --- linux-6.0.6/net/kcm/kcmsock.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/kcm/kcmsock.c 2023-01-18 18:27:39.000000000 +0000 @@ -162,7 +162,8 @@ /* Buffer limit is okay now, add to ready list */ list_add_tail(&kcm->wait_rx_list, &kcm->mux->kcm_rx_waiters); - kcm->rx_wait = true; + /* paired with lockless reads in kcm_rfree() */ + WRITE_ONCE(kcm->rx_wait, true); } static void kcm_rfree(struct sk_buff *skb) @@ -178,7 +179,7 @@ /* For reading rx_wait and rx_psock without holding lock */ smp_mb__after_atomic(); - if (!kcm->rx_wait && !kcm->rx_psock && + if (!READ_ONCE(kcm->rx_wait) && !READ_ONCE(kcm->rx_psock) && sk_rmem_alloc_get(sk) < sk->sk_rcvlowat) { spin_lock_bh(&mux->rx_lock); kcm_rcv_ready(kcm); @@ -221,7 +222,7 @@ struct sk_buff *skb; struct kcm_sock *kcm; - while ((skb = __skb_dequeue(head))) { + while ((skb = skb_dequeue(head))) { /* Reset destructor to avoid calling kcm_rcv_ready */ skb->destructor = sock_rfree; skb_orphan(skb); @@ -237,7 +238,8 @@ if (kcm_queue_rcv_skb(&kcm->sk, skb)) { /* Should mean socket buffer full */ list_del(&kcm->wait_rx_list); - kcm->rx_wait = false; + /* paired with lockless reads in kcm_rfree() */ + WRITE_ONCE(kcm->rx_wait, false); /* Commit rx_wait to read in kcm_free */ smp_wmb(); @@ -280,10 +282,12 @@ kcm = list_first_entry(&mux->kcm_rx_waiters, struct kcm_sock, wait_rx_list); list_del(&kcm->wait_rx_list); - kcm->rx_wait = false; + /* paired with lockless reads in kcm_rfree() */ + WRITE_ONCE(kcm->rx_wait, false); psock->rx_kcm = kcm; - kcm->rx_psock = psock; + /* paired with lockless reads in kcm_rfree() */ + WRITE_ONCE(kcm->rx_psock, psock); spin_unlock_bh(&mux->rx_lock); @@ -310,7 +314,8 @@ spin_lock_bh(&mux->rx_lock); psock->rx_kcm = NULL; - kcm->rx_psock = NULL; + /* paired with lockless reads in kcm_rfree() */ + WRITE_ONCE(kcm->rx_psock, NULL); /* Commit kcm->rx_psock before sk_rmem_alloc_get to sync with * kcm_rfree @@ -834,7 +839,7 @@ } get_page(page); - skb_fill_page_desc(skb, i, page, offset, size); + skb_fill_page_desc_noacc(skb, i, page, offset, size); skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG; coalesced: @@ -1080,53 +1085,17 @@ return err; } -static struct sk_buff *kcm_wait_data(struct sock *sk, int flags, - long timeo, int *err) -{ - struct sk_buff *skb; - - while (!(skb = skb_peek(&sk->sk_receive_queue))) { - if (sk->sk_err) { - *err = sock_error(sk); - return NULL; - } - - if (sock_flag(sk, SOCK_DONE)) - return NULL; - - if ((flags & MSG_DONTWAIT) || !timeo) { - *err = -EAGAIN; - return NULL; - } - - sk_wait_data(sk, &timeo, NULL); - - /* Handle signals */ - if (signal_pending(current)) { - *err = sock_intr_errno(timeo); - return NULL; - } - } - - return skb; -} - static int kcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, int flags) { struct sock *sk = sock->sk; struct kcm_sock *kcm = kcm_sk(sk); int err = 0; - long timeo; struct strp_msg *stm; int copied = 0; struct sk_buff *skb; - timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); - - lock_sock(sk); - - skb = kcm_wait_data(sk, flags, timeo, &err); + skb = skb_recv_datagram(sk, flags, &err); if (!skb) goto out; @@ -1157,14 +1126,11 @@ /* Finished with message */ msg->msg_flags |= MSG_EOR; KCM_STATS_INCR(kcm->stats.rx_msgs); - skb_unlink(skb, &sk->sk_receive_queue); - kfree_skb(skb); } } out: - release_sock(sk); - + skb_free_datagram(sk, skb); return copied ? : err; } @@ -1174,7 +1140,6 @@ { struct sock *sk = sock->sk; struct kcm_sock *kcm = kcm_sk(sk); - long timeo; struct strp_msg *stm; int err = 0; ssize_t copied; @@ -1182,11 +1147,7 @@ /* Only support splice for SOCKSEQPACKET */ - timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); - - lock_sock(sk); - - skb = kcm_wait_data(sk, flags, timeo, &err); + skb = skb_recv_datagram(sk, flags, &err); if (!skb) goto err_out; @@ -1214,13 +1175,11 @@ * finish reading the message. */ - release_sock(sk); - + skb_free_datagram(sk, skb); return copied; err_out: - release_sock(sk); - + skb_free_datagram(sk, skb); return err; } @@ -1240,7 +1199,8 @@ if (!kcm->rx_psock) { if (kcm->rx_wait) { list_del(&kcm->wait_rx_list); - kcm->rx_wait = false; + /* paired with lockless reads in kcm_rfree() */ + WRITE_ONCE(kcm->rx_wait, false); } requeue_rx_msgs(mux, &kcm->sk.sk_receive_queue); @@ -1793,7 +1753,8 @@ if (kcm->rx_wait) { list_del(&kcm->wait_rx_list); - kcm->rx_wait = false; + /* paired with lockless reads in kcm_rfree() */ + WRITE_ONCE(kcm->rx_wait, false); } /* Move any pending receive messages to other kcm sockets */ requeue_rx_msgs(mux, &sk->sk_receive_queue); @@ -1838,10 +1799,10 @@ kcm = kcm_sk(sk); mux = kcm->mux; + lock_sock(sk); sock_orphan(sk); kfree_skb(kcm->seq_skb); - lock_sock(sk); /* Purge queue under lock to avoid race condition with tx_work trying * to act when queue is nonempty. If tx_work runs after this point * it will just return. diff -Nru linux-6.0.6/net/key/af_key.c linux-6.0.12/net/key/af_key.c --- linux-6.0.6/net/key/af_key.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/key/af_key.c 2023-01-18 18:27:39.000000000 +0000 @@ -2905,7 +2905,7 @@ break; if (!aalg->pfkey_supported) continue; - if (aalg_tmpl_set(t, aalg) && aalg->available) + if (aalg_tmpl_set(t, aalg)) sz += sizeof(struct sadb_comb); } return sz + sizeof(struct sadb_prop); @@ -2923,7 +2923,7 @@ if (!ealg->pfkey_supported) continue; - if (!(ealg_tmpl_set(t, ealg) && ealg->available)) + if (!(ealg_tmpl_set(t, ealg))) continue; for (k = 1; ; k++) { @@ -2934,16 +2934,17 @@ if (!aalg->pfkey_supported) continue; - if (aalg_tmpl_set(t, aalg) && aalg->available) + if (aalg_tmpl_set(t, aalg)) sz += sizeof(struct sadb_comb); } } return sz + sizeof(struct sadb_prop); } -static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) +static int dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) { struct sadb_prop *p; + int sz = 0; int i; p = skb_put(skb, sizeof(struct sadb_prop)); @@ -2971,13 +2972,17 @@ c->sadb_comb_soft_addtime = 20*60*60; c->sadb_comb_hard_usetime = 8*60*60; c->sadb_comb_soft_usetime = 7*60*60; + sz += sizeof(*c); } } + + return sz + sizeof(*p); } -static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) +static int dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) { struct sadb_prop *p; + int sz = 0; int i, k; p = skb_put(skb, sizeof(struct sadb_prop)); @@ -3019,8 +3024,11 @@ c->sadb_comb_soft_addtime = 20*60*60; c->sadb_comb_hard_usetime = 8*60*60; c->sadb_comb_soft_usetime = 7*60*60; + sz += sizeof(*c); } } + + return sz + sizeof(*p); } static int key_notify_policy_expire(struct xfrm_policy *xp, const struct km_event *c) @@ -3150,6 +3158,7 @@ struct sadb_x_sec_ctx *sec_ctx; struct xfrm_sec_ctx *xfrm_ctx; int ctx_size = 0; + int alg_size = 0; sockaddr_size = pfkey_sockaddr_size(x->props.family); if (!sockaddr_size) @@ -3161,16 +3170,16 @@ sizeof(struct sadb_x_policy); if (x->id.proto == IPPROTO_AH) - size += count_ah_combs(t); + alg_size = count_ah_combs(t); else if (x->id.proto == IPPROTO_ESP) - size += count_esp_combs(t); + alg_size = count_esp_combs(t); if ((xfrm_ctx = x->security)) { ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len); size += sizeof(struct sadb_x_sec_ctx) + ctx_size; } - skb = alloc_skb(size + 16, GFP_ATOMIC); + skb = alloc_skb(size + alg_size + 16, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; @@ -3224,10 +3233,13 @@ pol->sadb_x_policy_priority = xp->priority; /* Set sadb_comb's. */ + alg_size = 0; if (x->id.proto == IPPROTO_AH) - dump_ah_combs(skb, t); + alg_size = dump_ah_combs(skb, t); else if (x->id.proto == IPPROTO_ESP) - dump_esp_combs(skb, t); + alg_size = dump_esp_combs(skb, t); + + hdr->sadb_msg_len += alg_size / 8; /* security context */ if (xfrm_ctx) { @@ -3382,7 +3394,7 @@ hdr->sadb_msg_len = size / sizeof(uint64_t); hdr->sadb_msg_errno = 0; hdr->sadb_msg_reserved = 0; - hdr->sadb_msg_seq = x->km.seq = get_acqseq(); + hdr->sadb_msg_seq = x->km.seq; hdr->sadb_msg_pid = 0; /* SA */ diff -Nru linux-6.0.6/net/mac80211/airtime.c linux-6.0.12/net/mac80211/airtime.c --- linux-6.0.6/net/mac80211/airtime.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mac80211/airtime.c 2023-01-18 18:27:39.000000000 +0000 @@ -452,6 +452,9 @@ (status->encoding == RX_ENC_HE && streams > 8))) return 0; + if (idx >= MCS_GROUP_RATES) + return 0; + duration = airtime_mcs_groups[group].duration[idx]; duration <<= airtime_mcs_groups[group].shift; *overhead = 36 + (streams << 2); diff -Nru linux-6.0.6/net/mac80211/main.c linux-6.0.12/net/mac80211/main.c --- linux-6.0.6/net/mac80211/main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mac80211/main.c 2023-01-18 18:27:39.000000000 +0000 @@ -1437,8 +1437,10 @@ ieee80211_led_exit(local); destroy_workqueue(local->workqueue); fail_workqueue: - if (local->wiphy_ciphers_allocated) + if (local->wiphy_ciphers_allocated) { kfree(local->hw.wiphy->cipher_suites); + local->wiphy_ciphers_allocated = false; + } kfree(local->int_scan_req); return result; } @@ -1506,8 +1508,10 @@ mutex_destroy(&local->iflist_mtx); mutex_destroy(&local->mtx); - if (local->wiphy_ciphers_allocated) + if (local->wiphy_ciphers_allocated) { kfree(local->hw.wiphy->cipher_suites); + local->wiphy_ciphers_allocated = false; + } idr_for_each(&local->ack_status_frames, ieee80211_free_ack_frame, NULL); diff -Nru linux-6.0.6/net/mac80211/mesh_pathtbl.c linux-6.0.12/net/mac80211/mesh_pathtbl.c --- linux-6.0.6/net/mac80211/mesh_pathtbl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mac80211/mesh_pathtbl.c 2023-01-18 18:27:39.000000000 +0000 @@ -710,7 +710,7 @@ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { - kfree_skb(skb); + ieee80211_free_txskb(&sdata->local->hw, skb); sdata->u.mesh.mshstats.dropped_frames_no_route++; } diff -Nru linux-6.0.6/net/mac80211/s1g.c linux-6.0.12/net/mac80211/s1g.c --- linux-6.0.6/net/mac80211/s1g.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mac80211/s1g.c 2023-01-18 18:27:39.000000000 +0000 @@ -112,6 +112,9 @@ goto out; } + /* TWT Information not supported yet */ + twt->control |= IEEE80211_TWT_CONTROL_RX_DISABLED; + drv_add_twt_setup(sdata->local, sdata, &sta->sta, twt); out: ieee80211_s1g_send_twt_setup(sdata, mgmt->sa, sdata->vif.addr, twt); diff -Nru linux-6.0.6/net/mac80211/tx.c linux-6.0.12/net/mac80211/tx.c --- linux-6.0.6/net/mac80211/tx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mac80211/tx.c 2023-01-18 18:27:39.000000000 +0000 @@ -4379,6 +4379,11 @@ if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; + if (unlikely(!ieee80211_sdata_running(sdata))) { + kfree_skb(skb); + return NETDEV_TX_OK; + } + if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) { struct sk_buff_head queue; diff -Nru linux-6.0.6/net/mac802154/rx.c linux-6.0.12/net/mac802154/rx.c --- linux-6.0.6/net/mac802154/rx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mac802154/rx.c 2023-01-18 18:27:39.000000000 +0000 @@ -132,7 +132,7 @@ ieee802154_parse_frame_start(struct sk_buff *skb, struct ieee802154_hdr *hdr) { int hlen; - struct ieee802154_mac_cb *cb = mac_cb_init(skb); + struct ieee802154_mac_cb *cb = mac_cb(skb); skb_reset_mac_header(skb); @@ -294,8 +294,9 @@ ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi) { struct ieee802154_local *local = hw_to_local(hw); + struct ieee802154_mac_cb *cb = mac_cb_init(skb); - mac_cb(skb)->lqi = lqi; + cb->lqi = lqi; skb->pkt_type = IEEE802154_RX_MSG; skb_queue_tail(&local->skb_queue, skb); tasklet_schedule(&local->tasklet); diff -Nru linux-6.0.6/net/mctp/af_mctp.c linux-6.0.12/net/mctp/af_mctp.c --- linux-6.0.6/net/mctp/af_mctp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mctp/af_mctp.c 2023-01-18 18:27:39.000000000 +0000 @@ -665,12 +665,14 @@ rc = mctp_neigh_init(); if (rc) - goto err_unreg_proto; + goto err_unreg_routes; mctp_device_init(); return 0; +err_unreg_routes: + mctp_routes_exit(); err_unreg_proto: proto_unregister(&mctp_proto); err_unreg_sock: diff -Nru linux-6.0.6/net/mctp/route.c linux-6.0.12/net/mctp/route.c --- linux-6.0.6/net/mctp/route.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mctp/route.c 2023-01-18 18:27:39.000000000 +0000 @@ -1400,7 +1400,7 @@ return register_pernet_subsys(&mctp_net_ops); } -void __exit mctp_routes_exit(void) +void mctp_routes_exit(void) { unregister_pernet_subsys(&mctp_net_ops); rtnl_unregister(PF_MCTP, RTM_DELROUTE); diff -Nru linux-6.0.6/net/mptcp/protocol.c linux-6.0.12/net/mptcp/protocol.c --- linux-6.0.6/net/mptcp/protocol.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mptcp/protocol.c 2023-01-18 18:27:39.000000000 +0000 @@ -2297,12 +2297,7 @@ goto out; } - /* if we are invoked by the msk cleanup code, the subflow is - * already orphaned - */ - if (ssk->sk_socket) - sock_orphan(ssk); - + sock_orphan(ssk); subflow->disposable = 1; /* if ssk hit tcp_done(), tcp_cleanup_ulp() cleared the related ops @@ -2833,7 +2828,11 @@ if (ssk == msk->first) subflow->fail_tout = 0; - sock_orphan(ssk); + /* detach from the parent socket, but allow data_ready to + * push incoming data into the mptcp stack, to properly ack it + */ + ssk->sk_socket = NULL; + ssk->sk_wq = NULL; unlock_sock_fast(ssk, slow); } sock_orphan(sk); @@ -2867,7 +2866,7 @@ sock_put(sk); } -static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk) +void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk) { #if IS_ENABLED(CONFIG_MPTCP_IPV6) const struct ipv6_pinfo *ssk6 = inet6_sk(ssk); @@ -3613,7 +3612,6 @@ if (mptcp_is_fully_established(newsk)) mptcp_pm_fully_established(msk, msk->first, GFP_KERNEL); - mptcp_copy_inaddrs(newsk, msk->first); mptcp_rcv_space_init(msk, msk->first); mptcp_propagate_sndbuf(newsk, msk->first); diff -Nru linux-6.0.6/net/mptcp/protocol.h linux-6.0.12/net/mptcp/protocol.h --- linux-6.0.6/net/mptcp/protocol.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mptcp/protocol.h 2023-01-18 18:27:39.000000000 +0000 @@ -597,6 +597,7 @@ int mptcp_allow_join_id0(const struct net *net); unsigned int mptcp_stale_loss_cnt(const struct net *net); int mptcp_get_pm_type(const struct net *net); +void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk); void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow, struct mptcp_options_received *mp_opt); bool __mptcp_retransmit_pending_data(struct sock *sk); diff -Nru linux-6.0.6/net/mptcp/subflow.c linux-6.0.12/net/mptcp/subflow.c --- linux-6.0.6/net/mptcp/subflow.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/mptcp/subflow.c 2023-01-18 18:27:39.000000000 +0000 @@ -723,6 +723,8 @@ goto dispose_child; } + if (new_msk) + mptcp_copy_inaddrs(new_msk, child); subflow_drop_ctx(child); goto out; } @@ -750,6 +752,11 @@ ctx->conn = new_msk; new_msk = NULL; + /* set msk addresses early to ensure mptcp_pm_get_local_id() + * uses the correct data + */ + mptcp_copy_inaddrs(ctx->conn, child); + /* with OoO packets we can reach here without ingress * mpc option */ @@ -1738,16 +1745,16 @@ for (msk = head; msk; msk = next) { struct sock *sk = (struct sock *)msk; - bool slow, do_cancel_work; + bool do_cancel_work; sock_hold(sk); - slow = lock_sock_fast_nested(sk); + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); next = msk->dl_next; msk->first = NULL; msk->dl_next = NULL; do_cancel_work = __mptcp_close(sk, 0); - unlock_sock_fast(sk, slow); + release_sock(sk); if (do_cancel_work) mptcp_cancel_work(sk); sock_put(sk); diff -Nru linux-6.0.6/net/netfilter/ipset/ip_set_core.c linux-6.0.12/net/netfilter/ipset/ip_set_core.c --- linux-6.0.6/net/netfilter/ipset/ip_set_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/ipset/ip_set_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -1719,11 +1719,13 @@ skb2 = nlmsg_new(payload, GFP_KERNEL); if (!skb2) return -ENOMEM; - rep = __nlmsg_put(skb2, NETLINK_CB(skb).portid, - nlh->nlmsg_seq, NLMSG_ERROR, payload, 0); + rep = nlmsg_put(skb2, NETLINK_CB(skb).portid, + nlh->nlmsg_seq, NLMSG_ERROR, payload, 0); errmsg = nlmsg_data(rep); errmsg->error = ret; - memcpy(&errmsg->msg, nlh, nlh->nlmsg_len); + unsafe_memcpy(&errmsg->msg, nlh, nlh->nlmsg_len, + /* Bounds checked by the skb layer. */); + cmdattr = (void *)&errmsg->msg + min_len; ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, cmdattr, diff -Nru linux-6.0.6/net/netfilter/ipset/ip_set_hash_gen.h linux-6.0.12/net/netfilter/ipset/ip_set_hash_gen.h --- linux-6.0.6/net/netfilter/ipset/ip_set_hash_gen.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/ipset/ip_set_hash_gen.h 2023-01-18 18:27:39.000000000 +0000 @@ -42,31 +42,8 @@ #define AHASH_MAX_SIZE (6 * AHASH_INIT_SIZE) /* Max muber of elements in the array block when tuned */ #define AHASH_MAX_TUNED 64 - #define AHASH_MAX(h) ((h)->bucketsize) -/* Max number of elements can be tuned */ -#ifdef IP_SET_HASH_WITH_MULTI -static u8 -tune_bucketsize(u8 curr, u32 multi) -{ - u32 n; - - if (multi < curr) - return curr; - - n = curr + AHASH_INIT_SIZE; - /* Currently, at listing one hash bucket must fit into a message. - * Therefore we have a hard limit here. - */ - return n > curr && n <= AHASH_MAX_TUNED ? n : curr; -} -#define TUNE_BUCKETSIZE(h, multi) \ - ((h)->bucketsize = tune_bucketsize((h)->bucketsize, multi)) -#else -#define TUNE_BUCKETSIZE(h, multi) -#endif - /* A hash bucket */ struct hbucket { struct rcu_head rcu; /* for call_rcu */ @@ -936,7 +913,12 @@ goto set_full; /* Create a new slot */ if (n->pos >= n->size) { - TUNE_BUCKETSIZE(h, multi); +#ifdef IP_SET_HASH_WITH_MULTI + if (h->bucketsize >= AHASH_MAX_TUNED) + goto set_full; + else if (h->bucketsize <= multi) + h->bucketsize += AHASH_INIT_SIZE; +#endif if (n->size >= AHASH_MAX(h)) { /* Trigger rehashing */ mtype_data_next(&h->next, d); diff -Nru linux-6.0.6/net/netfilter/ipset/ip_set_hash_ip.c linux-6.0.12/net/netfilter/ipset/ip_set_hash_ip.c --- linux-6.0.6/net/netfilter/ipset/ip_set_hash_ip.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/ipset/ip_set_hash_ip.c 2023-01-18 18:27:39.000000000 +0000 @@ -151,18 +151,16 @@ if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE) return -ERANGE; - if (retried) { + if (retried) ip = ntohl(h->next.ip); - e.ip = htonl(ip); - } for (; ip <= ip_to;) { + e.ip = htonl(ip); ret = adtfn(set, &e, &ext, &ext, flags); if (ret && !ip_set_eexist(ret, flags)) return ret; ip += hosts; - e.ip = htonl(ip); - if (e.ip == 0) + if (ip == 0) return 0; ret = 0; diff -Nru linux-6.0.6/net/netfilter/ipvs/ip_vs_app.c linux-6.0.12/net/netfilter/ipvs/ip_vs_app.c --- linux-6.0.6/net/netfilter/ipvs/ip_vs_app.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/ipvs/ip_vs_app.c 2023-01-18 18:27:39.000000000 +0000 @@ -599,13 +599,19 @@ int __net_init ip_vs_app_net_init(struct netns_ipvs *ipvs) { INIT_LIST_HEAD(&ipvs->app_list); - proc_create_net("ip_vs_app", 0, ipvs->net->proc_net, &ip_vs_app_seq_ops, - sizeof(struct seq_net_private)); +#ifdef CONFIG_PROC_FS + if (!proc_create_net("ip_vs_app", 0, ipvs->net->proc_net, + &ip_vs_app_seq_ops, + sizeof(struct seq_net_private))) + return -ENOMEM; +#endif return 0; } void __net_exit ip_vs_app_net_cleanup(struct netns_ipvs *ipvs) { unregister_ip_vs_app(ipvs, NULL /* all */); +#ifdef CONFIG_PROC_FS remove_proc_entry("ip_vs_app", ipvs->net->proc_net); +#endif } diff -Nru linux-6.0.6/net/netfilter/ipvs/ip_vs_conn.c linux-6.0.12/net/netfilter/ipvs/ip_vs_conn.c --- linux-6.0.6/net/netfilter/ipvs/ip_vs_conn.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/ipvs/ip_vs_conn.c 2023-01-18 18:27:39.000000000 +0000 @@ -1265,8 +1265,8 @@ * The drop rate array needs tuning for real environments. * Called from timer bh only => no locking */ - static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; - static char todrop_counter[9] = {0}; + static const signed char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + static signed char todrop_counter[9] = {0}; int i; /* if the conn entry hasn't lasted for 60 seconds, don't drop it. @@ -1447,20 +1447,36 @@ { atomic_set(&ipvs->conn_count, 0); - proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net, - &ip_vs_conn_seq_ops, sizeof(struct ip_vs_iter_state)); - proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net, - &ip_vs_conn_sync_seq_ops, - sizeof(struct ip_vs_iter_state)); +#ifdef CONFIG_PROC_FS + if (!proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net, + &ip_vs_conn_seq_ops, + sizeof(struct ip_vs_iter_state))) + goto err_conn; + + if (!proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net, + &ip_vs_conn_sync_seq_ops, + sizeof(struct ip_vs_iter_state))) + goto err_conn_sync; +#endif + return 0; + +#ifdef CONFIG_PROC_FS +err_conn_sync: + remove_proc_entry("ip_vs_conn", ipvs->net->proc_net); +err_conn: + return -ENOMEM; +#endif } void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs) { /* flush all the connection entries first */ ip_vs_conn_flush(ipvs); +#ifdef CONFIG_PROC_FS remove_proc_entry("ip_vs_conn", ipvs->net->proc_net); remove_proc_entry("ip_vs_conn_sync", ipvs->net->proc_net); +#endif } int __init ip_vs_conn_init(void) diff -Nru linux-6.0.6/net/netfilter/nf_conntrack_core.c linux-6.0.12/net/netfilter/nf_conntrack_core.c --- linux-6.0.6/net/netfilter/nf_conntrack_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/nf_conntrack_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -1781,7 +1781,7 @@ } #ifdef CONFIG_NF_CONNTRACK_MARK - ct->mark = exp->master->mark; + ct->mark = READ_ONCE(exp->master->mark); #endif #ifdef CONFIG_NF_CONNTRACK_SECMARK ct->secmark = exp->master->secmark; diff -Nru linux-6.0.6/net/netfilter/nf_conntrack_netlink.c linux-6.0.12/net/netfilter/nf_conntrack_netlink.c --- linux-6.0.6/net/netfilter/nf_conntrack_netlink.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/nf_conntrack_netlink.c 2023-01-18 18:27:39.000000000 +0000 @@ -328,9 +328,9 @@ } #ifdef CONFIG_NF_CONNTRACK_MARK -static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) +static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark) { - if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark))) + if (nla_put_be32(skb, CTA_MARK, htonl(mark))) goto nla_put_failure; return 0; @@ -543,7 +543,7 @@ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct) { if (ctnetlink_dump_status(skb, ct) < 0 || - ctnetlink_dump_mark(skb, ct) < 0 || + ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 || ctnetlink_dump_secctx(skb, ct) < 0 || ctnetlink_dump_id(skb, ct) < 0 || ctnetlink_dump_use(skb, ct) < 0 || @@ -722,6 +722,7 @@ struct sk_buff *skb; unsigned int type; unsigned int flags = 0, group; + u32 mark; int err; if (events & (1 << IPCT_DESTROY)) { @@ -826,8 +827,9 @@ } #ifdef CONFIG_NF_CONNTRACK_MARK - if ((events & (1 << IPCT_MARK) || ct->mark) - && ctnetlink_dump_mark(skb, ct) < 0) + mark = READ_ONCE(ct->mark); + if ((events & (1 << IPCT_MARK) || mark) && + ctnetlink_dump_mark(skb, mark) < 0) goto nla_put_failure; #endif nlmsg_end(skb, nlh); @@ -1154,7 +1156,7 @@ } #ifdef CONFIG_NF_CONNTRACK_MARK - if ((ct->mark & filter->mark.mask) != filter->mark.val) + if ((READ_ONCE(ct->mark) & filter->mark.mask) != filter->mark.val) goto ignore_entry; #endif status = (u32)READ_ONCE(ct->status); @@ -2002,9 +2004,9 @@ mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK])); mark = ntohl(nla_get_be32(cda[CTA_MARK])); - newmark = (ct->mark & mask) ^ mark; - if (newmark != ct->mark) - ct->mark = newmark; + newmark = (READ_ONCE(ct->mark) & mask) ^ mark; + if (newmark != READ_ONCE(ct->mark)) + WRITE_ONCE(ct->mark, newmark); } #endif @@ -2669,6 +2671,7 @@ { const struct nf_conntrack_zone *zone; struct nlattr *nest_parms; + u32 mark; zone = nf_ct_zone(ct); @@ -2730,7 +2733,8 @@ goto nla_put_failure; #ifdef CONFIG_NF_CONNTRACK_MARK - if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0) + mark = READ_ONCE(ct->mark); + if (mark && ctnetlink_dump_mark(skb, mark) < 0) goto nla_put_failure; #endif if (ctnetlink_dump_labels(skb, ct) < 0) diff -Nru linux-6.0.6/net/netfilter/nf_conntrack_standalone.c linux-6.0.12/net/netfilter/nf_conntrack_standalone.c --- linux-6.0.6/net/netfilter/nf_conntrack_standalone.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/nf_conntrack_standalone.c 2023-01-18 18:27:39.000000000 +0000 @@ -366,7 +366,7 @@ goto release; #if defined(CONFIG_NF_CONNTRACK_MARK) - seq_printf(s, "mark=%u ", ct->mark); + seq_printf(s, "mark=%u ", READ_ONCE(ct->mark)); #endif ct_show_secctx(s, ct); diff -Nru linux-6.0.6/net/netfilter/nf_flow_table_offload.c linux-6.0.12/net/netfilter/nf_flow_table_offload.c --- linux-6.0.6/net/netfilter/nf_flow_table_offload.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/nf_flow_table_offload.c 2023-01-18 18:27:39.000000000 +0000 @@ -1098,6 +1098,7 @@ struct flow_block_cb *block_cb, *next; int err = 0; + down_write(&flowtable->flow_block_lock); switch (cmd) { case FLOW_BLOCK_BIND: list_splice(&bo->cb_list, &flowtable->flow_block.cb_list); @@ -1112,6 +1113,7 @@ WARN_ON_ONCE(1); err = -EOPNOTSUPP; } + up_write(&flowtable->flow_block_lock); return err; } @@ -1168,7 +1170,9 @@ nf_flow_table_block_offload_init(bo, dev_net(dev), cmd, flowtable, extack); + down_write(&flowtable->flow_block_lock); err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_FT, bo); + up_write(&flowtable->flow_block_lock); if (err < 0) return err; diff -Nru linux-6.0.6/net/netfilter/nfnetlink.c linux-6.0.12/net/netfilter/nfnetlink.c --- linux-6.0.6/net/netfilter/nfnetlink.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/nfnetlink.c 2023-01-18 18:27:39.000000000 +0000 @@ -294,6 +294,7 @@ nfnl_lock(subsys_id); if (nfnl_dereference_protected(subsys_id) != ss || nfnetlink_find_client(type, ss) != nc) { + nfnl_unlock(subsys_id); err = -EAGAIN; break; } diff -Nru linux-6.0.6/net/netfilter/nf_tables_api.c linux-6.0.12/net/netfilter/nf_tables_api.c --- linux-6.0.6/net/netfilter/nf_tables_api.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/nf_tables_api.c 2023-01-18 18:27:39.000000000 +0000 @@ -5958,7 +5958,8 @@ &timeout); if (err) return err; - } else if (set->flags & NFT_SET_TIMEOUT) { + } else if (set->flags & NFT_SET_TIMEOUT && + !(flags & NFT_SET_ELEM_INTERVAL_END)) { timeout = set->timeout; } @@ -6024,7 +6025,8 @@ err = -EOPNOTSUPP; goto err_set_elem_expr; } - } else if (set->num_exprs > 0) { + } else if (set->num_exprs > 0 && + !(flags & NFT_SET_ELEM_INTERVAL_END)) { err = nft_set_elem_expr_clone(ctx, set, expr_array); if (err < 0) goto err_set_elem_expr_clone; @@ -8465,9 +8467,6 @@ nf_tables_chain_destroy(&trans->ctx); break; case NFT_MSG_DELRULE: - if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD) - nft_flow_rule_destroy(nft_trans_flow_rule(trans)); - nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans)); break; case NFT_MSG_DELSET: @@ -8973,6 +8972,9 @@ nft_rule_expr_deactivate(&trans->ctx, nft_trans_rule(trans), NFT_TRANS_COMMIT); + + if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD) + nft_flow_rule_destroy(nft_trans_flow_rule(trans)); break; case NFT_MSG_NEWSET: nft_clear(net, nft_trans_set(trans)); @@ -10030,6 +10032,8 @@ nft_net = nft_pernet(net); deleted = 0; mutex_lock(&nft_net->commit_mutex); + if (!list_empty(&nf_tables_destroy_list)) + rcu_barrier(); again: list_for_each_entry(table, &nft_net->tables, list) { if (nft_table_has_owner(table) && @@ -10088,7 +10092,8 @@ struct nftables_pernet *nft_net = nft_pernet(net); mutex_lock(&nft_net->commit_mutex); - if (!list_empty(&nft_net->commit_list)) + if (!list_empty(&nft_net->commit_list) || + !list_empty(&nft_net->module_list)) __nf_tables_abort(net, NFNL_ABORT_NONE); __nft_release_tables(net); mutex_unlock(&nft_net->commit_mutex); diff -Nru linux-6.0.6/net/netfilter/nft_ct.c linux-6.0.12/net/netfilter/nft_ct.c --- linux-6.0.6/net/netfilter/nft_ct.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/nft_ct.c 2023-01-18 18:27:39.000000000 +0000 @@ -98,7 +98,7 @@ return; #ifdef CONFIG_NF_CONNTRACK_MARK case NFT_CT_MARK: - *dest = ct->mark; + *dest = READ_ONCE(ct->mark); return; #endif #ifdef CONFIG_NF_CONNTRACK_SECMARK @@ -297,8 +297,8 @@ switch (priv->key) { #ifdef CONFIG_NF_CONNTRACK_MARK case NFT_CT_MARK: - if (ct->mark != value) { - ct->mark = value; + if (READ_ONCE(ct->mark) != value) { + WRITE_ONCE(ct->mark, value); nf_conntrack_event_cache(IPCT_MARK, ct); } break; diff -Nru linux-6.0.6/net/netfilter/nft_payload.c linux-6.0.12/net/netfilter/nft_payload.c --- linux-6.0.6/net/netfilter/nft_payload.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/nft_payload.c 2023-01-18 18:27:39.000000000 +0000 @@ -62,7 +62,7 @@ return false; if (offset + len > VLAN_ETH_HLEN + vlan_hlen) - ethlen -= offset + len - VLAN_ETH_HLEN + vlan_hlen; + ethlen -= offset + len - VLAN_ETH_HLEN - vlan_hlen; memcpy(dst_u8, vlanh + offset - vlan_hlen, ethlen); diff -Nru linux-6.0.6/net/netfilter/xt_connmark.c linux-6.0.12/net/netfilter/xt_connmark.c --- linux-6.0.6/net/netfilter/xt_connmark.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netfilter/xt_connmark.c 2023-01-18 18:27:39.000000000 +0000 @@ -30,6 +30,7 @@ u_int32_t new_targetmark; struct nf_conn *ct; u_int32_t newmark; + u_int32_t oldmark; ct = nf_ct_get(skb, &ctinfo); if (ct == NULL) @@ -37,14 +38,15 @@ switch (info->mode) { case XT_CONNMARK_SET: - newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; + oldmark = READ_ONCE(ct->mark); + newmark = (oldmark & ~info->ctmask) ^ info->ctmark; if (info->shift_dir == D_SHIFT_RIGHT) newmark >>= info->shift_bits; else newmark <<= info->shift_bits; - if (ct->mark != newmark) { - ct->mark = newmark; + if (READ_ONCE(ct->mark) != newmark) { + WRITE_ONCE(ct->mark, newmark); nf_conntrack_event_cache(IPCT_MARK, ct); } break; @@ -55,15 +57,15 @@ else new_targetmark <<= info->shift_bits; - newmark = (ct->mark & ~info->ctmask) ^ + newmark = (READ_ONCE(ct->mark) & ~info->ctmask) ^ new_targetmark; - if (ct->mark != newmark) { - ct->mark = newmark; + if (READ_ONCE(ct->mark) != newmark) { + WRITE_ONCE(ct->mark, newmark); nf_conntrack_event_cache(IPCT_MARK, ct); } break; case XT_CONNMARK_RESTORE: - new_targetmark = (ct->mark & info->ctmask); + new_targetmark = (READ_ONCE(ct->mark) & info->ctmask); if (info->shift_dir == D_SHIFT_RIGHT) new_targetmark >>= info->shift_bits; else @@ -126,7 +128,7 @@ if (ct == NULL) return false; - return ((ct->mark & info->mask) == info->mark) ^ info->invert; + return ((READ_ONCE(ct->mark) & info->mask) == info->mark) ^ info->invert; } static int connmark_mt_check(const struct xt_mtchk_param *par) diff -Nru linux-6.0.6/net/netlink/af_netlink.c linux-6.0.12/net/netlink/af_netlink.c --- linux-6.0.6/net/netlink/af_netlink.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/netlink/af_netlink.c 2023-01-18 18:27:39.000000000 +0000 @@ -2440,11 +2440,13 @@ return; } - rep = __nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, - NLMSG_ERROR, payload, flags); + rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, + NLMSG_ERROR, payload, flags); errmsg = nlmsg_data(rep); errmsg->error = err; - memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh)); + unsafe_memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) + ? nlh->nlmsg_len : sizeof(*nlh), + /* Bounds checked by the skb layer. */); if (nlk_has_extack && extack) { if (extack->_msg) { diff -Nru linux-6.0.6/net/nfc/nci/core.c linux-6.0.12/net/nfc/nci/core.c --- linux-6.0.6/net/nfc/nci/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/nfc/nci/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -542,7 +542,7 @@ skb_queue_purge(&ndev->tx_q); ndev->ops->close(ndev); - ndev->flags = 0; + ndev->flags &= BIT(NCI_UNREG); } done: diff -Nru linux-6.0.6/net/nfc/nci/data.c linux-6.0.12/net/nfc/nci/data.c --- linux-6.0.6/net/nfc/nci/data.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/nfc/nci/data.c 2023-01-18 18:27:39.000000000 +0000 @@ -279,8 +279,10 @@ nci_plen(skb->data)); conn_info = nci_get_conn_info_by_conn_id(ndev, nci_conn_id(skb->data)); - if (!conn_info) + if (!conn_info) { + kfree_skb(skb); return; + } /* strip the nci data header */ skb_pull(skb, NCI_DATA_HDR_SIZE); diff -Nru linux-6.0.6/net/openvswitch/conntrack.c linux-6.0.12/net/openvswitch/conntrack.c --- linux-6.0.6/net/openvswitch/conntrack.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/openvswitch/conntrack.c 2023-01-18 18:27:39.000000000 +0000 @@ -152,7 +152,7 @@ static u32 ovs_ct_get_mark(const struct nf_conn *ct) { #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) - return ct ? ct->mark : 0; + return ct ? READ_ONCE(ct->mark) : 0; #else return 0; #endif @@ -340,9 +340,9 @@ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) u32 new_mark; - new_mark = ct_mark | (ct->mark & ~(mask)); - if (ct->mark != new_mark) { - ct->mark = new_mark; + new_mark = ct_mark | (READ_ONCE(ct->mark) & ~(mask)); + if (READ_ONCE(ct->mark) != new_mark) { + WRITE_ONCE(ct->mark, new_mark); if (nf_ct_is_confirmed(ct)) nf_conntrack_event_cache(IPCT_MARK, ct); key->ct.mark = new_mark; diff -Nru linux-6.0.6/net/openvswitch/datapath.c linux-6.0.12/net/openvswitch/datapath.c --- linux-6.0.6/net/openvswitch/datapath.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/openvswitch/datapath.c 2023-01-18 18:27:39.000000000 +0000 @@ -1606,7 +1606,8 @@ if (IS_ERR(dp)) return; - WARN(dp->user_features, "Dropping previously announced user features\n"); + pr_warn("%s: Dropping previously announced user features\n", + ovs_dp_name(dp)); dp->user_features = 0; } diff -Nru linux-6.0.6/net/packet/af_packet.c linux-6.0.12/net/packet/af_packet.c --- linux-6.0.6/net/packet/af_packet.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/packet/af_packet.c 2023-01-18 18:27:39.000000000 +0000 @@ -2293,8 +2293,7 @@ if (skb->ip_summed == CHECKSUM_PARTIAL) status |= TP_STATUS_CSUMNOTREADY; else if (skb->pkt_type != PACKET_OUTGOING && - (skb->ip_summed == CHECKSUM_COMPLETE || - skb_csum_unnecessary(skb))) + skb_csum_unnecessary(skb)) status |= TP_STATUS_CSUM_VALID; if (snaplen > res) @@ -3520,8 +3519,7 @@ if (skb->ip_summed == CHECKSUM_PARTIAL) aux.tp_status |= TP_STATUS_CSUMNOTREADY; else if (skb->pkt_type != PACKET_OUTGOING && - (skb->ip_summed == CHECKSUM_COMPLETE || - skb_csum_unnecessary(skb))) + skb_csum_unnecessary(skb)) aux.tp_status |= TP_STATUS_CSUM_VALID; aux.tp_len = origlen; diff -Nru linux-6.0.6/net/rose/rose_link.c linux-6.0.12/net/rose/rose_link.c --- linux-6.0.6/net/rose/rose_link.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/rose/rose_link.c 2023-01-18 18:27:39.000000000 +0000 @@ -236,6 +236,9 @@ unsigned char *dptr; int len; + if (!neigh->dev) + return; + len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3; if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL) diff -Nru linux-6.0.6/net/rxrpc/ar-internal.h linux-6.0.12/net/rxrpc/ar-internal.h --- linux-6.0.6/net/rxrpc/ar-internal.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/rxrpc/ar-internal.h 2023-01-18 18:27:39.000000000 +0000 @@ -399,6 +399,7 @@ struct rxrpc_bundle { struct rxrpc_conn_parameters params; refcount_t ref; + atomic_t active; /* Number of active users */ unsigned int debug_id; bool try_upgrade; /* True if the bundle is attempting upgrade */ bool alloc_conn; /* True if someone's getting a conn */ diff -Nru linux-6.0.6/net/rxrpc/conn_client.c linux-6.0.12/net/rxrpc/conn_client.c --- linux-6.0.6/net/rxrpc/conn_client.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/rxrpc/conn_client.c 2023-01-18 18:27:39.000000000 +0000 @@ -40,6 +40,8 @@ DEFINE_IDR(rxrpc_client_conn_ids); static DEFINE_SPINLOCK(rxrpc_conn_id_lock); +static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle); + /* * Get a connection ID and epoch for a client connection from the global pool. * The connection struct pointer is then recorded in the idr radix tree. The @@ -123,6 +125,7 @@ bundle->params = *cp; rxrpc_get_peer(bundle->params.peer); refcount_set(&bundle->ref, 1); + atomic_set(&bundle->active, 1); spin_lock_init(&bundle->channel_lock); INIT_LIST_HEAD(&bundle->waiting_calls); } @@ -149,7 +152,7 @@ dead = __refcount_dec_and_test(&bundle->ref, &r); - _debug("PUT B=%x %d", d, r); + _debug("PUT B=%x %d", d, r - 1); if (dead) rxrpc_free_bundle(bundle); } @@ -338,6 +341,7 @@ rxrpc_free_bundle(candidate); found_bundle: rxrpc_get_bundle(bundle); + atomic_inc(&bundle->active); spin_unlock(&local->client_bundles_lock); _leave(" = %u [found]", bundle->debug_id); return bundle; @@ -435,6 +439,7 @@ if (old) trace_rxrpc_client(old, -1, rxrpc_client_replace); candidate->bundle_shift = shift; + atomic_inc(&bundle->active); bundle->conns[i] = candidate; for (j = 0; j < RXRPC_MAXCALLS; j++) set_bit(shift + j, &bundle->avail_chans); @@ -725,6 +730,7 @@ smp_rmb(); out_put_bundle: + rxrpc_deactivate_bundle(bundle); rxrpc_put_bundle(bundle); out: _leave(" = %d", ret); @@ -900,9 +906,8 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn) { struct rxrpc_bundle *bundle = conn->bundle; - struct rxrpc_local *local = bundle->params.local; unsigned int bindex; - bool need_drop = false, need_put = false; + bool need_drop = false; int i; _enter("C=%x", conn->debug_id); @@ -921,15 +926,22 @@ } spin_unlock(&bundle->channel_lock); - /* If there are no more connections, remove the bundle */ - if (!bundle->avail_chans) { - _debug("maybe unbundle"); - spin_lock(&local->client_bundles_lock); - - for (i = 0; i < ARRAY_SIZE(bundle->conns); i++) - if (bundle->conns[i]) - break; - if (i == ARRAY_SIZE(bundle->conns) && !bundle->params.exclusive) { + if (need_drop) { + rxrpc_deactivate_bundle(bundle); + rxrpc_put_connection(conn); + } +} + +/* + * Drop the active count on a bundle. + */ +static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle) +{ + struct rxrpc_local *local = bundle->params.local; + bool need_put = false; + + if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) { + if (!bundle->params.exclusive) { _debug("erase bundle"); rb_erase(&bundle->local_node, &local->client_bundles); need_put = true; @@ -939,10 +951,6 @@ if (need_put) rxrpc_put_bundle(bundle); } - - if (need_drop) - rxrpc_put_connection(conn); - _leave(""); } /* diff -Nru linux-6.0.6/net/sched/act_connmark.c linux-6.0.12/net/sched/act_connmark.c --- linux-6.0.6/net/sched/act_connmark.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sched/act_connmark.c 2023-01-18 18:27:39.000000000 +0000 @@ -62,7 +62,7 @@ c = nf_ct_get(skb, &ctinfo); if (c) { - skb->mark = c->mark; + skb->mark = READ_ONCE(c->mark); /* using overlimits stats to count how many packets marked */ ca->tcf_qstats.overlimits++; goto out; @@ -82,7 +82,7 @@ c = nf_ct_tuplehash_to_ctrack(thash); /* using overlimits stats to count how many packets marked */ ca->tcf_qstats.overlimits++; - skb->mark = c->mark; + skb->mark = READ_ONCE(c->mark); nf_ct_put(c); out: diff -Nru linux-6.0.6/net/sched/act_ct.c linux-6.0.12/net/sched/act_ct.c --- linux-6.0.6/net/sched/act_ct.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sched/act_ct.c 2023-01-18 18:27:39.000000000 +0000 @@ -178,7 +178,7 @@ entry = tcf_ct_flow_table_flow_action_get_next(action); entry->id = FLOW_ACTION_CT_METADATA; #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) - entry->ct_metadata.mark = ct->mark; + entry->ct_metadata.mark = READ_ONCE(ct->mark); #endif ctinfo = dir == IP_CT_DIR_ORIGINAL ? IP_CT_ESTABLISHED : IP_CT_ESTABLISHED_REPLY; @@ -940,9 +940,9 @@ if (!mask) return; - new_mark = mark | (ct->mark & ~(mask)); - if (ct->mark != new_mark) { - ct->mark = new_mark; + new_mark = mark | (READ_ONCE(ct->mark) & ~(mask)); + if (READ_ONCE(ct->mark) != new_mark) { + WRITE_ONCE(ct->mark, new_mark); if (nf_ct_is_confirmed(ct)) nf_conntrack_event_cache(IPCT_MARK, ct); } diff -Nru linux-6.0.6/net/sched/act_ctinfo.c linux-6.0.12/net/sched/act_ctinfo.c --- linux-6.0.6/net/sched/act_ctinfo.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sched/act_ctinfo.c 2023-01-18 18:27:39.000000000 +0000 @@ -33,7 +33,7 @@ { u8 dscp, newdscp; - newdscp = (((ct->mark & cp->dscpmask) >> cp->dscpmaskshift) << 2) & + newdscp = (((READ_ONCE(ct->mark) & cp->dscpmask) >> cp->dscpmaskshift) << 2) & ~INET_ECN_MASK; switch (proto) { @@ -73,7 +73,7 @@ struct sk_buff *skb) { ca->stats_cpmark_set++; - skb->mark = ct->mark & cp->cpmarkmask; + skb->mark = READ_ONCE(ct->mark) & cp->cpmarkmask; } static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a, @@ -131,7 +131,7 @@ } if (cp->mode & CTINFO_MODE_DSCP) - if (!cp->dscpstatemask || (ct->mark & cp->dscpstatemask)) + if (!cp->dscpstatemask || (READ_ONCE(ct->mark) & cp->dscpstatemask)) tcf_ctinfo_dscp_set(ct, ca, cp, skb, wlen, proto); if (cp->mode & CTINFO_MODE_CPMARK) diff -Nru linux-6.0.6/net/sched/Kconfig linux-6.0.12/net/sched/Kconfig --- linux-6.0.6/net/sched/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sched/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -976,7 +976,7 @@ config NET_ACT_CT tristate "connection tracking tc action" - depends on NET_CLS_ACT && NF_CONNTRACK && NF_NAT && NF_FLOW_TABLE + depends on NET_CLS_ACT && NF_CONNTRACK && (!NF_NAT || NF_NAT) && NF_FLOW_TABLE help Say Y here to allow sending the packets to conntrack module. diff -Nru linux-6.0.6/net/sched/sch_red.c linux-6.0.12/net/sched/sch_red.c --- linux-6.0.6/net/sched/sch_red.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sched/sch_red.c 2023-01-18 18:27:39.000000000 +0000 @@ -72,6 +72,7 @@ { struct red_sched_data *q = qdisc_priv(sch); struct Qdisc *child = q->qdisc; + unsigned int len; int ret; q->vars.qavg = red_calc_qavg(&q->parms, @@ -126,9 +127,10 @@ break; } + len = qdisc_pkt_len(skb); ret = qdisc_enqueue(skb, child, to_free); if (likely(ret == NET_XMIT_SUCCESS)) { - qdisc_qstats_backlog_inc(sch, skb); + sch->qstats.backlog += len; sch->q.qlen++; } else if (net_xmit_drop_count(ret)) { q->stats.pdrop++; diff -Nru linux-6.0.6/net/sctp/outqueue.c linux-6.0.12/net/sctp/outqueue.c --- linux-6.0.6/net/sctp/outqueue.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sctp/outqueue.c 2023-01-18 18:27:39.000000000 +0000 @@ -384,6 +384,7 @@ { struct sctp_outq *q = &asoc->outqueue; struct sctp_chunk *chk, *temp; + struct sctp_stream_out *sout; q->sched->unsched_all(&asoc->stream); @@ -398,12 +399,14 @@ sctp_sched_dequeue_common(q, chk); asoc->sent_cnt_removable--; asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; - if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) { - struct sctp_stream_out *streamout = - SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream); - streamout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; - } + sout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream); + sout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; + + /* clear out_curr if all frag chunks are pruned */ + if (asoc->stream.out_curr == sout && + list_is_last(&chk->frag_list, &chk->msg->chunks)) + asoc->stream.out_curr = NULL; msg_len -= chk->skb->truesize + sizeof(struct sctp_chunk); sctp_chunk_free(chk); diff -Nru linux-6.0.6/net/sctp/stream.c linux-6.0.12/net/sctp/stream.c --- linux-6.0.6/net/sctp/stream.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sctp/stream.c 2023-01-18 18:27:39.000000000 +0000 @@ -52,6 +52,19 @@ } } +static void sctp_stream_free_ext(struct sctp_stream *stream, __u16 sid) +{ + struct sctp_sched_ops *sched; + + if (!SCTP_SO(stream, sid)->ext) + return; + + sched = sctp_sched_ops_from_stream(stream); + sched->free_sid(stream, sid); + kfree(SCTP_SO(stream, sid)->ext); + SCTP_SO(stream, sid)->ext = NULL; +} + /* Migrates chunks from stream queues to new stream queues if needed, * but not across associations. Also, removes those chunks to streams * higher than the new max. @@ -70,16 +83,14 @@ * sctp_stream_update will swap ->out pointers. */ for (i = 0; i < outcnt; i++) { - kfree(SCTP_SO(new, i)->ext); + sctp_stream_free_ext(new, i); SCTP_SO(new, i)->ext = SCTP_SO(stream, i)->ext; SCTP_SO(stream, i)->ext = NULL; } } - for (i = outcnt; i < stream->outcnt; i++) { - kfree(SCTP_SO(stream, i)->ext); - SCTP_SO(stream, i)->ext = NULL; - } + for (i = outcnt; i < stream->outcnt; i++) + sctp_stream_free_ext(stream, i); } static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, @@ -174,9 +185,9 @@ struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream); int i; - sched->free(stream); + sched->unsched_all(stream); for (i = 0; i < stream->outcnt; i++) - kfree(SCTP_SO(stream, i)->ext); + sctp_stream_free_ext(stream, i); genradix_free(&stream->out); genradix_free(&stream->in); } diff -Nru linux-6.0.6/net/sctp/stream_sched.c linux-6.0.12/net/sctp/stream_sched.c --- linux-6.0.6/net/sctp/stream_sched.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sctp/stream_sched.c 2023-01-18 18:27:39.000000000 +0000 @@ -46,6 +46,10 @@ return 0; } +static void sctp_sched_fcfs_free_sid(struct sctp_stream *stream, __u16 sid) +{ +} + static void sctp_sched_fcfs_free(struct sctp_stream *stream) { } @@ -96,6 +100,7 @@ .get = sctp_sched_fcfs_get, .init = sctp_sched_fcfs_init, .init_sid = sctp_sched_fcfs_init_sid, + .free_sid = sctp_sched_fcfs_free_sid, .free = sctp_sched_fcfs_free, .enqueue = sctp_sched_fcfs_enqueue, .dequeue = sctp_sched_fcfs_dequeue, diff -Nru linux-6.0.6/net/sctp/stream_sched_prio.c linux-6.0.12/net/sctp/stream_sched_prio.c --- linux-6.0.6/net/sctp/stream_sched_prio.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sctp/stream_sched_prio.c 2023-01-18 18:27:39.000000000 +0000 @@ -204,6 +204,24 @@ return sctp_sched_prio_set(stream, sid, 0, gfp); } +static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid) +{ + struct sctp_stream_priorities *prio = SCTP_SO(stream, sid)->ext->prio_head; + int i; + + if (!prio) + return; + + SCTP_SO(stream, sid)->ext->prio_head = NULL; + for (i = 0; i < stream->outcnt; i++) { + if (SCTP_SO(stream, i)->ext && + SCTP_SO(stream, i)->ext->prio_head == prio) + return; + } + + kfree(prio); +} + static void sctp_sched_prio_free(struct sctp_stream *stream) { struct sctp_stream_priorities *prio, *n; @@ -323,6 +341,7 @@ .get = sctp_sched_prio_get, .init = sctp_sched_prio_init, .init_sid = sctp_sched_prio_init_sid, + .free_sid = sctp_sched_prio_free_sid, .free = sctp_sched_prio_free, .enqueue = sctp_sched_prio_enqueue, .dequeue = sctp_sched_prio_dequeue, diff -Nru linux-6.0.6/net/sctp/stream_sched_rr.c linux-6.0.12/net/sctp/stream_sched_rr.c --- linux-6.0.6/net/sctp/stream_sched_rr.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sctp/stream_sched_rr.c 2023-01-18 18:27:39.000000000 +0000 @@ -90,6 +90,10 @@ return 0; } +static void sctp_sched_rr_free_sid(struct sctp_stream *stream, __u16 sid) +{ +} + static void sctp_sched_rr_free(struct sctp_stream *stream) { sctp_sched_rr_unsched_all(stream); @@ -177,6 +181,7 @@ .get = sctp_sched_rr_get, .init = sctp_sched_rr_init, .init_sid = sctp_sched_rr_init_sid, + .free_sid = sctp_sched_rr_free_sid, .free = sctp_sched_rr_free, .enqueue = sctp_sched_rr_enqueue, .dequeue = sctp_sched_rr_dequeue, diff -Nru linux-6.0.6/net/smc/af_smc.c linux-6.0.12/net/smc/af_smc.c --- linux-6.0.6/net/smc/af_smc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/smc/af_smc.c 2023-01-18 18:27:39.000000000 +0000 @@ -3380,14 +3380,14 @@ rc = register_pernet_subsys(&smc_net_stat_ops); if (rc) - return rc; + goto out_pernet_subsys; smc_ism_init(); smc_clc_init(); rc = smc_nl_init(); if (rc) - goto out_pernet_subsys; + goto out_pernet_subsys_stat; rc = smc_pnet_init(); if (rc) @@ -3480,6 +3480,8 @@ smc_pnet_exit(); out_nl: smc_nl_exit(); +out_pernet_subsys_stat: + unregister_pernet_subsys(&smc_net_stat_ops); out_pernet_subsys: unregister_pernet_subsys(&smc_net_ops); diff -Nru linux-6.0.6/net/sunrpc/auth_gss/auth_gss.c linux-6.0.12/net/sunrpc/auth_gss/auth_gss.c --- linux-6.0.6/net/sunrpc/auth_gss/auth_gss.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sunrpc/auth_gss/auth_gss.c 2023-01-18 18:27:39.000000000 +0000 @@ -1989,7 +1989,7 @@ goto unwrap_failed; mic.len = len; mic.data = kmalloc(len, GFP_KERNEL); - if (!mic.data) + if (ZERO_OR_NULL_PTR(mic.data)) goto unwrap_failed; if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len)) goto unwrap_failed; diff -Nru linux-6.0.6/net/sunrpc/sysfs.c linux-6.0.12/net/sunrpc/sysfs.c --- linux-6.0.6/net/sunrpc/sysfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/sunrpc/sysfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -518,13 +518,16 @@ struct net *net) { struct rpc_sysfs_client *rpc_client; + struct rpc_sysfs_xprt_switch *xswitch = + (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs; + + if (!xswitch) + return; rpc_client = rpc_sysfs_client_alloc(rpc_sunrpc_client_kobj, net, clnt->cl_clid); if (rpc_client) { char name[] = "switch"; - struct rpc_sysfs_xprt_switch *xswitch = - (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs; int ret; clnt->cl_sysfs = rpc_client; @@ -558,6 +561,8 @@ rpc_xprt_switch->xprt_switch = xprt_switch; rpc_xprt_switch->xprt = xprt; kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_ADD); + } else { + xprt_switch->xps_sysfs = NULL; } } @@ -569,6 +574,9 @@ struct rpc_sysfs_xprt_switch *switch_obj = (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs; + if (!switch_obj) + return; + rpc_xprt = rpc_sysfs_xprt_alloc(&switch_obj->kobject, xprt, gfp_flags); if (rpc_xprt) { xprt->xprt_sysfs = rpc_xprt; diff -Nru linux-6.0.6/net/tipc/crypto.c linux-6.0.12/net/tipc/crypto.c --- linux-6.0.6/net/tipc/crypto.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/tipc/crypto.c 2023-01-18 18:27:39.000000000 +0000 @@ -1971,6 +1971,9 @@ /* Ok, everything's fine, try to synch own keys according to peers' */ tipc_crypto_key_synch(rx, *skb); + /* Re-fetch skb cb as skb might be changed in tipc_msg_validate */ + skb_cb = TIPC_SKB_CB(*skb); + /* Mark skb decrypted */ skb_cb->decrypted = 1; diff -Nru linux-6.0.6/net/tipc/discover.c linux-6.0.12/net/tipc/discover.c --- linux-6.0.6/net/tipc/discover.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/tipc/discover.c 2023-01-18 18:27:39.000000000 +0000 @@ -211,7 +211,10 @@ u32 self; int err; - skb_linearize(skb); + if (skb_linearize(skb)) { + kfree_skb(skb); + return; + } hdr = buf_msg(skb); if (caps & TIPC_NODE_ID128) diff -Nru linux-6.0.6/net/tipc/netlink_compat.c linux-6.0.12/net/tipc/netlink_compat.c --- linux-6.0.6/net/tipc/netlink_compat.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/tipc/netlink_compat.c 2023-01-18 18:27:39.000000000 +0000 @@ -880,7 +880,7 @@ }; ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req); - if (TLV_GET_DATA_LEN(msg->req) < sizeof(struct tipc_name_table_query)) + if (TLV_GET_DATA_LEN(msg->req) < (int)sizeof(struct tipc_name_table_query)) return -EINVAL; depth = ntohl(ntq->depth); diff -Nru linux-6.0.6/net/tipc/topsrv.c linux-6.0.12/net/tipc/topsrv.c --- linux-6.0.6/net/tipc/topsrv.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/tipc/topsrv.c 2023-01-18 18:27:39.000000000 +0000 @@ -176,7 +176,7 @@ conn_put(con); } -static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s) +static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *sock) { struct tipc_conn *con; int ret; @@ -202,10 +202,12 @@ } con->conid = ret; s->idr_in_use++; - spin_unlock_bh(&s->idr_lock); set_bit(CF_CONNECTED, &con->flags); con->server = s; + con->sock = sock; + conn_get(con); + spin_unlock_bh(&s->idr_lock); return con; } @@ -450,17 +452,24 @@ static void tipc_topsrv_accept(struct work_struct *work) { struct tipc_topsrv *srv = container_of(work, struct tipc_topsrv, awork); - struct socket *lsock = srv->listener; - struct socket *newsock; + struct socket *newsock, *lsock; struct tipc_conn *con; struct sock *newsk; int ret; + spin_lock_bh(&srv->idr_lock); + if (!srv->listener) { + spin_unlock_bh(&srv->idr_lock); + return; + } + lsock = srv->listener; + spin_unlock_bh(&srv->idr_lock); + while (1) { ret = kernel_accept(lsock, &newsock, O_NONBLOCK); if (ret < 0) return; - con = tipc_conn_alloc(srv); + con = tipc_conn_alloc(srv, newsock); if (IS_ERR(con)) { ret = PTR_ERR(con); sock_release(newsock); @@ -472,11 +481,11 @@ newsk->sk_data_ready = tipc_conn_data_ready; newsk->sk_write_space = tipc_conn_write_space; newsk->sk_user_data = con; - con->sock = newsock; write_unlock_bh(&newsk->sk_callback_lock); /* Wake up receive process in case of 'SYN+' message */ newsk->sk_data_ready(newsk); + conn_put(con); } } @@ -489,7 +498,7 @@ read_lock_bh(&sk->sk_callback_lock); srv = sk->sk_user_data; - if (srv->listener) + if (srv) queue_work(srv->rcv_wq, &srv->awork); read_unlock_bh(&sk->sk_callback_lock); } @@ -570,17 +579,17 @@ sub.filter = filter; *(u64 *)&sub.usr_handle = (u64)port; - con = tipc_conn_alloc(tipc_topsrv(net)); + con = tipc_conn_alloc(tipc_topsrv(net), NULL); if (IS_ERR(con)) return false; *conid = con->conid; - con->sock = NULL; rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub); - if (rc >= 0) - return true; + if (rc) + conn_put(con); + conn_put(con); - return false; + return !rc; } void tipc_topsrv_kern_unsubscr(struct net *net, int conid) @@ -699,8 +708,9 @@ __module_get(lsock->sk->sk_prot_creator->owner); srv->listener = NULL; spin_unlock_bh(&srv->idr_lock); - sock_release(lsock); + tipc_topsrv_work_stop(srv); + sock_release(lsock); idr_destroy(&srv->conn_idr); kfree(srv); } diff -Nru linux-6.0.6/net/unix/unix_bpf.c linux-6.0.12/net/unix/unix_bpf.c --- linux-6.0.6/net/unix/unix_bpf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/unix/unix_bpf.c 2023-01-18 18:27:39.000000000 +0000 @@ -145,12 +145,12 @@ if (restore) { sk->sk_write_space = psock->saved_write_space; - WRITE_ONCE(sk->sk_prot, psock->sk_proto); + sock_replace_proto(sk, psock->sk_proto); return 0; } unix_dgram_bpf_check_needs_rebuild(psock->sk_proto); - WRITE_ONCE(sk->sk_prot, &unix_dgram_bpf_prot); + sock_replace_proto(sk, &unix_dgram_bpf_prot); return 0; } @@ -158,12 +158,12 @@ { if (restore) { sk->sk_write_space = psock->saved_write_space; - WRITE_ONCE(sk->sk_prot, psock->sk_proto); + sock_replace_proto(sk, psock->sk_proto); return 0; } unix_stream_bpf_check_needs_rebuild(psock->sk_proto); - WRITE_ONCE(sk->sk_prot, &unix_stream_bpf_prot); + sock_replace_proto(sk, &unix_stream_bpf_prot); return 0; } diff -Nru linux-6.0.6/net/vmw_vsock/af_vsock.c linux-6.0.12/net/vmw_vsock/af_vsock.c --- linux-6.0.6/net/vmw_vsock/af_vsock.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/vmw_vsock/af_vsock.c 2023-01-18 18:27:39.000000000 +0000 @@ -1894,8 +1894,11 @@ err = 0; transport = vsk->transport; - while ((data = vsock_connectible_has_data(vsk)) == 0) { + while (1) { prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE); + data = vsock_connectible_has_data(vsk); + if (data != 0) + break; if (sk->sk_err != 0 || (sk->sk_shutdown & RCV_SHUTDOWN) || diff -Nru linux-6.0.6/net/wireless/reg.c linux-6.0.12/net/wireless/reg.c --- linux-6.0.6/net/wireless/reg.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/wireless/reg.c 2023-01-18 18:27:39.000000000 +0000 @@ -1084,6 +1084,8 @@ static int query_regdb_file(const char *alpha2) { + int err; + ASSERT_RTNL(); if (regdb) @@ -1093,9 +1095,13 @@ if (!alpha2) return -ENOMEM; - return request_firmware_nowait(THIS_MODULE, true, "regulatory.db", - ®_pdev->dev, GFP_KERNEL, - (void *)alpha2, regdb_fw_cb); + err = request_firmware_nowait(THIS_MODULE, true, "regulatory.db", + ®_pdev->dev, GFP_KERNEL, + (void *)alpha2, regdb_fw_cb); + if (err) + kfree(alpha2); + + return err; } int reg_reload_regdb(void) diff -Nru linux-6.0.6/net/wireless/scan.c linux-6.0.12/net/wireless/scan.c --- linux-6.0.6/net/wireless/scan.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/wireless/scan.c 2023-01-18 18:27:39.000000000 +0000 @@ -330,7 +330,8 @@ * determine if they are the same ie. */ if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) { - if (!memcmp(tmp_old + 2, tmp + 2, 5)) { + if (tmp_old[1] >= 5 && tmp[1] >= 5 && + !memcmp(tmp_old + 2, tmp + 2, 5)) { /* same vendor ie, copy from * subelement */ @@ -1674,7 +1675,9 @@ if (old == rcu_access_pointer(known->pub.ies)) rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies); - cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old); + cfg80211_update_hidden_bsses(known, + rcu_access_pointer(new->pub.beacon_ies), + old); if (old) kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); @@ -2524,10 +2527,15 @@ const struct cfg80211_bss_ies *ies1, *ies2; size_t ielen = len - offsetof(struct ieee80211_mgmt, u.probe_resp.variable); - struct cfg80211_non_tx_bss non_tx_data; + struct cfg80211_non_tx_bss non_tx_data = {}; res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt, len, gfp); + + /* don't do any further MBSSID handling for S1G */ + if (ieee80211_is_s1g_beacon(mgmt->frame_control)) + return res; + if (!res || !wiphy->support_mbssid || !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) return res; diff -Nru linux-6.0.6/net/wireless/util.c linux-6.0.12/net/wireless/util.c --- linux-6.0.6/net/wireless/util.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/wireless/util.c 2023-01-18 18:27:39.000000000 +0000 @@ -1555,10 +1555,12 @@ tmp = result; tmp *= SCALE; do_div(tmp, mcs_divisors[rate->mcs]); - result = tmp; /* and take NSS */ - result = (result * rate->nss) / 8; + tmp *= rate->nss; + do_div(tmp, 8); + + result = tmp; return result / 10000; } diff -Nru linux-6.0.6/net/wireless/wext-core.c linux-6.0.12/net/wireless/wext-core.c --- linux-6.0.6/net/wireless/wext-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/wireless/wext-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -468,6 +468,7 @@ struct __compat_iw_event *compat_event; struct compat_iw_point compat_wrqu; struct sk_buff *compskb; + int ptr_len; #endif /* @@ -582,6 +583,9 @@ nlmsg_end(skb, nlh); #ifdef CONFIG_COMPAT hdr_len = compat_event_type_size[descr->header_type]; + + /* ptr_len is remaining size in event header apart from LCP */ + ptr_len = hdr_len - IW_EV_COMPAT_LCP_LEN; event_len = hdr_len + extra_len; compskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); @@ -612,16 +616,15 @@ if (descr->header_type == IW_HEADER_TYPE_POINT) { compat_wrqu.length = wrqu->data.length; compat_wrqu.flags = wrqu->data.flags; - memcpy(&compat_event->pointer, - ((char *) &compat_wrqu) + IW_EV_COMPAT_POINT_OFF, - hdr_len - IW_EV_COMPAT_LCP_LEN); + memcpy(compat_event->ptr_bytes, + ((char *)&compat_wrqu) + IW_EV_COMPAT_POINT_OFF, + ptr_len); if (extra_len) - memcpy(((char *) compat_event) + hdr_len, - extra, extra_len); + memcpy(&compat_event->ptr_bytes[ptr_len], + extra, extra_len); } else { /* extra_len must be zero, so no if (extra) needed */ - memcpy(&compat_event->pointer, wrqu, - hdr_len - IW_EV_COMPAT_LCP_LEN); + memcpy(compat_event->ptr_bytes, wrqu, ptr_len); } nlmsg_end(compskb, nlh); diff -Nru linux-6.0.6/net/x25/x25_dev.c linux-6.0.12/net/x25/x25_dev.c --- linux-6.0.6/net/x25/x25_dev.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/x25/x25_dev.c 2023-01-18 18:27:39.000000000 +0000 @@ -117,7 +117,7 @@ if (!pskb_may_pull(skb, 1)) { x25_neigh_put(nb); - return 0; + goto drop; } switch (skb->data[0]) { diff -Nru linux-6.0.6/net/xfrm/xfrm_device.c linux-6.0.12/net/xfrm/xfrm_device.c --- linux-6.0.6/net/xfrm/xfrm_device.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/xfrm/xfrm_device.c 2023-01-18 18:27:39.000000000 +0000 @@ -97,6 +97,18 @@ } } +static inline bool xmit_xfrm_check_overflow(struct sk_buff *skb) +{ + struct xfrm_offload *xo = xfrm_offload(skb); + __u32 seq = xo->seq.low; + + seq += skb_shinfo(skb)->gso_segs; + if (unlikely(seq < xo->seq.low)) + return true; + + return false; +} + struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again) { int err; @@ -134,7 +146,8 @@ return skb; } - if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) { + if (skb_is_gso(skb) && (unlikely(x->xso.dev != dev) || + unlikely(xmit_xfrm_check_overflow(skb)))) { struct sk_buff *segs; /* Packet got rerouted, fixup features and segment it. */ diff -Nru linux-6.0.6/net/xfrm/xfrm_replay.c linux-6.0.12/net/xfrm/xfrm_replay.c --- linux-6.0.6/net/xfrm/xfrm_replay.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/net/xfrm/xfrm_replay.c 2023-01-18 18:27:39.000000000 +0000 @@ -714,7 +714,7 @@ oseq += skb_shinfo(skb)->gso_segs; } - if (unlikely(oseq < replay_esn->oseq)) { + if (unlikely(xo->seq.low < replay_esn->oseq)) { XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi; xo->seq.hi = oseq_hi; replay_esn->oseq_hi = oseq_hi; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/am335x-pcm-953.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm/am335x-pcm-953.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm/am335x-pcm-953.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/am335x-pcm-953.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -12,22 +12,20 @@ compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx"; /* Power */ - regulators { - vcc3v3: fixedregulator@1 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - }; + vcc3v3: fixedregulator1 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; - vcc1v8: fixedregulator@2 { - compatible = "regulator-fixed"; - regulator-name = "vcc1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - }; + vcc1v8: fixedregulator2 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; }; /* User IO */ diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/at91rm9200.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm/at91rm9200.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm/at91rm9200.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/at91rm9200.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -660,7 +660,7 @@ compatible = "atmel,at91rm9200-udc"; reg = <0xfffb0000 0x4000>; interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 2>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 1>; clock-names = "pclk", "hclk"; status = "disabled"; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/at91sam9g20ek_common.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm/at91sam9g20ek_common.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm/at91sam9g20ek_common.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/at91sam9g20ek_common.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -39,6 +39,13 @@ }; + usb1 { + pinctrl_usb1_vbus_gpio: usb1_vbus_gpio { + atmel,pins = + ; /* PC5 GPIO */ + }; + }; + mmc0_slot1 { pinctrl_board_mmc0_slot1: mmc0_slot1-board { atmel,pins = @@ -84,6 +91,8 @@ }; usb1: gadget@fffa4000 { + pinctrl-0 = <&pinctrl_usb1_vbus_gpio>; + pinctrl-names = "default"; atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6qdl-gw5910.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6qdl-gw5910.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6qdl-gw5910.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6qdl-gw5910.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -29,7 +29,7 @@ user-pb { label = "user_pb"; - gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>; + gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>; linux,code = ; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6qdl-gw5913.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6qdl-gw5913.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6qdl-gw5913.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6qdl-gw5913.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -26,7 +26,7 @@ user-pb { label = "user_pb"; - gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>; + gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>; linux,code = ; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6q-prti6q.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6q-prti6q.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6q-prti6q.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6q-prti6q.dts 2023-01-18 18:27:39.000000000 +0000 @@ -364,8 +364,8 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_wifi>; interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>; - ref-clock-frequency = "38400000"; - tcxo-clock-frequency = "19200000"; + ref-clock-frequency = <38400000>; + tcxo-clock-frequency = <19200000>; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6qp-yapp4-crux-plus.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6qp-yapp4-crux-plus.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6qp-yapp4-crux-plus.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6qp-yapp4-crux-plus.dts 2023-01-18 18:27:39.000000000 +0000 @@ -33,6 +33,10 @@ status = "okay"; }; +®_pu { + regulator-always-on; +}; + ®_usb_h1_vbus { status = "okay"; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6q-yapp4-crux.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6q-yapp4-crux.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/imx6q-yapp4-crux.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/imx6q-yapp4-crux.dts 2023-01-18 18:27:39.000000000 +0000 @@ -33,6 +33,10 @@ status = "okay"; }; +®_pu { + regulator-always-on; +}; + ®_usb_h1_vbus { status = "okay"; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/imx7s.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm/imx7s.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm/imx7s.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/imx7s.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -1270,10 +1270,10 @@ clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; }; - gpmi: nand-controller@33002000{ + gpmi: nand-controller@33002000 { compatible = "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/sama7g5-pinfunc.h linux-6.0.12/scripts/dtc/include-prefixes/arm/sama7g5-pinfunc.h --- linux-6.0.6/scripts/dtc/include-prefixes/arm/sama7g5-pinfunc.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/sama7g5-pinfunc.h 2023-01-18 18:27:39.000000000 +0000 @@ -261,7 +261,7 @@ #define PIN_PB2__FLEXCOM6_IO0 PINMUX_PIN(PIN_PB2, 2, 1) #define PIN_PB2__ADTRG PINMUX_PIN(PIN_PB2, 3, 1) #define PIN_PB2__A20 PINMUX_PIN(PIN_PB2, 4, 1) -#define PIN_PB2__FLEXCOM11_IO0 PINMUX_PIN(PIN_PB2, 6, 3) +#define PIN_PB2__FLEXCOM11_IO1 PINMUX_PIN(PIN_PB2, 6, 3) #define PIN_PB3 35 #define PIN_PB3__GPIO PINMUX_PIN(PIN_PB3, 0, 0) #define PIN_PB3__RF1 PINMUX_PIN(PIN_PB3, 1, 1) diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-href.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-href.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-href.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-href.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -24,6 +24,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-snowball.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-snowball.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-snowball.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-snowball.dts 2023-01-18 18:27:39.000000000 +0000 @@ -28,6 +28,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-codina.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-codina.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-codina.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-codina.dts 2023-01-18 18:27:39.000000000 +0000 @@ -57,6 +57,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-codina-tmo.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-codina-tmo.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-codina-tmo.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-codina-tmo.dts 2023-01-18 18:27:39.000000000 +0000 @@ -44,6 +44,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-gavini.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-gavini.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-gavini.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-gavini.dts 2023-01-18 18:27:39.000000000 +0000 @@ -30,6 +30,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-golden.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-golden.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-golden.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-golden.dts 2023-01-18 18:27:39.000000000 +0000 @@ -35,6 +35,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-janice.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-janice.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-janice.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-janice.dts 2023-01-18 18:27:39.000000000 +0000 @@ -30,6 +30,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-kyle.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-kyle.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-kyle.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-kyle.dts 2023-01-18 18:27:39.000000000 +0000 @@ -34,6 +34,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-skomer.dts linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-skomer.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-skomer.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm/ste-ux500-samsung-skomer.dts 2023-01-18 18:27:39.000000000 +0000 @@ -30,6 +30,14 @@ polling-delay = <0>; polling-delay-passive = <0>; thermal-sensors = <&bat_therm>; + + trips { + battery-crit-hi { + temperature = <70000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/arm/juno-base.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/arm/juno-base.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/arm/juno-base.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/arm/juno-base.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -751,12 +751,26 @@ polling-delay = <1000>; polling-delay-passive = <100>; thermal-sensors = <&scpi_sensors0 0>; + trips { + pmic_crit0: trip0 { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; soc { polling-delay = <1000>; polling-delay-passive = <100>; thermal-sensors = <&scpi_sensors0 3>; + trips { + soc_crit0: trip0 { + temperature = <80000>; + hysteresis = <2000>; + type = "critical"; + }; + }; }; big_cluster_thermal_zone: big-cluster { diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/fsl-ls1088a.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/fsl-ls1088a.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/fsl-ls1088a.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/fsl-ls1088a.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -779,6 +779,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(1)>; status = "disabled"; }; @@ -788,6 +791,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(1)>; status = "disabled"; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/fsl-ls208xa.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/fsl-ls208xa.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/fsl-ls208xa.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/fsl-ls208xa.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -533,6 +533,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(2)>; status = "disabled"; }; @@ -542,6 +545,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(2)>; status = "disabled"; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/fsl-lx2160a.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/fsl-lx2160a.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/fsl-lx2160a.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/fsl-lx2160a.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -1385,6 +1385,9 @@ #address-cells = <1>; #size-cells = <0>; little-endian; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(2)>; status = "disabled"; }; @@ -1395,6 +1398,9 @@ little-endian; #address-cells = <1>; #size-cells = <0>; + clock-frequency = <2500000>; + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL + QORIQ_CLK_PLL_DIV(2)>; status = "disabled"; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mm.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mm.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mm.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mm.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -276,6 +276,7 @@ assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; clock-names = "main_clk"; + power-domains = <&pgc_otg1>; }; usbphynop2: usbphynop2 { @@ -285,6 +286,7 @@ assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; clock-names = "main_clk"; + power-domains = <&pgc_otg2>; }; soc: soc@0 { @@ -674,13 +676,11 @@ pgc_otg1: power-domain@2 { #power-domain-cells = <0>; reg = ; - power-domains = <&pgc_hsiomix>; }; pgc_otg2: power-domain@3 { #power-domain-cells = <0>; reg = ; - power-domains = <&pgc_hsiomix>; }; pgc_gpumix: power-domain@4 { @@ -1186,7 +1186,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; phys = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>; - power-domains = <&pgc_otg1>; + power-domains = <&pgc_hsiomix>; status = "disabled"; }; @@ -1206,7 +1206,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; phys = <&usbphynop2>; fsl,usbmisc = <&usbmisc2 0>; - power-domains = <&pgc_otg2>; + power-domains = <&pgc_hsiomix>; status = "disabled"; }; @@ -1244,10 +1244,10 @@ clocks = <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>; }; - gpmi: nand-controller@33002000{ + gpmi: nand-controller@33002000 { compatible = "fsl,imx8mm-gpmi-nand", "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mm-mx8menlo.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mm-mx8menlo.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mm-mx8menlo.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mm-mx8menlo.dts 2023-01-18 18:27:39.000000000 +0000 @@ -250,21 +250,21 @@ /* SODIMM 96 */ MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x1c4 /* CPLD_D[7] */ - MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x1c4 + MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x184 /* CPLD_D[6] */ - MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x1c4 + MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x184 /* CPLD_D[5] */ - MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x1c4 + MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x184 /* CPLD_D[4] */ - MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x1c4 + MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x184 /* CPLD_D[3] */ - MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x1c4 + MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x184 /* CPLD_D[2] */ - MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x1c4 + MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x184 /* CPLD_D[1] */ - MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x1c4 + MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x184 /* CPLD_D[0] */ - MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x1c4 + MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x184 /* KBD_intK */ MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x1c4 /* DISP_reset */ diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mm-tqma8mqml-mba8mx.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mm-tqma8mqml-mba8mx.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mm-tqma8mqml-mba8mx.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mm-tqma8mqml-mba8mx.dts 2023-01-18 18:27:39.000000000 +0000 @@ -34,11 +34,25 @@ off-on-delay-us = <12000>; }; - extcon_usbotg1: extcon-usbotg1 { - compatible = "linux,extcon-usb-gpio"; + connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + type = "micro"; + label = "X19"; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usb1_extcon>; - id-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pinctrl_usb1_connector>; + id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usb_dr_connector: endpoint { + remote-endpoint = <&usb1_drd_sw>; + }; + }; + }; }; }; @@ -105,13 +119,19 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotg1>; dr_mode = "otg"; - extcon = <&extcon_usbotg1>; srp-disable; hnp-disable; adp-disable; power-active-high; over-current-active-low; + usb-role-switch; status = "okay"; + + port { + usb1_drd_sw: endpoint { + remote-endpoint = <&usb_dr_connector>; + }; + }; }; &usbotg2 { @@ -231,7 +251,7 @@ ; }; - pinctrl_usb1_extcon: usb1-extcongrp { + pinctrl_usb1_connector: usb1-connectorgrp { fsl,pins = ; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mn.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mn.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mn.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mn.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -662,7 +662,6 @@ pgc_otg1: power-domain@1 { #power-domain-cells = <0>; reg = ; - power-domains = <&pgc_hsiomix>; }; pgc_gpumix: power-domain@2 { @@ -1076,7 +1075,7 @@ assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>; phys = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>; - power-domains = <&pgc_otg1>; + power-domains = <&pgc_hsiomix>; status = "disabled"; }; @@ -1103,7 +1102,7 @@ gpmi: nand-controller@33002000 { compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; @@ -1175,5 +1174,6 @@ assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>; assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>; clock-names = "main_clk"; + power-domains = <&pgc_otg1>; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mp-verdin.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mp-verdin.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8mp-verdin.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8mp-verdin.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -339,16 +339,6 @@ "SODIMM_82", "SODIMM_70", "SODIMM_72"; - - ctrl-sleep-moci-hog { - gpio-hog; - /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */ - gpios = <29 GPIO_ACTIVE_HIGH>; - line-name = "CTRL_SLEEP_MOCI#"; - output-high; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_ctrl_sleep_moci>; - }; }; &gpio3 { @@ -417,6 +407,16 @@ "SODIMM_256", "SODIMM_48", "SODIMM_44"; + + ctrl-sleep-moci-hog { + gpio-hog; + /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */ + gpios = <29 GPIO_ACTIVE_HIGH>; + line-name = "CTRL_SLEEP_MOCI#"; + output-high; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ctrl_sleep_moci>; + }; }; /* On-module I2C */ diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8-ss-conn.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8-ss-conn.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx8-ss-conn.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx8-ss-conn.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -38,9 +38,9 @@ interrupts = ; reg = <0x5b010000 0x10000>; clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>, - <&sdhc0_lpcg IMX_LPCG_CLK_5>, - <&sdhc0_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "per", "ahb"; + <&sdhc0_lpcg IMX_LPCG_CLK_0>, + <&sdhc0_lpcg IMX_LPCG_CLK_5>; + clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_0>; status = "disabled"; }; @@ -49,9 +49,9 @@ interrupts = ; reg = <0x5b020000 0x10000>; clocks = <&sdhc1_lpcg IMX_LPCG_CLK_4>, - <&sdhc1_lpcg IMX_LPCG_CLK_5>, - <&sdhc1_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "per", "ahb"; + <&sdhc1_lpcg IMX_LPCG_CLK_0>, + <&sdhc1_lpcg IMX_LPCG_CLK_5>; + clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_1>; fsl,tuning-start-tap = <20>; fsl,tuning-step = <2>; @@ -62,9 +62,9 @@ interrupts = ; reg = <0x5b030000 0x10000>; clocks = <&sdhc2_lpcg IMX_LPCG_CLK_4>, - <&sdhc2_lpcg IMX_LPCG_CLK_5>, - <&sdhc2_lpcg IMX_LPCG_CLK_0>; - clock-names = "ipg", "per", "ahb"; + <&sdhc2_lpcg IMX_LPCG_CLK_0>, + <&sdhc2_lpcg IMX_LPCG_CLK_5>; + clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_2>; status = "disabled"; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx93.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx93.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/freescale/imx93.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/freescale/imx93.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -295,7 +295,10 @@ interrupts = ; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 32 32>; + clocks = <&clk IMX93_CLK_GPIO2_GATE>, + <&clk IMX93_CLK_GPIO2_GATE>; + clock-names = "gpio", "port"; + gpio-ranges = <&iomuxc 0 4 30>; }; gpio3: gpio@43820080 { @@ -306,7 +309,11 @@ interrupts = ; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 64 32>; + clocks = <&clk IMX93_CLK_GPIO3_GATE>, + <&clk IMX93_CLK_GPIO3_GATE>; + clock-names = "gpio", "port"; + gpio-ranges = <&iomuxc 0 84 8>, <&iomuxc 8 66 18>, + <&iomuxc 26 34 2>, <&iomuxc 28 0 4>; }; gpio4: gpio@43830080 { @@ -317,7 +324,10 @@ interrupts = ; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 96 32>; + clocks = <&clk IMX93_CLK_GPIO4_GATE>, + <&clk IMX93_CLK_GPIO4_GATE>; + clock-names = "gpio", "port"; + gpio-ranges = <&iomuxc 0 38 28>, <&iomuxc 28 36 2>; }; gpio1: gpio@47400080 { @@ -328,7 +338,10 @@ interrupts = ; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 0 32>; + clocks = <&clk IMX93_CLK_GPIO1_GATE>, + <&clk IMX93_CLK_GPIO1_GATE>; + clock-names = "gpio", "port"; + gpio-ranges = <&iomuxc 0 92 16>; }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/ipq8074.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/ipq8074.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/ipq8074.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/ipq8074.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -668,7 +668,7 @@ apcs_glb: mailbox@b111000 { compatible = "qcom,ipq8074-apcs-apps-global"; - reg = <0x0b111000 0x6000>; + reg = <0x0b111000 0x1000>; #clock-cells = <1>; #mbox-cells = <1>; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sa8155p-adp.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sa8155p-adp.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sa8155p-adp.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sa8155p-adp.dts 2023-01-18 18:27:39.000000000 +0000 @@ -43,7 +43,6 @@ regulator-always-on; regulator-boot-on; - regulator-allow-set-load; vin-supply = <&vreg_3p3>; }; @@ -137,6 +136,9 @@ regulator-max-microvolt = <880000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7a_1p8: ldo7 { @@ -152,6 +154,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l11a_0p8: ldo11 { @@ -258,6 +263,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7c_1p8: ldo7 { @@ -273,6 +281,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l10c_3p3: ldo10 { diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sa8295p-adp.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sa8295p-adp.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sa8295p-adp.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sa8295p-adp.dts 2023-01-18 18:27:39.000000000 +0000 @@ -83,6 +83,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l4c: ldo4 { @@ -98,6 +101,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7c: ldo7 { @@ -113,6 +119,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l17c: ldo17 { @@ -121,6 +130,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sc7280.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sc7280.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sc7280.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sc7280.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -2177,7 +2177,8 @@ lpass_audiocc: clock-controller@3300000 { compatible = "qcom,sc7280-lpassaudiocc"; - reg = <0 0x03300000 0 0x30000>; + reg = <0 0x03300000 0 0x30000>, + <0 0x032a9000 0 0x1000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>; clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src"; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sc8280xp-crd.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sc8280xp-crd.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sc8280xp-crd.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sc8280xp-crd.dts 2023-01-18 18:27:39.000000000 +0000 @@ -124,6 +124,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l13c: ldo13 { @@ -146,6 +149,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l4d: ldo4 { diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sc8280xp.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sc8280xp.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sc8280xp.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sc8280xp.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -885,13 +885,13 @@ ufs_mem_phy: phy@1d87000 { compatible = "qcom,sc8280xp-qmp-ufs-phy"; - reg = <0 0x01d87000 0 0xe10>; + reg = <0 0x01d87000 0 0x1c8>; #address-cells = <2>; #size-cells = <2>; ranges; clock-names = "ref", "ref_aux"; - clocks = <&rpmhcc RPMH_CXO_CLK>, + clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; resets = <&ufs_mem_hc 0>; @@ -953,13 +953,13 @@ ufs_card_phy: phy@1da7000 { compatible = "qcom,sc8280xp-qmp-ufs-phy"; - reg = <0 0x01da7000 0 0xe10>; + reg = <0 0x01da7000 0 0x1c8>; #address-cells = <2>; #size-cells = <2>; ranges; clock-names = "ref", "ref_aux"; - clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>, + clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_CARD_PHY_AUX_CLK>; resets = <&ufs_card_hc 0>; @@ -1181,26 +1181,16 @@ usb_0_ssphy: usb3-phy@88eb400 { reg = <0 0x088eb400 0 0x100>, <0 0x088eb600 0 0x3ec>, - <0 0x088ec400 0 0x1f0>, + <0 0x088ec400 0 0x364>, <0 0x088eba00 0 0x100>, <0 0x088ebc00 0 0x3ec>, - <0 0x088ec700 0 0x64>; + <0 0x088ec200 0 0x18>; #phy-cells = <0>; #clock-cells = <0>; clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; clock-names = "pipe0"; clock-output-names = "usb0_phy_pipe_clk_src"; }; - - usb_0_dpphy: dp-phy@88ed200 { - reg = <0 0x088ed200 0 0x200>, - <0 0x088ed400 0 0x200>, - <0 0x088eda00 0 0x200>, - <0 0x088ea600 0 0x200>, - <0 0x088ea800 0 0x200>; - #clock-cells = <1>; - #phy-cells = <0>; - }; }; usb_1_hsphy: phy@8902000 { @@ -1242,8 +1232,8 @@ usb_1_ssphy: usb3-phy@8903400 { reg = <0 0x08903400 0 0x100>, - <0 0x08903c00 0 0x3ec>, - <0 0x08904400 0 0x1f0>, + <0 0x08903600 0 0x3ec>, + <0 0x08904400 0 0x364>, <0 0x08903a00 0 0x100>, <0 0x08903c00 0 0x3ec>, <0 0x08904200 0 0x18>; @@ -1253,16 +1243,6 @@ clock-names = "pipe0"; clock-output-names = "usb1_phy_pipe_clk_src"; }; - - usb_1_dpphy: dp-phy@8904200 { - reg = <0 0x08904200 0 0x200>, - <0 0x08904400 0 0x200>, - <0 0x08904a00 0 0x200>, - <0 0x08904600 0 0x200>, - <0 0x08904800 0 0x200>; - #clock-cells = <1>; - #phy-cells = <0>; - }; }; system-cache-controller@9200000 { diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sm8150-sony-xperia-kumano.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sm8150-sony-xperia-kumano.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sm8150-sony-xperia-kumano.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sm8150-sony-xperia-kumano.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -348,6 +348,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7c_3p0: ldo7 { @@ -367,6 +370,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l10c_3p3: ldo10 { diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sm8250.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sm8250.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sm8250.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sm8250.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -334,6 +334,7 @@ exit-latency-us = <6562>; min-residency-us = <9987>; local-timer-stop; + status = "disabled"; }; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sm8250-sony-xperia-edo.dtsi linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sm8250-sony-xperia-edo.dtsi --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sm8250-sony-xperia-edo.dtsi 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sm8250-sony-xperia-edo.dtsi 2023-01-18 18:27:39.000000000 +0000 @@ -317,6 +317,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7c_2p85: ldo7 { @@ -339,6 +342,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l10c_3p3: ldo10 { diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sm8350-hdk.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sm8350-hdk.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/qcom/sm8350-hdk.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/qcom/sm8350-hdk.dts 2023-01-18 18:27:39.000000000 +0000 @@ -107,6 +107,9 @@ regulator-max-microvolt = <888000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l6b_1p2: ldo6 { @@ -115,6 +118,9 @@ regulator-max-microvolt = <1208000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l7b_2p96: ldo7 { @@ -123,6 +129,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; vreg_l9b_1p2: ldo9 { @@ -131,6 +140,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = ; regulator-allow-set-load; + regulator-allowed-modes = + ; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/rockchip/rk3399-puma-haikou.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/rockchip/rk3399-puma-haikou.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/rockchip/rk3399-puma-haikou.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/rockchip/rk3399-puma-haikou.dts 2023-01-18 18:27:39.000000000 +0000 @@ -207,7 +207,7 @@ cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; disable-wp; - max-frequency = <150000000>; + max-frequency = <40000000>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc3v3_baseboard>; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/rockchip/rk3566-quartz64-a.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/rockchip/rk3566-quartz64-a.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/rockchip/rk3566-quartz64-a.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/rockchip/rk3566-quartz64-a.dts 2023-01-18 18:27:39.000000000 +0000 @@ -740,7 +740,7 @@ &uart1 { pinctrl-names = "default"; - pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn>; + pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>; status = "okay"; uart-has-rtscts; @@ -748,13 +748,14 @@ compatible = "brcm,bcm43438-bt"; clocks = <&rk817 1>; clock-names = "lpo"; - device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; - host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; vbat-supply = <&vcc_sys>; vddio-supply = <&vcca1v8_pmu>; + max-speed = <3000000>; }; }; diff -Nru linux-6.0.6/scripts/dtc/include-prefixes/arm64/rockchip/rk3566-quartz64-b.dts linux-6.0.12/scripts/dtc/include-prefixes/arm64/rockchip/rk3566-quartz64-b.dts --- linux-6.0.6/scripts/dtc/include-prefixes/arm64/rockchip/rk3566-quartz64-b.dts 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/dtc/include-prefixes/arm64/rockchip/rk3566-quartz64-b.dts 2023-01-18 18:27:39.000000000 +0000 @@ -176,7 +176,7 @@ compatible = "rockchip,rk809"; reg = <0x20>; interrupt-parent = <&gpio0>; - interrupts = ; + interrupts = ; clock-output-names = "rk808-clkout1", "rk808-clkout2"; pinctrl-names = "default"; diff -Nru linux-6.0.6/scripts/faddr2line linux-6.0.12/scripts/faddr2line --- linux-6.0.6/scripts/faddr2line 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/scripts/faddr2line 2023-01-18 18:27:39.000000000 +0000 @@ -74,7 +74,8 @@ find_dir_prefix() { local objfile=$1 - local start_kernel_addr=$(${READELF} --symbols --wide $objfile | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') + local start_kernel_addr=$(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | + ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') [[ -z $start_kernel_addr ]] && return local file_line=$(${ADDR2LINE} -e $objfile $start_kernel_addr) @@ -178,7 +179,7 @@ found=2 break fi - done < <(${READELF} --symbols --wide $objfile | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) + done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) if [[ $found = 0 ]]; then warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size" @@ -259,7 +260,7 @@ DONE=1 - done < <(${READELF} --symbols --wide $objfile | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn') + done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn') } [[ $# -lt 2 ]] && usage diff -Nru linux-6.0.6/security/commoncap.c linux-6.0.12/security/commoncap.c --- linux-6.0.6/security/commoncap.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/security/commoncap.c 2023-01-18 18:27:39.000000000 +0000 @@ -401,8 +401,10 @@ &tmpbuf, size, GFP_NOFS); dput(dentry); - if (ret < 0 || !tmpbuf) - return ret; + if (ret < 0 || !tmpbuf) { + size = ret; + goto out_free; + } fs_ns = inode->i_sb->s_user_ns; cap = (struct vfs_cap_data *) tmpbuf; diff -Nru linux-6.0.6/sound/aoa/soundbus/i2sbus/core.c linux-6.0.12/sound/aoa/soundbus/i2sbus/core.c --- linux-6.0.6/sound/aoa/soundbus/i2sbus/core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/aoa/soundbus/i2sbus/core.c 2023-01-18 18:27:39.000000000 +0000 @@ -147,6 +147,7 @@ return rc; } +/* Returns 1 if added, 0 for otherwise; don't return a negative value! */ /* FIXME: look at device node refcounting */ static int i2sbus_add_dev(struct macio_dev *macio, struct i2sbus_control *control, @@ -213,7 +214,7 @@ * either as the second one in that case is just a modem. */ if (!ok) { kfree(dev); - return -ENODEV; + return 0; } mutex_init(&dev->lock); @@ -302,6 +303,10 @@ if (soundbus_add_one(&dev->sound)) { printk(KERN_DEBUG "i2sbus: device registration error!\n"); + if (dev->sound.ofdev.dev.kobj.state_initialized) { + soundbus_dev_put(&dev->sound); + return 0; + } goto err; } diff -Nru linux-6.0.6/sound/arm/pxa2xx-ac97-lib.c linux-6.0.12/sound/arm/pxa2xx-ac97-lib.c --- linux-6.0.6/sound/arm/pxa2xx-ac97-lib.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/arm/pxa2xx-ac97-lib.c 2023-01-18 18:27:39.000000000 +0000 @@ -402,8 +402,10 @@ goto err_clk2; irq = platform_get_irq(dev, 0); - if (!irq) + if (irq < 0) { + ret = irq; goto err_irq; + } ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL); if (ret < 0) diff -Nru linux-6.0.6/sound/core/control.c linux-6.0.12/sound/core/control.c --- linux-6.0.6/sound/core/control.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/core/control.c 2023-01-18 18:27:39.000000000 +0000 @@ -753,6 +753,29 @@ } EXPORT_SYMBOL(snd_ctl_rename_id); +/** + * snd_ctl_rename - rename the control on the card + * @card: the card instance + * @kctl: the control to rename + * @name: the new name + * + * Renames the specified control on the card to the new name. + * + * Make sure to take the control write lock - down_write(&card->controls_rwsem). + */ +void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, + const char *name) +{ + remove_hash_entries(card, kctl); + + if (strscpy(kctl->id.name, name, sizeof(kctl->id.name)) < 0) + pr_warn("ALSA: Renamed control new name '%s' truncated to '%s'\n", + name, kctl->id.name); + + add_hash_entries(card, kctl); +} +EXPORT_SYMBOL(snd_ctl_rename); + #ifndef CONFIG_SND_CTL_FAST_LOOKUP static struct snd_kcontrol * snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid) diff -Nru linux-6.0.6/sound/core/memalloc.c linux-6.0.12/sound/core/memalloc.c --- linux-6.0.6/sound/core/memalloc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/core/memalloc.c 2023-01-18 18:27:39.000000000 +0000 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -528,17 +529,17 @@ sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir, DEFAULT_GFP, 0); - if (!sgt) { #ifdef CONFIG_SND_DMA_SGBUF + if (!sgt && !get_dma_ops(dmab->dev.dev)) { if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; else dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK; return snd_dma_sg_fallback_alloc(dmab, size); -#else - return NULL; -#endif } +#endif + if (!sgt) + return NULL; dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, sg_dma_address(sgt->sgl)); @@ -874,7 +875,7 @@ /* * Entry points */ -static const struct snd_malloc_ops *dma_ops[] = { +static const struct snd_malloc_ops *snd_dma_ops[] = { [SNDRV_DMA_TYPE_CONTINUOUS] = &snd_dma_continuous_ops, [SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops, #ifdef CONFIG_HAS_DMA @@ -900,7 +901,7 @@ if (WARN_ON_ONCE(!dmab)) return NULL; if (WARN_ON_ONCE(dmab->dev.type <= SNDRV_DMA_TYPE_UNKNOWN || - dmab->dev.type >= ARRAY_SIZE(dma_ops))) + dmab->dev.type >= ARRAY_SIZE(snd_dma_ops))) return NULL; - return dma_ops[dmab->dev.type]; + return snd_dma_ops[dmab->dev.type]; } diff -Nru linux-6.0.6/sound/firewire/dice/dice-stream.c linux-6.0.12/sound/firewire/dice/dice-stream.c --- linux-6.0.6/sound/firewire/dice/dice-stream.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/firewire/dice/dice-stream.c 2023-01-18 18:27:39.000000000 +0000 @@ -59,7 +59,7 @@ static int select_clock(struct snd_dice *dice, unsigned int rate) { - __be32 reg; + __be32 reg, new; u32 data; int i; int err; @@ -83,15 +83,17 @@ if (completion_done(&dice->clock_accepted)) reinit_completion(&dice->clock_accepted); - reg = cpu_to_be32(data); + new = cpu_to_be32(data); err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT, - ®, sizeof(reg)); + &new, sizeof(new)); if (err < 0) return err; if (wait_for_completion_timeout(&dice->clock_accepted, - msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) - return -ETIMEDOUT; + msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) { + if (reg != new) + return -ETIMEDOUT; + } return 0; } diff -Nru linux-6.0.6/sound/hda/hdac_sysfs.c linux-6.0.12/sound/hda/hdac_sysfs.c --- linux-6.0.6/sound/hda/hdac_sysfs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/hda/hdac_sysfs.c 2023-01-18 18:27:39.000000000 +0000 @@ -346,8 +346,10 @@ return -ENOMEM; kobject_init(kobj, &widget_ktype); err = kobject_add(kobj, parent, "%02x", nid); - if (err < 0) + if (err < 0) { + kobject_put(kobj); return err; + } err = sysfs_create_group(kobj, group); if (err < 0) { kobject_put(kobj); diff -Nru linux-6.0.6/sound/hda/intel-dsp-config.c linux-6.0.12/sound/hda/intel-dsp-config.c --- linux-6.0.6/sound/hda/intel-dsp-config.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/hda/intel-dsp-config.c 2023-01-18 18:27:39.000000000 +0000 @@ -321,6 +321,11 @@ } }, { + .flags = FLAG_SOF, + .device = 0x34c8, + .codec_hid = &essx_83x6, + }, + { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .device = 0x34c8, }, diff -Nru linux-6.0.6/sound/pci/ac97/ac97_codec.c linux-6.0.12/sound/pci/ac97/ac97_codec.c --- linux-6.0.6/sound/pci/ac97/ac97_codec.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/ac97/ac97_codec.c 2023-01-18 18:27:39.000000000 +0000 @@ -2009,6 +2009,7 @@ err = device_register(&ac97->dev); if (err < 0) { ac97_err(ac97, "Can't register ac97 bus\n"); + put_device(&ac97->dev); ac97->dev.bus = NULL; return err; } @@ -2655,11 +2656,18 @@ */ static void set_ctl_name(char *dst, const char *src, const char *suffix) { - if (suffix) - sprintf(dst, "%s %s", src, suffix); - else - strcpy(dst, src); -} + const size_t msize = SNDRV_CTL_ELEM_ID_NAME_MAXLEN; + + if (suffix) { + if (snprintf(dst, msize, "%s %s", src, suffix) >= msize) + pr_warn("ALSA: AC97 control name '%s %s' truncated to '%s'\n", + src, suffix, dst); + } else { + if (strscpy(dst, src, msize) < 0) + pr_warn("ALSA: AC97 control name '%s' truncated to '%s'\n", + src, dst); + } +} /* remove the control with the given name and optional suffix */ static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, @@ -2686,8 +2694,11 @@ const char *dst, const char *suffix) { struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix); + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + if (kctl) { - set_ctl_name(kctl->id.name, dst, suffix); + set_ctl_name(name, dst, suffix); + snd_ctl_rename(ac97->bus->card, kctl, name); return 0; } return -ENOENT; @@ -2706,11 +2717,17 @@ const char *s2, const char *suffix) { struct snd_kcontrol *kctl1, *kctl2; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + kctl1 = ctl_find(ac97, s1, suffix); kctl2 = ctl_find(ac97, s2, suffix); if (kctl1 && kctl2) { - set_ctl_name(kctl1->id.name, s2, suffix); - set_ctl_name(kctl2->id.name, s1, suffix); + set_ctl_name(name, s2, suffix); + snd_ctl_rename(ac97->bus->card, kctl1, name); + + set_ctl_name(name, s1, suffix); + snd_ctl_rename(ac97->bus->card, kctl2, name); + return 0; } return -ENOENT; diff -Nru linux-6.0.6/sound/pci/au88x0/au88x0_core.c linux-6.0.12/sound/pci/au88x0/au88x0_core.c --- linux-6.0.6/sound/pci/au88x0/au88x0_core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/au88x0/au88x0_core.c 2023-01-18 18:27:39.000000000 +0000 @@ -1998,7 +1998,7 @@ out: Mean checkout if != 0. Else mean Checkin resource. restype: Indicates type of resource to be checked in or out. */ -static char +static int vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype) { int i, qty = resnum[restype], resinuse = 0; diff -Nru linux-6.0.6/sound/pci/au88x0/au88x0.h linux-6.0.12/sound/pci/au88x0/au88x0.h --- linux-6.0.6/sound/pci/au88x0/au88x0.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/au88x0/au88x0.h 2023-01-18 18:27:39.000000000 +0000 @@ -141,7 +141,7 @@ #ifndef CHIP_AU8810 stream_t dma_wt[NR_WT]; wt_voice_t wt_voice[NR_WT]; /* WT register cache. */ - char mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */ + s8 mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */ #endif /* Global resources */ @@ -235,8 +235,8 @@ static void vortex_connect_default(vortex_t * vortex, int en); static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type, int subdev); -static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, - int restype); +static int vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, + int restype); #ifndef CHIP_AU8810 static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch); static void vortex_wt_connect(vortex_t * vortex, int en); diff -Nru linux-6.0.6/sound/pci/ca0106/ca0106_mixer.c linux-6.0.12/sound/pci/ca0106/ca0106_mixer.c --- linux-6.0.6/sound/pci/ca0106/ca0106_mixer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/ca0106/ca0106_mixer.c 2023-01-18 18:27:39.000000000 +0000 @@ -720,7 +720,7 @@ { struct snd_kcontrol *kctl = ctl_find(card, src); if (kctl) { - strcpy(kctl->id.name, dst); + snd_ctl_rename(card, kctl, dst); return 0; } return -ENOENT; diff -Nru linux-6.0.6/sound/pci/emu10k1/emumixer.c linux-6.0.12/sound/pci/emu10k1/emumixer.c --- linux-6.0.6/sound/pci/emu10k1/emumixer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/emu10k1/emumixer.c 2023-01-18 18:27:39.000000000 +0000 @@ -1767,7 +1767,7 @@ { struct snd_kcontrol *kctl = ctl_find(card, src); if (kctl) { - strcpy(kctl->id.name, dst); + snd_ctl_rename(card, kctl, dst); return 0; } return -ENOENT; diff -Nru linux-6.0.6/sound/pci/hda/hda_intel.c linux-6.0.12/sound/pci/hda/hda_intel.c --- linux-6.0.6/sound/pci/hda/hda_intel.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/hda/hda_intel.c 2023-01-18 18:27:39.000000000 +0000 @@ -2723,6 +2723,9 @@ { PCI_DEVICE(0x1002, 0xab28), .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | AZX_DCAPS_PM_RUNTIME }, + { PCI_DEVICE(0x1002, 0xab30), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | + AZX_DCAPS_PM_RUNTIME }, { PCI_DEVICE(0x1002, 0xab38), .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | AZX_DCAPS_PM_RUNTIME }, diff -Nru linux-6.0.6/sound/pci/hda/patch_ca0132.c linux-6.0.12/sound/pci/hda/patch_ca0132.c --- linux-6.0.6/sound/pci/hda/patch_ca0132.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/hda/patch_ca0132.c 2023-01-18 18:27:39.000000000 +0000 @@ -1306,6 +1306,7 @@ SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI), SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI), SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI), + SND_PCI_QUIRK(0x3842, 0x1055, "EVGA Z390 DARK", QUIRK_R3DI), SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D), SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D), SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5), diff -Nru linux-6.0.6/sound/pci/hda/patch_realtek.c linux-6.0.12/sound/pci/hda/patch_realtek.c --- linux-6.0.6/sound/pci/hda/patch_realtek.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/hda/patch_realtek.c 2023-01-18 18:27:39.000000000 +0000 @@ -2141,7 +2141,7 @@ kctl = snd_hda_find_mixer_ctl(codec, oldname); if (kctl) - strcpy(kctl->id.name, newname); + snd_ctl_rename(codec->card, kctl, newname); } static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec, @@ -9333,6 +9333,7 @@ SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x896d, "HP ZBook Firefly 16 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), @@ -9351,6 +9352,7 @@ SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89c0, "HP ZBook Power 15.6 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), @@ -9405,12 +9407,14 @@ SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), @@ -9442,6 +9446,8 @@ SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_AMP), + SND_PCI_QUIRK(0x144d, 0xc1a3, "Samsung Galaxy Book Pro (NP935XDB-KC1SE)", ALC298_FIXUP_SAMSUNG_AMP), + SND_PCI_QUIRK(0x144d, 0xc1a6, "Samsung Galaxy Book Pro 360 (NP930QBD)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP), @@ -9615,6 +9621,7 @@ SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK), + SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20), diff -Nru linux-6.0.6/sound/pci/rme9652/hdsp.c linux-6.0.12/sound/pci/rme9652/hdsp.c --- linux-6.0.6/sound/pci/rme9652/hdsp.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/rme9652/hdsp.c 2023-01-18 18:27:39.000000000 +0000 @@ -433,7 +433,7 @@ struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *input; struct snd_rawmidi_substream *output; - char istimer; /* timer in use */ + signed char istimer; /* timer in use */ struct timer_list timer; spinlock_t lock; int pending; @@ -480,7 +480,7 @@ pid_t playback_pid; int running; int system_sample_rate; - const char *channel_map; + const signed char *channel_map; int dev; int irq; unsigned long port; @@ -502,7 +502,7 @@ where the data for that channel can be read/written from/to. */ -static const char channel_map_df_ss[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_df_ss[HDSP_MAX_CHANNELS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }; @@ -517,7 +517,7 @@ -1, -1, -1, -1, -1, -1, -1, -1 }; -static const char channel_map_ds[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_ds[HDSP_MAX_CHANNELS] = { /* ADAT channels are remapped */ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, /* channels 12 and 13 are S/PDIF */ @@ -526,7 +526,7 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = { /* ADAT channels */ 0, 1, 2, 3, 4, 5, 6, 7, /* SPDIF */ @@ -540,7 +540,7 @@ -1, -1 }; -static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = { /* ADAT */ 1, 3, 5, 7, /* SPDIF */ @@ -554,7 +554,7 @@ -1, -1, -1, -1, -1, -1 }; -static const char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = { /* ADAT is disabled in this mode */ /* SPDIF */ 8, 9, @@ -3939,7 +3939,7 @@ return hdsp_hw_pointer(hdsp); } -static char *hdsp_channel_buffer_location(struct hdsp *hdsp, +static signed char *hdsp_channel_buffer_location(struct hdsp *hdsp, int stream, int channel) @@ -3964,7 +3964,7 @@ void __user *src, unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) return -EINVAL; @@ -3982,7 +3982,7 @@ void *src, unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); if (snd_BUG_ON(!channel_buf)) @@ -3996,7 +3996,7 @@ void __user *dst, unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) return -EINVAL; @@ -4014,7 +4014,7 @@ void *dst, unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); if (snd_BUG_ON(!channel_buf)) @@ -4028,7 +4028,7 @@ unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); if (snd_BUG_ON(!channel_buf)) diff -Nru linux-6.0.6/sound/pci/rme9652/rme9652.c linux-6.0.12/sound/pci/rme9652/rme9652.c --- linux-6.0.6/sound/pci/rme9652/rme9652.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/pci/rme9652/rme9652.c 2023-01-18 18:27:39.000000000 +0000 @@ -230,7 +230,7 @@ int last_spdif_sample_rate; /* so that we can catch externally ... */ int last_adat_sample_rate; /* ... induced rate changes */ - const char *channel_map; + const signed char *channel_map; struct snd_card *card; struct snd_pcm *pcm; @@ -247,12 +247,12 @@ where the data for that channel can be read/written from/to. */ -static const char channel_map_9652_ss[26] = { +static const signed char channel_map_9652_ss[26] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }; -static const char channel_map_9636_ss[26] = { +static const signed char channel_map_9636_ss[26] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* channels 16 and 17 are S/PDIF */ 24, 25, @@ -260,7 +260,7 @@ -1, -1, -1, -1, -1, -1, -1, -1 }; -static const char channel_map_9652_ds[26] = { +static const signed char channel_map_9652_ds[26] = { /* ADAT channels are remapped */ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, /* channels 12 and 13 are S/PDIF */ @@ -269,7 +269,7 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -static const char channel_map_9636_ds[26] = { +static const signed char channel_map_9636_ds[26] = { /* ADAT channels are remapped */ 1, 3, 5, 7, 9, 11, 13, 15, /* channels 8 and 9 are S/PDIF */ @@ -1819,7 +1819,7 @@ return rme9652_hw_pointer(rme9652); } -static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652, +static signed char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652, int stream, int channel) @@ -1847,7 +1847,7 @@ void __user *src, unsigned long count) { struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES)) return -EINVAL; @@ -1867,7 +1867,7 @@ void *src, unsigned long count) { struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = rme9652_channel_buffer_location(rme9652, substream->pstr->stream, @@ -1883,7 +1883,7 @@ void __user *dst, unsigned long count) { struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES)) return -EINVAL; @@ -1903,7 +1903,7 @@ void *dst, unsigned long count) { struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = rme9652_channel_buffer_location(rme9652, substream->pstr->stream, @@ -1919,7 +1919,7 @@ unsigned long count) { struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = rme9652_channel_buffer_location (rme9652, substream->pstr->stream, diff -Nru linux-6.0.6/sound/soc/amd/yc/acp6x-mach.c linux-6.0.12/sound/soc/amd/yc/acp6x-mach.c --- linux-6.0.6/sound/soc/amd/yc/acp6x-mach.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/amd/yc/acp6x-mach.c 2023-01-18 18:27:39.000000000 +0000 @@ -49,6 +49,27 @@ .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21D0"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21D0"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21D1"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21D2"), } }, @@ -185,6 +206,13 @@ DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"), + } + }, {} }; diff -Nru linux-6.0.6/sound/soc/codecs/hdac_hda.h linux-6.0.12/sound/soc/codecs/hdac_hda.h --- linux-6.0.6/sound/soc/codecs/hdac_hda.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/hdac_hda.h 2023-01-18 18:27:39.000000000 +0000 @@ -14,7 +14,7 @@ HDAC_HDMI_1_DAI_ID, HDAC_HDMI_2_DAI_ID, HDAC_HDMI_3_DAI_ID, - HDAC_LAST_DAI_ID = HDAC_HDMI_3_DAI_ID, + HDAC_DAI_ID_NUM }; struct hdac_hda_pcm { @@ -24,7 +24,7 @@ struct hdac_hda_priv { struct hda_codec codec; - struct hdac_hda_pcm pcm[HDAC_LAST_DAI_ID]; + struct hdac_hda_pcm pcm[HDAC_DAI_ID_NUM]; bool need_display_power; }; diff -Nru linux-6.0.6/sound/soc/codecs/jz4725b.c linux-6.0.12/sound/soc/codecs/jz4725b.c --- linux-6.0.6/sound/soc/codecs/jz4725b.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/jz4725b.c 2023-01-18 18:27:39.000000000 +0000 @@ -136,14 +136,17 @@ #define REG_CGR3_GO1L_OFFSET 0 #define REG_CGR3_GO1L_MASK (0x1f << REG_CGR3_GO1L_OFFSET) +#define REG_CGR10_GIL_OFFSET 0 +#define REG_CGR10_GIR_OFFSET 4 + struct jz_icdc { struct regmap *regmap; void __iomem *base; struct clk *clk; }; -static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_dac_tlv, -2250, 0); -static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_line_tlv, -1500, 600); +static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv, 0, 150, 0); +static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0); static const struct snd_kcontrol_new jz4725b_codec_controls[] = { SOC_DOUBLE_TLV("Master Playback Volume", @@ -151,11 +154,11 @@ REG_CGR1_GODL_OFFSET, REG_CGR1_GODR_OFFSET, 0xf, 1, jz4725b_dac_tlv), - SOC_DOUBLE_R_TLV("Master Capture Volume", - JZ4725B_CODEC_REG_CGR3, - JZ4725B_CODEC_REG_CGR2, - REG_CGR2_GO1R_OFFSET, - 0x1f, 1, jz4725b_line_tlv), + SOC_DOUBLE_TLV("Master Capture Volume", + JZ4725B_CODEC_REG_CGR10, + REG_CGR10_GIL_OFFSET, + REG_CGR10_GIR_OFFSET, + 0xf, 0, jz4725b_adc_tlv), SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1, REG_CR1_DAC_MUTE_OFFSET, 1, 1), @@ -180,7 +183,7 @@ jz4725b_codec_adc_src_texts, jz4725b_codec_adc_src_values); static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl = - SOC_DAPM_ENUM("Route", jz4725b_codec_adc_src_enum); + SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum); static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = { SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1, @@ -225,7 +228,7 @@ SND_SOC_DAPM_ADC("ADC", "Capture", JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1), - SND_SOC_DAPM_MUX("ADC Source", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0, &jz4725b_codec_adc_src_ctrl), /* Mixer */ @@ -236,7 +239,8 @@ SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1, REG_CR1_DACSEL_OFFSET, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Line In", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1, + REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0), SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1, REG_CR1_HP_DIS_OFFSET, 1, NULL, 0), @@ -283,11 +287,11 @@ {"Mixer", NULL, "DAC to Mixer"}, {"Mixer to ADC", NULL, "Mixer"}, - {"ADC Source", "Mixer", "Mixer to ADC"}, - {"ADC Source", "Line In", "Line In"}, - {"ADC Source", "Mic 1", "Mic 1"}, - {"ADC Source", "Mic 2", "Mic 2"}, - {"ADC", NULL, "ADC Source"}, + {"ADC Source Capture Route", "Mixer", "Mixer to ADC"}, + {"ADC Source Capture Route", "Line In", "Line In"}, + {"ADC Source Capture Route", "Mic 1", "Mic 1"}, + {"ADC Source Capture Route", "Mic 2", "Mic 2"}, + {"ADC", NULL, "ADC Source Capture Route"}, {"Out Stage", NULL, "Mixer"}, {"HP Out", NULL, "Out Stage"}, diff -Nru linux-6.0.6/sound/soc/codecs/Kconfig linux-6.0.12/sound/soc/codecs/Kconfig --- linux-6.0.6/sound/soc/codecs/Kconfig 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/Kconfig 2023-01-18 18:27:39.000000000 +0000 @@ -1599,6 +1599,7 @@ config SND_SOC_TLV320ADC3XXX tristate "Texas Instruments TLV320ADC3001/3101 audio ADC" depends on I2C + depends on GPIOLIB help Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101 ADCs. diff -Nru linux-6.0.6/sound/soc/codecs/max98373-i2c.c linux-6.0.12/sound/soc/codecs/max98373-i2c.c --- linux-6.0.6/sound/soc/codecs/max98373-i2c.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/max98373-i2c.c 2023-01-18 18:27:39.000000000 +0000 @@ -549,6 +549,10 @@ max98373->cache = devm_kcalloc(&i2c->dev, max98373->cache_num, sizeof(*max98373->cache), GFP_KERNEL); + if (!max98373->cache) { + ret = -ENOMEM; + return ret; + } for (i = 0; i < max98373->cache_num; i++) max98373->cache[i].reg = max98373_i2c_cache_reg[i]; diff -Nru linux-6.0.6/sound/soc/codecs/mt6660.c linux-6.0.12/sound/soc/codecs/mt6660.c --- linux-6.0.6/sound/soc/codecs/mt6660.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/mt6660.c 2023-01-18 18:27:39.000000000 +0000 @@ -503,14 +503,14 @@ dev_err(chip->dev, "read chip revision fail\n"); goto probe_fail; } + pm_runtime_set_active(chip->dev); + pm_runtime_enable(chip->dev); ret = devm_snd_soc_register_component(chip->dev, &mt6660_component_driver, &mt6660_codec_dai, 1); - if (!ret) { - pm_runtime_set_active(chip->dev); - pm_runtime_enable(chip->dev); - } + if (ret) + pm_runtime_disable(chip->dev); return ret; diff -Nru linux-6.0.6/sound/soc/codecs/rt1019.c linux-6.0.12/sound/soc/codecs/rt1019.c --- linux-6.0.6/sound/soc/codecs/rt1019.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/rt1019.c 2023-01-18 18:27:39.000000000 +0000 @@ -391,18 +391,18 @@ unsigned int rx_mask, int slots, int slot_width) { struct snd_soc_component *component = dai->component; - unsigned int val = 0, rx_slotnum; + unsigned int cn = 0, cl = 0, rx_slotnum; int ret = 0, first_bit; switch (slots) { case 4: - val |= RT1019_I2S_TX_4CH; + cn = RT1019_I2S_TX_4CH; break; case 6: - val |= RT1019_I2S_TX_6CH; + cn = RT1019_I2S_TX_6CH; break; case 8: - val |= RT1019_I2S_TX_8CH; + cn = RT1019_I2S_TX_8CH; break; case 2: break; @@ -412,16 +412,16 @@ switch (slot_width) { case 20: - val |= RT1019_I2S_DL_20; + cl = RT1019_TDM_CL_20; break; case 24: - val |= RT1019_I2S_DL_24; + cl = RT1019_TDM_CL_24; break; case 32: - val |= RT1019_I2S_DL_32; + cl = RT1019_TDM_CL_32; break; case 8: - val |= RT1019_I2S_DL_8; + cl = RT1019_TDM_CL_8; break; case 16: break; @@ -470,8 +470,10 @@ goto _set_tdm_err_; } + snd_soc_component_update_bits(component, RT1019_TDM_1, + RT1019_TDM_CL_MASK, cl); snd_soc_component_update_bits(component, RT1019_TDM_2, - RT1019_I2S_CH_TX_MASK | RT1019_I2S_DF_MASK, val); + RT1019_I2S_CH_TX_MASK, cn); _set_tdm_err_: return ret; diff -Nru linux-6.0.6/sound/soc/codecs/rt1019.h linux-6.0.12/sound/soc/codecs/rt1019.h --- linux-6.0.6/sound/soc/codecs/rt1019.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/rt1019.h 2023-01-18 18:27:39.000000000 +0000 @@ -95,6 +95,12 @@ #define RT1019_TDM_BCLK_MASK (0x1 << 6) #define RT1019_TDM_BCLK_NORM (0x0 << 6) #define RT1019_TDM_BCLK_INV (0x1 << 6) +#define RT1019_TDM_CL_MASK (0x7) +#define RT1019_TDM_CL_8 (0x4) +#define RT1019_TDM_CL_32 (0x3) +#define RT1019_TDM_CL_24 (0x2) +#define RT1019_TDM_CL_20 (0x1) +#define RT1019_TDM_CL_16 (0x0) /* 0x0401 TDM Control-2 */ #define RT1019_I2S_CH_TX_MASK (0x3 << 6) diff -Nru linux-6.0.6/sound/soc/codecs/rt1308-sdw.h linux-6.0.12/sound/soc/codecs/rt1308-sdw.h --- linux-6.0.6/sound/soc/codecs/rt1308-sdw.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/rt1308-sdw.h 2023-01-18 18:27:39.000000000 +0000 @@ -139,10 +139,12 @@ { 0x3005, 0x23 }, { 0x3008, 0x02 }, { 0x300a, 0x00 }, + { 0xc000 | (RT1308_DATA_PATH << 4), 0x00 }, { 0xc003 | (RT1308_DAC_SET << 4), 0x00 }, { 0xc000 | (RT1308_POWER << 4), 0x00 }, { 0xc001 | (RT1308_POWER << 4), 0x00 }, { 0xc002 | (RT1308_POWER << 4), 0x00 }, + { 0xc000 | (RT1308_POWER_STATUS << 4), 0x00 }, }; #define RT1308_SDW_OFFSET 0xc000 diff -Nru linux-6.0.6/sound/soc/codecs/rt5514-spi.c linux-6.0.12/sound/soc/codecs/rt5514-spi.c --- linux-6.0.6/sound/soc/codecs/rt5514-spi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/rt5514-spi.c 2023-01-18 18:27:39.000000000 +0000 @@ -298,13 +298,14 @@ } static const struct snd_soc_component_driver rt5514_spi_component = { - .name = DRV_NAME, - .probe = rt5514_spi_pcm_probe, - .open = rt5514_spi_pcm_open, - .hw_params = rt5514_spi_hw_params, - .hw_free = rt5514_spi_hw_free, - .pointer = rt5514_spi_pcm_pointer, - .pcm_construct = rt5514_spi_pcm_new, + .name = DRV_NAME, + .probe = rt5514_spi_pcm_probe, + .open = rt5514_spi_pcm_open, + .hw_params = rt5514_spi_hw_params, + .hw_free = rt5514_spi_hw_free, + .pointer = rt5514_spi_pcm_pointer, + .pcm_construct = rt5514_spi_pcm_new, + .legacy_dai_naming = 1, }; /** diff -Nru linux-6.0.6/sound/soc/codecs/rt5677-spi.c linux-6.0.12/sound/soc/codecs/rt5677-spi.c --- linux-6.0.6/sound/soc/codecs/rt5677-spi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/rt5677-spi.c 2023-01-18 18:27:39.000000000 +0000 @@ -396,15 +396,16 @@ } static const struct snd_soc_component_driver rt5677_spi_dai_component = { - .name = DRV_NAME, - .probe = rt5677_spi_pcm_probe, - .open = rt5677_spi_pcm_open, - .close = rt5677_spi_pcm_close, - .hw_params = rt5677_spi_hw_params, - .hw_free = rt5677_spi_hw_free, - .prepare = rt5677_spi_prepare, - .pointer = rt5677_spi_pcm_pointer, - .pcm_construct = rt5677_spi_pcm_new, + .name = DRV_NAME, + .probe = rt5677_spi_pcm_probe, + .open = rt5677_spi_pcm_open, + .close = rt5677_spi_pcm_close, + .hw_params = rt5677_spi_hw_params, + .hw_free = rt5677_spi_hw_free, + .prepare = rt5677_spi_prepare, + .pointer = rt5677_spi_pcm_pointer, + .pcm_construct = rt5677_spi_pcm_new, + .legacy_dai_naming = 1, }; /* Select a suitable transfer command for the next transfer to ensure diff -Nru linux-6.0.6/sound/soc/codecs/rt5682s.c linux-6.0.12/sound/soc/codecs/rt5682s.c --- linux-6.0.6/sound/soc/codecs/rt5682s.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/rt5682s.c 2023-01-18 18:27:39.000000000 +0000 @@ -1932,7 +1932,7 @@ unsigned int rx_mask, int slots, int slot_width) { struct snd_soc_component *component = dai->component; - unsigned int cl, val = 0; + unsigned int cl, val = 0, tx_slotnum; if (tx_mask || rx_mask) snd_soc_component_update_bits(component, @@ -1941,6 +1941,16 @@ snd_soc_component_update_bits(component, RT5682S_TDM_ADDA_CTRL_2, RT5682S_TDM_EN, 0); + /* Tx slot configuration */ + tx_slotnum = hweight_long(tx_mask); + if (tx_slotnum) { + if (tx_slotnum > slots) { + dev_err(component->dev, "Invalid or oversized Tx slots.\n"); + return -EINVAL; + } + val |= (tx_slotnum - 1) << RT5682S_TDM_ADC_DL_SFT; + } + switch (slots) { case 4: val |= RT5682S_TDM_TX_CH_4; @@ -1961,7 +1971,8 @@ } snd_soc_component_update_bits(component, RT5682S_TDM_CTRL, - RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK, val); + RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK | + RT5682S_TDM_ADC_DL_MASK, val); switch (slot_width) { case 8: diff -Nru linux-6.0.6/sound/soc/codecs/rt5682s.h linux-6.0.12/sound/soc/codecs/rt5682s.h --- linux-6.0.6/sound/soc/codecs/rt5682s.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/rt5682s.h 2023-01-18 18:27:39.000000000 +0000 @@ -899,6 +899,7 @@ #define RT5682S_TDM_RX_CH_8 (0x3 << 8) #define RT5682S_TDM_ADC_LCA_MASK (0x7 << 4) #define RT5682S_TDM_ADC_LCA_SFT 4 +#define RT5682S_TDM_ADC_DL_MASK (0x3 << 0) #define RT5682S_TDM_ADC_DL_SFT 0 /* TDM control 2 (0x007a) */ diff -Nru linux-6.0.6/sound/soc/codecs/sgtl5000.c linux-6.0.12/sound/soc/codecs/sgtl5000.c --- linux-6.0.6/sound/soc/codecs/sgtl5000.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/sgtl5000.c 2023-01-18 18:27:39.000000000 +0000 @@ -1794,6 +1794,7 @@ { struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client); + regmap_write(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL, SGTL5000_CHIP_CLK_CTRL_DEFAULT); regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT); regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT); diff -Nru linux-6.0.6/sound/soc/codecs/tas2764.c linux-6.0.12/sound/soc/codecs/tas2764.c --- linux-6.0.6/sound/soc/codecs/tas2764.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/tas2764.c 2023-01-18 18:27:39.000000000 +0000 @@ -386,20 +386,13 @@ if (tx_mask == 0 || rx_mask != 0) return -EINVAL; - if (slots == 1) { - if (tx_mask != 1) - return -EINVAL; - left_slot = 0; - right_slot = 0; + left_slot = __ffs(tx_mask); + tx_mask &= ~(1 << left_slot); + if (tx_mask == 0) { + right_slot = left_slot; } else { - left_slot = __ffs(tx_mask); - tx_mask &= ~(1 << left_slot); - if (tx_mask == 0) { - right_slot = left_slot; - } else { - right_slot = __ffs(tx_mask); - tx_mask &= ~(1 << right_slot); - } + right_slot = __ffs(tx_mask); + tx_mask &= ~(1 << right_slot); } if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) diff -Nru linux-6.0.6/sound/soc/codecs/tas2770.c linux-6.0.12/sound/soc/codecs/tas2770.c --- linux-6.0.6/sound/soc/codecs/tas2770.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/tas2770.c 2023-01-18 18:27:39.000000000 +0000 @@ -395,21 +395,13 @@ if (tx_mask == 0 || rx_mask != 0) return -EINVAL; - if (slots == 1) { - if (tx_mask != 1) - return -EINVAL; - - left_slot = 0; - right_slot = 0; + left_slot = __ffs(tx_mask); + tx_mask &= ~(1 << left_slot); + if (tx_mask == 0) { + right_slot = left_slot; } else { - left_slot = __ffs(tx_mask); - tx_mask &= ~(1 << left_slot); - if (tx_mask == 0) { - right_slot = left_slot; - } else { - right_slot = __ffs(tx_mask); - tx_mask &= ~(1 << right_slot); - } + right_slot = __ffs(tx_mask); + tx_mask &= ~(1 << right_slot); } if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) diff -Nru linux-6.0.6/sound/soc/codecs/tas2780.c linux-6.0.12/sound/soc/codecs/tas2780.c --- linux-6.0.6/sound/soc/codecs/tas2780.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/tas2780.c 2023-01-18 18:27:39.000000000 +0000 @@ -380,20 +380,13 @@ if (tx_mask == 0 || rx_mask != 0) return -EINVAL; - if (slots == 1) { - if (tx_mask != 1) - return -EINVAL; - left_slot = 0; - right_slot = 0; + left_slot = __ffs(tx_mask); + tx_mask &= ~(1 << left_slot); + if (tx_mask == 0) { + right_slot = left_slot; } else { - left_slot = __ffs(tx_mask); - tx_mask &= ~(1 << left_slot); - if (tx_mask == 0) { - right_slot = left_slot; - } else { - right_slot = __ffs(tx_mask); - tx_mask &= ~(1 << right_slot); - } + right_slot = __ffs(tx_mask); + tx_mask &= ~(1 << right_slot); } if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) diff -Nru linux-6.0.6/sound/soc/codecs/tlv320adc3xxx.c linux-6.0.12/sound/soc/codecs/tlv320adc3xxx.c --- linux-6.0.6/sound/soc/codecs/tlv320adc3xxx.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/tlv320adc3xxx.c 2023-01-18 18:27:39.000000000 +0000 @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -1025,7 +1026,9 @@ static void adc3xxx_free_gpio(struct adc3xxx *adc3xxx) { +#ifdef CONFIG_GPIOLIB gpiochip_remove(&adc3xxx->gpio_chip); +#endif } static void adc3xxx_init_gpio(struct adc3xxx *adc3xxx) @@ -1450,7 +1453,7 @@ .of_match_table = tlv320adc3xxx_of_match, }, .probe_new = adc3xxx_i2c_probe, - .remove = adc3xxx_i2c_remove, + .remove = __exit_p(adc3xxx_i2c_remove), .id_table = adc3xxx_i2c_id, }; diff -Nru linux-6.0.6/sound/soc/codecs/wm5102.c linux-6.0.12/sound/soc/codecs/wm5102.c --- linux-6.0.6/sound/soc/codecs/wm5102.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/wm5102.c 2023-01-18 18:27:39.000000000 +0000 @@ -2099,6 +2099,9 @@ regmap_update_bits(arizona->regmap, wm5102_digital_vu[i], WM5102_DIG_VU, WM5102_DIG_VU); + pm_runtime_enable(&pdev->dev); + pm_runtime_idle(&pdev->dev); + ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, "ADSP2 Compressed IRQ", wm5102_adsp2_irq, wm5102); @@ -2131,9 +2134,6 @@ goto err_spk_irqs; } - pm_runtime_enable(&pdev->dev); - pm_runtime_idle(&pdev->dev); - return ret; err_spk_irqs: diff -Nru linux-6.0.6/sound/soc/codecs/wm5110.c linux-6.0.12/sound/soc/codecs/wm5110.c --- linux-6.0.6/sound/soc/codecs/wm5110.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/wm5110.c 2023-01-18 18:27:39.000000000 +0000 @@ -2457,6 +2457,9 @@ regmap_update_bits(arizona->regmap, wm5110_digital_vu[i], WM5110_DIG_VU, WM5110_DIG_VU); + pm_runtime_enable(&pdev->dev); + pm_runtime_idle(&pdev->dev); + ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, "ADSP2 Compressed IRQ", wm5110_adsp2_irq, wm5110); @@ -2489,9 +2492,6 @@ goto err_spk_irqs; } - pm_runtime_enable(&pdev->dev); - pm_runtime_idle(&pdev->dev); - return ret; err_spk_irqs: diff -Nru linux-6.0.6/sound/soc/codecs/wm8962.c linux-6.0.12/sound/soc/codecs/wm8962.c --- linux-6.0.6/sound/soc/codecs/wm8962.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/wm8962.c 2023-01-18 18:27:39.000000000 +0000 @@ -1840,6 +1840,49 @@ 4, 1, 0, inmix_tlv), }; +static int tp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int ret, reg, val, mask; + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0) { + dev_err(component->dev, "Failed to resume device: %d\n", ret); + return ret; + } + + reg = WM8962_ADDITIONAL_CONTROL_4; + + if (!strcmp(w->name, "TEMP_HP")) { + mask = WM8962_TEMP_ENA_HP_MASK; + val = WM8962_TEMP_ENA_HP; + } else if (!strcmp(w->name, "TEMP_SPK")) { + mask = WM8962_TEMP_ENA_SPK_MASK; + val = WM8962_TEMP_ENA_SPK; + } else { + pm_runtime_put(component->dev); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMD: + val = 0; + fallthrough; + case SND_SOC_DAPM_POST_PMU: + ret = snd_soc_component_update_bits(component, reg, mask, val); + break; + default: + WARN(1, "Invalid event %d\n", event); + pm_runtime_put(component->dev); + return -EINVAL; + } + + pm_runtime_put(component->dev); + + return 0; +} + static int cp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2140,8 +2183,10 @@ SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT, WM8962_DSP2_ENA_SHIFT, 0, dsp2_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), -SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event, + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_SUPPLY("TEMP_SPK", SND_SOC_NOPM, 0, 0, tp_event, + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, inpgal, ARRAY_SIZE(inpgal)), @@ -3763,6 +3808,11 @@ if (ret < 0) goto err_pm_runtime; + regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4, + WM8962_TEMP_ENA_HP_MASK, 0); + regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4, + WM8962_TEMP_ENA_SPK_MASK, 0); + regcache_cache_only(wm8962->regmap, true); /* The drivers should power up as needed */ diff -Nru linux-6.0.6/sound/soc/codecs/wm8997.c linux-6.0.12/sound/soc/codecs/wm8997.c --- linux-6.0.6/sound/soc/codecs/wm8997.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/codecs/wm8997.c 2023-01-18 18:27:39.000000000 +0000 @@ -1161,6 +1161,9 @@ regmap_update_bits(arizona->regmap, wm8997_digital_vu[i], WM8997_DIG_VU, WM8997_DIG_VU); + pm_runtime_enable(&pdev->dev); + pm_runtime_idle(&pdev->dev); + arizona_init_common(arizona); ret = arizona_init_vol_limit(arizona); @@ -1179,9 +1182,6 @@ goto err_spk_irqs; } - pm_runtime_enable(&pdev->dev); - pm_runtime_idle(&pdev->dev); - return ret; err_spk_irqs: diff -Nru linux-6.0.6/sound/soc/fsl/fsl_asrc.c linux-6.0.12/sound/soc/fsl/fsl_asrc.c --- linux-6.0.6/sound/soc/fsl/fsl_asrc.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/fsl/fsl_asrc.c 2023-01-18 18:27:39.000000000 +0000 @@ -1224,7 +1224,7 @@ } ret = pm_runtime_put_sync(&pdev->dev); - if (ret < 0) + if (ret < 0 && ret != -ENOSYS) goto err_pm_get_sync; ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component, diff -Nru linux-6.0.6/sound/soc/fsl/fsl_esai.c linux-6.0.12/sound/soc/fsl/fsl_esai.c --- linux-6.0.6/sound/soc/fsl/fsl_esai.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/fsl/fsl_esai.c 2023-01-18 18:27:39.000000000 +0000 @@ -1069,7 +1069,7 @@ regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); ret = pm_runtime_put_sync(&pdev->dev); - if (ret < 0) + if (ret < 0 && ret != -ENOSYS) goto err_pm_get_sync; /* diff -Nru linux-6.0.6/sound/soc/fsl/fsl_sai.c linux-6.0.12/sound/soc/fsl/fsl_sai.c --- linux-6.0.6/sound/soc/fsl/fsl_sai.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/fsl/fsl_sai.c 2023-01-18 18:27:39.000000000 +0000 @@ -1415,7 +1415,7 @@ } ret = pm_runtime_put_sync(dev); - if (ret < 0) + if (ret < 0 && ret != -ENOSYS) goto err_pm_get_sync; /* diff -Nru linux-6.0.6/sound/soc/intel/boards/bytcht_es8316.c linux-6.0.12/sound/soc/intel/boards/bytcht_es8316.c --- linux-6.0.6/sound/soc/intel/boards/bytcht_es8316.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/intel/boards/bytcht_es8316.c 2023-01-18 18:27:39.000000000 +0000 @@ -443,6 +443,13 @@ | BYT_CHT_ES8316_INTMIC_IN2_MAP | BYT_CHT_ES8316_JD_INVERTED), }, + { /* Nanote UMPC-01 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"), + DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"), + }, + .driver_data = (void *)BYT_CHT_ES8316_INTMIC_IN1_MAP, + }, { /* Teclast X98 Plus II */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), diff -Nru linux-6.0.6/sound/soc/intel/boards/sof_es8336.c linux-6.0.12/sound/soc/intel/boards/sof_es8336.c --- linux-6.0.6/sound/soc/intel/boards/sof_es8336.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/intel/boards/sof_es8336.c 2023-01-18 18:27:39.000000000 +0000 @@ -63,6 +63,7 @@ struct snd_soc_jack jack; struct list_head hdmi_pcm_list; bool speaker_en; + struct delayed_work pcm_pop_work; }; struct sof_hdmi_pcm { @@ -111,6 +112,46 @@ dev_info(dev, "quirk headset at mic1 port enabled\n"); } +static void pcm_pop_work_events(struct work_struct *work) +{ + struct sof_es8336_private *priv = + container_of(work, struct sof_es8336_private, pcm_pop_work.work); + + gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en); + + if (quirk & SOF_ES8336_HEADPHONE_GPIO) + gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en); + +} + +static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_card *card = rtd->card; + struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: + break; + + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + if (priv->speaker_en == false) + if (substream->stream == 0) { + cancel_delayed_work(&priv->pcm_pop_work); + gpiod_set_value_cansleep(priv->gpio_speakers, true); + } + break; + default: + return -EINVAL; + } + + return 0; +} + static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -122,19 +163,7 @@ priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event); - if (SND_SOC_DAPM_EVENT_ON(event)) - msleep(70); - - gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en); - - if (!(quirk & SOF_ES8336_HEADPHONE_GPIO)) - return 0; - - if (SND_SOC_DAPM_EVENT_ON(event)) - msleep(70); - - gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en); - + queue_delayed_work(system_wq, &priv->pcm_pop_work, msecs_to_jiffies(70)); return 0; } @@ -344,6 +373,7 @@ /* machine stream operations */ static struct snd_soc_ops sof_es8336_ops = { .hw_params = sof_es8336_hw_params, + .trigger = sof_8336_trigger, }; static struct snd_soc_dai_link_component platform_component[] = { @@ -722,7 +752,8 @@ } INIT_LIST_HEAD(&priv->hdmi_pcm_list); - + INIT_DELAYED_WORK(&priv->pcm_pop_work, + pcm_pop_work_events); snd_soc_card_set_drvdata(card, priv); if (mach->mach_params.dmic_num > 0) { @@ -751,6 +782,7 @@ struct snd_soc_card *card = platform_get_drvdata(pdev); struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); + cancel_delayed_work(&priv->pcm_pop_work); gpiod_put(priv->gpio_speakers); device_remove_software_node(priv->codec_dev); put_device(priv->codec_dev); diff -Nru linux-6.0.6/sound/soc/intel/boards/sof_rt5682.c linux-6.0.12/sound/soc/intel/boards/sof_rt5682.c --- linux-6.0.6/sound/soc/intel/boards/sof_rt5682.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/intel/boards/sof_rt5682.c 2023-01-18 18:27:39.000000000 +0000 @@ -225,6 +225,18 @@ SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, + { + .callback = sof_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"), + }, + .driver_data = (void *)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(2) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(0) | + SOF_RT5682_NUM_HDMIDEV(4) + ), + }, {} }; diff -Nru linux-6.0.6/sound/soc/intel/boards/sof_sdw.c linux-6.0.12/sound/soc/intel/boards/sof_sdw.c --- linux-6.0.6/sound/soc/intel/boards/sof_sdw.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/intel/boards/sof_sdw.c 2023-01-18 18:27:39.000000000 +0000 @@ -202,6 +202,17 @@ SOF_SDW_PCH_DMIC | RT711_JD1), }, + { + /* NUC15 LAPBC710 skews */ + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_PCH_DMIC | + RT711_JD1), + }, /* TigerLake-SDCA devices */ { .callback = sof_sdw_quirk_cb, diff -Nru linux-6.0.6/sound/soc/intel/common/Makefile linux-6.0.12/sound/soc/intel/common/Makefile --- linux-6.0.6/sound/soc/intel/common/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/intel/common/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -9,7 +9,7 @@ soc-acpi-intel-cml-match.o soc-acpi-intel-icl-match.o \ soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \ soc-acpi-intel-jsl-match.o soc-acpi-intel-adl-match.o \ - soc-acpi-intel-mtl-match.o \ + soc-acpi-intel-rpl-match.o soc-acpi-intel-mtl-match.o \ soc-acpi-intel-hda-match.o \ soc-acpi-intel-sdw-mockup-match.o diff -Nru linux-6.0.6/sound/soc/intel/common/soc-acpi-intel-icl-match.c linux-6.0.12/sound/soc/intel/common/soc-acpi-intel-icl-match.c --- linux-6.0.6/sound/soc/intel/common/soc-acpi-intel-icl-match.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/intel/common/soc-acpi-intel-icl-match.c 2023-01-18 18:27:39.000000000 +0000 @@ -10,6 +10,11 @@ #include #include "../skylake/skl.h" +static const struct snd_soc_acpi_codecs essx_83x6 = { + .num_codecs = 3, + .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, +}; + static struct skl_machine_pdata icl_pdata = { .use_tplg_pcm = true, }; @@ -27,6 +32,14 @@ .drv_name = "sof_rt5682", .sof_tplg_filename = "sof-icl-rt5682.tplg", }, + { + .comp_ids = &essx_83x6, + .drv_name = "sof-essx8336", + .sof_tplg_filename = "sof-icl-es8336", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER | + SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | + SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines); diff -Nru linux-6.0.6/sound/soc/intel/common/soc-acpi-intel-rpl-match.c linux-6.0.12/sound/soc/intel/common/soc-acpi-intel-rpl-match.c --- linux-6.0.6/sound/soc/intel/common/soc-acpi-intel-rpl-match.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-6.0.12/sound/soc/intel/common/soc-acpi-intel-rpl-match.c 2023-01-18 18:27:39.000000000 +0000 @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * soc-apci-intel-rpl-match.c - tables and support for RPL ACPI enumeration. + * + * Copyright (c) 2022 Intel Corporation. + */ + +#include +#include + +static const struct snd_soc_acpi_endpoint single_endpoint = { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, +}; + +static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { + { + .adr = 0x000020025D071100ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + } +}; + +static const struct snd_soc_acpi_link_adr rpl_rvp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_0_adr), + .adr_d = rt711_0_adr, + }, + {} +}; + +struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_machines); + +/* this table is used when there is no I2S codec present */ +struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { + { + .link_mask = 0x1, /* link0 required */ + .links = rpl_rvp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711.tplg", + }, + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_sdw_machines); diff -Nru linux-6.0.6/sound/soc/qcom/lpass-cpu.c linux-6.0.12/sound/soc/qcom/lpass-cpu.c --- linux-6.0.6/sound/soc/qcom/lpass-cpu.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/qcom/lpass-cpu.c 2023-01-18 18:27:39.000000000 +0000 @@ -782,10 +782,20 @@ return true; if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v)) return true; + if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v)) + return true; + if (reg == LPASS_HDMI_TX_PARITY_ADDR(v)) + return true; for (i = 0; i < v->hdmi_rdma_channels; ++i) { if (reg == LPAIF_HDMI_RDMACURR_REG(v, i)) return true; + if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i)) + return true; + if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i)) + return true; + if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i)) + return true; } return false; } diff -Nru linux-6.0.6/sound/soc/soc-core.c linux-6.0.12/sound/soc/soc-core.c --- linux-6.0.6/sound/soc/soc-core.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/soc-core.c 2023-01-18 18:27:39.000000000 +0000 @@ -3472,10 +3472,23 @@ static int __init snd_soc_init(void) { + int ret; + snd_soc_debugfs_init(); - snd_soc_util_init(); + ret = snd_soc_util_init(); + if (ret) + goto err_util_init; + + ret = platform_driver_register(&soc_driver); + if (ret) + goto err_register; + return 0; - return platform_driver_register(&soc_driver); +err_register: + snd_soc_util_exit(); +err_util_init: + snd_soc_debugfs_exit(); + return ret; } module_init(snd_soc_init); diff -Nru linux-6.0.6/sound/soc/soc-ops.c linux-6.0.12/sound/soc/soc-ops.c --- linux-6.0.6/sound/soc/soc-ops.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/soc-ops.c 2023-01-18 18:27:39.000000000 +0000 @@ -452,7 +452,7 @@ val = ucontrol->value.integer.value[0]; if (mc->platform_max && val > mc->platform_max) return -EINVAL; - if (val > max - min) + if (val > max) return -EINVAL; val_mask = mask << shift; val = (val + min) & mask; diff -Nru linux-6.0.6/sound/soc/soc-pcm.c linux-6.0.12/sound/soc/soc-pcm.c --- linux-6.0.6/sound/soc/soc-pcm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/soc-pcm.c 2023-01-18 18:27:39.000000000 +0000 @@ -800,11 +800,6 @@ ret = snd_soc_dai_startup(dai, substream); if (ret < 0) goto err; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dai->tx_mask = 0; - else - dai->rx_mask = 0; } /* Dynamic PCM DAI links compat checks use dynamic capabilities */ diff -Nru linux-6.0.6/sound/soc/soc-utils.c linux-6.0.12/sound/soc/soc-utils.c --- linux-6.0.6/sound/soc/soc-utils.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/soc-utils.c 2023-01-18 18:27:39.000000000 +0000 @@ -263,7 +263,7 @@ return ret; } -void __exit snd_soc_util_exit(void) +void snd_soc_util_exit(void) { platform_driver_unregister(&soc_dummy_driver); platform_device_unregister(soc_dummy_dev); diff -Nru linux-6.0.6/sound/soc/sof/intel/pci-mtl.c linux-6.0.12/sound/soc/sof/intel/pci-mtl.c --- linux-6.0.6/sound/soc/sof/intel/pci-mtl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/sof/intel/pci-mtl.c 2023-01-18 18:27:39.000000000 +0000 @@ -38,7 +38,7 @@ [SOF_INTEL_IPC4] = "intel/sof-ace-tplg", }, .default_fw_filename = { - [SOF_INTEL_IPC4] = "dsp_basefw.bin", + [SOF_INTEL_IPC4] = "sof-mtl.ri", }, .nocodec_tplg_filename = "sof-mtl-nocodec.tplg", .ops = &sof_mtl_ops, diff -Nru linux-6.0.6/sound/soc/sof/intel/pci-tgl.c linux-6.0.12/sound/soc/sof/intel/pci-tgl.c --- linux-6.0.6/sound/soc/sof/intel/pci-tgl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/sof/intel/pci-tgl.c 2023-01-18 18:27:39.000000000 +0000 @@ -159,6 +159,90 @@ .ops_init = sof_tgl_ops_init, }; +static const struct sof_dev_desc adl_n_desc = { + .machines = snd_soc_acpi_intel_adl_machines, + .alt_machines = snd_soc_acpi_intel_adl_sdw_machines, + .use_acpi_target_states = true, + .resindex_lpe_base = 0, + .resindex_pcicfg_base = -1, + .resindex_imr_base = -1, + .irqindex_host_ipc = -1, + .chip_info = &tgl_chip_info, + .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4), + .ipc_default = SOF_IPC, + .default_fw_path = { + [SOF_IPC] = "intel/sof", + [SOF_INTEL_IPC4] = "intel/avs/adl-n", + }, + .default_tplg_path = { + [SOF_IPC] = "intel/sof-tplg", + [SOF_INTEL_IPC4] = "intel/avs-tplg", + }, + .default_fw_filename = { + [SOF_IPC] = "sof-adl-n.ri", + [SOF_INTEL_IPC4] = "dsp_basefw.bin", + }, + .nocodec_tplg_filename = "sof-adl-nocodec.tplg", + .ops = &sof_tgl_ops, + .ops_init = sof_tgl_ops_init, +}; + +static const struct sof_dev_desc rpls_desc = { + .machines = snd_soc_acpi_intel_rpl_machines, + .alt_machines = snd_soc_acpi_intel_rpl_sdw_machines, + .use_acpi_target_states = true, + .resindex_lpe_base = 0, + .resindex_pcicfg_base = -1, + .resindex_imr_base = -1, + .irqindex_host_ipc = -1, + .chip_info = &adls_chip_info, + .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4), + .ipc_default = SOF_IPC, + .default_fw_path = { + [SOF_IPC] = "intel/sof", + [SOF_INTEL_IPC4] = "intel/avs/rpl-s", + }, + .default_tplg_path = { + [SOF_IPC] = "intel/sof-tplg", + [SOF_INTEL_IPC4] = "intel/avs-tplg", + }, + .default_fw_filename = { + [SOF_IPC] = "sof-rpl-s.ri", + [SOF_INTEL_IPC4] = "dsp_basefw.bin", + }, + .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", + .ops = &sof_tgl_ops, + .ops_init = sof_tgl_ops_init, +}; + +static const struct sof_dev_desc rpl_desc = { + .machines = snd_soc_acpi_intel_rpl_machines, + .alt_machines = snd_soc_acpi_intel_rpl_sdw_machines, + .use_acpi_target_states = true, + .resindex_lpe_base = 0, + .resindex_pcicfg_base = -1, + .resindex_imr_base = -1, + .irqindex_host_ipc = -1, + .chip_info = &tgl_chip_info, + .ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4), + .ipc_default = SOF_IPC, + .default_fw_path = { + [SOF_IPC] = "intel/sof", + [SOF_INTEL_IPC4] = "intel/avs/rpl", + }, + .default_tplg_path = { + [SOF_IPC] = "intel/sof-tplg", + [SOF_INTEL_IPC4] = "intel/avs-tplg", + }, + .default_fw_filename = { + [SOF_IPC] = "sof-rpl.ri", + [SOF_INTEL_IPC4] = "dsp_basefw.bin", + }, + .nocodec_tplg_filename = "sof-rpl-nocodec.tplg", + .ops = &sof_tgl_ops, + .ops_init = sof_tgl_ops_init, +}; + /* PCI IDs */ static const struct pci_device_id sof_pci_ids[] = { { PCI_DEVICE(0x8086, 0xa0c8), /* TGL-LP */ @@ -172,7 +256,7 @@ { PCI_DEVICE(0x8086, 0x7ad0), /* ADL-S */ .driver_data = (unsigned long)&adls_desc}, { PCI_DEVICE(0x8086, 0x7a50), /* RPL-S */ - .driver_data = (unsigned long)&adls_desc}, + .driver_data = (unsigned long)&rpls_desc}, { PCI_DEVICE(0x8086, 0x51c8), /* ADL-P */ .driver_data = (unsigned long)&adl_desc}, { PCI_DEVICE(0x8086, 0x51cd), /* ADL-P */ @@ -180,13 +264,13 @@ { PCI_DEVICE(0x8086, 0x51c9), /* ADL-PS */ .driver_data = (unsigned long)&adl_desc}, { PCI_DEVICE(0x8086, 0x51ca), /* RPL-P */ - .driver_data = (unsigned long)&adl_desc}, + .driver_data = (unsigned long)&rpl_desc}, { PCI_DEVICE(0x8086, 0x51cb), /* RPL-P */ - .driver_data = (unsigned long)&adl_desc}, + .driver_data = (unsigned long)&rpl_desc}, { PCI_DEVICE(0x8086, 0x51cc), /* ADL-M */ .driver_data = (unsigned long)&adl_desc}, { PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */ - .driver_data = (unsigned long)&adl_desc}, + .driver_data = (unsigned long)&adl_n_desc}, { 0, } }; MODULE_DEVICE_TABLE(pci, sof_pci_ids); diff -Nru linux-6.0.6/sound/soc/sof/ipc3-topology.c linux-6.0.12/sound/soc/sof/ipc3-topology.c --- linux-6.0.6/sound/soc/sof/ipc3-topology.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/sof/ipc3-topology.c 2023-01-18 18:27:39.000000000 +0000 @@ -2242,6 +2242,7 @@ struct sof_ipc_fw_version *v = &sdev->fw_ready.version; struct snd_sof_widget *swidget; struct snd_sof_route *sroute; + bool dyn_widgets = false; int ret; /* @@ -2251,12 +2252,14 @@ * topology loading the sound card unavailable to open PCMs. */ list_for_each_entry(swidget, &sdev->widget_list, list) { - if (swidget->dynamic_pipeline_widget) + if (swidget->dynamic_pipeline_widget) { + dyn_widgets = true; continue; + } - /* Do not free widgets for static pipelines with FW ABI older than 3.19 */ + /* Do not free widgets for static pipelines with FW older than SOF2.2 */ if (!verify && !swidget->dynamic_pipeline_widget && - v->abi_version < SOF_ABI_VER(3, 19, 0)) { + SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) { swidget->use_count = 0; swidget->complete = 0; continue; @@ -2270,9 +2273,11 @@ /* * Tear down all pipelines associated with PCMs that did not get suspended * and unset the prepare flag so that they can be set up again during resume. - * Skip this step for older firmware. + * Skip this step for older firmware unless topology has any + * dynamic pipeline (in which case the step is mandatory). */ - if (!verify && v->abi_version >= SOF_ABI_VER(3, 19, 0)) { + if (!verify && (dyn_widgets || SOF_FW_VER(v->major, v->minor, v->micro) >= + SOF_FW_VER(2, 2, 0))) { ret = sof_tear_down_left_over_pipelines(sdev); if (ret < 0) { dev_err(sdev->dev, "failed to tear down paused pipelines\n"); diff -Nru linux-6.0.6/sound/soc/sof/topology.c linux-6.0.12/sound/soc/sof/topology.c --- linux-6.0.6/sound/soc/sof/topology.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/sof/topology.c 2023-01-18 18:27:39.000000000 +0000 @@ -1346,16 +1346,6 @@ break; } - if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) { - swidget->core = SOF_DSP_PRIMARY_CORE; - } else { - int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples, - swidget->num_tuples); - - if (core >= 0) - swidget->core = core; - } - /* check token parsing reply */ if (ret < 0) { dev_err(scomp->dev, @@ -1367,6 +1357,16 @@ return ret; } + if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) { + swidget->core = SOF_DSP_PRIMARY_CORE; + } else { + int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples, + swidget->num_tuples); + + if (core >= 0) + swidget->core = core; + } + /* bind widget to external event */ if (tw->event_type) { if (widget_ops[w->id].bind_event) { diff -Nru linux-6.0.6/sound/soc/stm/stm32_adfsdm.c linux-6.0.12/sound/soc/stm/stm32_adfsdm.c --- linux-6.0.6/sound/soc/stm/stm32_adfsdm.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/soc/stm/stm32_adfsdm.c 2023-01-18 18:27:39.000000000 +0000 @@ -304,6 +304,11 @@ return 0; } +static void stm32_adfsdm_cleanup(void *data) +{ + iio_channel_release_all_cb(data); +} + static struct snd_soc_component_driver stm32_adfsdm_soc_platform = { .open = stm32_adfsdm_pcm_open, .close = stm32_adfsdm_pcm_close, @@ -350,6 +355,12 @@ if (IS_ERR(priv->iio_cb)) return PTR_ERR(priv->iio_cb); + ret = devm_add_action_or_reset(&pdev->dev, stm32_adfsdm_cleanup, priv->iio_cb); + if (ret < 0) { + dev_err(&pdev->dev, "Unable to add action\n"); + return ret; + } + component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL); if (!component) return -ENOMEM; diff -Nru linux-6.0.6/sound/synth/emux/emux.c linux-6.0.12/sound/synth/emux/emux.c --- linux-6.0.6/sound/synth/emux/emux.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/synth/emux/emux.c 2023-01-18 18:27:39.000000000 +0000 @@ -126,15 +126,10 @@ */ int snd_emux_free(struct snd_emux *emu) { - unsigned long flags; - if (! emu) return -EINVAL; - spin_lock_irqsave(&emu->voice_lock, flags); - if (emu->timer_active) - del_timer(&emu->tlist); - spin_unlock_irqrestore(&emu->voice_lock, flags); + del_timer_sync(&emu->tlist); snd_emux_proc_free(emu); snd_emux_delete_virmidi(emu); diff -Nru linux-6.0.6/sound/usb/card.c linux-6.0.12/sound/usb/card.c --- linux-6.0.6/sound/usb/card.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/usb/card.c 2023-01-18 18:27:39.000000000 +0000 @@ -742,6 +742,18 @@ return NULL; } +/* register card if we reach to the last interface or to the specified + * one given via option + */ +static int try_to_register_card(struct snd_usb_audio *chip, int ifnum) +{ + if (check_delayed_register_option(chip) == ifnum || + chip->last_iface == ifnum || + usb_interface_claimed(usb_ifnum_to_if(chip->dev, chip->last_iface))) + return snd_card_register(chip->card); + return 0; +} + /* * probe the active usb device * @@ -880,15 +892,9 @@ chip->need_delayed_register = false; /* clear again */ } - /* register card if we reach to the last interface or to the specified - * one given via option - */ - if (check_delayed_register_option(chip) == ifnum || - usb_interface_claimed(usb_ifnum_to_if(dev, chip->last_iface))) { - err = snd_card_register(chip->card); - if (err < 0) - goto __error; - } + err = try_to_register_card(chip, ifnum); + if (err < 0) + goto __error_no_register; if (chip->quirk_flags & QUIRK_FLAG_SHARE_MEDIA_DEVICE) { /* don't want to fail when snd_media_device_create() fails */ @@ -907,6 +913,11 @@ return 0; __error: + /* in the case of error in secondary interface, still try to register */ + if (chip) + try_to_register_card(chip, ifnum); + + __error_no_register: if (chip) { /* chip->active is inside the chip->card object, * decrement before memory is possibly returned. diff -Nru linux-6.0.6/sound/usb/endpoint.c linux-6.0.12/sound/usb/endpoint.c --- linux-6.0.6/sound/usb/endpoint.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/usb/endpoint.c 2023-01-18 18:27:39.000000000 +0000 @@ -923,7 +923,8 @@ usb_audio_dbg(chip, "Closing EP 0x%x (count %d)\n", ep->ep_num, ep->opened); - if (!--ep->iface_ref->opened) + if (!--ep->iface_ref->opened && + !(chip->quirk_flags & QUIRK_FLAG_IFACE_SKIP_CLOSE)) endpoint_set_interface(chip, ep, false); if (!--ep->opened) { diff -Nru linux-6.0.6/sound/usb/implicit.c linux-6.0.12/sound/usb/implicit.c --- linux-6.0.6/sound/usb/implicit.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/usb/implicit.c 2023-01-18 18:27:39.000000000 +0000 @@ -47,6 +47,8 @@ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = { /* Fixed EP */ /* FIXME: check the availability of generic matching */ + IMPLICIT_FB_FIXED_DEV(0x0763, 0x2030, 0x81, 3), /* M-Audio Fast Track C400 */ + IMPLICIT_FB_FIXED_DEV(0x0763, 0x2031, 0x81, 3), /* M-Audio Fast Track C600 */ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2), /* M-Audio FastTrack Ultra */ IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */ diff -Nru linux-6.0.6/sound/usb/midi.c linux-6.0.12/sound/usb/midi.c --- linux-6.0.6/sound/usb/midi.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/usb/midi.c 2023-01-18 18:27:39.000000000 +0000 @@ -1133,10 +1133,8 @@ port = &umidi->endpoints[i].out->ports[j]; break; } - if (!port) { - snd_BUG(); + if (!port) return -ENXIO; - } substream->runtime->private_data = port; port->state = STATE_UNKNOWN; diff -Nru linux-6.0.6/sound/usb/mixer.c linux-6.0.12/sound/usb/mixer.c --- linux-6.0.6/sound/usb/mixer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/usb/mixer.c 2023-01-18 18:27:39.000000000 +0000 @@ -1631,7 +1631,7 @@ if (!found) return; - strscpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); + snd_ctl_rename(card, kctl, "Headphone"); } static const struct usb_feature_control_info *get_feature_control_info(int control) diff -Nru linux-6.0.6/sound/usb/quirks.c linux-6.0.12/sound/usb/quirks.c --- linux-6.0.6/sound/usb/quirks.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/usb/quirks.c 2023-01-18 18:27:39.000000000 +0000 @@ -1913,6 +1913,7 @@ /* XMOS based USB DACs */ switch (chip->usb_id) { case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */ + case USB_ID(0x21ed, 0xd75a): /* Accuphase DAC-60 option card */ case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */ case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ if (fp->altsetting == 2) @@ -2185,6 +2186,8 @@ QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */ + QUIRK_FLAG_IFACE_SKIP_CLOSE), /* Vendor matches */ VENDOR_FLG(0x045e, /* MS Lifecam */ diff -Nru linux-6.0.6/sound/usb/quirks-table.h linux-6.0.12/sound/usb/quirks-table.h --- linux-6.0.6/sound/usb/quirks-table.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/usb/quirks-table.h 2023-01-18 18:27:39.000000000 +0000 @@ -2050,6 +2050,10 @@ } }, { + /* M-Audio Micro */ + USB_DEVICE_VENDOR_SPEC(0x0763, 0x201a), +}, +{ USB_DEVICE_VENDOR_SPEC(0x0763, 0x2030), .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { /* .vendor_name = "M-Audio", */ diff -Nru linux-6.0.6/sound/usb/usbaudio.h linux-6.0.12/sound/usb/usbaudio.h --- linux-6.0.6/sound/usb/usbaudio.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/sound/usb/usbaudio.h 2023-01-18 18:27:39.000000000 +0000 @@ -170,6 +170,8 @@ * Apply the generic implicit feedback sync mode (same as implicit_fb=1 option) * QUIRK_FLAG_SKIP_IMPLICIT_FB * Don't apply implicit feedback sync mode + * QUIRK_FLAG_IFACE_SKIP_CLOSE + * Don't closed interface during setting sample rate */ #define QUIRK_FLAG_GET_SAMPLE_RATE (1U << 0) @@ -191,5 +193,6 @@ #define QUIRK_FLAG_SET_IFACE_FIRST (1U << 16) #define QUIRK_FLAG_GENERIC_IMPLICIT_FB (1U << 17) #define QUIRK_FLAG_SKIP_IMPLICIT_FB (1U << 18) +#define QUIRK_FLAG_IFACE_SKIP_CLOSE (1U << 19) #endif /* __USBAUDIO_H */ diff -Nru linux-6.0.6/tools/arch/x86/include/asm/msr-index.h linux-6.0.12/tools/arch/x86/include/asm/msr-index.h --- linux-6.0.6/tools/arch/x86/include/asm/msr-index.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/arch/x86/include/asm/msr-index.h 2023-01-18 18:27:39.000000000 +0000 @@ -530,6 +530,11 @@ #define MSR_AMD64_CPUID_FN_1 0xc0011004 #define MSR_AMD64_LS_CFG 0xc0011020 #define MSR_AMD64_DC_CFG 0xc0011022 + +#define MSR_AMD64_DE_CFG 0xc0011029 +#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1 +#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT) + #define MSR_AMD64_BU_CFG2 0xc001102a #define MSR_AMD64_IBSFETCHCTL 0xc0011030 #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 @@ -632,9 +637,6 @@ #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL #define FAM10H_MMIO_CONF_BASE_SHIFT 20 #define MSR_FAM10H_NODE_ID 0xc001100c -#define MSR_F10H_DECFG 0xc0011029 -#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT 1 -#define MSR_F10H_DECFG_LFENCE_SERIALIZE BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT) /* K8 MSRs */ #define MSR_K8_TOP_MEM1 0xc001001a diff -Nru linux-6.0.6/tools/bpf/bpftool/common.c linux-6.0.12/tools/bpf/bpftool/common.c --- linux-6.0.6/tools/bpf/bpftool/common.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/bpf/bpftool/common.c 2023-01-18 18:27:39.000000000 +0000 @@ -300,6 +300,9 @@ int err; int fd; + if (!REQ_ARGS(3)) + return -EINVAL; + fd = get_fd(&argc, &argv); if (fd < 0) return fd; diff -Nru linux-6.0.6/tools/hv/lsvmbus.8 linux-6.0.12/tools/hv/lsvmbus.8 --- linux-6.0.6/tools/hv/lsvmbus.8 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/hv/lsvmbus.8 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -.\" This page Copyright (C) 2016 Andy Whitcroft -.\" Distributed under the GPL v2 or later. -.TH LSVMBUS 8 -.SH NAME -lsvmbus \- List Hyper-V VMBus devices -.SH SYNOPSIS -.ft B -.B lsvmbus [-vv] -.br -.SH DESCRIPTION -\fBlsvmbus\fP -displays devices attached to the Hyper-V VMBus. -.SH OPTIONS -.\" -.TP -.B -v -With -v more information is printed including the VMBus Rel_ID, class ID, -Rel_ID, and which channel is bound to which virtual processor. Use -vv -for additional detail including the Device_ID and the sysfs path. -.\" -.SH AUTHORS -.nf -Written by Dexuan Cui diff -Nru linux-6.0.6/tools/iio/iio_generic_buffer.c linux-6.0.12/tools/iio/iio_generic_buffer.c --- linux-6.0.6/tools/iio/iio_generic_buffer.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/iio/iio_generic_buffer.c 2023-01-18 18:27:39.000000000 +0000 @@ -715,12 +715,12 @@ continue; } - toread = buf_len; } else { usleep(timedelay); - toread = 64; } + toread = buf_len; + read_size = read(buf_fd, data, toread * scan_size); if (read_size < 0) { if (errno == EAGAIN) { diff -Nru linux-6.0.6/tools/iio/iio_utils.c linux-6.0.12/tools/iio/iio_utils.c --- linux-6.0.6/tools/iio/iio_utils.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/iio/iio_utils.c 2023-01-18 18:27:39.000000000 +0000 @@ -547,6 +547,10 @@ { int count = 0; + /* It takes a digit to represent zero */ + if (!num) + return 1; + while (num != 0) { num /= 10; count++; diff -Nru linux-6.0.6/tools/include/nolibc/string.h linux-6.0.12/tools/include/nolibc/string.h --- linux-6.0.6/tools/include/nolibc/string.h 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/include/nolibc/string.h 2023-01-18 18:27:39.000000000 +0000 @@ -19,9 +19,9 @@ int memcmp(const void *s1, const void *s2, size_t n) { size_t ofs = 0; - char c1 = 0; + int c1 = 0; - while (ofs < n && !(c1 = ((char *)s1)[ofs] - ((char *)s2)[ofs])) { + while (ofs < n && !(c1 = ((unsigned char *)s1)[ofs] - ((unsigned char *)s2)[ofs])) { ofs++; } return c1; @@ -125,14 +125,18 @@ } /* this function is only used with arguments that are not constants or when - * it's not known because optimizations are disabled. + * it's not known because optimizations are disabled. Note that gcc 12 + * recognizes an strlen() pattern and replaces it with a jump to strlen(), + * thus itself, hence the asm() statement below that's meant to disable this + * confusing practice. */ static __attribute__((unused)) -size_t nolibc_strlen(const char *str) +size_t strlen(const char *str) { size_t len; - for (len = 0; str[len]; len++); + for (len = 0; str[len]; len++) + asm(""); return len; } @@ -140,13 +144,12 @@ * the two branches, then will rely on an external definition of strlen(). */ #if defined(__OPTIMIZE__) +#define nolibc_strlen(x) strlen(x) #define strlen(str) ({ \ __builtin_constant_p((str)) ? \ __builtin_strlen((str)) : \ nolibc_strlen((str)); \ }) -#else -#define strlen(str) nolibc_strlen((str)) #endif static __attribute__((unused)) diff -Nru linux-6.0.6/tools/lib/bpf/libbpf.c linux-6.0.12/tools/lib/bpf/libbpf.c --- linux-6.0.6/tools/lib/bpf/libbpf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/lib/bpf/libbpf.c 2023-01-18 18:27:39.000000000 +0000 @@ -11143,7 +11143,7 @@ } *link = bpf_program__attach_raw_tracepoint(prog, tp_name); - return libbpf_get_error(link); + return libbpf_get_error(*link); } /* Common logic for all BPF program types that attach to a btf_id */ diff -Nru linux-6.0.6/tools/lib/bpf/ringbuf.c linux-6.0.12/tools/lib/bpf/ringbuf.c --- linux-6.0.6/tools/lib/bpf/ringbuf.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/lib/bpf/ringbuf.c 2023-01-18 18:27:39.000000000 +0000 @@ -59,6 +59,7 @@ __u32 len = sizeof(info); struct epoll_event *e; struct ring *r; + __u64 mmap_sz; void *tmp; int err; @@ -97,8 +98,7 @@ r->mask = info.max_entries - 1; /* Map writable consumer page */ - tmp = mmap(NULL, rb->page_size, PROT_READ | PROT_WRITE, MAP_SHARED, - map_fd, 0); + tmp = mmap(NULL, rb->page_size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); if (tmp == MAP_FAILED) { err = -errno; pr_warn("ringbuf: failed to mmap consumer page for map fd=%d: %d\n", @@ -111,8 +111,12 @@ * data size to allow simple reading of samples that wrap around the * end of a ring buffer. See kernel implementation for details. * */ - tmp = mmap(NULL, rb->page_size + 2 * info.max_entries, PROT_READ, - MAP_SHARED, map_fd, rb->page_size); + mmap_sz = rb->page_size + 2 * (__u64)info.max_entries; + if (mmap_sz != (__u64)(size_t)mmap_sz) { + pr_warn("ringbuf: ring buffer size (%u) is too big\n", info.max_entries); + return libbpf_err(-E2BIG); + } + tmp = mmap(NULL, (size_t)mmap_sz, PROT_READ, MAP_SHARED, map_fd, rb->page_size); if (tmp == MAP_FAILED) { err = -errno; ringbuf_unmap_ring(rb, r); diff -Nru linux-6.0.6/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json linux-6.0.12/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json --- linux-6.0.6/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json 2023-01-18 18:27:39.000000000 +0000 @@ -112,21 +112,21 @@ "MetricName": "indirect_branch" }, { - "MetricExpr": "(armv8_pmuv3_0@event\\=0x1014@ + armv8_pmuv3_0@event\\=0x1018@) / BR_MIS_PRED", + "MetricExpr": "(armv8_pmuv3_0@event\\=0x1013@ + armv8_pmuv3_0@event\\=0x1016@) / BR_MIS_PRED", "PublicDescription": "Push branch L3 topdown metric", "BriefDescription": "Push branch L3 topdown metric", "MetricGroup": "TopDownL3", "MetricName": "push_branch" }, { - "MetricExpr": "armv8_pmuv3_0@event\\=0x100c@ / BR_MIS_PRED", + "MetricExpr": "armv8_pmuv3_0@event\\=0x100d@ / BR_MIS_PRED", "PublicDescription": "Pop branch L3 topdown metric", "BriefDescription": "Pop branch L3 topdown metric", "MetricGroup": "TopDownL3", "MetricName": "pop_branch" }, { - "MetricExpr": "(BR_MIS_PRED - armv8_pmuv3_0@event\\=0x1010@ - armv8_pmuv3_0@event\\=0x1014@ - armv8_pmuv3_0@event\\=0x1018@ - armv8_pmuv3_0@event\\=0x100c@) / BR_MIS_PRED", + "MetricExpr": "(BR_MIS_PRED - armv8_pmuv3_0@event\\=0x1010@ - armv8_pmuv3_0@event\\=0x1013@ - armv8_pmuv3_0@event\\=0x1016@ - armv8_pmuv3_0@event\\=0x100d@) / BR_MIS_PRED", "PublicDescription": "Other branch L3 topdown metric", "BriefDescription": "Other branch L3 topdown metric", "MetricGroup": "TopDownL3", diff -Nru linux-6.0.6/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json linux-6.0.12/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json --- linux-6.0.6/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json 2023-01-18 18:27:39.000000000 +0000 @@ -1,13 +1,13 @@ [ { "MetricName": "VEC_GROUP_PUMP_RETRY_RATIO_P01", - "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP01\\,chip\\=?@ / hv_24x7@PM_PB_VG_PUMP01\\,chip\\=?@) * 100", + "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP01\\,chip\\=?@ / (1 + hv_24x7@PM_PB_VG_PUMP01\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "VEC_GROUP_PUMP_RETRY_RATIO_P23", - "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP23\\,chip\\=?@ / hv_24x7@PM_PB_VG_PUMP23\\,chip\\=?@) * 100", + "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP23\\,chip\\=?@ / (1 + hv_24x7@PM_PB_VG_PUMP23\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, @@ -61,13 +61,13 @@ }, { "MetricName": "REMOTE_NODE_PUMPS_RETRIES_RATIO_P01", - "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP01\\,chip\\=?@ / hv_24x7@PM_PB_RNS_PUMP01\\,chip\\=?@) * 100", + "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP01\\,chip\\=?@ / (1 + hv_24x7@PM_PB_RNS_PUMP01\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "REMOTE_NODE_PUMPS_RETRIES_RATIO_P23", - "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP23\\,chip\\=?@ / hv_24x7@PM_PB_RNS_PUMP23\\,chip\\=?@) * 100", + "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP23\\,chip\\=?@ / (1 + hv_24x7@PM_PB_RNS_PUMP23\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, @@ -151,193 +151,193 @@ }, { "MetricName": "XLINK0_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK1_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK2_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK3_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK4_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK5_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK6_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK7_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK0_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK1_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK2_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK3_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK4_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK5_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK6_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "XLINK7_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK0_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK1_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK2_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK3_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK4_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK5_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK6_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK7_OUT_TOTAL_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK0_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK1_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK2_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK3_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK4_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK5_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK6_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, { "MetricName": "ALINK7_OUT_DATA_UTILIZATION", - "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", + "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100", "ScaleUnit": "1.063%", "AggregationMode": "PerChip" }, diff -Nru linux-6.0.6/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json linux-6.0.12/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json --- linux-6.0.6/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json 1970-01-01 00:00:00.000000000 +0000 +++ linux-6.0.12/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json 2023-01-18 18:27:39.000000000 +0000 @@ -0,0 +1,1101 @@ +[ + { + "Unit": "PAI-CRYPTO", + "EventCode": "4096", + "EventName": "CRYPTO_ALL", + "BriefDescription": "CRYPTO ALL", + "PublicDescription": "Sums of all non zero cryptography counters" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4097", + "EventName": "KM_DEA", + "BriefDescription": "KM DEA", + "PublicDescription": "KM-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4098", + "EventName": "KM_TDEA_128", + "BriefDescription": "KM TDEA 128", + "PublicDescription": "KM-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4099", + "EventName": "KM_TDEA_192", + "BriefDescription": "KM TDEA 192", + "PublicDescription": "KM-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4100", + "EventName": "KM_ENCRYPTED_DEA", + "BriefDescription": "KM ENCRYPTED DEA", + "PublicDescription": "KM-Encrypted-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4101", + "EventName": "KM_ENCRYPTED_TDEA_128", + "BriefDescription": "KM ENCRYPTED TDEA 128", + "PublicDescription": "KM-Encrypted-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4102", + "EventName": "KM_ENCRYPTED_TDEA_192", + "BriefDescription": "KM ENCRYPTED TDEA 192", + "PublicDescription": "KM-Encrypted-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4103", + "EventName": "KM_AES_128", + "BriefDescription": "KM AES 128", + "PublicDescription": "KM-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4104", + "EventName": "KM_AES_192", + "BriefDescription": "KM AES 192", + "PublicDescription": "KM-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4105", + "EventName": "KM_AES_256", + "BriefDescription": "KM AES 256", + "PublicDescription": "KM-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4106", + "EventName": "KM_ENCRYPTED_AES_128", + "BriefDescription": "KM ENCRYPTED AES 128", + "PublicDescription": "KM-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4107", + "EventName": "KM_ENCRYPTED_AES_192", + "BriefDescription": "KM ENCRYPTED AES 192", + "PublicDescription": "KM-Encrypted-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4108", + "EventName": "KM_ENCRYPTED_AES_256", + "BriefDescription": "KM ENCRYPTED AES 256", + "PublicDescription": "KM-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4109", + "EventName": "KM_XTS_AES_128", + "BriefDescription": "KM XTS AES 128", + "PublicDescription": "KM-XTS-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4110", + "EventName": "KM_XTS_AES_256", + "BriefDescription": "KM XTS AES 256", + "PublicDescription": "KM-XTS-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4111", + "EventName": "KM_XTS_ENCRYPTED_AES_128", + "BriefDescription": "KM XTS ENCRYPTED AES 128", + "PublicDescription": "KM-XTS-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4112", + "EventName": "KM_XTS_ENCRYPTED_AES_256", + "BriefDescription": "KM XTS ENCRYPTED AES 256", + "PublicDescription": "KM-XTS-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4113", + "EventName": "KMC_DEA", + "BriefDescription": "KMC DEA", + "PublicDescription": "KMC-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4114", + "EventName": "KMC_TDEA_128", + "BriefDescription": "KMC TDEA 128", + "PublicDescription": "KMC-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4115", + "EventName": "KMC_TDEA_192", + "BriefDescription": "KMC TDEA 192", + "PublicDescription": "KMC-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4116", + "EventName": "KMC_ENCRYPTED_DEA", + "BriefDescription": "KMC ENCRYPTED DEA", + "PublicDescription": "KMC-Encrypted-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4117", + "EventName": "KMC_ENCRYPTED_TDEA_128", + "BriefDescription": "KMC ENCRYPTED TDEA 128", + "PublicDescription": "KMC-Encrypted-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4118", + "EventName": "KMC_ENCRYPTED_TDEA_192", + "BriefDescription": "KMC ENCRYPTED TDEA 192", + "PublicDescription": "KMC-Encrypted-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4119", + "EventName": "KMC_AES_128", + "BriefDescription": "KMC AES 128", + "PublicDescription": "KMC-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4120", + "EventName": "KMC_AES_192", + "BriefDescription": "KMC AES 192", + "PublicDescription": "KMC-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4121", + "EventName": "KMC_AES_256", + "BriefDescription": "KMC AES 256", + "PublicDescription": "KMC-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4122", + "EventName": "KMC_ENCRYPTED_AES_128", + "BriefDescription": "KMC ENCRYPTED AES 128", + "PublicDescription": "KMC-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4123", + "EventName": "KMC_ENCRYPTED_AES_192", + "BriefDescription": "KMC ENCRYPTED AES 192", + "PublicDescription": "KMC-Encrypted-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4124", + "EventName": "KMC_ENCRYPTED_AES_256", + "BriefDescription": "KMC ENCRYPTED AES 256", + "PublicDescription": "KMC-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4125", + "EventName": "KMC_PRNG", + "BriefDescription": "KMC PRNG", + "PublicDescription": "KMC-PRNG function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4126", + "EventName": "KMA_GCM_AES_128", + "BriefDescription": "KMA GCM AES 128", + "PublicDescription": "KMA-GCM-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4127", + "EventName": "KMA_GCM_AES_192", + "BriefDescription": "KMA GCM AES 192", + "PublicDescription": "KMA-GCM-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4128", + "EventName": "KMA_GCM_AES_256", + "BriefDescription": "KMA GCM AES 256", + "PublicDescription": "KMA-GCM-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4129", + "EventName": "KMA_GCM_ENCRYPTED_AES_128", + "BriefDescription": "KMA GCM ENCRYPTED AES 128", + "PublicDescription": "KMA-GCM-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4130", + "EventName": "KMA_GCM_ENCRYPTED_AES_192", + "BriefDescription": "KMA GCM ENCRYPTED AES 192", + "PublicDescription": "KMA-GCM-Encrypted-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4131", + "EventName": "KMA_GCM_ENCRYPTED_AES_256", + "BriefDescription": "KMA GCM ENCRYPTED AES 256", + "PublicDescription": "KMA-GCM-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4132", + "EventName": "KMF_DEA", + "BriefDescription": "KMF DEA", + "PublicDescription": "KMF-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4133", + "EventName": "KMF_TDEA_128", + "BriefDescription": "KMF TDEA 128", + "PublicDescription": "KMF-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4134", + "EventName": "KMF_TDEA_192", + "BriefDescription": "KMF TDEA 192", + "PublicDescription": "KMF-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4135", + "EventName": "KMF_ENCRYPTED_DEA", + "BriefDescription": "KMF ENCRYPTED DEA", + "PublicDescription": "KMF-Encrypted-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4136", + "EventName": "KMF_ENCRYPTED_TDEA_128", + "BriefDescription": "KMF ENCRYPTED TDEA 128", + "PublicDescription": "KMF-Encrypted-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4137", + "EventName": "KMF_ENCRYPTED_TDEA_192", + "BriefDescription": "KMF ENCRYPTED TDEA 192", + "PublicDescription": "KMF-Encrypted-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4138", + "EventName": "KMF_AES_128", + "BriefDescription": "KMF AES 128", + "PublicDescription": "KMF-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4139", + "EventName": "KMF_AES_192", + "BriefDescription": "KMF AES 192", + "PublicDescription": "KMF-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4140", + "EventName": "KMF_AES_256", + "BriefDescription": "KMF AES 256", + "PublicDescription": "KMF-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4141", + "EventName": "KMF_ENCRYPTED_AES_128", + "BriefDescription": "KMF ENCRYPTED AES 128", + "PublicDescription": "KMF-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4142", + "EventName": "KMF_ENCRYPTED_AES_192", + "BriefDescription": "KMF ENCRYPTED AES 192", + "PublicDescription": "KMF-Encrypted-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4143", + "EventName": "KMF_ENCRYPTED_AES_256", + "BriefDescription": "KMF ENCRYPTED AES 256", + "PublicDescription": "KMF-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4144", + "EventName": "KMCTR_DEA", + "BriefDescription": "KMCTR DEA", + "PublicDescription": "KMCTR-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4145", + "EventName": "KMCTR_TDEA_128", + "BriefDescription": "KMCTR TDEA 128", + "PublicDescription": "KMCTR-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4146", + "EventName": "KMCTR_TDEA_192", + "BriefDescription": "KMCTR TDEA 192", + "PublicDescription": "KMCTR-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4147", + "EventName": "KMCTR_ENCRYPTED_DEA", + "BriefDescription": "KMCTR ENCRYPTED DEA", + "PublicDescription": "KMCTR-Encrypted-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4148", + "EventName": "KMCTR_ENCRYPTED_TDEA_128", + "BriefDescription": "KMCTR ENCRYPTED TDEA 128", + "PublicDescription": "KMCTR-Encrypted-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4149", + "EventName": "KMCTR_ENCRYPTED_TDEA_192", + "BriefDescription": "KMCTR ENCRYPTED TDEA 192", + "PublicDescription": "KMCTR-Encrypted-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4150", + "EventName": "KMCTR_AES_128", + "BriefDescription": "KMCTR AES 128", + "PublicDescription": "KMCTR-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4151", + "EventName": "KMCTR_AES_192", + "BriefDescription": "KMCTR AES 192", + "PublicDescription": "KMCTR-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4152", + "EventName": "KMCTR_AES_256", + "BriefDescription": "KMCTR AES 256", + "PublicDescription": "KMCTR-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4153", + "EventName": "KMCTR_ENCRYPTED_AES_128", + "BriefDescription": "KMCTR ENCRYPTED AES 128", + "PublicDescription": "KMCTR-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4154", + "EventName": "KMCTR_ENCRYPTED_AES_192", + "BriefDescription": "KMCTR ENCRYPTED AES 192", + "PublicDescription": "KMCTR-Encrypted-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4155", + "EventName": "KMCTR_ENCRYPTED_AES_256", + "BriefDescription": "KMCTR ENCRYPTED AES 256", + "PublicDescription": "KMCTR-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4156", + "EventName": "KMO_DEA", + "BriefDescription": "KMO DEA", + "PublicDescription": "KMO-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4157", + "EventName": "KMO_TDEA_128", + "BriefDescription": "KMO TDEA 128", + "PublicDescription": "KMO-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4158", + "EventName": "KMO_TDEA_192", + "BriefDescription": "KMO TDEA 192", + "PublicDescription": "KMO-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4159", + "EventName": "KMO_ENCRYPTED_DEA", + "BriefDescription": "KMO ENCRYPTED DEA", + "PublicDescription": "KMO-Encrypted-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4160", + "EventName": "KMO_ENCRYPTED_TDEA_128", + "BriefDescription": "KMO ENCRYPTED TDEA 128", + "PublicDescription": "KMO-Encrypted-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4161", + "EventName": "KMO_ENCRYPTED_TDEA_192", + "BriefDescription": "KMO ENCRYPTED TDEA 192", + "PublicDescription": "KMO-Encrypted-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4162", + "EventName": "KMO_AES_128", + "BriefDescription": "KMO AES 128", + "PublicDescription": "KMO-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4163", + "EventName": "KMO_AES_192", + "BriefDescription": "KMO AES 192", + "PublicDescription": "KMO-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4164", + "EventName": "KMO_AES_256", + "BriefDescription": "KMO AES 256", + "PublicDescription": "KMO-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4165", + "EventName": "KMO_ENCRYPTED_AES_128", + "BriefDescription": "KMO ENCRYPTED AES 128", + "PublicDescription": "KMO-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4166", + "EventName": "KMO_ENCRYPTED_AES_192", + "BriefDescription": "KMO ENCRYPTED AES 192", + "PublicDescription": "KMO-Encrypted-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4167", + "EventName": "KMO_ENCRYPTED_AES_256", + "BriefDescription": "KMO ENCRYPTED AES 256", + "PublicDescription": "KMO-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4168", + "EventName": "KIMD_SHA_1", + "BriefDescription": "KIMD SHA 1", + "PublicDescription": "KIMD-SHA-1 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4169", + "EventName": "KIMD_SHA_256", + "BriefDescription": "KIMD SHA 256", + "PublicDescription": "KIMD-SHA-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4170", + "EventName": "KIMD_SHA_512", + "BriefDescription": "KIMD SHA 512", + "PublicDescription": "KIMD-SHA-512 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4171", + "EventName": "KIMD_SHA3_224", + "BriefDescription": "KIMD SHA3 224", + "PublicDescription": "KIMD-SHA3-224 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4172", + "EventName": "KIMD_SHA3_256", + "BriefDescription": "KIMD SHA3 256", + "PublicDescription": "KIMD-SHA3-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4173", + "EventName": "KIMD_SHA3_384", + "BriefDescription": "KIMD SHA3 384", + "PublicDescription": "KIMD-SHA3-384 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4174", + "EventName": "KIMD_SHA3_512", + "BriefDescription": "KIMD SHA3 512", + "PublicDescription": "KIMD-SHA3-512 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4175", + "EventName": "KIMD_SHAKE_128", + "BriefDescription": "KIMD SHAKE 128", + "PublicDescription": "KIMD-SHAKE-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4176", + "EventName": "KIMD_SHAKE_256", + "BriefDescription": "KIMD SHAKE 256", + "PublicDescription": "KIMD-SHAKE-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4177", + "EventName": "KIMD_GHASH", + "BriefDescription": "KIMD GHASH", + "PublicDescription": "KIMD-GHASH function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4178", + "EventName": "KLMD_SHA_1", + "BriefDescription": "KLMD SHA 1", + "PublicDescription": "KLMD-SHA-1 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4179", + "EventName": "KLMD_SHA_256", + "BriefDescription": "KLMD SHA 256", + "PublicDescription": "KLMD-SHA-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4180", + "EventName": "KLMD_SHA_512", + "BriefDescription": "KLMD SHA 512", + "PublicDescription": "KLMD-SHA-512 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4181", + "EventName": "KLMD_SHA3_224", + "BriefDescription": "KLMD SHA3 224", + "PublicDescription": "KLMD-SHA3-224 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4182", + "EventName": "KLMD_SHA3_256", + "BriefDescription": "KLMD SHA3 256", + "PublicDescription": "KLMD-SHA3-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4183", + "EventName": "KLMD_SHA3_384", + "BriefDescription": "KLMD SHA3 384", + "PublicDescription": "KLMD-SHA3-384 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4184", + "EventName": "KLMD_SHA3_512", + "BriefDescription": "KLMD SHA3 512", + "PublicDescription": "KLMD-SHA3-512 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4185", + "EventName": "KLMD_SHAKE_128", + "BriefDescription": "KLMD SHAKE 128", + "PublicDescription": "KLMD-SHAKE-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4186", + "EventName": "KLMD_SHAKE_256", + "BriefDescription": "KLMD SHAKE 256", + "PublicDescription": "KLMD-SHAKE-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4187", + "EventName": "KMAC_DEA", + "BriefDescription": "KMAC DEA", + "PublicDescription": "KMAC-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4188", + "EventName": "KMAC_TDEA_128", + "BriefDescription": "KMAC TDEA 128", + "PublicDescription": "KMAC-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4189", + "EventName": "KMAC_TDEA_192", + "BriefDescription": "KMAC TDEA 192", + "PublicDescription": "KMAC-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4190", + "EventName": "KMAC_ENCRYPTED_DEA", + "BriefDescription": "KMAC ENCRYPTED DEA", + "PublicDescription": "KMAC-Encrypted-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4191", + "EventName": "KMAC_ENCRYPTED_TDEA_128", + "BriefDescription": "KMAC ENCRYPTED TDEA 128", + "PublicDescription": "KMAC-Encrypted-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4192", + "EventName": "KMAC_ENCRYPTED_TDEA_192", + "BriefDescription": "KMAC ENCRYPTED TDEA 192", + "PublicDescription": "KMAC-Encrypted-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4193", + "EventName": "KMAC_AES_128", + "BriefDescription": "KMAC AES 128", + "PublicDescription": "KMAC-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4194", + "EventName": "KMAC_AES_192", + "BriefDescription": "KMAC AES 192", + "PublicDescription": "KMAC-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4195", + "EventName": "KMAC_AES_256", + "BriefDescription": "KMAC AES 256", + "PublicDescription": "KMAC-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4196", + "EventName": "KMAC_ENCRYPTED_AES_128", + "BriefDescription": "KMAC ENCRYPTED AES 128", + "PublicDescription": "KMAC-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4197", + "EventName": "KMAC_ENCRYPTED_AES_192", + "BriefDescription": "KMAC ENCRYPTED AES 192", + "PublicDescription": "KMAC-Encrypted-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4198", + "EventName": "KMAC_ENCRYPTED_AES_256", + "BriefDescription": "KMAC ENCRYPTED AES 256", + "PublicDescription": "KMAC-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4199", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_DEA", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING DEA", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4200", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_128", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 128", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4201", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_192", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 192", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4202", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_DEA", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED DEA", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-DEA function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4203", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_128", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 128", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4204", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_192", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 192", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4205", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_128", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 128", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4206", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_192", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 192", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4207", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_256", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 256", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4208", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_128", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 128", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4209", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_192", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 192", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 192 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4210", + "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_256A", + "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 256A", + "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 256A function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4211", + "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_128", + "BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 128", + "PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4212", + "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_256", + "BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 256", + "PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4213", + "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_128", + "BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 128", + "PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-128 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4214", + "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_256", + "BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 256", + "PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4215", + "EventName": "PCC_SCALAR_MULTIPLY_P256", + "BriefDescription": "PCC SCALAR MULTIPLY P256", + "PublicDescription": "PCC-Scalar-Multiply-P256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4216", + "EventName": "PCC_SCALAR_MULTIPLY_P384", + "BriefDescription": "PCC SCALAR MULTIPLY P384", + "PublicDescription": "PCC-Scalar-Multiply-P384 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4217", + "EventName": "PCC_SCALAR_MULTIPLY_P521", + "BriefDescription": "PCC SCALAR MULTIPLY P521", + "PublicDescription": "PCC-Scalar-Multiply-P521 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4218", + "EventName": "PCC_SCALAR_MULTIPLY_ED25519", + "BriefDescription": "PCC SCALAR MULTIPLY ED25519", + "PublicDescription": "PCC-Scalar-Multiply-Ed25519 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4219", + "EventName": "PCC_SCALAR_MULTIPLY_ED448", + "BriefDescription": "PCC SCALAR MULTIPLY ED448", + "PublicDescription": "PCC-Scalar-Multiply-Ed448 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4220", + "EventName": "PCC_SCALAR_MULTIPLY_X25519", + "BriefDescription": "PCC SCALAR MULTIPLY X25519", + "PublicDescription": "PCC-Scalar-Multiply-X25519 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4221", + "EventName": "PCC_SCALAR_MULTIPLY_X448", + "BriefDescription": "PCC SCALAR MULTIPLY X448", + "PublicDescription": "PCC-Scalar-Multiply-X448 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4222", + "EventName": "PRNO_SHA_512_DRNG", + "BriefDescription": "PRNO SHA 512 DRNG", + "PublicDescription": "PRNO-SHA-512-DRNG function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4223", + "EventName": "PRNO_TRNG_QUERY_RAW_TO_CONDITIONED_RATIO", + "BriefDescription": "PRNO TRNG QUERY RAW TO CONDITIONED RATIO", + "PublicDescription": "PRNO-TRNG-Query-Raw-to-Conditioned-Ratio function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4224", + "EventName": "PRNO_TRNG", + "BriefDescription": "PRNO TRNG", + "PublicDescription": "PRNO-TRNG function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4225", + "EventName": "KDSA_ECDSA_VERIFY_P256", + "BriefDescription": "KDSA ECDSA VERIFY P256", + "PublicDescription": "KDSA-ECDSA-Verify-P256 function ending with CC=0 or CC=2" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4226", + "EventName": "KDSA_ECDSA_VERIFY_P384", + "BriefDescription": "KDSA ECDSA VERIFY P384", + "PublicDescription": "KDSA-ECDSA-Verify-P384 function ending with CC=0 or CC=2" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4227", + "EventName": "KDSA_ECDSA_VERIFY_P521", + "BriefDescription": "KDSA ECDSA VERIFY P521", + "PublicDescription": "KDSA-ECDSA-Verify-P521 function ending with CC=0 or CC=2" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4228", + "EventName": "KDSA_ECDSA_SIGN_P256", + "BriefDescription": "KDSA ECDSA SIGN P256", + "PublicDescription": "KDSA-ECDSA-Sign-P256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4229", + "EventName": "KDSA_ECDSA_SIGN_P384", + "BriefDescription": "KDSA ECDSA SIGN P384", + "PublicDescription": "KDSA-ECDSA-Sign-P384 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4230", + "EventName": "KDSA_ECDSA_SIGN_P521", + "BriefDescription": "KDSA ECDSA SIGN P521", + "PublicDescription": "KDSA-ECDSA-Sign-P521 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4231", + "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P256", + "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P256", + "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P256 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4232", + "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P384", + "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P384", + "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P384 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4233", + "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P521", + "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P521", + "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P521 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4234", + "EventName": "KDSA_EDDSA_VERIFY_ED25519", + "BriefDescription": "KDSA EDDSA VERIFY ED25519", + "PublicDescription": "KDSA-EdDSA-Verify-Ed25519 function ending with CC=0 or CC=2" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4235", + "EventName": "KDSA_EDDSA_VERIFY_ED448", + "BriefDescription": "KDSA EDDSA VERIFY ED448", + "PublicDescription": "KDSA-EdDSA-Verify-Ed448 function ending with CC=0 or CC=2" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4236", + "EventName": "KDSA_EDDSA_SIGN_ED25519", + "BriefDescription": "KDSA EDDSA SIGN ED25519", + "PublicDescription": "KDSA-EdDSA-Sign-Ed25519 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4237", + "EventName": "KDSA_EDDSA_SIGN_ED448", + "BriefDescription": "KDSA EDDSA SIGN ED448", + "PublicDescription": "KDSA-EdDSA-Sign-Ed448 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4238", + "EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED25519", + "BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED25519", + "PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed25519 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4239", + "EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED448", + "BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED448", + "PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed448 function ending with CC=0" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4240", + "EventName": "PCKMO_ENCRYPT_DEA_KEY", + "BriefDescription": "PCKMO ENCRYPT DEA KEY", + "PublicDescription": "PCKMO-Encrypt-DEA-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4241", + "EventName": "PCKMO_ENCRYPT_TDEA_128_KEY", + "BriefDescription": "PCKMO ENCRYPT TDEA 128 KEY", + "PublicDescription": "PCKMO-Encrypt-TDEA-128-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4242", + "EventName": "PCKMO_ENCRYPT_TDEA_192_KEY", + "BriefDescription": "PCKMO ENCRYPT TDEA 192 KEY", + "PublicDescription": "PCKMO-Encrypt-TDEA-192-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4243", + "EventName": "PCKMO_ENCRYPT_AES_128_KEY", + "BriefDescription": "PCKMO ENCRYPT AES 128 KEY", + "PublicDescription": "PCKMO-Encrypt-AES-128-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4244", + "EventName": "PCKMO_ENCRYPT_AES_192_KEY", + "BriefDescription": "PCKMO ENCRYPT AES 192 KEY", + "PublicDescription": "PCKMO-Encrypt-AES-192-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4245", + "EventName": "PCKMO_ENCRYPT_AES_256_KEY", + "BriefDescription": "PCKMO ENCRYPT AES 256 KEY", + "PublicDescription": "PCKMO-Encrypt-AES-256-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4246", + "EventName": "PCKMO_ENCRYPT_ECC_P256_KEY", + "BriefDescription": "PCKMO ENCRYPT ECC P256 KEY", + "PublicDescription": "PCKMO-Encrypt-ECC-P256-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4247", + "EventName": "PCKMO_ENCRYPT_ECC_P384_KEY", + "BriefDescription": "PCKMO ENCRYPT ECC P384 KEY", + "PublicDescription": "PCKMO-Encrypt-ECC-P384-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4248", + "EventName": "PCKMO_ENCRYPT_ECC_P521_KEY", + "BriefDescription": "PCKMO ENCRYPT ECC P521 KEY", + "PublicDescription": "PCKMO-Encrypt-ECC-P521-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4249", + "EventName": "PCKMO_ENCRYPT_ECC_ED25519_KEY", + "BriefDescription": "PCKMO ENCRYPT ECC ED25519 KEY", + "PublicDescription": "PCKMO-Encrypt-ECC-Ed25519-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4250", + "EventName": "PCKMO_ENCRYPT_ECC_ED448_KEY", + "BriefDescription": "PCKMO ENCRYPT ECC ED448 KEY", + "PublicDescription": "PCKMO-Encrypt-ECC-Ed448-key function" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4251", + "EventName": "IBM_RESERVED_155", + "BriefDescription": "IBM RESERVED_155", + "PublicDescription": "Reserved for IBM use" + }, + { + "Unit": "PAI-CRYPTO", + "EventCode": "4252", + "EventName": "IBM_RESERVED_156", + "BriefDescription": "IBM RESERVED_156", + "PublicDescription": "Reserved for IBM use" + } +] diff -Nru linux-6.0.6/tools/perf/pmu-events/arch/s390/cf_z16/pai.json linux-6.0.12/tools/perf/pmu-events/arch/s390/cf_z16/pai.json --- linux-6.0.6/tools/perf/pmu-events/arch/s390/cf_z16/pai.json 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/perf/pmu-events/arch/s390/cf_z16/pai.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,1101 +0,0 @@ -[ - { - "Unit": "PAI-CRYPTO", - "EventCode": "4096", - "EventName": "CRYPTO_ALL", - "BriefDescription": "CRYPTO ALL", - "PublicDescription": "Sums of all non zero cryptography counters" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4097", - "EventName": "KM_DEA", - "BriefDescription": "KM DEA", - "PublicDescription": "KM-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4098", - "EventName": "KM_TDEA_128", - "BriefDescription": "KM TDEA 128", - "PublicDescription": "KM-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4099", - "EventName": "KM_TDEA_192", - "BriefDescription": "KM TDEA 192", - "PublicDescription": "KM-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4100", - "EventName": "KM_ENCRYPTED_DEA", - "BriefDescription": "KM ENCRYPTED DEA", - "PublicDescription": "KM-Encrypted-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4101", - "EventName": "KM_ENCRYPTED_TDEA_128", - "BriefDescription": "KM ENCRYPTED TDEA 128", - "PublicDescription": "KM-Encrypted-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4102", - "EventName": "KM_ENCRYPTED_TDEA_192", - "BriefDescription": "KM ENCRYPTED TDEA 192", - "PublicDescription": "KM-Encrypted-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4103", - "EventName": "KM_AES_128", - "BriefDescription": "KM AES 128", - "PublicDescription": "KM-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4104", - "EventName": "KM_AES_192", - "BriefDescription": "KM AES 192", - "PublicDescription": "KM-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4105", - "EventName": "KM_AES_256", - "BriefDescription": "KM AES 256", - "PublicDescription": "KM-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4106", - "EventName": "KM_ENCRYPTED_AES_128", - "BriefDescription": "KM ENCRYPTED AES 128", - "PublicDescription": "KM-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4107", - "EventName": "KM_ENCRYPTED_AES_192", - "BriefDescription": "KM ENCRYPTED AES 192", - "PublicDescription": "KM-Encrypted-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4108", - "EventName": "KM_ENCRYPTED_AES_256", - "BriefDescription": "KM ENCRYPTED AES 256", - "PublicDescription": "KM-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4109", - "EventName": "KM_XTS_AES_128", - "BriefDescription": "KM XTS AES 128", - "PublicDescription": "KM-XTS-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4110", - "EventName": "KM_XTS_AES_256", - "BriefDescription": "KM XTS AES 256", - "PublicDescription": "KM-XTS-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4111", - "EventName": "KM_XTS_ENCRYPTED_AES_128", - "BriefDescription": "KM XTS ENCRYPTED AES 128", - "PublicDescription": "KM-XTS-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4112", - "EventName": "KM_XTS_ENCRYPTED_AES_256", - "BriefDescription": "KM XTS ENCRYPTED AES 256", - "PublicDescription": "KM-XTS-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4113", - "EventName": "KMC_DEA", - "BriefDescription": "KMC DEA", - "PublicDescription": "KMC-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4114", - "EventName": "KMC_TDEA_128", - "BriefDescription": "KMC TDEA 128", - "PublicDescription": "KMC-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4115", - "EventName": "KMC_TDEA_192", - "BriefDescription": "KMC TDEA 192", - "PublicDescription": "KMC-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4116", - "EventName": "KMC_ENCRYPTED_DEA", - "BriefDescription": "KMC ENCRYPTED DEA", - "PublicDescription": "KMC-Encrypted-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4117", - "EventName": "KMC_ENCRYPTED_TDEA_128", - "BriefDescription": "KMC ENCRYPTED TDEA 128", - "PublicDescription": "KMC-Encrypted-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4118", - "EventName": "KMC_ENCRYPTED_TDEA_192", - "BriefDescription": "KMC ENCRYPTED TDEA 192", - "PublicDescription": "KMC-Encrypted-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4119", - "EventName": "KMC_AES_128", - "BriefDescription": "KMC AES 128", - "PublicDescription": "KMC-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4120", - "EventName": "KMC_AES_192", - "BriefDescription": "KMC AES 192", - "PublicDescription": "KMC-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4121", - "EventName": "KMC_AES_256", - "BriefDescription": "KMC AES 256", - "PublicDescription": "KMC-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4122", - "EventName": "KMC_ENCRYPTED_AES_128", - "BriefDescription": "KMC ENCRYPTED AES 128", - "PublicDescription": "KMC-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4123", - "EventName": "KMC_ENCRYPTED_AES_192", - "BriefDescription": "KMC ENCRYPTED AES 192", - "PublicDescription": "KMC-Encrypted-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4124", - "EventName": "KMC_ENCRYPTED_AES_256", - "BriefDescription": "KMC ENCRYPTED AES 256", - "PublicDescription": "KMC-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4125", - "EventName": "KMC_PRNG", - "BriefDescription": "KMC PRNG", - "PublicDescription": "KMC-PRNG function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4126", - "EventName": "KMA_GCM_AES_128", - "BriefDescription": "KMA GCM AES 128", - "PublicDescription": "KMA-GCM-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4127", - "EventName": "KMA_GCM_AES_192", - "BriefDescription": "KMA GCM AES 192", - "PublicDescription": "KMA-GCM-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4128", - "EventName": "KMA_GCM_AES_256", - "BriefDescription": "KMA GCM AES 256", - "PublicDescription": "KMA-GCM-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4129", - "EventName": "KMA_GCM_ENCRYPTED_AES_128", - "BriefDescription": "KMA GCM ENCRYPTED AES 128", - "PublicDescription": "KMA-GCM-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4130", - "EventName": "KMA_GCM_ENCRYPTED_AES_192", - "BriefDescription": "KMA GCM ENCRYPTED AES 192", - "PublicDescription": "KMA-GCM-Encrypted-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4131", - "EventName": "KMA_GCM_ENCRYPTED_AES_256", - "BriefDescription": "KMA GCM ENCRYPTED AES 256", - "PublicDescription": "KMA-GCM-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4132", - "EventName": "KMF_DEA", - "BriefDescription": "KMF DEA", - "PublicDescription": "KMF-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4133", - "EventName": "KMF_TDEA_128", - "BriefDescription": "KMF TDEA 128", - "PublicDescription": "KMF-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4134", - "EventName": "KMF_TDEA_192", - "BriefDescription": "KMF TDEA 192", - "PublicDescription": "KMF-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4135", - "EventName": "KMF_ENCRYPTED_DEA", - "BriefDescription": "KMF ENCRYPTED DEA", - "PublicDescription": "KMF-Encrypted-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4136", - "EventName": "KMF_ENCRYPTED_TDEA_128", - "BriefDescription": "KMF ENCRYPTED TDEA 128", - "PublicDescription": "KMF-Encrypted-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4137", - "EventName": "KMF_ENCRYPTED_TDEA_192", - "BriefDescription": "KMF ENCRYPTED TDEA 192", - "PublicDescription": "KMF-Encrypted-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4138", - "EventName": "KMF_AES_128", - "BriefDescription": "KMF AES 128", - "PublicDescription": "KMF-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4139", - "EventName": "KMF_AES_192", - "BriefDescription": "KMF AES 192", - "PublicDescription": "KMF-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4140", - "EventName": "KMF_AES_256", - "BriefDescription": "KMF AES 256", - "PublicDescription": "KMF-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4141", - "EventName": "KMF_ENCRYPTED_AES_128", - "BriefDescription": "KMF ENCRYPTED AES 128", - "PublicDescription": "KMF-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4142", - "EventName": "KMF_ENCRYPTED_AES_192", - "BriefDescription": "KMF ENCRYPTED AES 192", - "PublicDescription": "KMF-Encrypted-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4143", - "EventName": "KMF_ENCRYPTED_AES_256", - "BriefDescription": "KMF ENCRYPTED AES 256", - "PublicDescription": "KMF-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4144", - "EventName": "KMCTR_DEA", - "BriefDescription": "KMCTR DEA", - "PublicDescription": "KMCTR-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4145", - "EventName": "KMCTR_TDEA_128", - "BriefDescription": "KMCTR TDEA 128", - "PublicDescription": "KMCTR-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4146", - "EventName": "KMCTR_TDEA_192", - "BriefDescription": "KMCTR TDEA 192", - "PublicDescription": "KMCTR-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4147", - "EventName": "KMCTR_ENCRYPTED_DEA", - "BriefDescription": "KMCTR ENCRYPTED DEA", - "PublicDescription": "KMCTR-Encrypted-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4148", - "EventName": "KMCTR_ENCRYPTED_TDEA_128", - "BriefDescription": "KMCTR ENCRYPTED TDEA 128", - "PublicDescription": "KMCTR-Encrypted-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4149", - "EventName": "KMCTR_ENCRYPTED_TDEA_192", - "BriefDescription": "KMCTR ENCRYPTED TDEA 192", - "PublicDescription": "KMCTR-Encrypted-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4150", - "EventName": "KMCTR_AES_128", - "BriefDescription": "KMCTR AES 128", - "PublicDescription": "KMCTR-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4151", - "EventName": "KMCTR_AES_192", - "BriefDescription": "KMCTR AES 192", - "PublicDescription": "KMCTR-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4152", - "EventName": "KMCTR_AES_256", - "BriefDescription": "KMCTR AES 256", - "PublicDescription": "KMCTR-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4153", - "EventName": "KMCTR_ENCRYPTED_AES_128", - "BriefDescription": "KMCTR ENCRYPTED AES 128", - "PublicDescription": "KMCTR-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4154", - "EventName": "KMCTR_ENCRYPTED_AES_192", - "BriefDescription": "KMCTR ENCRYPTED AES 192", - "PublicDescription": "KMCTR-Encrypted-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4155", - "EventName": "KMCTR_ENCRYPTED_AES_256", - "BriefDescription": "KMCTR ENCRYPTED AES 256", - "PublicDescription": "KMCTR-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4156", - "EventName": "KMO_DEA", - "BriefDescription": "KMO DEA", - "PublicDescription": "KMO-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4157", - "EventName": "KMO_TDEA_128", - "BriefDescription": "KMO TDEA 128", - "PublicDescription": "KMO-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4158", - "EventName": "KMO_TDEA_192", - "BriefDescription": "KMO TDEA 192", - "PublicDescription": "KMO-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4159", - "EventName": "KMO_ENCRYPTED_DEA", - "BriefDescription": "KMO ENCRYPTED DEA", - "PublicDescription": "KMO-Encrypted-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4160", - "EventName": "KMO_ENCRYPTED_TDEA_128", - "BriefDescription": "KMO ENCRYPTED TDEA 128", - "PublicDescription": "KMO-Encrypted-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4161", - "EventName": "KMO_ENCRYPTED_TDEA_192", - "BriefDescription": "KMO ENCRYPTED TDEA 192", - "PublicDescription": "KMO-Encrypted-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4162", - "EventName": "KMO_AES_128", - "BriefDescription": "KMO AES 128", - "PublicDescription": "KMO-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4163", - "EventName": "KMO_AES_192", - "BriefDescription": "KMO AES 192", - "PublicDescription": "KMO-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4164", - "EventName": "KMO_AES_256", - "BriefDescription": "KMO AES 256", - "PublicDescription": "KMO-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4165", - "EventName": "KMO_ENCRYPTED_AES_128", - "BriefDescription": "KMO ENCRYPTED AES 128", - "PublicDescription": "KMO-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4166", - "EventName": "KMO_ENCRYPTED_AES_192", - "BriefDescription": "KMO ENCRYPTED AES 192", - "PublicDescription": "KMO-Encrypted-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4167", - "EventName": "KMO_ENCRYPTED_AES_256", - "BriefDescription": "KMO ENCRYPTED AES 256", - "PublicDescription": "KMO-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4168", - "EventName": "KIMD_SHA_1", - "BriefDescription": "KIMD SHA 1", - "PublicDescription": "KIMD-SHA-1 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4169", - "EventName": "KIMD_SHA_256", - "BriefDescription": "KIMD SHA 256", - "PublicDescription": "KIMD-SHA-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4170", - "EventName": "KIMD_SHA_512", - "BriefDescription": "KIMD SHA 512", - "PublicDescription": "KIMD-SHA-512 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4171", - "EventName": "KIMD_SHA3_224", - "BriefDescription": "KIMD SHA3 224", - "PublicDescription": "KIMD-SHA3-224 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4172", - "EventName": "KIMD_SHA3_256", - "BriefDescription": "KIMD SHA3 256", - "PublicDescription": "KIMD-SHA3-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4173", - "EventName": "KIMD_SHA3_384", - "BriefDescription": "KIMD SHA3 384", - "PublicDescription": "KIMD-SHA3-384 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4174", - "EventName": "KIMD_SHA3_512", - "BriefDescription": "KIMD SHA3 512", - "PublicDescription": "KIMD-SHA3-512 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4175", - "EventName": "KIMD_SHAKE_128", - "BriefDescription": "KIMD SHAKE 128", - "PublicDescription": "KIMD-SHAKE-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4176", - "EventName": "KIMD_SHAKE_256", - "BriefDescription": "KIMD SHAKE 256", - "PublicDescription": "KIMD-SHAKE-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4177", - "EventName": "KIMD_GHASH", - "BriefDescription": "KIMD GHASH", - "PublicDescription": "KIMD-GHASH function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4178", - "EventName": "KLMD_SHA_1", - "BriefDescription": "KLMD SHA 1", - "PublicDescription": "KLMD-SHA-1 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4179", - "EventName": "KLMD_SHA_256", - "BriefDescription": "KLMD SHA 256", - "PublicDescription": "KLMD-SHA-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4180", - "EventName": "KLMD_SHA_512", - "BriefDescription": "KLMD SHA 512", - "PublicDescription": "KLMD-SHA-512 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4181", - "EventName": "KLMD_SHA3_224", - "BriefDescription": "KLMD SHA3 224", - "PublicDescription": "KLMD-SHA3-224 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4182", - "EventName": "KLMD_SHA3_256", - "BriefDescription": "KLMD SHA3 256", - "PublicDescription": "KLMD-SHA3-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4183", - "EventName": "KLMD_SHA3_384", - "BriefDescription": "KLMD SHA3 384", - "PublicDescription": "KLMD-SHA3-384 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4184", - "EventName": "KLMD_SHA3_512", - "BriefDescription": "KLMD SHA3 512", - "PublicDescription": "KLMD-SHA3-512 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4185", - "EventName": "KLMD_SHAKE_128", - "BriefDescription": "KLMD SHAKE 128", - "PublicDescription": "KLMD-SHAKE-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4186", - "EventName": "KLMD_SHAKE_256", - "BriefDescription": "KLMD SHAKE 256", - "PublicDescription": "KLMD-SHAKE-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4187", - "EventName": "KMAC_DEA", - "BriefDescription": "KMAC DEA", - "PublicDescription": "KMAC-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4188", - "EventName": "KMAC_TDEA_128", - "BriefDescription": "KMAC TDEA 128", - "PublicDescription": "KMAC-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4189", - "EventName": "KMAC_TDEA_192", - "BriefDescription": "KMAC TDEA 192", - "PublicDescription": "KMAC-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4190", - "EventName": "KMAC_ENCRYPTED_DEA", - "BriefDescription": "KMAC ENCRYPTED DEA", - "PublicDescription": "KMAC-Encrypted-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4191", - "EventName": "KMAC_ENCRYPTED_TDEA_128", - "BriefDescription": "KMAC ENCRYPTED TDEA 128", - "PublicDescription": "KMAC-Encrypted-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4192", - "EventName": "KMAC_ENCRYPTED_TDEA_192", - "BriefDescription": "KMAC ENCRYPTED TDEA 192", - "PublicDescription": "KMAC-Encrypted-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4193", - "EventName": "KMAC_AES_128", - "BriefDescription": "KMAC AES 128", - "PublicDescription": "KMAC-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4194", - "EventName": "KMAC_AES_192", - "BriefDescription": "KMAC AES 192", - "PublicDescription": "KMAC-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4195", - "EventName": "KMAC_AES_256", - "BriefDescription": "KMAC AES 256", - "PublicDescription": "KMAC-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4196", - "EventName": "KMAC_ENCRYPTED_AES_128", - "BriefDescription": "KMAC ENCRYPTED AES 128", - "PublicDescription": "KMAC-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4197", - "EventName": "KMAC_ENCRYPTED_AES_192", - "BriefDescription": "KMAC ENCRYPTED AES 192", - "PublicDescription": "KMAC-Encrypted-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4198", - "EventName": "KMAC_ENCRYPTED_AES_256", - "BriefDescription": "KMAC ENCRYPTED AES 256", - "PublicDescription": "KMAC-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4199", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_DEA", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING DEA", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4200", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_128", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 128", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4201", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_192", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 192", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4202", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_DEA", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED DEA", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-DEA function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4203", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_128", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 128", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4204", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_192", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 192", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4205", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_128", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 128", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4206", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_192", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 192", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4207", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_256", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 256", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4208", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_128", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 128", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4209", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_192", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 192", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 192 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4210", - "EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_256A", - "BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 256A", - "PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 256A function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4211", - "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_128", - "BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 128", - "PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4212", - "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_256", - "BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 256", - "PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4213", - "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_128", - "BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 128", - "PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-128 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4214", - "EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_256", - "BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 256", - "PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4215", - "EventName": "PCC_SCALAR_MULTIPLY_P256", - "BriefDescription": "PCC SCALAR MULTIPLY P256", - "PublicDescription": "PCC-Scalar-Multiply-P256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4216", - "EventName": "PCC_SCALAR_MULTIPLY_P384", - "BriefDescription": "PCC SCALAR MULTIPLY P384", - "PublicDescription": "PCC-Scalar-Multiply-P384 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4217", - "EventName": "PCC_SCALAR_MULTIPLY_P521", - "BriefDescription": "PCC SCALAR MULTIPLY P521", - "PublicDescription": "PCC-Scalar-Multiply-P521 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4218", - "EventName": "PCC_SCALAR_MULTIPLY_ED25519", - "BriefDescription": "PCC SCALAR MULTIPLY ED25519", - "PublicDescription": "PCC-Scalar-Multiply-Ed25519 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4219", - "EventName": "PCC_SCALAR_MULTIPLY_ED448", - "BriefDescription": "PCC SCALAR MULTIPLY ED448", - "PublicDescription": "PCC-Scalar-Multiply-Ed448 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4220", - "EventName": "PCC_SCALAR_MULTIPLY_X25519", - "BriefDescription": "PCC SCALAR MULTIPLY X25519", - "PublicDescription": "PCC-Scalar-Multiply-X25519 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4221", - "EventName": "PCC_SCALAR_MULTIPLY_X448", - "BriefDescription": "PCC SCALAR MULTIPLY X448", - "PublicDescription": "PCC-Scalar-Multiply-X448 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4222", - "EventName": "PRNO_SHA_512_DRNG", - "BriefDescription": "PRNO SHA 512 DRNG", - "PublicDescription": "PRNO-SHA-512-DRNG function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4223", - "EventName": "PRNO_TRNG_QUERY_RAW_TO_CONDITIONED_RATIO", - "BriefDescription": "PRNO TRNG QUERY RAW TO CONDITIONED RATIO", - "PublicDescription": "PRNO-TRNG-Query-Raw-to-Conditioned-Ratio function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4224", - "EventName": "PRNO_TRNG", - "BriefDescription": "PRNO TRNG", - "PublicDescription": "PRNO-TRNG function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4225", - "EventName": "KDSA_ECDSA_VERIFY_P256", - "BriefDescription": "KDSA ECDSA VERIFY P256", - "PublicDescription": "KDSA-ECDSA-Verify-P256 function ending with CC=0 or CC=2" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4226", - "EventName": "KDSA_ECDSA_VERIFY_P384", - "BriefDescription": "KDSA ECDSA VERIFY P384", - "PublicDescription": "KDSA-ECDSA-Verify-P384 function ending with CC=0 or CC=2" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4227", - "EventName": "KDSA_ECDSA_VERIFY_P521", - "BriefDescription": "KDSA ECDSA VERIFY P521", - "PublicDescription": "KDSA-ECDSA-Verify-P521 function ending with CC=0 or CC=2" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4228", - "EventName": "KDSA_ECDSA_SIGN_P256", - "BriefDescription": "KDSA ECDSA SIGN P256", - "PublicDescription": "KDSA-ECDSA-Sign-P256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4229", - "EventName": "KDSA_ECDSA_SIGN_P384", - "BriefDescription": "KDSA ECDSA SIGN P384", - "PublicDescription": "KDSA-ECDSA-Sign-P384 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4230", - "EventName": "KDSA_ECDSA_SIGN_P521", - "BriefDescription": "KDSA ECDSA SIGN P521", - "PublicDescription": "KDSA-ECDSA-Sign-P521 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4231", - "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P256", - "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P256", - "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P256 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4232", - "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P384", - "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P384", - "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P384 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4233", - "EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P521", - "BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P521", - "PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P521 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4234", - "EventName": "KDSA_EDDSA_VERIFY_ED25519", - "BriefDescription": "KDSA EDDSA VERIFY ED25519", - "PublicDescription": "KDSA-EdDSA-Verify-Ed25519 function ending with CC=0 or CC=2" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4235", - "EventName": "KDSA_EDDSA_VERIFY_ED448", - "BriefDescription": "KDSA EDDSA VERIFY ED448", - "PublicDescription": "KDSA-EdDSA-Verify-Ed448 function ending with CC=0 or CC=2" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4236", - "EventName": "KDSA_EDDSA_SIGN_ED25519", - "BriefDescription": "KDSA EDDSA SIGN ED25519", - "PublicDescription": "KDSA-EdDSA-Sign-Ed25519 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4237", - "EventName": "KDSA_EDDSA_SIGN_ED448", - "BriefDescription": "KDSA EDDSA SIGN ED448", - "PublicDescription": "KDSA-EdDSA-Sign-Ed448 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4238", - "EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED25519", - "BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED25519", - "PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed25519 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4239", - "EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED448", - "BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED448", - "PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed448 function ending with CC=0" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4240", - "EventName": "PCKMO_ENCRYPT_DEA_KEY", - "BriefDescription": "PCKMO ENCRYPT DEA KEY", - "PublicDescription": "PCKMO-Encrypt-DEA-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4241", - "EventName": "PCKMO_ENCRYPT_TDEA_128_KEY", - "BriefDescription": "PCKMO ENCRYPT TDEA 128 KEY", - "PublicDescription": "PCKMO-Encrypt-TDEA-128-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4242", - "EventName": "PCKMO_ENCRYPT_TDEA_192_KEY", - "BriefDescription": "PCKMO ENCRYPT TDEA 192 KEY", - "PublicDescription": "PCKMO-Encrypt-TDEA-192-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4243", - "EventName": "PCKMO_ENCRYPT_AES_128_KEY", - "BriefDescription": "PCKMO ENCRYPT AES 128 KEY", - "PublicDescription": "PCKMO-Encrypt-AES-128-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4244", - "EventName": "PCKMO_ENCRYPT_AES_192_KEY", - "BriefDescription": "PCKMO ENCRYPT AES 192 KEY", - "PublicDescription": "PCKMO-Encrypt-AES-192-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4245", - "EventName": "PCKMO_ENCRYPT_AES_256_KEY", - "BriefDescription": "PCKMO ENCRYPT AES 256 KEY", - "PublicDescription": "PCKMO-Encrypt-AES-256-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4246", - "EventName": "PCKMO_ENCRYPT_ECC_P256_KEY", - "BriefDescription": "PCKMO ENCRYPT ECC P256 KEY", - "PublicDescription": "PCKMO-Encrypt-ECC-P256-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4247", - "EventName": "PCKMO_ENCRYPT_ECC_P384_KEY", - "BriefDescription": "PCKMO ENCRYPT ECC P384 KEY", - "PublicDescription": "PCKMO-Encrypt-ECC-P384-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4248", - "EventName": "PCKMO_ENCRYPT_ECC_P521_KEY", - "BriefDescription": "PCKMO ENCRYPT ECC P521 KEY", - "PublicDescription": "PCKMO-Encrypt-ECC-P521-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4249", - "EventName": "PCKMO_ENCRYPT_ECC_ED25519_KEY", - "BriefDescription": "PCKMO ENCRYPT ECC ED25519 KEY", - "PublicDescription": "PCKMO-Encrypt-ECC-Ed25519-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4250", - "EventName": "PCKMO_ENCRYPT_ECC_ED448_KEY", - "BriefDescription": "PCKMO ENCRYPT ECC ED448 KEY", - "PublicDescription": "PCKMO-Encrypt-ECC-Ed448-key function" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4251", - "EventName": "IBM_RESERVED_155", - "BriefDescription": "IBM RESERVED_155", - "PublicDescription": "Reserved for IBM use" - }, - { - "Unit": "PAI-CRYPTO", - "EventCode": "4252", - "EventName": "IBM_RESERVED_156", - "BriefDescription": "IBM RESERVED_156", - "PublicDescription": "Reserved for IBM use" - } -] diff -Nru linux-6.0.6/tools/perf/tests/shell/test_brstack.sh linux-6.0.12/tools/perf/tests/shell/test_brstack.sh --- linux-6.0.6/tools/perf/tests/shell/test_brstack.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/perf/tests/shell/test_brstack.sh 2023-01-18 18:27:39.000000000 +0000 @@ -13,7 +13,10 @@ # skip the test if the hardware doesn't support branch stack sampling # and if the architecture doesn't support filter types: any,save_type,u -perf record -b -o- -B --branch-filter any,save_type,u true > /dev/null 2>&1 || exit 2 +if ! perf record -o- --no-buildid --branch-filter any,save_type,u -- true > /dev/null 2>&1 ; then + echo "skip: system doesn't support filter types: any,save_type,u" + exit 2 +fi TMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX) diff -Nru linux-6.0.6/tools/perf/util/auxtrace.c linux-6.0.12/tools/perf/util/auxtrace.c --- linux-6.0.6/tools/perf/util/auxtrace.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/perf/util/auxtrace.c 2023-01-18 18:27:39.000000000 +0000 @@ -2308,11 +2308,19 @@ bool near; }; +static bool kern_sym_name_match(const char *kname, const char *name) +{ + size_t n = strlen(name); + + return !strcmp(kname, name) || + (!strncmp(kname, name, n) && kname[n] == '\t'); +} + static bool kern_sym_match(struct sym_args *args, const char *name, char type) { /* A function with the same name, and global or the n'th found or any */ return kallsyms__is_function(type) && - !strcmp(name, args->name) && + kern_sym_name_match(name, args->name) && ((args->global && isupper(type)) || (args->selected && ++(args->cnt) == args->idx) || (!args->global && !args->selected)); diff -Nru linux-6.0.6/tools/perf/util/parse-branch-options.c linux-6.0.12/tools/perf/util/parse-branch-options.c --- linux-6.0.6/tools/perf/util/parse-branch-options.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/perf/util/parse-branch-options.c 2023-01-18 18:27:39.000000000 +0000 @@ -101,8 +101,10 @@ /* * cannot set it twice, -b + --branch-filter for instance */ - if (*mode) + if (*mode) { + pr_err("Error: Can't use --branch-any (-b) with --branch-filter (-j).\n"); return -1; + } return parse_branch_str(str, mode); } diff -Nru linux-6.0.6/tools/perf/util/stat-display.c linux-6.0.12/tools/perf/util/stat-display.c --- linux-6.0.6/tools/perf/util/stat-display.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/perf/util/stat-display.c 2023-01-18 18:27:39.000000000 +0000 @@ -273,7 +273,7 @@ fputc('\n', os->fh); if (os->prefix) - fprintf(os->fh, "%s%s", os->prefix, config->csv_sep); + fprintf(os->fh, "%s", os->prefix); aggr_printout(config, os->evsel, os->id, os->nr); for (i = 0; i < os->nfields; i++) fputs(config->csv_sep, os->fh); @@ -556,7 +556,7 @@ [AGGR_CORE] = 2, [AGGR_THREAD] = 1, [AGGR_UNSET] = 0, - [AGGR_NODE] = 0, + [AGGR_NODE] = 1, }; pm = config->metric_only ? print_metric_only_csv : print_metric_csv; @@ -1126,6 +1126,7 @@ [AGGR_SOCKET] = 12, [AGGR_NONE] = 6, [AGGR_THREAD] = 24, + [AGGR_NODE] = 6, [AGGR_GLOBAL] = 0, }; @@ -1135,6 +1136,7 @@ [AGGR_SOCKET] = "socket,cpus", [AGGR_NONE] = "cpu,", [AGGR_THREAD] = "comm-pid,", + [AGGR_NODE] = "node,", [AGGR_GLOBAL] = "" }; diff -Nru linux-6.0.6/tools/testing/cxl/test/cxl.c linux-6.0.12/tools/testing/cxl/test/cxl.c --- linux-6.0.6/tools/testing/cxl/test/cxl.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/cxl/test/cxl.c 2023-01-18 18:27:39.000000000 +0000 @@ -695,7 +695,7 @@ pdev = platform_device_alloc("cxl_switch_uport", i); if (!pdev) - goto err_port; + goto err_uport; pdev->dev.parent = &root_port->dev; rc = platform_device_add(pdev); @@ -713,7 +713,7 @@ pdev = platform_device_alloc("cxl_switch_dport", i); if (!pdev) - goto err_port; + goto err_dport; pdev->dev.parent = &uport->dev; rc = platform_device_add(pdev); diff -Nru linux-6.0.6/tools/testing/selftests/bpf/test_progs.c linux-6.0.12/tools/testing/selftests/bpf/test_progs.c --- linux-6.0.6/tools/testing/selftests/bpf/test_progs.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/bpf/test_progs.c 2023-01-18 18:27:39.000000000 +0000 @@ -993,7 +993,7 @@ msg->subtest_done.have_log); break; case MSG_TEST_LOG: - sprintf(buf, "MSG_TEST_LOG (cnt: %ld, last: %d)", + sprintf(buf, "MSG_TEST_LOG (cnt: %zu, last: %d)", strlen(msg->test_log.log_buf), msg->test_log.is_last); break; diff -Nru linux-6.0.6/tools/testing/selftests/bpf/test_verifier.c linux-6.0.12/tools/testing/selftests/bpf/test_verifier.c --- linux-6.0.6/tools/testing/selftests/bpf/test_verifier.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/bpf/test_verifier.c 2023-01-18 18:27:39.000000000 +0000 @@ -1260,7 +1260,7 @@ bzero(&info, sizeof(info)); info.xlated_prog_len = xlated_prog_len; - info.xlated_prog_insns = (__u64)*buf; + info.xlated_prog_insns = (__u64)(unsigned long)*buf; if (bpf_obj_get_info_by_fd(fd_prog, &info, &info_len)) { perror("second bpf_obj_get_info_by_fd failed"); goto out_free_buf; diff -Nru linux-6.0.6/tools/testing/selftests/bpf/verifier/ref_tracking.c linux-6.0.12/tools/testing/selftests/bpf/verifier/ref_tracking.c --- linux-6.0.6/tools/testing/selftests/bpf/verifier/ref_tracking.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/bpf/verifier/ref_tracking.c 2023-01-18 18:27:39.000000000 +0000 @@ -905,3 +905,39 @@ .result_unpriv = REJECT, .errstr_unpriv = "unknown func", }, +{ + "reference tracking: try to leak released ptr reg", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_LD_MAP_FD(BPF_REG_1, 0), + BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + BPF_MOV64_REG(BPF_REG_9, BPF_REG_0), + + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_LD_MAP_FD(BPF_REG_1, 0), + BPF_MOV64_IMM(BPF_REG_2, 8), + BPF_MOV64_IMM(BPF_REG_3, 0), + BPF_EMIT_CALL(BPF_FUNC_ringbuf_reserve), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), + + BPF_MOV64_REG(BPF_REG_1, BPF_REG_8), + BPF_MOV64_IMM(BPF_REG_2, 0), + BPF_EMIT_CALL(BPF_FUNC_ringbuf_discard), + BPF_MOV64_IMM(BPF_REG_0, 0), + + BPF_STX_MEM(BPF_DW, BPF_REG_9, BPF_REG_8, 0), + BPF_EXIT_INSN() + }, + .fixup_map_array_48b = { 4 }, + .fixup_map_ringbuf = { 11 }, + .result = ACCEPT, + .result_unpriv = REJECT, + .errstr_unpriv = "R8 !read_ok" +}, diff -Nru linux-6.0.6/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh linux-6.0.12/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh --- linux-6.0.6/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh 2023-01-18 18:27:39.000000000 +0000 @@ -14,7 +14,7 @@ REQUIRE_MZ=no NUM_NETIFS=0 lib_dir=$(dirname "$0") -source "$lib_dir"/../../../net/forwarding/lib.sh +source "$lib_dir"/net_forwarding_lib.sh source "$lib_dir"/lag_lib.sh diff -Nru linux-6.0.6/tools/testing/selftests/drivers/net/bonding/Makefile linux-6.0.12/tools/testing/selftests/drivers/net/bonding/Makefile --- linux-6.0.6/tools/testing/selftests/drivers/net/bonding/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/drivers/net/bonding/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -5,6 +5,8 @@ dev_addr_lists.sh \ bond-arp-interval-causes-panic.sh -TEST_FILES := lag_lib.sh +TEST_FILES := \ + lag_lib.sh \ + net_forwarding_lib.sh include ../../../lib.mk diff -Nru linux-6.0.6/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh linux-6.0.12/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh --- linux-6.0.6/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh 1970-01-01 00:00:00.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh 2023-01-18 18:27:39.000000000 +0000 @@ -0,0 +1,1686 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +############################################################################## +# Defines + +# Kselftest framework requirement - SKIP code is 4. +ksft_skip=4 + +# Can be overridden by the configuration file. +PING=${PING:=ping} +PING6=${PING6:=ping6} +MZ=${MZ:=mausezahn} +ARPING=${ARPING:=arping} +TEAMD=${TEAMD:=teamd} +WAIT_TIME=${WAIT_TIME:=5} +PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} +PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no} +NETIF_TYPE=${NETIF_TYPE:=veth} +NETIF_CREATE=${NETIF_CREATE:=yes} +MCD=${MCD:=smcrouted} +MC_CLI=${MC_CLI:=smcroutectl} +PING_COUNT=${PING_COUNT:=10} +PING_TIMEOUT=${PING_TIMEOUT:=5} +WAIT_TIMEOUT=${WAIT_TIMEOUT:=20} +INTERFACE_TIMEOUT=${INTERFACE_TIMEOUT:=600} +LOW_AGEING_TIME=${LOW_AGEING_TIME:=1000} +REQUIRE_JQ=${REQUIRE_JQ:=yes} +REQUIRE_MZ=${REQUIRE_MZ:=yes} +REQUIRE_MTOOLS=${REQUIRE_MTOOLS:=no} +STABLE_MAC_ADDRS=${STABLE_MAC_ADDRS:=no} +TCPDUMP_EXTRA_FLAGS=${TCPDUMP_EXTRA_FLAGS:=} + +relative_path="${BASH_SOURCE%/*}" +if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then + relative_path="." +fi + +if [[ -f $relative_path/forwarding.config ]]; then + source "$relative_path/forwarding.config" +fi + +############################################################################## +# Sanity checks + +check_tc_version() +{ + tc -j &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing JSON support" + exit $ksft_skip + fi +} + +# Old versions of tc don't understand "mpls_uc" +check_tc_mpls_support() +{ + local dev=$1; shift + + tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ + matchall action pipe &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing MPLS support" + return $ksft_skip + fi + tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ + matchall +} + +# Old versions of tc produce invalid json output for mpls lse statistics +check_tc_mpls_lse_stats() +{ + local dev=$1; shift + local ret; + + tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ + flower mpls lse depth 2 \ + action continue &> /dev/null + + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc-flower is missing extended MPLS support" + return $ksft_skip + fi + + tc -j filter show dev $dev ingress protocol mpls_uc | jq . &> /dev/null + ret=$? + tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ + flower + + if [[ $ret -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc-flower produces invalid json output for extended MPLS filters" + return $ksft_skip + fi +} + +check_tc_shblock_support() +{ + tc filter help 2>&1 | grep block &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing shared block support" + exit $ksft_skip + fi +} + +check_tc_chain_support() +{ + tc help 2>&1|grep chain &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing chain support" + exit $ksft_skip + fi +} + +check_tc_action_hw_stats_support() +{ + tc actions help 2>&1 | grep -q hw_stats + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing action hw_stats support" + exit $ksft_skip + fi +} + +check_ethtool_lanes_support() +{ + ethtool --help 2>&1| grep lanes &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: ethtool too old; it is missing lanes support" + exit $ksft_skip + fi +} + +check_locked_port_support() +{ + if ! bridge -d link show | grep -q " locked"; then + echo "SKIP: iproute2 too old; Locked port feature not supported." + return $ksft_skip + fi +} + +if [[ "$(id -u)" -ne 0 ]]; then + echo "SKIP: need root privileges" + exit $ksft_skip +fi + +if [[ "$CHECK_TC" = "yes" ]]; then + check_tc_version +fi + +require_command() +{ + local cmd=$1; shift + + if [[ ! -x "$(command -v "$cmd")" ]]; then + echo "SKIP: $cmd not installed" + exit $ksft_skip + fi +} + +if [[ "$REQUIRE_JQ" = "yes" ]]; then + require_command jq +fi +if [[ "$REQUIRE_MZ" = "yes" ]]; then + require_command $MZ +fi +if [[ "$REQUIRE_MTOOLS" = "yes" ]]; then + # https://github.com/vladimiroltean/mtools/ + # patched for IPv6 support + require_command msend + require_command mreceive +fi + +if [[ ! -v NUM_NETIFS ]]; then + echo "SKIP: importer does not define \"NUM_NETIFS\"" + exit $ksft_skip +fi + +############################################################################## +# Command line options handling + +count=0 + +while [[ $# -gt 0 ]]; do + if [[ "$count" -eq "0" ]]; then + unset NETIFS + declare -A NETIFS + fi + count=$((count + 1)) + NETIFS[p$count]="$1" + shift +done + +############################################################################## +# Network interfaces configuration + +create_netif_veth() +{ + local i + + for ((i = 1; i <= NUM_NETIFS; ++i)); do + local j=$((i+1)) + + ip link show dev ${NETIFS[p$i]} &> /dev/null + if [[ $? -ne 0 ]]; then + ip link add ${NETIFS[p$i]} type veth \ + peer name ${NETIFS[p$j]} + if [[ $? -ne 0 ]]; then + echo "Failed to create netif" + exit 1 + fi + fi + i=$j + done +} + +create_netif() +{ + case "$NETIF_TYPE" in + veth) create_netif_veth + ;; + *) echo "Can not create interfaces of type \'$NETIF_TYPE\'" + exit 1 + ;; + esac +} + +declare -A MAC_ADDR_ORIG +mac_addr_prepare() +{ + local new_addr= + local dev= + + for ((i = 1; i <= NUM_NETIFS; ++i)); do + dev=${NETIFS[p$i]} + new_addr=$(printf "00:01:02:03:04:%02x" $i) + + MAC_ADDR_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].address') + # Strip quotes + MAC_ADDR_ORIG["$dev"]=${MAC_ADDR_ORIG["$dev"]//\"/} + ip link set dev $dev address $new_addr + done +} + +mac_addr_restore() +{ + local dev= + + for ((i = 1; i <= NUM_NETIFS; ++i)); do + dev=${NETIFS[p$i]} + ip link set dev $dev address ${MAC_ADDR_ORIG["$dev"]} + done +} + +if [[ "$NETIF_CREATE" = "yes" ]]; then + create_netif +fi + +if [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then + mac_addr_prepare +fi + +for ((i = 1; i <= NUM_NETIFS; ++i)); do + ip link show dev ${NETIFS[p$i]} &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: could not find all required interfaces" + exit $ksft_skip + fi +done + +############################################################################## +# Helpers + +# Exit status to return at the end. Set in case one of the tests fails. +EXIT_STATUS=0 +# Per-test return value. Clear at the beginning of each test. +RET=0 + +check_err() +{ + local err=$1 + local msg=$2 + + if [[ $RET -eq 0 && $err -ne 0 ]]; then + RET=$err + retmsg=$msg + fi +} + +check_fail() +{ + local err=$1 + local msg=$2 + + if [[ $RET -eq 0 && $err -eq 0 ]]; then + RET=1 + retmsg=$msg + fi +} + +check_err_fail() +{ + local should_fail=$1; shift + local err=$1; shift + local what=$1; shift + + if ((should_fail)); then + check_fail $err "$what succeeded, but should have failed" + else + check_err $err "$what failed" + fi +} + +log_test() +{ + local test_name=$1 + local opt_str=$2 + + if [[ $# -eq 2 ]]; then + opt_str="($opt_str)" + fi + + if [[ $RET -ne 0 ]]; then + EXIT_STATUS=1 + printf "TEST: %-60s [FAIL]\n" "$test_name $opt_str" + if [[ ! -z "$retmsg" ]]; then + printf "\t%s\n" "$retmsg" + fi + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then + echo "Hit enter to continue, 'q' to quit" + read a + [ "$a" = "q" ] && exit 1 + fi + return 1 + fi + + printf "TEST: %-60s [ OK ]\n" "$test_name $opt_str" + return 0 +} + +log_test_skip() +{ + local test_name=$1 + local opt_str=$2 + + printf "TEST: %-60s [SKIP]\n" "$test_name $opt_str" + return 0 +} + +log_info() +{ + local msg=$1 + + echo "INFO: $msg" +} + +busywait() +{ + local timeout=$1; shift + + local start_time="$(date -u +%s%3N)" + while true + do + local out + out=$("$@") + local ret=$? + if ((!ret)); then + echo -n "$out" + return 0 + fi + + local current_time="$(date -u +%s%3N)" + if ((current_time - start_time > timeout)); then + echo -n "$out" + return 1 + fi + done +} + +not() +{ + "$@" + [[ $? != 0 ]] +} + +get_max() +{ + local arr=("$@") + + max=${arr[0]} + for cur in ${arr[@]}; do + if [[ $cur -gt $max ]]; then + max=$cur + fi + done + + echo $max +} + +grep_bridge_fdb() +{ + local addr=$1; shift + local word + local flag + + if [ "$1" == "self" ] || [ "$1" == "master" ]; then + word=$1; shift + if [ "$1" == "-v" ]; then + flag=$1; shift + fi + fi + + $@ | grep $addr | grep $flag "$word" +} + +wait_for_port_up() +{ + "$@" | grep -q "Link detected: yes" +} + +wait_for_offload() +{ + "$@" | grep -q offload +} + +wait_for_trap() +{ + "$@" | grep -q trap +} + +until_counter_is() +{ + local expr=$1; shift + local current=$("$@") + + echo $((current)) + ((current $expr)) +} + +busywait_for_counter() +{ + local timeout=$1; shift + local delta=$1; shift + + local base=$("$@") + busywait "$timeout" until_counter_is ">= $((base + delta))" "$@" +} + +setup_wait_dev() +{ + local dev=$1; shift + local wait_time=${1:-$WAIT_TIME}; shift + + setup_wait_dev_with_timeout "$dev" $INTERFACE_TIMEOUT $wait_time + + if (($?)); then + check_err 1 + log_test setup_wait_dev ": Interface $dev does not come up." + exit 1 + fi +} + +setup_wait_dev_with_timeout() +{ + local dev=$1; shift + local max_iterations=${1:-$WAIT_TIMEOUT}; shift + local wait_time=${1:-$WAIT_TIME}; shift + local i + + for ((i = 1; i <= $max_iterations; ++i)); do + ip link show dev $dev up \ + | grep 'state UP' &> /dev/null + if [[ $? -ne 0 ]]; then + sleep 1 + else + sleep $wait_time + return 0 + fi + done + + return 1 +} + +setup_wait() +{ + local num_netifs=${1:-$NUM_NETIFS} + local i + + for ((i = 1; i <= num_netifs; ++i)); do + setup_wait_dev ${NETIFS[p$i]} 0 + done + + # Make sure links are ready. + sleep $WAIT_TIME +} + +cmd_jq() +{ + local cmd=$1 + local jq_exp=$2 + local jq_opts=$3 + local ret + local output + + output="$($cmd)" + # it the command fails, return error right away + ret=$? + if [[ $ret -ne 0 ]]; then + return $ret + fi + output=$(echo $output | jq -r $jq_opts "$jq_exp") + ret=$? + if [[ $ret -ne 0 ]]; then + return $ret + fi + echo $output + # return success only in case of non-empty output + [ ! -z "$output" ] +} + +lldpad_app_wait_set() +{ + local dev=$1; shift + + while lldptool -t -i $dev -V APP -c app | grep -Eq "pending|unknown"; do + echo "$dev: waiting for lldpad to push pending APP updates" + sleep 5 + done +} + +lldpad_app_wait_del() +{ + # Give lldpad a chance to push down the changes. If the device is downed + # too soon, the updates will be left pending. However, they will have + # been struck off the lldpad's DB already, so we won't be able to tell + # they are pending. Then on next test iteration this would cause + # weirdness as newly-added APP rules conflict with the old ones, + # sometimes getting stuck in an "unknown" state. + sleep 5 +} + +pre_cleanup() +{ + if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then + echo "Pausing before cleanup, hit any key to continue" + read + fi + + if [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then + mac_addr_restore + fi +} + +vrf_prepare() +{ + ip -4 rule add pref 32765 table local + ip -4 rule del pref 0 + ip -6 rule add pref 32765 table local + ip -6 rule del pref 0 +} + +vrf_cleanup() +{ + ip -6 rule add pref 0 table local + ip -6 rule del pref 32765 + ip -4 rule add pref 0 table local + ip -4 rule del pref 32765 +} + +__last_tb_id=0 +declare -A __TB_IDS + +__vrf_td_id_assign() +{ + local vrf_name=$1 + + __last_tb_id=$((__last_tb_id + 1)) + __TB_IDS[$vrf_name]=$__last_tb_id + return $__last_tb_id +} + +__vrf_td_id_lookup() +{ + local vrf_name=$1 + + return ${__TB_IDS[$vrf_name]} +} + +vrf_create() +{ + local vrf_name=$1 + local tb_id + + __vrf_td_id_assign $vrf_name + tb_id=$? + + ip link add dev $vrf_name type vrf table $tb_id + ip -4 route add table $tb_id unreachable default metric 4278198272 + ip -6 route add table $tb_id unreachable default metric 4278198272 +} + +vrf_destroy() +{ + local vrf_name=$1 + local tb_id + + __vrf_td_id_lookup $vrf_name + tb_id=$? + + ip -6 route del table $tb_id unreachable default metric 4278198272 + ip -4 route del table $tb_id unreachable default metric 4278198272 + ip link del dev $vrf_name +} + +__addr_add_del() +{ + local if_name=$1 + local add_del=$2 + local array + + shift + shift + array=("${@}") + + for addrstr in "${array[@]}"; do + ip address $add_del $addrstr dev $if_name + done +} + +__simple_if_init() +{ + local if_name=$1; shift + local vrf_name=$1; shift + local addrs=("${@}") + + ip link set dev $if_name master $vrf_name + ip link set dev $if_name up + + __addr_add_del $if_name add "${addrs[@]}" +} + +__simple_if_fini() +{ + local if_name=$1; shift + local addrs=("${@}") + + __addr_add_del $if_name del "${addrs[@]}" + + ip link set dev $if_name down + ip link set dev $if_name nomaster +} + +simple_if_init() +{ + local if_name=$1 + local vrf_name + local array + + shift + vrf_name=v$if_name + array=("${@}") + + vrf_create $vrf_name + ip link set dev $vrf_name up + __simple_if_init $if_name $vrf_name "${array[@]}" +} + +simple_if_fini() +{ + local if_name=$1 + local vrf_name + local array + + shift + vrf_name=v$if_name + array=("${@}") + + __simple_if_fini $if_name "${array[@]}" + vrf_destroy $vrf_name +} + +tunnel_create() +{ + local name=$1; shift + local type=$1; shift + local local=$1; shift + local remote=$1; shift + + ip link add name $name type $type \ + local $local remote $remote "$@" + ip link set dev $name up +} + +tunnel_destroy() +{ + local name=$1; shift + + ip link del dev $name +} + +vlan_create() +{ + local if_name=$1; shift + local vid=$1; shift + local vrf=$1; shift + local ips=("${@}") + local name=$if_name.$vid + + ip link add name $name link $if_name type vlan id $vid + if [ "$vrf" != "" ]; then + ip link set dev $name master $vrf + fi + ip link set dev $name up + __addr_add_del $name add "${ips[@]}" +} + +vlan_destroy() +{ + local if_name=$1; shift + local vid=$1; shift + local name=$if_name.$vid + + ip link del dev $name +} + +team_create() +{ + local if_name=$1; shift + local mode=$1; shift + + require_command $TEAMD + $TEAMD -t $if_name -d -c '{"runner": {"name": "'$mode'"}}' + for slave in "$@"; do + ip link set dev $slave down + ip link set dev $slave master $if_name + ip link set dev $slave up + done + ip link set dev $if_name up +} + +team_destroy() +{ + local if_name=$1; shift + + $TEAMD -t $if_name -k +} + +master_name_get() +{ + local if_name=$1 + + ip -j link show dev $if_name | jq -r '.[]["master"]' +} + +link_stats_get() +{ + local if_name=$1; shift + local dir=$1; shift + local stat=$1; shift + + ip -j -s link show dev $if_name \ + | jq '.[]["stats64"]["'$dir'"]["'$stat'"]' +} + +link_stats_tx_packets_get() +{ + link_stats_get $1 tx packets +} + +link_stats_rx_errors_get() +{ + link_stats_get $1 rx errors +} + +tc_rule_stats_get() +{ + local dev=$1; shift + local pref=$1; shift + local dir=$1; shift + local selector=${1:-.packets}; shift + + tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \ + | jq ".[1].options.actions[].stats$selector" +} + +tc_rule_handle_stats_get() +{ + local id=$1; shift + local handle=$1; shift + local selector=${1:-.packets}; shift + + tc -j -s filter show $id \ + | jq ".[] | select(.options.handle == $handle) | \ + .options.actions[0].stats$selector" +} + +ethtool_stats_get() +{ + local dev=$1; shift + local stat=$1; shift + + ethtool -S $dev | grep "^ *$stat:" | head -n 1 | cut -d: -f2 +} + +qdisc_stats_get() +{ + local dev=$1; shift + local handle=$1; shift + local selector=$1; shift + + tc -j -s qdisc show dev "$dev" \ + | jq '.[] | select(.handle == "'"$handle"'") | '"$selector" +} + +qdisc_parent_stats_get() +{ + local dev=$1; shift + local parent=$1; shift + local selector=$1; shift + + tc -j -s qdisc show dev "$dev" invisible \ + | jq '.[] | select(.parent == "'"$parent"'") | '"$selector" +} + +ipv6_stats_get() +{ + local dev=$1; shift + local stat=$1; shift + + cat /proc/net/dev_snmp6/$dev | grep "^$stat" | cut -f2 +} + +hw_stats_get() +{ + local suite=$1; shift + local if_name=$1; shift + local dir=$1; shift + local stat=$1; shift + + ip -j stats show dev $if_name group offload subgroup $suite | + jq ".[0].stats64.$dir.$stat" +} + +humanize() +{ + local speed=$1; shift + + for unit in bps Kbps Mbps Gbps; do + if (($(echo "$speed < 1024" | bc))); then + break + fi + + speed=$(echo "scale=1; $speed / 1024" | bc) + done + + echo "$speed${unit}" +} + +rate() +{ + local t0=$1; shift + local t1=$1; shift + local interval=$1; shift + + echo $((8 * (t1 - t0) / interval)) +} + +packets_rate() +{ + local t0=$1; shift + local t1=$1; shift + local interval=$1; shift + + echo $(((t1 - t0) / interval)) +} + +mac_get() +{ + local if_name=$1 + + ip -j link show dev $if_name | jq -r '.[]["address"]' +} + +ipv6_lladdr_get() +{ + local if_name=$1 + + ip -j addr show dev $if_name | \ + jq -r '.[]["addr_info"][] | select(.scope == "link").local' | \ + head -1 +} + +bridge_ageing_time_get() +{ + local bridge=$1 + local ageing_time + + # Need to divide by 100 to convert to seconds. + ageing_time=$(ip -j -d link show dev $bridge \ + | jq '.[]["linkinfo"]["info_data"]["ageing_time"]') + echo $((ageing_time / 100)) +} + +declare -A SYSCTL_ORIG +sysctl_set() +{ + local key=$1; shift + local value=$1; shift + + SYSCTL_ORIG[$key]=$(sysctl -n $key) + sysctl -qw $key=$value +} + +sysctl_restore() +{ + local key=$1; shift + + sysctl -qw $key=${SYSCTL_ORIG["$key"]} +} + +forwarding_enable() +{ + sysctl_set net.ipv4.conf.all.forwarding 1 + sysctl_set net.ipv6.conf.all.forwarding 1 +} + +forwarding_restore() +{ + sysctl_restore net.ipv6.conf.all.forwarding + sysctl_restore net.ipv4.conf.all.forwarding +} + +declare -A MTU_ORIG +mtu_set() +{ + local dev=$1; shift + local mtu=$1; shift + + MTU_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].mtu') + ip link set dev $dev mtu $mtu +} + +mtu_restore() +{ + local dev=$1; shift + + ip link set dev $dev mtu ${MTU_ORIG["$dev"]} +} + +tc_offload_check() +{ + local num_netifs=${1:-$NUM_NETIFS} + + for ((i = 1; i <= num_netifs; ++i)); do + ethtool -k ${NETIFS[p$i]} \ + | grep "hw-tc-offload: on" &> /dev/null + if [[ $? -ne 0 ]]; then + return 1 + fi + done + + return 0 +} + +trap_install() +{ + local dev=$1; shift + local direction=$1; shift + + # Some devices may not support or need in-hardware trapping of traffic + # (e.g. the veth pairs that this library creates for non-existent + # loopbacks). Use continue instead, so that there is a filter in there + # (some tests check counters), and so that other filters are still + # processed. + tc filter add dev $dev $direction pref 1 \ + flower skip_sw action trap 2>/dev/null \ + || tc filter add dev $dev $direction pref 1 \ + flower action continue +} + +trap_uninstall() +{ + local dev=$1; shift + local direction=$1; shift + + tc filter del dev $dev $direction pref 1 flower +} + +slow_path_trap_install() +{ + # For slow-path testing, we need to install a trap to get to + # slow path the packets that would otherwise be switched in HW. + if [ "${tcflags/skip_hw}" != "$tcflags" ]; then + trap_install "$@" + fi +} + +slow_path_trap_uninstall() +{ + if [ "${tcflags/skip_hw}" != "$tcflags" ]; then + trap_uninstall "$@" + fi +} + +__icmp_capture_add_del() +{ + local add_del=$1; shift + local pref=$1; shift + local vsuf=$1; shift + local tundev=$1; shift + local filter=$1; shift + + tc filter $add_del dev "$tundev" ingress \ + proto ip$vsuf pref $pref \ + flower ip_proto icmp$vsuf $filter \ + action pass +} + +icmp_capture_install() +{ + __icmp_capture_add_del add 100 "" "$@" +} + +icmp_capture_uninstall() +{ + __icmp_capture_add_del del 100 "" "$@" +} + +icmp6_capture_install() +{ + __icmp_capture_add_del add 100 v6 "$@" +} + +icmp6_capture_uninstall() +{ + __icmp_capture_add_del del 100 v6 "$@" +} + +__vlan_capture_add_del() +{ + local add_del=$1; shift + local pref=$1; shift + local dev=$1; shift + local filter=$1; shift + + tc filter $add_del dev "$dev" ingress \ + proto 802.1q pref $pref \ + flower $filter \ + action pass +} + +vlan_capture_install() +{ + __vlan_capture_add_del add 100 "$@" +} + +vlan_capture_uninstall() +{ + __vlan_capture_add_del del 100 "$@" +} + +__dscp_capture_add_del() +{ + local add_del=$1; shift + local dev=$1; shift + local base=$1; shift + local dscp; + + for prio in {0..7}; do + dscp=$((base + prio)) + __icmp_capture_add_del $add_del $((dscp + 100)) "" $dev \ + "skip_hw ip_tos $((dscp << 2))" + done +} + +dscp_capture_install() +{ + local dev=$1; shift + local base=$1; shift + + __dscp_capture_add_del add $dev $base +} + +dscp_capture_uninstall() +{ + local dev=$1; shift + local base=$1; shift + + __dscp_capture_add_del del $dev $base +} + +dscp_fetch_stats() +{ + local dev=$1; shift + local base=$1; shift + + for prio in {0..7}; do + local dscp=$((base + prio)) + local t=$(tc_rule_stats_get $dev $((dscp + 100))) + echo "[$dscp]=$t " + done +} + +matchall_sink_create() +{ + local dev=$1; shift + + tc qdisc add dev $dev clsact + tc filter add dev $dev ingress \ + pref 10000 \ + matchall \ + action drop +} + +tests_run() +{ + local current_test + + for current_test in ${TESTS:-$ALL_TESTS}; do + $current_test + done +} + +multipath_eval() +{ + local desc="$1" + local weight_rp12=$2 + local weight_rp13=$3 + local packets_rp12=$4 + local packets_rp13=$5 + local weights_ratio packets_ratio diff + + RET=0 + + if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then + weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \ + | bc -l) + else + weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" \ + | bc -l) + fi + + if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then + check_err 1 "Packet difference is 0" + log_test "Multipath" + log_info "Expected ratio $weights_ratio" + return + fi + + if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then + packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \ + | bc -l) + else + packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" \ + | bc -l) + fi + + diff=$(echo $weights_ratio - $packets_ratio | bc -l) + diff=${diff#-} + + test "$(echo "$diff / $weights_ratio > 0.15" | bc -l)" -eq 0 + check_err $? "Too large discrepancy between expected and measured ratios" + log_test "$desc" + log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio" +} + +in_ns() +{ + local name=$1; shift + + ip netns exec $name bash <<-EOF + NUM_NETIFS=0 + source lib.sh + $(for a in "$@"; do printf "%q${IFS:0:1}" "$a"; done) + EOF +} + +############################################################################## +# Tests + +ping_do() +{ + local if_name=$1 + local dip=$2 + local args=$3 + local vrf_name + + vrf_name=$(master_name_get $if_name) + ip vrf exec $vrf_name \ + $PING $args $dip -c $PING_COUNT -i 0.1 \ + -w $PING_TIMEOUT &> /dev/null +} + +ping_test() +{ + RET=0 + + ping_do $1 $2 + check_err $? + log_test "ping$3" +} + +ping6_do() +{ + local if_name=$1 + local dip=$2 + local args=$3 + local vrf_name + + vrf_name=$(master_name_get $if_name) + ip vrf exec $vrf_name \ + $PING6 $args $dip -c $PING_COUNT -i 0.1 \ + -w $PING_TIMEOUT &> /dev/null +} + +ping6_test() +{ + RET=0 + + ping6_do $1 $2 + check_err $? + log_test "ping6$3" +} + +learning_test() +{ + local bridge=$1 + local br_port1=$2 # Connected to `host1_if`. + local host1_if=$3 + local host2_if=$4 + local mac=de:ad:be:ef:13:37 + local ageing_time + + RET=0 + + bridge -j fdb show br $bridge brport $br_port1 \ + | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null + check_fail $? "Found FDB record when should not" + + # Disable unknown unicast flooding on `br_port1` to make sure + # packets are only forwarded through the port after a matching + # FDB entry was installed. + bridge link set dev $br_port1 flood off + + ip link set $host1_if promisc on + tc qdisc add dev $host1_if ingress + tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \ + flower dst_mac $mac action drop + + $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q + sleep 1 + + tc -j -s filter show dev $host1_if ingress \ + | jq -e ".[] | select(.options.handle == 101) \ + | select(.options.actions[0].stats.packets == 1)" &> /dev/null + check_fail $? "Packet reached first host when should not" + + $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q + sleep 1 + + bridge -j fdb show br $bridge brport $br_port1 \ + | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null + check_err $? "Did not find FDB record when should" + + $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q + sleep 1 + + tc -j -s filter show dev $host1_if ingress \ + | jq -e ".[] | select(.options.handle == 101) \ + | select(.options.actions[0].stats.packets == 1)" &> /dev/null + check_err $? "Packet did not reach second host when should" + + # Wait for 10 seconds after the ageing time to make sure FDB + # record was aged-out. + ageing_time=$(bridge_ageing_time_get $bridge) + sleep $((ageing_time + 10)) + + bridge -j fdb show br $bridge brport $br_port1 \ + | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null + check_fail $? "Found FDB record when should not" + + bridge link set dev $br_port1 learning off + + $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q + sleep 1 + + bridge -j fdb show br $bridge brport $br_port1 \ + | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null + check_fail $? "Found FDB record when should not" + + bridge link set dev $br_port1 learning on + + tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower + tc qdisc del dev $host1_if ingress + ip link set $host1_if promisc off + + bridge link set dev $br_port1 flood on + + log_test "FDB learning" +} + +flood_test_do() +{ + local should_flood=$1 + local mac=$2 + local ip=$3 + local host1_if=$4 + local host2_if=$5 + local err=0 + + # Add an ACL on `host2_if` which will tell us whether the packet + # was flooded to it or not. + ip link set $host2_if promisc on + tc qdisc add dev $host2_if ingress + tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \ + flower dst_mac $mac action drop + + $MZ $host1_if -c 1 -p 64 -b $mac -B $ip -t ip -q + sleep 1 + + tc -j -s filter show dev $host2_if ingress \ + | jq -e ".[] | select(.options.handle == 101) \ + | select(.options.actions[0].stats.packets == 1)" &> /dev/null + if [[ $? -ne 0 && $should_flood == "true" || \ + $? -eq 0 && $should_flood == "false" ]]; then + err=1 + fi + + tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower + tc qdisc del dev $host2_if ingress + ip link set $host2_if promisc off + + return $err +} + +flood_unicast_test() +{ + local br_port=$1 + local host1_if=$2 + local host2_if=$3 + local mac=de:ad:be:ef:13:37 + local ip=192.0.2.100 + + RET=0 + + bridge link set dev $br_port flood off + + flood_test_do false $mac $ip $host1_if $host2_if + check_err $? "Packet flooded when should not" + + bridge link set dev $br_port flood on + + flood_test_do true $mac $ip $host1_if $host2_if + check_err $? "Packet was not flooded when should" + + log_test "Unknown unicast flood" +} + +flood_multicast_test() +{ + local br_port=$1 + local host1_if=$2 + local host2_if=$3 + local mac=01:00:5e:00:00:01 + local ip=239.0.0.1 + + RET=0 + + bridge link set dev $br_port mcast_flood off + + flood_test_do false $mac $ip $host1_if $host2_if + check_err $? "Packet flooded when should not" + + bridge link set dev $br_port mcast_flood on + + flood_test_do true $mac $ip $host1_if $host2_if + check_err $? "Packet was not flooded when should" + + log_test "Unregistered multicast flood" +} + +flood_test() +{ + # `br_port` is connected to `host2_if` + local br_port=$1 + local host1_if=$2 + local host2_if=$3 + + flood_unicast_test $br_port $host1_if $host2_if + flood_multicast_test $br_port $host1_if $host2_if +} + +__start_traffic() +{ + local pktsize=$1; shift + local proto=$1; shift + local h_in=$1; shift # Where the traffic egresses the host + local sip=$1; shift + local dip=$1; shift + local dmac=$1; shift + + $MZ $h_in -p $pktsize -A $sip -B $dip -c 0 \ + -a own -b $dmac -t "$proto" -q "$@" & + sleep 1 +} + +start_traffic_pktsize() +{ + local pktsize=$1; shift + + __start_traffic $pktsize udp "$@" +} + +start_tcp_traffic_pktsize() +{ + local pktsize=$1; shift + + __start_traffic $pktsize tcp "$@" +} + +start_traffic() +{ + start_traffic_pktsize 8000 "$@" +} + +start_tcp_traffic() +{ + start_tcp_traffic_pktsize 8000 "$@" +} + +stop_traffic() +{ + # Suppress noise from killing mausezahn. + { kill %% && wait %%; } 2>/dev/null +} + +declare -A cappid +declare -A capfile +declare -A capout + +tcpdump_start() +{ + local if_name=$1; shift + local ns=$1; shift + + capfile[$if_name]=$(mktemp) + capout[$if_name]=$(mktemp) + + if [ -z $ns ]; then + ns_cmd="" + else + ns_cmd="ip netns exec ${ns}" + fi + + if [ -z $SUDO_USER ] ; then + capuser="" + else + capuser="-Z $SUDO_USER" + fi + + $ns_cmd tcpdump $TCPDUMP_EXTRA_FLAGS -e -n -Q in -i $if_name \ + -s 65535 -B 32768 $capuser -w ${capfile[$if_name]} \ + > "${capout[$if_name]}" 2>&1 & + cappid[$if_name]=$! + + sleep 1 +} + +tcpdump_stop() +{ + local if_name=$1 + local pid=${cappid[$if_name]} + + $ns_cmd kill "$pid" && wait "$pid" + sleep 1 +} + +tcpdump_cleanup() +{ + local if_name=$1 + + rm ${capfile[$if_name]} ${capout[$if_name]} +} + +tcpdump_show() +{ + local if_name=$1 + + tcpdump -e -n -r ${capfile[$if_name]} 2>&1 +} + +# return 0 if the packet wasn't seen on host2_if or 1 if it was +mcast_packet_test() +{ + local mac=$1 + local src_ip=$2 + local ip=$3 + local host1_if=$4 + local host2_if=$5 + local seen=0 + local tc_proto="ip" + local mz_v6arg="" + + # basic check to see if we were passed an IPv4 address, if not assume IPv6 + if [[ ! $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + tc_proto="ipv6" + mz_v6arg="-6" + fi + + # Add an ACL on `host2_if` which will tell us whether the packet + # was received by it or not. + tc qdisc add dev $host2_if ingress + tc filter add dev $host2_if ingress protocol $tc_proto pref 1 handle 101 \ + flower ip_proto udp dst_mac $mac action drop + + $MZ $host1_if $mz_v6arg -c 1 -p 64 -b $mac -A $src_ip -B $ip -t udp "dp=4096,sp=2048" -q + sleep 1 + + tc -j -s filter show dev $host2_if ingress \ + | jq -e ".[] | select(.options.handle == 101) \ + | select(.options.actions[0].stats.packets == 1)" &> /dev/null + if [[ $? -eq 0 ]]; then + seen=1 + fi + + tc filter del dev $host2_if ingress protocol $tc_proto pref 1 handle 101 flower + tc qdisc del dev $host2_if ingress + + return $seen +} + +brmcast_check_sg_entries() +{ + local report=$1; shift + local slist=("$@") + local sarg="" + + for src in "${slist[@]}"; do + sarg="${sarg} and .source_list[].address == \"$src\"" + done + bridge -j -d -s mdb show dev br0 \ + | jq -e ".[].mdb[] | \ + select(.grp == \"$TEST_GROUP\" and .source_list != null $sarg)" &>/dev/null + check_err $? "Wrong *,G entry source list after $report report" + + for sgent in "${slist[@]}"; do + bridge -j -d -s mdb show dev br0 \ + | jq -e ".[].mdb[] | \ + select(.grp == \"$TEST_GROUP\" and .src == \"$sgent\")" &>/dev/null + check_err $? "Missing S,G entry ($sgent, $TEST_GROUP)" + done +} + +brmcast_check_sg_fwding() +{ + local should_fwd=$1; shift + local sources=("$@") + + for src in "${sources[@]}"; do + local retval=0 + + mcast_packet_test $TEST_GROUP_MAC $src $TEST_GROUP $h2 $h1 + retval=$? + if [ $should_fwd -eq 1 ]; then + check_fail $retval "Didn't forward traffic from S,G ($src, $TEST_GROUP)" + else + check_err $retval "Forwarded traffic for blocked S,G ($src, $TEST_GROUP)" + fi + done +} + +brmcast_check_sg_state() +{ + local is_blocked=$1; shift + local sources=("$@") + local should_fail=1 + + if [ $is_blocked -eq 1 ]; then + should_fail=0 + fi + + for src in "${sources[@]}"; do + bridge -j -d -s mdb show dev br0 \ + | jq -e ".[].mdb[] | \ + select(.grp == \"$TEST_GROUP\" and .source_list != null) | + .source_list[] | + select(.address == \"$src\") | + select(.timer == \"0.00\")" &>/dev/null + check_err_fail $should_fail $? "Entry $src has zero timer" + + bridge -j -d -s mdb show dev br0 \ + | jq -e ".[].mdb[] | \ + select(.grp == \"$TEST_GROUP\" and .src == \"$src\" and \ + .flags[] == \"blocked\")" &>/dev/null + check_err_fail $should_fail $? "Entry $src has blocked flag" + done +} + +mc_join() +{ + local if_name=$1 + local group=$2 + local vrf_name=$(master_name_get $if_name) + + # We don't care about actual reception, just about joining the + # IP multicast group and adding the L2 address to the device's + # MAC filtering table + ip vrf exec $vrf_name \ + mreceive -g $group -I $if_name > /dev/null 2>&1 & + mreceive_pid=$! + + sleep 1 +} + +mc_leave() +{ + kill "$mreceive_pid" && wait "$mreceive_pid" +} + +mc_send() +{ + local if_name=$1 + local groups=$2 + local vrf_name=$(master_name_get $if_name) + + ip vrf exec $vrf_name \ + msend -g $groups -I $if_name -c 1 > /dev/null 2>&1 +} + +start_ip_monitor() +{ + local mtype=$1; shift + local ip=${1-ip}; shift + + # start the monitor in the background + tmpfile=`mktemp /var/run/nexthoptestXXX` + mpid=`($ip monitor $mtype > $tmpfile & echo $!) 2>/dev/null` + sleep 0.2 + echo "$mpid $tmpfile" +} + +stop_ip_monitor() +{ + local mpid=$1; shift + local tmpfile=$1; shift + local el=$1; shift + local what=$1; shift + + sleep 0.2 + kill $mpid + local lines=`grep '^\w' $tmpfile | wc -l` + test $lines -eq $el + check_err $? "$what: $lines lines of events, expected $el" + rm -rf $tmpfile +} + +hw_stats_monitor_test() +{ + local dev=$1; shift + local type=$1; shift + local make_suitable=$1; shift + local make_unsuitable=$1; shift + local ip=${1-ip}; shift + + RET=0 + + # Expect a notification about enablement. + local ipmout=$(start_ip_monitor stats "$ip") + $ip stats set dev $dev ${type}_stats on + stop_ip_monitor $ipmout 1 "${type}_stats enablement" + + # Expect a notification about offload. + local ipmout=$(start_ip_monitor stats "$ip") + $make_suitable + stop_ip_monitor $ipmout 1 "${type}_stats installation" + + # Expect a notification about loss of offload. + local ipmout=$(start_ip_monitor stats "$ip") + $make_unsuitable + stop_ip_monitor $ipmout 1 "${type}_stats deinstallation" + + # Expect a notification about disablement + local ipmout=$(start_ip_monitor stats "$ip") + $ip stats set dev $dev ${type}_stats off + stop_ip_monitor $ipmout 1 "${type}_stats disablement" + + log_test "${type}_stats notifications" +} diff -Nru linux-6.0.6/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh linux-6.0.12/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh --- linux-6.0.6/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh 2023-01-18 18:27:39.000000000 +0000 @@ -18,8 +18,8 @@ REQUIRE_JQ="no" REQUIRE_MZ="no" NETIF_CREATE="no" -lib_dir=$(dirname $0)/../../../net/forwarding -source $lib_dir/lib.sh +lib_dir=$(dirname "$0") +source "$lib_dir"/lib.sh cleanup() { echo "Cleaning up" diff -Nru linux-6.0.6/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh linux-6.0.12/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh --- linux-6.0.6/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh 2023-01-18 18:27:39.000000000 +0000 @@ -11,14 +11,14 @@ REQUIRE_MZ=no NUM_NETIFS=0 lib_dir=$(dirname "$0") -source "$lib_dir"/../../../net/forwarding/lib.sh +source "$lib_dir"/net_forwarding_lib.sh -source "$lib_dir"/../bonding/lag_lib.sh +source "$lib_dir"/lag_lib.sh destroy() { - local ifnames=(dummy0 dummy1 team0 mv0) + local ifnames=(dummy1 dummy2 team0 mv0) local ifname for ifname in "${ifnames[@]}"; do diff -Nru linux-6.0.6/tools/testing/selftests/drivers/net/team/lag_lib.sh linux-6.0.12/tools/testing/selftests/drivers/net/team/lag_lib.sh --- linux-6.0.6/tools/testing/selftests/drivers/net/team/lag_lib.sh 1970-01-01 00:00:00.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/drivers/net/team/lag_lib.sh 2023-01-18 18:27:39.000000000 +0000 @@ -0,0 +1,61 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# Test that a link aggregation device (bonding, team) removes the hardware +# addresses that it adds on its underlying devices. +test_LAG_cleanup() +{ + local driver=$1 + local mode=$2 + local ucaddr="02:00:00:12:34:56" + local addr6="fe80::78:9abc/64" + local mcaddr="33:33:ff:78:9a:bc" + local name + + ip link add dummy1 type dummy + ip link add dummy2 type dummy + if [ "$driver" = "bonding" ]; then + name="bond1" + ip link add "$name" up type bond mode "$mode" + ip link set dev dummy1 master "$name" + ip link set dev dummy2 master "$name" + elif [ "$driver" = "team" ]; then + name="team0" + teamd -d -c ' + { + "device": "'"$name"'", + "runner": { + "name": "'"$mode"'" + }, + "ports": { + "dummy1": + {}, + "dummy2": + {} + } + } + ' + ip link set dev "$name" up + else + check_err 1 + log_test test_LAG_cleanup ": unknown driver \"$driver\"" + return + fi + + # Used to test dev->uc handling + ip link add mv0 link "$name" up address "$ucaddr" type macvlan + # Used to test dev->mc handling + ip address add "$addr6" dev "$name" + ip link set dev "$name" down + ip link del "$name" + + not grep_bridge_fdb "$ucaddr" bridge fdb show >/dev/null + check_err $? "macvlan unicast address still present on a slave" + + not grep_bridge_fdb "$mcaddr" bridge fdb show >/dev/null + check_err $? "IPv6 solicited-node multicast mac address still present on a slave" + + cleanup + + log_test "$driver cleanup mode $mode" +} diff -Nru linux-6.0.6/tools/testing/selftests/drivers/net/team/Makefile linux-6.0.12/tools/testing/selftests/drivers/net/team/Makefile --- linux-6.0.6/tools/testing/selftests/drivers/net/team/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/drivers/net/team/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -3,4 +3,8 @@ TEST_PROGS := dev_addr_lists.sh +TEST_FILES := \ + lag_lib.sh \ + net_forwarding_lib.sh + include ../../../lib.mk diff -Nru linux-6.0.6/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh linux-6.0.12/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh --- linux-6.0.6/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh 1970-01-01 00:00:00.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh 2023-01-18 18:27:39.000000000 +0000 @@ -0,0 +1,1686 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +############################################################################## +# Defines + +# Kselftest framework requirement - SKIP code is 4. +ksft_skip=4 + +# Can be overridden by the configuration file. +PING=${PING:=ping} +PING6=${PING6:=ping6} +MZ=${MZ:=mausezahn} +ARPING=${ARPING:=arping} +TEAMD=${TEAMD:=teamd} +WAIT_TIME=${WAIT_TIME:=5} +PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} +PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no} +NETIF_TYPE=${NETIF_TYPE:=veth} +NETIF_CREATE=${NETIF_CREATE:=yes} +MCD=${MCD:=smcrouted} +MC_CLI=${MC_CLI:=smcroutectl} +PING_COUNT=${PING_COUNT:=10} +PING_TIMEOUT=${PING_TIMEOUT:=5} +WAIT_TIMEOUT=${WAIT_TIMEOUT:=20} +INTERFACE_TIMEOUT=${INTERFACE_TIMEOUT:=600} +LOW_AGEING_TIME=${LOW_AGEING_TIME:=1000} +REQUIRE_JQ=${REQUIRE_JQ:=yes} +REQUIRE_MZ=${REQUIRE_MZ:=yes} +REQUIRE_MTOOLS=${REQUIRE_MTOOLS:=no} +STABLE_MAC_ADDRS=${STABLE_MAC_ADDRS:=no} +TCPDUMP_EXTRA_FLAGS=${TCPDUMP_EXTRA_FLAGS:=} + +relative_path="${BASH_SOURCE%/*}" +if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then + relative_path="." +fi + +if [[ -f $relative_path/forwarding.config ]]; then + source "$relative_path/forwarding.config" +fi + +############################################################################## +# Sanity checks + +check_tc_version() +{ + tc -j &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing JSON support" + exit $ksft_skip + fi +} + +# Old versions of tc don't understand "mpls_uc" +check_tc_mpls_support() +{ + local dev=$1; shift + + tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ + matchall action pipe &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing MPLS support" + return $ksft_skip + fi + tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ + matchall +} + +# Old versions of tc produce invalid json output for mpls lse statistics +check_tc_mpls_lse_stats() +{ + local dev=$1; shift + local ret; + + tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ + flower mpls lse depth 2 \ + action continue &> /dev/null + + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc-flower is missing extended MPLS support" + return $ksft_skip + fi + + tc -j filter show dev $dev ingress protocol mpls_uc | jq . &> /dev/null + ret=$? + tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ + flower + + if [[ $ret -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc-flower produces invalid json output for extended MPLS filters" + return $ksft_skip + fi +} + +check_tc_shblock_support() +{ + tc filter help 2>&1 | grep block &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing shared block support" + exit $ksft_skip + fi +} + +check_tc_chain_support() +{ + tc help 2>&1|grep chain &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing chain support" + exit $ksft_skip + fi +} + +check_tc_action_hw_stats_support() +{ + tc actions help 2>&1 | grep -q hw_stats + if [[ $? -ne 0 ]]; then + echo "SKIP: iproute2 too old; tc is missing action hw_stats support" + exit $ksft_skip + fi +} + +check_ethtool_lanes_support() +{ + ethtool --help 2>&1| grep lanes &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: ethtool too old; it is missing lanes support" + exit $ksft_skip + fi +} + +check_locked_port_support() +{ + if ! bridge -d link show | grep -q " locked"; then + echo "SKIP: iproute2 too old; Locked port feature not supported." + return $ksft_skip + fi +} + +if [[ "$(id -u)" -ne 0 ]]; then + echo "SKIP: need root privileges" + exit $ksft_skip +fi + +if [[ "$CHECK_TC" = "yes" ]]; then + check_tc_version +fi + +require_command() +{ + local cmd=$1; shift + + if [[ ! -x "$(command -v "$cmd")" ]]; then + echo "SKIP: $cmd not installed" + exit $ksft_skip + fi +} + +if [[ "$REQUIRE_JQ" = "yes" ]]; then + require_command jq +fi +if [[ "$REQUIRE_MZ" = "yes" ]]; then + require_command $MZ +fi +if [[ "$REQUIRE_MTOOLS" = "yes" ]]; then + # https://github.com/vladimiroltean/mtools/ + # patched for IPv6 support + require_command msend + require_command mreceive +fi + +if [[ ! -v NUM_NETIFS ]]; then + echo "SKIP: importer does not define \"NUM_NETIFS\"" + exit $ksft_skip +fi + +############################################################################## +# Command line options handling + +count=0 + +while [[ $# -gt 0 ]]; do + if [[ "$count" -eq "0" ]]; then + unset NETIFS + declare -A NETIFS + fi + count=$((count + 1)) + NETIFS[p$count]="$1" + shift +done + +############################################################################## +# Network interfaces configuration + +create_netif_veth() +{ + local i + + for ((i = 1; i <= NUM_NETIFS; ++i)); do + local j=$((i+1)) + + ip link show dev ${NETIFS[p$i]} &> /dev/null + if [[ $? -ne 0 ]]; then + ip link add ${NETIFS[p$i]} type veth \ + peer name ${NETIFS[p$j]} + if [[ $? -ne 0 ]]; then + echo "Failed to create netif" + exit 1 + fi + fi + i=$j + done +} + +create_netif() +{ + case "$NETIF_TYPE" in + veth) create_netif_veth + ;; + *) echo "Can not create interfaces of type \'$NETIF_TYPE\'" + exit 1 + ;; + esac +} + +declare -A MAC_ADDR_ORIG +mac_addr_prepare() +{ + local new_addr= + local dev= + + for ((i = 1; i <= NUM_NETIFS; ++i)); do + dev=${NETIFS[p$i]} + new_addr=$(printf "00:01:02:03:04:%02x" $i) + + MAC_ADDR_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].address') + # Strip quotes + MAC_ADDR_ORIG["$dev"]=${MAC_ADDR_ORIG["$dev"]//\"/} + ip link set dev $dev address $new_addr + done +} + +mac_addr_restore() +{ + local dev= + + for ((i = 1; i <= NUM_NETIFS; ++i)); do + dev=${NETIFS[p$i]} + ip link set dev $dev address ${MAC_ADDR_ORIG["$dev"]} + done +} + +if [[ "$NETIF_CREATE" = "yes" ]]; then + create_netif +fi + +if [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then + mac_addr_prepare +fi + +for ((i = 1; i <= NUM_NETIFS; ++i)); do + ip link show dev ${NETIFS[p$i]} &> /dev/null + if [[ $? -ne 0 ]]; then + echo "SKIP: could not find all required interfaces" + exit $ksft_skip + fi +done + +############################################################################## +# Helpers + +# Exit status to return at the end. Set in case one of the tests fails. +EXIT_STATUS=0 +# Per-test return value. Clear at the beginning of each test. +RET=0 + +check_err() +{ + local err=$1 + local msg=$2 + + if [[ $RET -eq 0 && $err -ne 0 ]]; then + RET=$err + retmsg=$msg + fi +} + +check_fail() +{ + local err=$1 + local msg=$2 + + if [[ $RET -eq 0 && $err -eq 0 ]]; then + RET=1 + retmsg=$msg + fi +} + +check_err_fail() +{ + local should_fail=$1; shift + local err=$1; shift + local what=$1; shift + + if ((should_fail)); then + check_fail $err "$what succeeded, but should have failed" + else + check_err $err "$what failed" + fi +} + +log_test() +{ + local test_name=$1 + local opt_str=$2 + + if [[ $# -eq 2 ]]; then + opt_str="($opt_str)" + fi + + if [[ $RET -ne 0 ]]; then + EXIT_STATUS=1 + printf "TEST: %-60s [FAIL]\n" "$test_name $opt_str" + if [[ ! -z "$retmsg" ]]; then + printf "\t%s\n" "$retmsg" + fi + if [ "${PAUSE_ON_FAIL}" = "yes" ]; then + echo "Hit enter to continue, 'q' to quit" + read a + [ "$a" = "q" ] && exit 1 + fi + return 1 + fi + + printf "TEST: %-60s [ OK ]\n" "$test_name $opt_str" + return 0 +} + +log_test_skip() +{ + local test_name=$1 + local opt_str=$2 + + printf "TEST: %-60s [SKIP]\n" "$test_name $opt_str" + return 0 +} + +log_info() +{ + local msg=$1 + + echo "INFO: $msg" +} + +busywait() +{ + local timeout=$1; shift + + local start_time="$(date -u +%s%3N)" + while true + do + local out + out=$("$@") + local ret=$? + if ((!ret)); then + echo -n "$out" + return 0 + fi + + local current_time="$(date -u +%s%3N)" + if ((current_time - start_time > timeout)); then + echo -n "$out" + return 1 + fi + done +} + +not() +{ + "$@" + [[ $? != 0 ]] +} + +get_max() +{ + local arr=("$@") + + max=${arr[0]} + for cur in ${arr[@]}; do + if [[ $cur -gt $max ]]; then + max=$cur + fi + done + + echo $max +} + +grep_bridge_fdb() +{ + local addr=$1; shift + local word + local flag + + if [ "$1" == "self" ] || [ "$1" == "master" ]; then + word=$1; shift + if [ "$1" == "-v" ]; then + flag=$1; shift + fi + fi + + $@ | grep $addr | grep $flag "$word" +} + +wait_for_port_up() +{ + "$@" | grep -q "Link detected: yes" +} + +wait_for_offload() +{ + "$@" | grep -q offload +} + +wait_for_trap() +{ + "$@" | grep -q trap +} + +until_counter_is() +{ + local expr=$1; shift + local current=$("$@") + + echo $((current)) + ((current $expr)) +} + +busywait_for_counter() +{ + local timeout=$1; shift + local delta=$1; shift + + local base=$("$@") + busywait "$timeout" until_counter_is ">= $((base + delta))" "$@" +} + +setup_wait_dev() +{ + local dev=$1; shift + local wait_time=${1:-$WAIT_TIME}; shift + + setup_wait_dev_with_timeout "$dev" $INTERFACE_TIMEOUT $wait_time + + if (($?)); then + check_err 1 + log_test setup_wait_dev ": Interface $dev does not come up." + exit 1 + fi +} + +setup_wait_dev_with_timeout() +{ + local dev=$1; shift + local max_iterations=${1:-$WAIT_TIMEOUT}; shift + local wait_time=${1:-$WAIT_TIME}; shift + local i + + for ((i = 1; i <= $max_iterations; ++i)); do + ip link show dev $dev up \ + | grep 'state UP' &> /dev/null + if [[ $? -ne 0 ]]; then + sleep 1 + else + sleep $wait_time + return 0 + fi + done + + return 1 +} + +setup_wait() +{ + local num_netifs=${1:-$NUM_NETIFS} + local i + + for ((i = 1; i <= num_netifs; ++i)); do + setup_wait_dev ${NETIFS[p$i]} 0 + done + + # Make sure links are ready. + sleep $WAIT_TIME +} + +cmd_jq() +{ + local cmd=$1 + local jq_exp=$2 + local jq_opts=$3 + local ret + local output + + output="$($cmd)" + # it the command fails, return error right away + ret=$? + if [[ $ret -ne 0 ]]; then + return $ret + fi + output=$(echo $output | jq -r $jq_opts "$jq_exp") + ret=$? + if [[ $ret -ne 0 ]]; then + return $ret + fi + echo $output + # return success only in case of non-empty output + [ ! -z "$output" ] +} + +lldpad_app_wait_set() +{ + local dev=$1; shift + + while lldptool -t -i $dev -V APP -c app | grep -Eq "pending|unknown"; do + echo "$dev: waiting for lldpad to push pending APP updates" + sleep 5 + done +} + +lldpad_app_wait_del() +{ + # Give lldpad a chance to push down the changes. If the device is downed + # too soon, the updates will be left pending. However, they will have + # been struck off the lldpad's DB already, so we won't be able to tell + # they are pending. Then on next test iteration this would cause + # weirdness as newly-added APP rules conflict with the old ones, + # sometimes getting stuck in an "unknown" state. + sleep 5 +} + +pre_cleanup() +{ + if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then + echo "Pausing before cleanup, hit any key to continue" + read + fi + + if [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then + mac_addr_restore + fi +} + +vrf_prepare() +{ + ip -4 rule add pref 32765 table local + ip -4 rule del pref 0 + ip -6 rule add pref 32765 table local + ip -6 rule del pref 0 +} + +vrf_cleanup() +{ + ip -6 rule add pref 0 table local + ip -6 rule del pref 32765 + ip -4 rule add pref 0 table local + ip -4 rule del pref 32765 +} + +__last_tb_id=0 +declare -A __TB_IDS + +__vrf_td_id_assign() +{ + local vrf_name=$1 + + __last_tb_id=$((__last_tb_id + 1)) + __TB_IDS[$vrf_name]=$__last_tb_id + return $__last_tb_id +} + +__vrf_td_id_lookup() +{ + local vrf_name=$1 + + return ${__TB_IDS[$vrf_name]} +} + +vrf_create() +{ + local vrf_name=$1 + local tb_id + + __vrf_td_id_assign $vrf_name + tb_id=$? + + ip link add dev $vrf_name type vrf table $tb_id + ip -4 route add table $tb_id unreachable default metric 4278198272 + ip -6 route add table $tb_id unreachable default metric 4278198272 +} + +vrf_destroy() +{ + local vrf_name=$1 + local tb_id + + __vrf_td_id_lookup $vrf_name + tb_id=$? + + ip -6 route del table $tb_id unreachable default metric 4278198272 + ip -4 route del table $tb_id unreachable default metric 4278198272 + ip link del dev $vrf_name +} + +__addr_add_del() +{ + local if_name=$1 + local add_del=$2 + local array + + shift + shift + array=("${@}") + + for addrstr in "${array[@]}"; do + ip address $add_del $addrstr dev $if_name + done +} + +__simple_if_init() +{ + local if_name=$1; shift + local vrf_name=$1; shift + local addrs=("${@}") + + ip link set dev $if_name master $vrf_name + ip link set dev $if_name up + + __addr_add_del $if_name add "${addrs[@]}" +} + +__simple_if_fini() +{ + local if_name=$1; shift + local addrs=("${@}") + + __addr_add_del $if_name del "${addrs[@]}" + + ip link set dev $if_name down + ip link set dev $if_name nomaster +} + +simple_if_init() +{ + local if_name=$1 + local vrf_name + local array + + shift + vrf_name=v$if_name + array=("${@}") + + vrf_create $vrf_name + ip link set dev $vrf_name up + __simple_if_init $if_name $vrf_name "${array[@]}" +} + +simple_if_fini() +{ + local if_name=$1 + local vrf_name + local array + + shift + vrf_name=v$if_name + array=("${@}") + + __simple_if_fini $if_name "${array[@]}" + vrf_destroy $vrf_name +} + +tunnel_create() +{ + local name=$1; shift + local type=$1; shift + local local=$1; shift + local remote=$1; shift + + ip link add name $name type $type \ + local $local remote $remote "$@" + ip link set dev $name up +} + +tunnel_destroy() +{ + local name=$1; shift + + ip link del dev $name +} + +vlan_create() +{ + local if_name=$1; shift + local vid=$1; shift + local vrf=$1; shift + local ips=("${@}") + local name=$if_name.$vid + + ip link add name $name link $if_name type vlan id $vid + if [ "$vrf" != "" ]; then + ip link set dev $name master $vrf + fi + ip link set dev $name up + __addr_add_del $name add "${ips[@]}" +} + +vlan_destroy() +{ + local if_name=$1; shift + local vid=$1; shift + local name=$if_name.$vid + + ip link del dev $name +} + +team_create() +{ + local if_name=$1; shift + local mode=$1; shift + + require_command $TEAMD + $TEAMD -t $if_name -d -c '{"runner": {"name": "'$mode'"}}' + for slave in "$@"; do + ip link set dev $slave down + ip link set dev $slave master $if_name + ip link set dev $slave up + done + ip link set dev $if_name up +} + +team_destroy() +{ + local if_name=$1; shift + + $TEAMD -t $if_name -k +} + +master_name_get() +{ + local if_name=$1 + + ip -j link show dev $if_name | jq -r '.[]["master"]' +} + +link_stats_get() +{ + local if_name=$1; shift + local dir=$1; shift + local stat=$1; shift + + ip -j -s link show dev $if_name \ + | jq '.[]["stats64"]["'$dir'"]["'$stat'"]' +} + +link_stats_tx_packets_get() +{ + link_stats_get $1 tx packets +} + +link_stats_rx_errors_get() +{ + link_stats_get $1 rx errors +} + +tc_rule_stats_get() +{ + local dev=$1; shift + local pref=$1; shift + local dir=$1; shift + local selector=${1:-.packets}; shift + + tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \ + | jq ".[1].options.actions[].stats$selector" +} + +tc_rule_handle_stats_get() +{ + local id=$1; shift + local handle=$1; shift + local selector=${1:-.packets}; shift + + tc -j -s filter show $id \ + | jq ".[] | select(.options.handle == $handle) | \ + .options.actions[0].stats$selector" +} + +ethtool_stats_get() +{ + local dev=$1; shift + local stat=$1; shift + + ethtool -S $dev | grep "^ *$stat:" | head -n 1 | cut -d: -f2 +} + +qdisc_stats_get() +{ + local dev=$1; shift + local handle=$1; shift + local selector=$1; shift + + tc -j -s qdisc show dev "$dev" \ + | jq '.[] | select(.handle == "'"$handle"'") | '"$selector" +} + +qdisc_parent_stats_get() +{ + local dev=$1; shift + local parent=$1; shift + local selector=$1; shift + + tc -j -s qdisc show dev "$dev" invisible \ + | jq '.[] | select(.parent == "'"$parent"'") | '"$selector" +} + +ipv6_stats_get() +{ + local dev=$1; shift + local stat=$1; shift + + cat /proc/net/dev_snmp6/$dev | grep "^$stat" | cut -f2 +} + +hw_stats_get() +{ + local suite=$1; shift + local if_name=$1; shift + local dir=$1; shift + local stat=$1; shift + + ip -j stats show dev $if_name group offload subgroup $suite | + jq ".[0].stats64.$dir.$stat" +} + +humanize() +{ + local speed=$1; shift + + for unit in bps Kbps Mbps Gbps; do + if (($(echo "$speed < 1024" | bc))); then + break + fi + + speed=$(echo "scale=1; $speed / 1024" | bc) + done + + echo "$speed${unit}" +} + +rate() +{ + local t0=$1; shift + local t1=$1; shift + local interval=$1; shift + + echo $((8 * (t1 - t0) / interval)) +} + +packets_rate() +{ + local t0=$1; shift + local t1=$1; shift + local interval=$1; shift + + echo $(((t1 - t0) / interval)) +} + +mac_get() +{ + local if_name=$1 + + ip -j link show dev $if_name | jq -r '.[]["address"]' +} + +ipv6_lladdr_get() +{ + local if_name=$1 + + ip -j addr show dev $if_name | \ + jq -r '.[]["addr_info"][] | select(.scope == "link").local' | \ + head -1 +} + +bridge_ageing_time_get() +{ + local bridge=$1 + local ageing_time + + # Need to divide by 100 to convert to seconds. + ageing_time=$(ip -j -d link show dev $bridge \ + | jq '.[]["linkinfo"]["info_data"]["ageing_time"]') + echo $((ageing_time / 100)) +} + +declare -A SYSCTL_ORIG +sysctl_set() +{ + local key=$1; shift + local value=$1; shift + + SYSCTL_ORIG[$key]=$(sysctl -n $key) + sysctl -qw $key=$value +} + +sysctl_restore() +{ + local key=$1; shift + + sysctl -qw $key=${SYSCTL_ORIG["$key"]} +} + +forwarding_enable() +{ + sysctl_set net.ipv4.conf.all.forwarding 1 + sysctl_set net.ipv6.conf.all.forwarding 1 +} + +forwarding_restore() +{ + sysctl_restore net.ipv6.conf.all.forwarding + sysctl_restore net.ipv4.conf.all.forwarding +} + +declare -A MTU_ORIG +mtu_set() +{ + local dev=$1; shift + local mtu=$1; shift + + MTU_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].mtu') + ip link set dev $dev mtu $mtu +} + +mtu_restore() +{ + local dev=$1; shift + + ip link set dev $dev mtu ${MTU_ORIG["$dev"]} +} + +tc_offload_check() +{ + local num_netifs=${1:-$NUM_NETIFS} + + for ((i = 1; i <= num_netifs; ++i)); do + ethtool -k ${NETIFS[p$i]} \ + | grep "hw-tc-offload: on" &> /dev/null + if [[ $? -ne 0 ]]; then + return 1 + fi + done + + return 0 +} + +trap_install() +{ + local dev=$1; shift + local direction=$1; shift + + # Some devices may not support or need in-hardware trapping of traffic + # (e.g. the veth pairs that this library creates for non-existent + # loopbacks). Use continue instead, so that there is a filter in there + # (some tests check counters), and so that other filters are still + # processed. + tc filter add dev $dev $direction pref 1 \ + flower skip_sw action trap 2>/dev/null \ + || tc filter add dev $dev $direction pref 1 \ + flower action continue +} + +trap_uninstall() +{ + local dev=$1; shift + local direction=$1; shift + + tc filter del dev $dev $direction pref 1 flower +} + +slow_path_trap_install() +{ + # For slow-path testing, we need to install a trap to get to + # slow path the packets that would otherwise be switched in HW. + if [ "${tcflags/skip_hw}" != "$tcflags" ]; then + trap_install "$@" + fi +} + +slow_path_trap_uninstall() +{ + if [ "${tcflags/skip_hw}" != "$tcflags" ]; then + trap_uninstall "$@" + fi +} + +__icmp_capture_add_del() +{ + local add_del=$1; shift + local pref=$1; shift + local vsuf=$1; shift + local tundev=$1; shift + local filter=$1; shift + + tc filter $add_del dev "$tundev" ingress \ + proto ip$vsuf pref $pref \ + flower ip_proto icmp$vsuf $filter \ + action pass +} + +icmp_capture_install() +{ + __icmp_capture_add_del add 100 "" "$@" +} + +icmp_capture_uninstall() +{ + __icmp_capture_add_del del 100 "" "$@" +} + +icmp6_capture_install() +{ + __icmp_capture_add_del add 100 v6 "$@" +} + +icmp6_capture_uninstall() +{ + __icmp_capture_add_del del 100 v6 "$@" +} + +__vlan_capture_add_del() +{ + local add_del=$1; shift + local pref=$1; shift + local dev=$1; shift + local filter=$1; shift + + tc filter $add_del dev "$dev" ingress \ + proto 802.1q pref $pref \ + flower $filter \ + action pass +} + +vlan_capture_install() +{ + __vlan_capture_add_del add 100 "$@" +} + +vlan_capture_uninstall() +{ + __vlan_capture_add_del del 100 "$@" +} + +__dscp_capture_add_del() +{ + local add_del=$1; shift + local dev=$1; shift + local base=$1; shift + local dscp; + + for prio in {0..7}; do + dscp=$((base + prio)) + __icmp_capture_add_del $add_del $((dscp + 100)) "" $dev \ + "skip_hw ip_tos $((dscp << 2))" + done +} + +dscp_capture_install() +{ + local dev=$1; shift + local base=$1; shift + + __dscp_capture_add_del add $dev $base +} + +dscp_capture_uninstall() +{ + local dev=$1; shift + local base=$1; shift + + __dscp_capture_add_del del $dev $base +} + +dscp_fetch_stats() +{ + local dev=$1; shift + local base=$1; shift + + for prio in {0..7}; do + local dscp=$((base + prio)) + local t=$(tc_rule_stats_get $dev $((dscp + 100))) + echo "[$dscp]=$t " + done +} + +matchall_sink_create() +{ + local dev=$1; shift + + tc qdisc add dev $dev clsact + tc filter add dev $dev ingress \ + pref 10000 \ + matchall \ + action drop +} + +tests_run() +{ + local current_test + + for current_test in ${TESTS:-$ALL_TESTS}; do + $current_test + done +} + +multipath_eval() +{ + local desc="$1" + local weight_rp12=$2 + local weight_rp13=$3 + local packets_rp12=$4 + local packets_rp13=$5 + local weights_ratio packets_ratio diff + + RET=0 + + if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then + weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \ + | bc -l) + else + weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" \ + | bc -l) + fi + + if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then + check_err 1 "Packet difference is 0" + log_test "Multipath" + log_info "Expected ratio $weights_ratio" + return + fi + + if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then + packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \ + | bc -l) + else + packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" \ + | bc -l) + fi + + diff=$(echo $weights_ratio - $packets_ratio | bc -l) + diff=${diff#-} + + test "$(echo "$diff / $weights_ratio > 0.15" | bc -l)" -eq 0 + check_err $? "Too large discrepancy between expected and measured ratios" + log_test "$desc" + log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio" +} + +in_ns() +{ + local name=$1; shift + + ip netns exec $name bash <<-EOF + NUM_NETIFS=0 + source lib.sh + $(for a in "$@"; do printf "%q${IFS:0:1}" "$a"; done) + EOF +} + +############################################################################## +# Tests + +ping_do() +{ + local if_name=$1 + local dip=$2 + local args=$3 + local vrf_name + + vrf_name=$(master_name_get $if_name) + ip vrf exec $vrf_name \ + $PING $args $dip -c $PING_COUNT -i 0.1 \ + -w $PING_TIMEOUT &> /dev/null +} + +ping_test() +{ + RET=0 + + ping_do $1 $2 + check_err $? + log_test "ping$3" +} + +ping6_do() +{ + local if_name=$1 + local dip=$2 + local args=$3 + local vrf_name + + vrf_name=$(master_name_get $if_name) + ip vrf exec $vrf_name \ + $PING6 $args $dip -c $PING_COUNT -i 0.1 \ + -w $PING_TIMEOUT &> /dev/null +} + +ping6_test() +{ + RET=0 + + ping6_do $1 $2 + check_err $? + log_test "ping6$3" +} + +learning_test() +{ + local bridge=$1 + local br_port1=$2 # Connected to `host1_if`. + local host1_if=$3 + local host2_if=$4 + local mac=de:ad:be:ef:13:37 + local ageing_time + + RET=0 + + bridge -j fdb show br $bridge brport $br_port1 \ + | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null + check_fail $? "Found FDB record when should not" + + # Disable unknown unicast flooding on `br_port1` to make sure + # packets are only forwarded through the port after a matching + # FDB entry was installed. + bridge link set dev $br_port1 flood off + + ip link set $host1_if promisc on + tc qdisc add dev $host1_if ingress + tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \ + flower dst_mac $mac action drop + + $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q + sleep 1 + + tc -j -s filter show dev $host1_if ingress \ + | jq -e ".[] | select(.options.handle == 101) \ + | select(.options.actions[0].stats.packets == 1)" &> /dev/null + check_fail $? "Packet reached first host when should not" + + $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q + sleep 1 + + bridge -j fdb show br $bridge brport $br_port1 \ + | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null + check_err $? "Did not find FDB record when should" + + $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q + sleep 1 + + tc -j -s filter show dev $host1_if ingress \ + | jq -e ".[] | select(.options.handle == 101) \ + | select(.options.actions[0].stats.packets == 1)" &> /dev/null + check_err $? "Packet did not reach second host when should" + + # Wait for 10 seconds after the ageing time to make sure FDB + # record was aged-out. + ageing_time=$(bridge_ageing_time_get $bridge) + sleep $((ageing_time + 10)) + + bridge -j fdb show br $bridge brport $br_port1 \ + | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null + check_fail $? "Found FDB record when should not" + + bridge link set dev $br_port1 learning off + + $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q + sleep 1 + + bridge -j fdb show br $bridge brport $br_port1 \ + | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null + check_fail $? "Found FDB record when should not" + + bridge link set dev $br_port1 learning on + + tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower + tc qdisc del dev $host1_if ingress + ip link set $host1_if promisc off + + bridge link set dev $br_port1 flood on + + log_test "FDB learning" +} + +flood_test_do() +{ + local should_flood=$1 + local mac=$2 + local ip=$3 + local host1_if=$4 + local host2_if=$5 + local err=0 + + # Add an ACL on `host2_if` which will tell us whether the packet + # was flooded to it or not. + ip link set $host2_if promisc on + tc qdisc add dev $host2_if ingress + tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \ + flower dst_mac $mac action drop + + $MZ $host1_if -c 1 -p 64 -b $mac -B $ip -t ip -q + sleep 1 + + tc -j -s filter show dev $host2_if ingress \ + | jq -e ".[] | select(.options.handle == 101) \ + | select(.options.actions[0].stats.packets == 1)" &> /dev/null + if [[ $? -ne 0 && $should_flood == "true" || \ + $? -eq 0 && $should_flood == "false" ]]; then + err=1 + fi + + tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower + tc qdisc del dev $host2_if ingress + ip link set $host2_if promisc off + + return $err +} + +flood_unicast_test() +{ + local br_port=$1 + local host1_if=$2 + local host2_if=$3 + local mac=de:ad:be:ef:13:37 + local ip=192.0.2.100 + + RET=0 + + bridge link set dev $br_port flood off + + flood_test_do false $mac $ip $host1_if $host2_if + check_err $? "Packet flooded when should not" + + bridge link set dev $br_port flood on + + flood_test_do true $mac $ip $host1_if $host2_if + check_err $? "Packet was not flooded when should" + + log_test "Unknown unicast flood" +} + +flood_multicast_test() +{ + local br_port=$1 + local host1_if=$2 + local host2_if=$3 + local mac=01:00:5e:00:00:01 + local ip=239.0.0.1 + + RET=0 + + bridge link set dev $br_port mcast_flood off + + flood_test_do false $mac $ip $host1_if $host2_if + check_err $? "Packet flooded when should not" + + bridge link set dev $br_port mcast_flood on + + flood_test_do true $mac $ip $host1_if $host2_if + check_err $? "Packet was not flooded when should" + + log_test "Unregistered multicast flood" +} + +flood_test() +{ + # `br_port` is connected to `host2_if` + local br_port=$1 + local host1_if=$2 + local host2_if=$3 + + flood_unicast_test $br_port $host1_if $host2_if + flood_multicast_test $br_port $host1_if $host2_if +} + +__start_traffic() +{ + local pktsize=$1; shift + local proto=$1; shift + local h_in=$1; shift # Where the traffic egresses the host + local sip=$1; shift + local dip=$1; shift + local dmac=$1; shift + + $MZ $h_in -p $pktsize -A $sip -B $dip -c 0 \ + -a own -b $dmac -t "$proto" -q "$@" & + sleep 1 +} + +start_traffic_pktsize() +{ + local pktsize=$1; shift + + __start_traffic $pktsize udp "$@" +} + +start_tcp_traffic_pktsize() +{ + local pktsize=$1; shift + + __start_traffic $pktsize tcp "$@" +} + +start_traffic() +{ + start_traffic_pktsize 8000 "$@" +} + +start_tcp_traffic() +{ + start_tcp_traffic_pktsize 8000 "$@" +} + +stop_traffic() +{ + # Suppress noise from killing mausezahn. + { kill %% && wait %%; } 2>/dev/null +} + +declare -A cappid +declare -A capfile +declare -A capout + +tcpdump_start() +{ + local if_name=$1; shift + local ns=$1; shift + + capfile[$if_name]=$(mktemp) + capout[$if_name]=$(mktemp) + + if [ -z $ns ]; then + ns_cmd="" + else + ns_cmd="ip netns exec ${ns}" + fi + + if [ -z $SUDO_USER ] ; then + capuser="" + else + capuser="-Z $SUDO_USER" + fi + + $ns_cmd tcpdump $TCPDUMP_EXTRA_FLAGS -e -n -Q in -i $if_name \ + -s 65535 -B 32768 $capuser -w ${capfile[$if_name]} \ + > "${capout[$if_name]}" 2>&1 & + cappid[$if_name]=$! + + sleep 1 +} + +tcpdump_stop() +{ + local if_name=$1 + local pid=${cappid[$if_name]} + + $ns_cmd kill "$pid" && wait "$pid" + sleep 1 +} + +tcpdump_cleanup() +{ + local if_name=$1 + + rm ${capfile[$if_name]} ${capout[$if_name]} +} + +tcpdump_show() +{ + local if_name=$1 + + tcpdump -e -n -r ${capfile[$if_name]} 2>&1 +} + +# return 0 if the packet wasn't seen on host2_if or 1 if it was +mcast_packet_test() +{ + local mac=$1 + local src_ip=$2 + local ip=$3 + local host1_if=$4 + local host2_if=$5 + local seen=0 + local tc_proto="ip" + local mz_v6arg="" + + # basic check to see if we were passed an IPv4 address, if not assume IPv6 + if [[ ! $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + tc_proto="ipv6" + mz_v6arg="-6" + fi + + # Add an ACL on `host2_if` which will tell us whether the packet + # was received by it or not. + tc qdisc add dev $host2_if ingress + tc filter add dev $host2_if ingress protocol $tc_proto pref 1 handle 101 \ + flower ip_proto udp dst_mac $mac action drop + + $MZ $host1_if $mz_v6arg -c 1 -p 64 -b $mac -A $src_ip -B $ip -t udp "dp=4096,sp=2048" -q + sleep 1 + + tc -j -s filter show dev $host2_if ingress \ + | jq -e ".[] | select(.options.handle == 101) \ + | select(.options.actions[0].stats.packets == 1)" &> /dev/null + if [[ $? -eq 0 ]]; then + seen=1 + fi + + tc filter del dev $host2_if ingress protocol $tc_proto pref 1 handle 101 flower + tc qdisc del dev $host2_if ingress + + return $seen +} + +brmcast_check_sg_entries() +{ + local report=$1; shift + local slist=("$@") + local sarg="" + + for src in "${slist[@]}"; do + sarg="${sarg} and .source_list[].address == \"$src\"" + done + bridge -j -d -s mdb show dev br0 \ + | jq -e ".[].mdb[] | \ + select(.grp == \"$TEST_GROUP\" and .source_list != null $sarg)" &>/dev/null + check_err $? "Wrong *,G entry source list after $report report" + + for sgent in "${slist[@]}"; do + bridge -j -d -s mdb show dev br0 \ + | jq -e ".[].mdb[] | \ + select(.grp == \"$TEST_GROUP\" and .src == \"$sgent\")" &>/dev/null + check_err $? "Missing S,G entry ($sgent, $TEST_GROUP)" + done +} + +brmcast_check_sg_fwding() +{ + local should_fwd=$1; shift + local sources=("$@") + + for src in "${sources[@]}"; do + local retval=0 + + mcast_packet_test $TEST_GROUP_MAC $src $TEST_GROUP $h2 $h1 + retval=$? + if [ $should_fwd -eq 1 ]; then + check_fail $retval "Didn't forward traffic from S,G ($src, $TEST_GROUP)" + else + check_err $retval "Forwarded traffic for blocked S,G ($src, $TEST_GROUP)" + fi + done +} + +brmcast_check_sg_state() +{ + local is_blocked=$1; shift + local sources=("$@") + local should_fail=1 + + if [ $is_blocked -eq 1 ]; then + should_fail=0 + fi + + for src in "${sources[@]}"; do + bridge -j -d -s mdb show dev br0 \ + | jq -e ".[].mdb[] | \ + select(.grp == \"$TEST_GROUP\" and .source_list != null) | + .source_list[] | + select(.address == \"$src\") | + select(.timer == \"0.00\")" &>/dev/null + check_err_fail $should_fail $? "Entry $src has zero timer" + + bridge -j -d -s mdb show dev br0 \ + | jq -e ".[].mdb[] | \ + select(.grp == \"$TEST_GROUP\" and .src == \"$src\" and \ + .flags[] == \"blocked\")" &>/dev/null + check_err_fail $should_fail $? "Entry $src has blocked flag" + done +} + +mc_join() +{ + local if_name=$1 + local group=$2 + local vrf_name=$(master_name_get $if_name) + + # We don't care about actual reception, just about joining the + # IP multicast group and adding the L2 address to the device's + # MAC filtering table + ip vrf exec $vrf_name \ + mreceive -g $group -I $if_name > /dev/null 2>&1 & + mreceive_pid=$! + + sleep 1 +} + +mc_leave() +{ + kill "$mreceive_pid" && wait "$mreceive_pid" +} + +mc_send() +{ + local if_name=$1 + local groups=$2 + local vrf_name=$(master_name_get $if_name) + + ip vrf exec $vrf_name \ + msend -g $groups -I $if_name -c 1 > /dev/null 2>&1 +} + +start_ip_monitor() +{ + local mtype=$1; shift + local ip=${1-ip}; shift + + # start the monitor in the background + tmpfile=`mktemp /var/run/nexthoptestXXX` + mpid=`($ip monitor $mtype > $tmpfile & echo $!) 2>/dev/null` + sleep 0.2 + echo "$mpid $tmpfile" +} + +stop_ip_monitor() +{ + local mpid=$1; shift + local tmpfile=$1; shift + local el=$1; shift + local what=$1; shift + + sleep 0.2 + kill $mpid + local lines=`grep '^\w' $tmpfile | wc -l` + test $lines -eq $el + check_err $? "$what: $lines lines of events, expected $el" + rm -rf $tmpfile +} + +hw_stats_monitor_test() +{ + local dev=$1; shift + local type=$1; shift + local make_suitable=$1; shift + local make_unsuitable=$1; shift + local ip=${1-ip}; shift + + RET=0 + + # Expect a notification about enablement. + local ipmout=$(start_ip_monitor stats "$ip") + $ip stats set dev $dev ${type}_stats on + stop_ip_monitor $ipmout 1 "${type}_stats enablement" + + # Expect a notification about offload. + local ipmout=$(start_ip_monitor stats "$ip") + $make_suitable + stop_ip_monitor $ipmout 1 "${type}_stats installation" + + # Expect a notification about loss of offload. + local ipmout=$(start_ip_monitor stats "$ip") + $make_unsuitable + stop_ip_monitor $ipmout 1 "${type}_stats deinstallation" + + # Expect a notification about disablement + local ipmout=$(start_ip_monitor stats "$ip") + $ip stats set dev $dev ${type}_stats off + stop_ip_monitor $ipmout 1 "${type}_stats disablement" + + log_test "${type}_stats notifications" +} diff -Nru linux-6.0.6/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc linux-6.0.12/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc --- linux-6.0.6/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc 2023-01-18 18:27:39.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 # description: Generic dynamic event - check if duplicate events are caught -# requires: dynamic_events "e[:[/]] . []":README +# requires: dynamic_events "e[:[/][]] . []":README echo 0 > events/enable diff -Nru linux-6.0.6/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc linux-6.0.12/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc --- linux-6.0.6/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc 2023-01-18 18:27:39.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 # description: event trigger - test inter-event histogram trigger eprobe on synthetic event -# requires: dynamic_events synthetic_events events/syscalls/sys_enter_openat/hist "e[:[/]] . []":README +# requires: dynamic_events synthetic_events events/syscalls/sys_enter_openat/hist "e[:[/][]] . []":README echo 0 > events/enable diff -Nru linux-6.0.6/tools/testing/selftests/futex/functional/Makefile linux-6.0.12/tools/testing/selftests/futex/functional/Makefile --- linux-6.0.6/tools/testing/selftests/futex/functional/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/futex/functional/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -3,11 +3,11 @@ CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES) $(KHDR_INCLUDES) LDLIBS := -lpthread -lrt -HEADERS := \ +LOCAL_HDRS := \ ../include/futextest.h \ ../include/atomic.h \ ../include/logging.h -TEST_GEN_FILES := \ +TEST_GEN_PROGS := \ futex_wait_timeout \ futex_wait_wouldblock \ futex_requeue_pi \ @@ -24,5 +24,3 @@ top_srcdir = ../../../../.. DEFAULT_INSTALL_HDR_PATH := 1 include ../../lib.mk - -$(TEST_GEN_FILES): $(HEADERS) diff -Nru linux-6.0.6/tools/testing/selftests/intel_pstate/Makefile linux-6.0.12/tools/testing/selftests/intel_pstate/Makefile --- linux-6.0.6/tools/testing/selftests/intel_pstate/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/intel_pstate/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -2,10 +2,10 @@ CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE LDLIBS += -lm -uname_M := $(shell uname -m 2>/dev/null || echo not) -ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) +ARCH ?= $(shell uname -m 2>/dev/null || echo not) +ARCH_PROCESSED := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/) -ifeq (x86,$(ARCH)) +ifeq (x86,$(ARCH_PROCESSED)) TEST_GEN_FILES := msr aperf endif diff -Nru linux-6.0.6/tools/testing/selftests/kexec/Makefile linux-6.0.12/tools/testing/selftests/kexec/Makefile --- linux-6.0.6/tools/testing/selftests/kexec/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/kexec/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -1,10 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only # Makefile for kexec tests -uname_M := $(shell uname -m 2>/dev/null || echo not) -ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) +ARCH ?= $(shell uname -m 2>/dev/null || echo not) +ARCH_PROCESSED := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/) -ifeq ($(ARCH),$(filter $(ARCH),x86 ppc64le)) +ifeq ($(ARCH_PROCESSED),$(filter $(ARCH_PROCESSED),x86 ppc64le)) TEST_PROGS := test_kexec_load.sh test_kexec_file_load.sh TEST_FILES := kexec_common_lib.sh diff -Nru linux-6.0.6/tools/testing/selftests/kvm/memslot_modification_stress_test.c linux-6.0.12/tools/testing/selftests/kvm/memslot_modification_stress_test.c --- linux-6.0.6/tools/testing/selftests/kvm/memslot_modification_stress_test.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/kvm/memslot_modification_stress_test.c 2023-01-18 18:27:39.000000000 +0000 @@ -67,7 +67,7 @@ static void add_remove_memslot(struct kvm_vm *vm, useconds_t delay, uint64_t nr_modifications) { - const uint64_t pages = 1; + uint64_t pages = max_t(int, vm->page_size, getpagesize()) / vm->page_size; uint64_t gpa; int i; diff -Nru linux-6.0.6/tools/testing/selftests/landlock/Makefile linux-6.0.12/tools/testing/selftests/landlock/Makefile --- linux-6.0.6/tools/testing/selftests/landlock/Makefile 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/landlock/Makefile 2023-01-18 18:27:39.000000000 +0000 @@ -3,7 +3,6 @@ # First run: make -C ../../../.. headers_install CFLAGS += -Wall -O2 $(KHDR_INCLUDES) -LDLIBS += -lcap LOCAL_HDRS += common.h @@ -13,10 +12,12 @@ TEST_GEN_PROGS_EXTENDED := true -# Static linking for short targets: +# Short targets: +$(TEST_GEN_PROGS): LDLIBS += -lcap $(TEST_GEN_PROGS_EXTENDED): LDFLAGS += -static include ../lib.mk -# Static linking for targets with $(OUTPUT)/ prefix: +# Targets with $(OUTPUT)/ prefix: +$(TEST_GEN_PROGS): LDLIBS += -lcap $(TEST_GEN_PROGS_EXTENDED): LDFLAGS += -static diff -Nru linux-6.0.6/tools/testing/selftests/lib.mk linux-6.0.12/tools/testing/selftests/lib.mk --- linux-6.0.6/tools/testing/selftests/lib.mk 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/lib.mk 2023-01-18 18:27:39.000000000 +0000 @@ -70,7 +70,7 @@ run_tests: all ifdef building_out_of_srctree @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ - rsync -aq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ + rsync -aLq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ fi @if [ "X$(TEST_PROGS)" != "X" ]; then \ $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \ @@ -84,7 +84,7 @@ define INSTALL_SINGLE_RULE $(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH)) - $(if $(INSTALL_LIST),rsync -a $(INSTALL_LIST) $(INSTALL_PATH)/) + $(if $(INSTALL_LIST),rsync -aL $(INSTALL_LIST) $(INSTALL_PATH)/) endef define INSTALL_RULE diff -Nru linux-6.0.6/tools/testing/selftests/net/fib_nexthops.sh linux-6.0.12/tools/testing/selftests/net/fib_nexthops.sh --- linux-6.0.6/tools/testing/selftests/net/fib_nexthops.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/net/fib_nexthops.sh 2023-01-18 18:27:39.000000000 +0000 @@ -1223,6 +1223,22 @@ log_test $rc 0 "Delete nexthop route warning" run_cmd "$IP route delete 172.16.101.1/32 nhid 12" run_cmd "$IP nexthop del id 12" + + run_cmd "$IP nexthop add id 21 via 172.16.1.6 dev veth1" + run_cmd "$IP ro add 172.16.101.0/24 nhid 21" + run_cmd "$IP ro del 172.16.101.0/24 nexthop via 172.16.1.7 dev veth1 nexthop via 172.16.1.8 dev veth1" + log_test $? 2 "Delete multipath route with only nh id based entry" + + run_cmd "$IP nexthop add id 22 via 172.16.1.6 dev veth1" + run_cmd "$IP ro add 172.16.102.0/24 nhid 22" + run_cmd "$IP ro del 172.16.102.0/24 dev veth1" + log_test $? 2 "Delete route when specifying only nexthop device" + + run_cmd "$IP ro del 172.16.102.0/24 via 172.16.1.6" + log_test $? 2 "Delete route when specifying only gateway" + + run_cmd "$IP ro del 172.16.102.0/24" + log_test $? 0 "Delete route when not specifying nexthop attributes" } ipv4_grp_fcnal() diff -Nru linux-6.0.6/tools/testing/selftests/net/io_uring_zerocopy_tx.sh linux-6.0.12/tools/testing/selftests/net/io_uring_zerocopy_tx.sh --- linux-6.0.6/tools/testing/selftests/net/io_uring_zerocopy_tx.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/net/io_uring_zerocopy_tx.sh 2023-01-18 18:27:39.000000000 +0000 @@ -29,7 +29,7 @@ for IP in "${IPs[@]}"; do for mode in $(seq 1 3); do $0 "$IP" udp -m "$mode" -t 1 -n 32 - $0 "$IP" tcp -m "$mode" -t 1 -n 32 + $0 "$IP" tcp -m "$mode" -t 1 -n 1 done done diff -Nru linux-6.0.6/tools/testing/selftests/net/mptcp/mptcp_join.sh linux-6.0.12/tools/testing/selftests/net/mptcp/mptcp_join.sh --- linux-6.0.6/tools/testing/selftests/net/mptcp/mptcp_join.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/net/mptcp/mptcp_join.sh 2023-01-18 18:27:39.000000000 +0000 @@ -2105,7 +2105,7 @@ pm_nl_set_limits $ns2 1 3 pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow - run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 slow + run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 speed_10 chk_join_nr 3 3 3 chk_add_nr 1 1 chk_rm_nr 2 2 @@ -2118,7 +2118,7 @@ pm_nl_add_endpoint $ns1 10.0.3.1 flags signal pm_nl_add_endpoint $ns1 10.0.4.1 flags signal pm_nl_set_limits $ns2 3 3 - run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow + run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10 chk_join_nr 3 3 3 chk_add_nr 3 3 chk_rm_nr 3 3 invert @@ -2131,7 +2131,7 @@ pm_nl_add_endpoint $ns1 10.0.3.1 flags signal pm_nl_add_endpoint $ns1 10.0.14.1 flags signal pm_nl_set_limits $ns2 3 3 - run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow + run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10 chk_join_nr 1 1 1 chk_add_nr 3 3 chk_rm_nr 3 1 invert diff -Nru linux-6.0.6/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh linux-6.0.12/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh --- linux-6.0.6/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh 2023-01-18 18:27:39.000000000 +0000 @@ -35,8 +35,9 @@ ns1="ns1-$rndh" ns2="ns2-$rndh" + ns_sbox="ns_sbox-$rndh" - for netns in "$ns1" "$ns2";do + for netns in "$ns1" "$ns2" "$ns_sbox";do ip netns add $netns || exit $ksft_skip ip -net $netns link set lo up ip netns exec $netns sysctl -q net.mptcp.enabled=1 @@ -73,7 +74,7 @@ cleanup() { - for netns in "$ns1" "$ns2"; do + for netns in "$ns1" "$ns2" "$ns_sbox"; do ip netns del $netns done rm -f "$cin" "$cout" @@ -243,7 +244,7 @@ { local lret=0 - ./mptcp_sockopt + ip netns exec "$ns_sbox" ./mptcp_sockopt lret=$? if [ $lret -ne 0 ]; then @@ -252,7 +253,7 @@ return fi - ./mptcp_sockopt -6 + ip netns exec "$ns_sbox" ./mptcp_sockopt -6 lret=$? if [ $lret -ne 0 ]; then diff -Nru linux-6.0.6/tools/testing/selftests/net/mptcp/simult_flows.sh linux-6.0.12/tools/testing/selftests/net/mptcp/simult_flows.sh --- linux-6.0.6/tools/testing/selftests/net/mptcp/simult_flows.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/net/mptcp/simult_flows.sh 2023-01-18 18:27:39.000000000 +0000 @@ -247,9 +247,10 @@ tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1 tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2 - # time is measured in ms, account for transfer size, affegated link speed + # time is measured in ms, account for transfer size, aggregated link speed # and header overhead (10%) - local time=$((size * 8 * 1000 * 10 / (( $rate1 + $rate2) * 1024 *1024 * 9) )) + # ms byte -> bit 10% mbit -> kbit -> bit 10% + local time=$((1000 * size * 8 * 10 / ((rate1 + rate2) * 1000 * 1000 * 9) )) # mptcp_connect will do some sleeps to allow the mp_join handshake # completion (see mptcp_connect): 200ms on each side, add some slack diff -Nru linux-6.0.6/tools/testing/selftests/net/udpgro_bench.sh linux-6.0.12/tools/testing/selftests/net/udpgro_bench.sh --- linux-6.0.6/tools/testing/selftests/net/udpgro_bench.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/net/udpgro_bench.sh 2023-01-18 18:27:39.000000000 +0000 @@ -39,7 +39,7 @@ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -t ${rx_args} -r & # Hack: let bg programs complete the startup - sleep 0.1 + sleep 0.2 ./udpgso_bench_tx ${tx_args} } diff -Nru linux-6.0.6/tools/testing/selftests/net/udpgro_frglist.sh linux-6.0.12/tools/testing/selftests/net/udpgro_frglist.sh --- linux-6.0.6/tools/testing/selftests/net/udpgro_frglist.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/net/udpgro_frglist.sh 2023-01-18 18:27:39.000000000 +0000 @@ -44,7 +44,7 @@ ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r & # Hack: let bg programs complete the startup - sleep 0.1 + sleep 0.2 ./udpgso_bench_tx ${tx_args} } diff -Nru linux-6.0.6/tools/testing/selftests/net/udpgro.sh linux-6.0.12/tools/testing/selftests/net/udpgro.sh --- linux-6.0.6/tools/testing/selftests/net/udpgro.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/net/udpgro.sh 2023-01-18 18:27:39.000000000 +0000 @@ -50,7 +50,7 @@ echo "failed" & # Hack: let bg programs complete the startup - sleep 0.1 + sleep 0.2 ./udpgso_bench_tx ${tx_args} ret=$? wait $(jobs -p) @@ -117,7 +117,7 @@ echo "failed" & # Hack: let bg programs complete the startup - sleep 0.1 + sleep 0.2 ./udpgso_bench_tx ${tx_args} -p 12345 sleep 0.1 # first UDP GSO socket should be closed at this point diff -Nru linux-6.0.6/tools/testing/selftests/pidfd/pidfd_wait.c linux-6.0.12/tools/testing/selftests/pidfd/pidfd_wait.c --- linux-6.0.6/tools/testing/selftests/pidfd/pidfd_wait.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/testing/selftests/pidfd/pidfd_wait.c 2023-01-18 18:27:39.000000000 +0000 @@ -95,20 +95,28 @@ .flags = CLONE_PIDFD | CLONE_PARENT_SETTID, .exit_signal = SIGCHLD, }; + int pfd[2]; pid_t pid; siginfo_t info = { .si_signo = 0, }; + ASSERT_EQ(pipe(pfd), 0); pid = sys_clone3(&args); ASSERT_GE(pid, 0); if (pid == 0) { + char buf[2]; + + close(pfd[1]); kill(getpid(), SIGSTOP); + ASSERT_EQ(read(pfd[0], buf, 1), 1); + close(pfd[0]); kill(getpid(), SIGSTOP); exit(EXIT_SUCCESS); } + close(pfd[0]); ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WSTOPPED, NULL), 0); ASSERT_EQ(info.si_signo, SIGCHLD); ASSERT_EQ(info.si_code, CLD_STOPPED); @@ -117,6 +125,8 @@ ASSERT_EQ(sys_pidfd_send_signal(pidfd, SIGCONT, NULL, 0), 0); ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WCONTINUED, NULL), 0); + ASSERT_EQ(write(pfd[1], "C", 1), 1); + close(pfd[1]); ASSERT_EQ(info.si_signo, SIGCHLD); ASSERT_EQ(info.si_code, CLD_CONTINUED); ASSERT_EQ(info.si_pid, parent_tid); diff -Nru linux-6.0.6/tools/vm/slabinfo-gnuplot.sh linux-6.0.12/tools/vm/slabinfo-gnuplot.sh --- linux-6.0.6/tools/vm/slabinfo-gnuplot.sh 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/tools/vm/slabinfo-gnuplot.sh 2023-01-18 18:27:39.000000000 +0000 @@ -150,7 +150,7 @@ let lines=3 out=`basename "$in"`"-slabs-by-loss" `cat "$in" | grep -A "$lines" 'Slabs sorted by loss' |\ - egrep -iv '\-\-|Name|Slabs'\ + grep -E -iv '\-\-|Name|Slabs'\ | awk '{print $1" "$4+$2*$3" "$4}' > "$out"` if [ $? -eq 0 ]; then do_slabs_plotting "$out" @@ -159,7 +159,7 @@ let lines=3 out=`basename "$in"`"-slabs-by-size" `cat "$in" | grep -A "$lines" 'Slabs sorted by size' |\ - egrep -iv '\-\-|Name|Slabs'\ + grep -E -iv '\-\-|Name|Slabs'\ | awk '{print $1" "$4" "$4-$2*$3}' > "$out"` if [ $? -eq 0 ]; then do_slabs_plotting "$out" diff -Nru linux-6.0.6/virt/kvm/kvm_main.c linux-6.0.12/virt/kvm/kvm_main.c --- linux-6.0.6/virt/kvm/kvm_main.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/virt/kvm/kvm_main.c 2023-01-18 18:27:39.000000000 +0000 @@ -5404,6 +5404,7 @@ int (*get)(void *, u64 *), int (*set)(void *, u64), const char *fmt) { + int ret; struct kvm_stat_data *stat_data = (struct kvm_stat_data *) inode->i_private; @@ -5415,15 +5416,13 @@ if (!kvm_get_kvm_safe(stat_data->kvm)) return -ENOENT; - if (simple_attr_open(inode, file, get, - kvm_stats_debugfs_mode(stat_data->desc) & 0222 - ? set : NULL, - fmt)) { + ret = simple_attr_open(inode, file, get, + kvm_stats_debugfs_mode(stat_data->desc) & 0222 + ? set : NULL, fmt); + if (ret) kvm_put_kvm(stat_data->kvm); - return -ENOMEM; - } - return 0; + return ret; } static int kvm_debugfs_release(struct inode *inode, struct file *file) diff -Nru linux-6.0.6/virt/kvm/pfncache.c linux-6.0.12/virt/kvm/pfncache.c --- linux-6.0.6/virt/kvm/pfncache.c 2022-11-21 20:20:50.000000000 +0000 +++ linux-6.0.12/virt/kvm/pfncache.c 2023-01-18 18:27:39.000000000 +0000 @@ -81,6 +81,9 @@ { struct kvm_memslots *slots = kvm_memslots(kvm); + if (!gpc->active) + return false; + if ((gpa & ~PAGE_MASK) + len > PAGE_SIZE) return false; @@ -240,10 +243,11 @@ { struct kvm_memslots *slots = kvm_memslots(kvm); unsigned long page_offset = gpa & ~PAGE_MASK; - kvm_pfn_t old_pfn, new_pfn; + bool unmap_old = false; unsigned long old_uhva; + kvm_pfn_t old_pfn; void *old_khva; - int ret = 0; + int ret; /* * If must fit within a single page. The 'len' argument is @@ -261,6 +265,11 @@ write_lock_irq(&gpc->lock); + if (!gpc->active) { + ret = -EINVAL; + goto out_unlock; + } + old_pfn = gpc->pfn; old_khva = gpc->khva - offset_in_page(gpc->khva); old_uhva = gpc->uhva; @@ -288,9 +297,15 @@ if (!gpc->valid || old_uhva != gpc->uhva) { ret = hva_to_pfn_retry(kvm, gpc); } else { - /* If the HVA→PFN mapping was already valid, don't unmap it. */ + /* + * If the HVA→PFN mapping was already valid, don't unmap it. + * But do update gpc->khva because the offset within the page + * may have changed. + */ + gpc->khva = old_khva + page_offset; old_pfn = KVM_PFN_ERR_FAULT; old_khva = NULL; + ret = 0; } out: @@ -305,14 +320,15 @@ gpc->khva = NULL; } - /* Snapshot the new pfn before dropping the lock! */ - new_pfn = gpc->pfn; + /* Detect a pfn change before dropping the lock! */ + unmap_old = (old_pfn != gpc->pfn); +out_unlock: write_unlock_irq(&gpc->lock); mutex_unlock(&gpc->refresh_lock); - if (old_pfn != new_pfn) + if (unmap_old) gpc_unmap_khva(kvm, old_pfn, old_khva); return ret; @@ -346,42 +362,61 @@ } EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_unmap); +void kvm_gpc_init(struct gfn_to_pfn_cache *gpc) +{ + rwlock_init(&gpc->lock); + mutex_init(&gpc->refresh_lock); +} +EXPORT_SYMBOL_GPL(kvm_gpc_init); -int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, - struct kvm_vcpu *vcpu, enum pfn_cache_usage usage, - gpa_t gpa, unsigned long len) +int kvm_gpc_activate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, + struct kvm_vcpu *vcpu, enum pfn_cache_usage usage, + gpa_t gpa, unsigned long len) { WARN_ON_ONCE(!usage || (usage & KVM_GUEST_AND_HOST_USE_PFN) != usage); if (!gpc->active) { - rwlock_init(&gpc->lock); - mutex_init(&gpc->refresh_lock); - gpc->khva = NULL; gpc->pfn = KVM_PFN_ERR_FAULT; gpc->uhva = KVM_HVA_ERR_BAD; gpc->vcpu = vcpu; gpc->usage = usage; gpc->valid = false; - gpc->active = true; spin_lock(&kvm->gpc_lock); list_add(&gpc->list, &kvm->gpc_list); spin_unlock(&kvm->gpc_lock); + + /* + * Activate the cache after adding it to the list, a concurrent + * refresh must not establish a mapping until the cache is + * reachable by mmu_notifier events. + */ + write_lock_irq(&gpc->lock); + gpc->active = true; + write_unlock_irq(&gpc->lock); } return kvm_gfn_to_pfn_cache_refresh(kvm, gpc, gpa, len); } -EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_init); +EXPORT_SYMBOL_GPL(kvm_gpc_activate); -void kvm_gfn_to_pfn_cache_destroy(struct kvm *kvm, struct gfn_to_pfn_cache *gpc) +void kvm_gpc_deactivate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc) { if (gpc->active) { + /* + * Deactivate the cache before removing it from the list, KVM + * must stall mmu_notifier events until all users go away, i.e. + * until gpc->lock is dropped and refresh is guaranteed to fail. + */ + write_lock_irq(&gpc->lock); + gpc->active = false; + write_unlock_irq(&gpc->lock); + spin_lock(&kvm->gpc_lock); list_del(&gpc->list); spin_unlock(&kvm->gpc_lock); kvm_gfn_to_pfn_cache_unmap(kvm, gpc); - gpc->active = false; } } -EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_destroy); +EXPORT_SYMBOL_GPL(kvm_gpc_deactivate);