diff options
author | Mike Pagano <mpagano@gentoo.org> | 2024-11-14 09:56:40 -0500 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2024-11-14 09:56:40 -0500 |
commit | 8ea9563158fa9749428b5f64ca647cdc41d324ba (patch) | |
tree | 699778b9ab9159528e3b5dccda5569b7ddeafa8f | |
parent | Linux patch 5.15.171 (diff) | |
download | linux-patches-8ea9563158fa9749428b5f64ca647cdc41d324ba.tar.gz linux-patches-8ea9563158fa9749428b5f64ca647cdc41d324ba.tar.bz2 linux-patches-8ea9563158fa9749428b5f64ca647cdc41d324ba.zip |
Linux patch 5.15.1725.15-182
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1171_linux-5.15.172.patch | 2248 |
2 files changed, 2252 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 6259518b..35c500f5 100644 --- a/0000_README +++ b/0000_README @@ -727,6 +727,10 @@ Patch: 1170_linux-5.15.171.patch From: https://www.kernel.org Desc: Linux 5.15.171 +Patch: 1171_linux-5.15.172.patch +From: https://www.kernel.org +Desc: Linux 5.15.172 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1171_linux-5.15.172.patch b/1171_linux-5.15.172.patch new file mode 100644 index 00000000..ff8d8ade --- /dev/null +++ b/1171_linux-5.15.172.patch @@ -0,0 +1,2248 @@ +diff --git a/Makefile b/Makefile +index 1081b50f0932a3..87744128698719 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 15 +-SUBLEVEL = 171 ++SUBLEVEL = 172 + EXTRAVERSION = + NAME = Trick or Treat + +diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts +index e817eba8c622ba..0c8cd25d0ba5c6 100644 +--- a/arch/arm/boot/dts/rk3036-kylin.dts ++++ b/arch/arm/boot/dts/rk3036-kylin.dts +@@ -300,8 +300,8 @@ regulator-state-mem { + &i2c2 { + status = "okay"; + +- rt5616: rt5616@1b { +- compatible = "rt5616"; ++ rt5616: audio-codec@1b { ++ compatible = "realtek,rt5616"; + reg = <0x1b>; + clocks = <&cru SCLK_I2S_OUT>; + clock-names = "mclk"; +diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi +index 0af1a86f9dc45c..d7a86f21cf23fe 100644 +--- a/arch/arm/boot/dts/rk3036.dtsi ++++ b/arch/arm/boot/dts/rk3036.dtsi +@@ -382,12 +382,13 @@ reboot-mode { + }; + }; + +- acodec: acodec-ana@20030000 { +- compatible = "rk3036-codec"; ++ acodec: audio-codec@20030000 { ++ compatible = "rockchip,rk3036-codec"; + reg = <0x20030000 0x4000>; +- rockchip,grf = <&grf>; + clock-names = "acodec_pclk"; + clocks = <&cru PCLK_ACODEC>; ++ rockchip,grf = <&grf>; ++ #sound-dai-cells = <0>; + status = "disabled"; + }; + +@@ -397,7 +398,6 @@ hdmi: hdmi@20034000 { + interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_HDMI>; + clock-names = "pclk"; +- rockchip,grf = <&grf>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_ctl>; + status = "disabled"; +@@ -550,11 +550,11 @@ i2c0: i2c@20072000 { + }; + + spi: spi@20074000 { +- compatible = "rockchip,rockchip-spi"; ++ compatible = "rockchip,rk3036-spi"; + reg = <0x20074000 0x1000>; + interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&cru PCLK_SPI>, <&cru SCLK_SPI>; +- clock-names = "apb-pclk","spi_pclk"; ++ clocks = <&cru SCLK_SPI>, <&cru PCLK_SPI>; ++ clock-names = "spiclk", "apb_pclk"; + dmas = <&pdma 8>, <&pdma 9>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; +diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +index 4e8cde8972e82f..b5130e7be8263c 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi +@@ -740,7 +740,7 @@ usdhc1: mmc@30b40000 { + compatible = "fsl,imx8mp-usdhc", "fsl,imx7d-usdhc"; + reg = <0x30b40000 0x10000>; + interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&clk IMX8MP_CLK_DUMMY>, ++ clocks = <&clk IMX8MP_CLK_IPG_ROOT>, + <&clk IMX8MP_CLK_NAND_USDHC_BUS>, + <&clk IMX8MP_CLK_USDHC1_ROOT>; + clock-names = "ipg", "ahb", "per"; +@@ -754,7 +754,7 @@ usdhc2: mmc@30b50000 { + compatible = "fsl,imx8mp-usdhc", "fsl,imx7d-usdhc"; + reg = <0x30b50000 0x10000>; + interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&clk IMX8MP_CLK_DUMMY>, ++ clocks = <&clk IMX8MP_CLK_IPG_ROOT>, + <&clk IMX8MP_CLK_NAND_USDHC_BUS>, + <&clk IMX8MP_CLK_USDHC2_ROOT>; + clock-names = "ipg", "ahb", "per"; +@@ -768,7 +768,7 @@ usdhc3: mmc@30b60000 { + compatible = "fsl,imx8mp-usdhc", "fsl,imx7d-usdhc"; + reg = <0x30b60000 0x10000>; + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&clk IMX8MP_CLK_DUMMY>, ++ clocks = <&clk IMX8MP_CLK_IPG_ROOT>, + <&clk IMX8MP_CLK_NAND_USDHC_BUS>, + <&clk IMX8MP_CLK_USDHC3_ROOT>; + clock-names = "ipg", "ahb", "per"; +diff --git a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts +index 7ea48167747c62..70aeca428b3807 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts +@@ -36,14 +36,14 @@ leds { + + power_led: led-0 { + label = "firefly:red:power"; +- linux,default-trigger = "ir-power-click"; ++ linux,default-trigger = "default-on"; + default-state = "on"; + gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + }; + + user_led: led-1 { + label = "firefly:blue:user"; +- linux,default-trigger = "ir-user-click"; ++ linux,default-trigger = "rc-feedback"; + default-state = "off"; + gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 21755dd5b4c45e..f73cb7667babac 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -711,8 +711,7 @@ hdmi: hdmi@ff3c0000 { + compatible = "rockchip,rk3328-dw-hdmi"; + reg = <0x0 0xff3c0000 0x0 0x20000>; + reg-io-width = <4>; +- interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>, +- <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_HDMI>, + <&cru SCLK_HDMI_SFC>, + <&cru SCLK_RTC32K>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi +index bcd7977fb0f8ec..6b28bfec8b4b62 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi +@@ -60,7 +60,6 @@ i2c@0 { + fan: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; +- #cooling-cells = <2>; + }; + + rtc_twi: rtc@6f { +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi +index 25dc61c26a9431..68d59394a93043 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi +@@ -574,7 +574,7 @@ &uart0 { + bluetooth { + compatible = "brcm,bcm43438-bt"; + clocks = <&rk808 1>; +- clock-names = "ext_clock"; ++ clock-names = "txco"; + device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; + shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts +index f6b2199a42bdac..3b168da34617bf 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts +@@ -163,7 +163,7 @@ &i2c1 { + status = "okay"; + + rt5651: rt5651@1a { +- compatible = "rockchip,rt5651"; ++ compatible = "realtek,rt5651"; + reg = <0x1a>; + clocks = <&cru SCLK_I2S_8CH_OUT>; + clock-names = "mclk"; +diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c +index 63ead3f1d29479..890c74c52bebcb 100644 +--- a/drivers/acpi/prmt.c ++++ b/drivers/acpi/prmt.c +@@ -52,7 +52,7 @@ struct prm_context_buffer { + static LIST_HEAD(prm_module_list); + + struct prm_handler_info { +- guid_t guid; ++ efi_guid_t guid; + void *handler_addr; + u64 static_data_buffer_addr; + u64 acpi_param_buffer_addr; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +index 2f250dc861947e..592ca0cfe61d0b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -133,8 +133,8 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif, + &buffer); + obj = (union acpi_object *)buffer.pointer; + +- /* Fail if calling the method fails and ATIF is supported */ +- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ++ /* Fail if calling the method fails */ ++ if (ACPI_FAILURE(status)) { + DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", + acpi_format_exception(status)); + kfree(obj); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +index aa057ceecf068d..2ca7a5d5ea64bb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -401,7 +401,7 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user + ssize_t result = 0; + int r; + +- if (size & 0x3 || *pos & 0x3) ++ if (size > 4096 || size & 0x3 || *pos & 0x3) + return -EINVAL; + + if (!adev->didt_wreg) +@@ -1523,11 +1523,11 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev) + amdgpu_securedisplay_debugfs_init(adev); + amdgpu_fw_attestation_debugfs_init(adev); + +- debugfs_create_file("amdgpu_evict_vram", 0444, root, adev, ++ debugfs_create_file("amdgpu_evict_vram", 0400, root, adev, + &amdgpu_evict_vram_fops); +- debugfs_create_file("amdgpu_evict_gtt", 0444, root, adev, ++ debugfs_create_file("amdgpu_evict_gtt", 0400, root, adev, + &amdgpu_evict_gtt_fops); +- debugfs_create_file("amdgpu_test_ib", 0444, root, adev, ++ debugfs_create_file("amdgpu_test_ib", 0400, root, adev, + &amdgpu_debugfs_test_ib_fops); + debugfs_create_file("amdgpu_vm_info", 0444, root, adev, + &amdgpu_debugfs_vm_info_fops); +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 15f4a804779745..07c2e5e38fcbaa 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1664,7 +1664,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) + + u32 len = hid_report_len(report) + 7; + +- return kmalloc(len, flags); ++ return kzalloc(len, flags); + } + EXPORT_SYMBOL_GPL(hid_alloc_report_buf); + +diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c +index 500e0c6d17f617..69126d8034f54c 100644 +--- a/drivers/irqchip/irq-gic-v3.c ++++ b/drivers/irqchip/irq-gic-v3.c +@@ -429,6 +429,13 @@ static int gic_irq_set_irqchip_state(struct irq_data *d, + } + + gic_poke_irq(d, reg); ++ ++ /* ++ * Force read-back to guarantee that the active state has taken ++ * effect, and won't race with a guest-driven deactivation. ++ */ ++ if (reg == GICD_ISACTIVER) ++ gic_peek_irq(d, reg); + return 0; + } + +diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c +index 24cd28ea2c5957..31c4100d38c1ae 100644 +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -1988,7 +1988,6 @@ struct cache_args { + sector_t cache_sectors; + + struct dm_dev *origin_dev; +- sector_t origin_sectors; + + uint32_t block_size; + +@@ -2070,6 +2069,7 @@ static int parse_cache_dev(struct cache_args *ca, struct dm_arg_set *as, + static int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as, + char **error) + { ++ sector_t origin_sectors; + int r; + + if (!at_least_one_arg(as, error)) +@@ -2082,8 +2082,8 @@ static int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as, + return r; + } + +- ca->origin_sectors = get_dev_size(ca->origin_dev); +- if (ca->ti->len > ca->origin_sectors) { ++ origin_sectors = get_dev_size(ca->origin_dev); ++ if (ca->ti->len > origin_sectors) { + *error = "Device size larger than cached device"; + return -EINVAL; + } +@@ -2392,7 +2392,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) + + ca->metadata_dev = ca->origin_dev = ca->cache_dev = NULL; + +- origin_blocks = cache->origin_sectors = ca->origin_sectors; ++ origin_blocks = cache->origin_sectors = ti->len; + origin_blocks = block_div(origin_blocks, ca->block_size); + cache->origin_blocks = to_oblock(origin_blocks); + +@@ -2880,19 +2880,19 @@ static dm_cblock_t get_cache_dev_size(struct cache *cache) + static bool can_resize(struct cache *cache, dm_cblock_t new_size) + { + if (from_cblock(new_size) > from_cblock(cache->cache_size)) { +- if (cache->sized) { +- DMERR("%s: unable to extend cache due to missing cache table reload", +- cache_device_name(cache)); +- return false; +- } ++ DMERR("%s: unable to extend cache due to missing cache table reload", ++ cache_device_name(cache)); ++ return false; + } + + /* + * We can't drop a dirty block when shrinking the cache. + */ +- while (from_cblock(new_size) < from_cblock(cache->cache_size)) { +- new_size = to_cblock(from_cblock(new_size) + 1); +- if (is_dirty(cache, new_size)) { ++ if (cache->loaded_mappings) { ++ new_size = to_cblock(find_next_bit(cache->dirty_bitset, ++ from_cblock(cache->cache_size), ++ from_cblock(new_size))); ++ if (new_size != cache->cache_size) { + DMERR("%s: unable to shrink cache; cache block %llu is dirty", + cache_device_name(cache), + (unsigned long long) from_cblock(new_size)); +@@ -2928,20 +2928,15 @@ static int cache_preresume(struct dm_target *ti) + /* + * Check to see if the cache has resized. + */ +- if (!cache->sized) { +- r = resize_cache_dev(cache, csize); +- if (r) +- return r; +- +- cache->sized = true; +- +- } else if (csize != cache->cache_size) { ++ if (!cache->sized || csize != cache->cache_size) { + if (!can_resize(cache, csize)) + return -EINVAL; + + r = resize_cache_dev(cache, csize); + if (r) + return r; ++ ++ cache->sized = true; + } + + if (!cache->loaded_mappings) { +diff --git a/drivers/md/dm-unstripe.c b/drivers/md/dm-unstripe.c +index fdc8921e5c19f0..e69d297b9122ff 100644 +--- a/drivers/md/dm-unstripe.c ++++ b/drivers/md/dm-unstripe.c +@@ -84,8 +84,8 @@ static int unstripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) + } + uc->physical_start = start; + +- uc->unstripe_offset = uc->unstripe * uc->chunk_size; +- uc->unstripe_width = (uc->stripes - 1) * uc->chunk_size; ++ uc->unstripe_offset = (sector_t)uc->unstripe * uc->chunk_size; ++ uc->unstripe_width = (sector_t)(uc->stripes - 1) * uc->chunk_size; + uc->chunk_shift = is_power_of_2(uc->chunk_size) ? fls(uc->chunk_size) - 1 : 0; + + tmp_len = ti->len; +diff --git a/drivers/media/cec/usb/pulse8/pulse8-cec.c b/drivers/media/cec/usb/pulse8/pulse8-cec.c +index ba67587bd43ec0..171366fe35443b 100644 +--- a/drivers/media/cec/usb/pulse8/pulse8-cec.c ++++ b/drivers/media/cec/usb/pulse8/pulse8-cec.c +@@ -685,7 +685,7 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, + err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4); + if (err) + return err; +- date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; ++ date = ((unsigned)data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + dev_info(pulse8->dev, "Firmware build date %ptT\n", &date); + + dev_dbg(pulse8->dev, "Persistent config:\n"); +diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +index 68968bfa2edc18..533c8bb8fd886d 100644 +--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c ++++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +@@ -1789,6 +1789,9 @@ static void tpg_precalculate_line(struct tpg_data *tpg) + unsigned p; + unsigned x; + ++ if (WARN_ON_ONCE(!tpg->src_width || !tpg->scaled_width)) ++ return; ++ + switch (tpg->pattern) { + case TPG_PAT_GREEN: + contrast = TPG_COLOR_100_RED; +diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c +index d76ac3ec93c2fe..762058d748ddf5 100644 +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -443,8 +443,8 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra + + default: + fepriv->auto_step++; +- fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */ +- break; ++ fepriv->auto_sub_step = 0; ++ continue; + } + + if (!ready) fepriv->auto_sub_step++; +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 661588fc64f6a8..71344ae26fea73 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -96,10 +96,15 @@ static DECLARE_RWSEM(minor_rwsem); + static int dvb_device_open(struct inode *inode, struct file *file) + { + struct dvb_device *dvbdev; ++ unsigned int minor = iminor(inode); ++ ++ if (minor >= MAX_DVB_MINORS) ++ return -ENODEV; + + mutex_lock(&dvbdev_mutex); + down_read(&minor_rwsem); +- dvbdev = dvb_minors[iminor(inode)]; ++ ++ dvbdev = dvb_minors[minor]; + + if (dvbdev && dvbdev->fops) { + int err = 0; +@@ -539,7 +544,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + for (minor = 0; minor < MAX_DVB_MINORS; minor++) + if (dvb_minors[minor] == NULL) + break; +- if (minor == MAX_DVB_MINORS) { ++ if (minor >= MAX_DVB_MINORS) { + if (new_node) { + list_del (&new_node->list_head); + kfree(dvbdevfops); +@@ -554,6 +559,14 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + } + #else + minor = nums2minor(adap->num, type, id); ++ if (minor >= MAX_DVB_MINORS) { ++ dvb_media_device_free(dvbdev); ++ list_del(&dvbdev->list_head); ++ kfree(dvbdev); ++ *pdvbdev = NULL; ++ mutex_unlock(&dvbdev_register_lock); ++ return ret; ++ } + #endif + dvbdev->minor = minor; + dvb_minors[minor] = dvb_device_get(dvbdev); +diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c +index 8b978a9f74a4e5..f5dd3a81725a72 100644 +--- a/drivers/media/dvb-frontends/cx24116.c ++++ b/drivers/media/dvb-frontends/cx24116.c +@@ -741,6 +741,7 @@ static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr) + { + struct cx24116_state *state = fe->demodulator_priv; + u8 snr_reading; ++ int ret; + static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ + 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667, + 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667, +@@ -749,7 +750,11 @@ static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr) + + dprintk("%s()\n", __func__); + +- snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); ++ ret = cx24116_readreg(state, CX24116_REG_QUALITY0); ++ if (ret < 0) ++ return ret; ++ ++ snr_reading = ret; + + if (snr_reading >= 0xa0 /* 100% */) + *snr = 0xffff; +diff --git a/drivers/media/dvb-frontends/stb0899_algo.c b/drivers/media/dvb-frontends/stb0899_algo.c +index df89c33dac23c5..40537c4ccb0d75 100644 +--- a/drivers/media/dvb-frontends/stb0899_algo.c ++++ b/drivers/media/dvb-frontends/stb0899_algo.c +@@ -269,7 +269,7 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state) + + short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3; + int index = 0; +- u8 cfr[2]; ++ u8 cfr[2] = {0}; + u8 reg; + + internal->status = NOCARRIER; +diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c +index d688ffff7a0745..5ed5a22b946ff4 100644 +--- a/drivers/media/i2c/adv7604.c ++++ b/drivers/media/i2c/adv7604.c +@@ -2517,10 +2517,10 @@ static int adv76xx_log_status(struct v4l2_subdev *sd) + const struct adv76xx_chip_info *info = state->info; + struct v4l2_dv_timings timings; + struct stdi_readback stdi; +- u8 reg_io_0x02 = io_read(sd, 0x02); ++ int ret; ++ u8 reg_io_0x02; + u8 edid_enabled; + u8 cable_det; +- + static const char * const csc_coeff_sel_rb[16] = { + "bypassed", "YPbPr601 -> RGB", "reserved", "YPbPr709 -> RGB", + "reserved", "RGB -> YPbPr601", "reserved", "RGB -> YPbPr709", +@@ -2619,13 +2619,21 @@ static int adv76xx_log_status(struct v4l2_subdev *sd) + v4l2_info(sd, "-----Color space-----\n"); + v4l2_info(sd, "RGB quantization range ctrl: %s\n", + rgb_quantization_range_txt[state->rgb_quantization_range]); +- v4l2_info(sd, "Input color space: %s\n", +- input_color_space_txt[reg_io_0x02 >> 4]); +- v4l2_info(sd, "Output color space: %s %s, alt-gamma %s\n", +- (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr", +- (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? +- "(16-235)" : "(0-255)", +- (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); ++ ++ ret = io_read(sd, 0x02); ++ if (ret < 0) { ++ v4l2_info(sd, "Can't read Input/Output color space\n"); ++ } else { ++ reg_io_0x02 = ret; ++ ++ v4l2_info(sd, "Input color space: %s\n", ++ input_color_space_txt[reg_io_0x02 >> 4]); ++ v4l2_info(sd, "Output color space: %s %s, alt-gamma %s\n", ++ (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr", ++ (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? ++ "(16-235)" : "(0-255)", ++ (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); ++ } + v4l2_info(sd, "Color space conversion: %s\n", + csc_coeff_sel_rb[cp_read(sd, info->cp_csc) >> 4]); + +diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c +index 7d0ab19c38bb91..5cfb49ddcbeead 100644 +--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c ++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c +@@ -775,11 +775,14 @@ static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx) + (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2; + jpeg_buffer.curr = 0; + +- word = 0; +- + if (get_word_be(&jpeg_buffer, &word)) + return; +- jpeg_buffer.size = (long)word - 2; ++ ++ if (word < 2) ++ jpeg_buffer.size = 0; ++ else ++ jpeg_buffer.size = (long)word - 2; ++ + jpeg_buffer.data += 2; + jpeg_buffer.curr = 0; + +@@ -1058,6 +1061,7 @@ static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word) + if (byte == -1) + return -1; + *word = (unsigned int)byte | temp; ++ + return 0; + } + +@@ -1145,7 +1149,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, + if (get_word_be(&jpeg_buffer, &word)) + break; + length = (long)word - 2; +- if (!length) ++ if (length <= 0) + return false; + sof = jpeg_buffer.curr; /* after 0xffc0 */ + sof_len = length; +@@ -1176,7 +1180,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, + if (get_word_be(&jpeg_buffer, &word)) + break; + length = (long)word - 2; +- if (!length) ++ if (length <= 0) + return false; + if (n_dqt >= S5P_JPEG_MAX_MARKER) + return false; +@@ -1189,7 +1193,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, + if (get_word_be(&jpeg_buffer, &word)) + break; + length = (long)word - 2; +- if (!length) ++ if (length <= 0) + return false; + if (n_dht >= S5P_JPEG_MAX_MARKER) + return false; +@@ -1214,6 +1218,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, + if (get_word_be(&jpeg_buffer, &word)) + break; + length = (long)word - 2; ++ /* No need to check underflows as skip() does it */ + skip(&jpeg_buffer, length); + break; + } +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index ef5788899503cd..73a2d960d68901 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -645,7 +645,7 @@ static int uvc_parse_format(struct uvc_device *dev, + /* Parse the frame descriptors. Only uncompressed, MJPEG and frame + * based formats have frame descriptors. + */ +- while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && ++ while (ftype && buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && + buffer[2] == ftype) { + frame = &format->frame[format->nframes]; + if (ftype != UVC_VS_FRAME_FRAME_BASED) +diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c +index db9baa0bd05fad..80243282f74357 100644 +--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c +@@ -712,9 +712,10 @@ static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c) + for (i = 0; i < master->ncontrols; i++) + cur_to_new(master->cluster[i]); + ret = call_op(master, g_volatile_ctrl); +- new_to_user(c, ctrl); ++ if (!ret) ++ ret = new_to_user(c, ctrl); + } else { +- cur_to_user(c, ctrl); ++ ret = cur_to_user(c, ctrl); + } + v4l2_ctrl_unlock(master); + return ret; +@@ -729,7 +730,10 @@ int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control) + if (!ctrl || !ctrl->is_int) + return -EINVAL; + ret = get_ctrl(ctrl, &c); +- control->value = c.value; ++ ++ if (!ret) ++ control->value = c.value; ++ + return ret; + } + EXPORT_SYMBOL(v4l2_g_ctrl); +@@ -770,10 +774,11 @@ static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, + int ret; + + v4l2_ctrl_lock(ctrl); +- user_to_new(c, ctrl); +- ret = set_ctrl(fh, ctrl, 0); ++ ret = user_to_new(c, ctrl); ++ if (!ret) ++ ret = set_ctrl(fh, ctrl, 0); + if (!ret) +- cur_to_user(c, ctrl); ++ ret = cur_to_user(c, ctrl); + v4l2_ctrl_unlock(ctrl); + return ret; + } +diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c +index e04d4e7cc86832..8ab43f1272bd9a 100644 +--- a/drivers/net/can/c_can/c_can_main.c ++++ b/drivers/net/can/c_can/c_can_main.c +@@ -1022,7 +1022,6 @@ static int c_can_handle_bus_err(struct net_device *dev, + + /* common for all type of bus errors */ + priv->can.can_stats.bus_error++; +- stats->rx_errors++; + + /* propagate the error condition to the CAN stack */ + skb = alloc_can_err_skb(dev, &cf); +@@ -1038,26 +1037,32 @@ static int c_can_handle_bus_err(struct net_device *dev, + case LEC_STUFF_ERROR: + netdev_dbg(dev, "stuff error\n"); + cf->data[2] |= CAN_ERR_PROT_STUFF; ++ stats->rx_errors++; + break; + case LEC_FORM_ERROR: + netdev_dbg(dev, "form error\n"); + cf->data[2] |= CAN_ERR_PROT_FORM; ++ stats->rx_errors++; + break; + case LEC_ACK_ERROR: + netdev_dbg(dev, "ack error\n"); + cf->data[3] = CAN_ERR_PROT_LOC_ACK; ++ stats->tx_errors++; + break; + case LEC_BIT1_ERROR: + netdev_dbg(dev, "bit1 error\n"); + cf->data[2] |= CAN_ERR_PROT_BIT1; ++ stats->tx_errors++; + break; + case LEC_BIT0_ERROR: + netdev_dbg(dev, "bit0 error\n"); + cf->data[2] |= CAN_ERR_PROT_BIT0; ++ stats->tx_errors++; + break; + case LEC_CRC_ERROR: + netdev_dbg(dev, "CRC error\n"); + cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; ++ stats->rx_errors++; + break; + default: + break; +diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c +index 333333692caa5f..bafa63e5ce2529 100644 +--- a/drivers/net/ethernet/arc/emac_main.c ++++ b/drivers/net/ethernet/arc/emac_main.c +@@ -111,6 +111,7 @@ static void arc_emac_tx_clean(struct net_device *ndev) + { + struct arc_emac_priv *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; ++ struct device *dev = ndev->dev.parent; + unsigned int i; + + for (i = 0; i < TX_BD_NUM; i++) { +@@ -140,7 +141,7 @@ static void arc_emac_tx_clean(struct net_device *ndev) + stats->tx_bytes += skb->len; + } + +- dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr), ++ dma_unmap_single(dev, dma_unmap_addr(tx_buff, addr), + dma_unmap_len(tx_buff, len), DMA_TO_DEVICE); + + /* return the sk_buff to system */ +@@ -174,6 +175,7 @@ static void arc_emac_tx_clean(struct net_device *ndev) + static int arc_emac_rx(struct net_device *ndev, int budget) + { + struct arc_emac_priv *priv = netdev_priv(ndev); ++ struct device *dev = ndev->dev.parent; + unsigned int work_done; + + for (work_done = 0; work_done < budget; work_done++) { +@@ -223,9 +225,9 @@ static int arc_emac_rx(struct net_device *ndev, int budget) + continue; + } + +- addr = dma_map_single(&ndev->dev, (void *)skb->data, ++ addr = dma_map_single(dev, (void *)skb->data, + EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); +- if (dma_mapping_error(&ndev->dev, addr)) { ++ if (dma_mapping_error(dev, addr)) { + if (net_ratelimit()) + netdev_err(ndev, "cannot map dma buffer\n"); + dev_kfree_skb(skb); +@@ -237,7 +239,7 @@ static int arc_emac_rx(struct net_device *ndev, int budget) + } + + /* unmap previosly mapped skb */ +- dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), ++ dma_unmap_single(dev, dma_unmap_addr(rx_buff, addr), + dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); + + pktlen = info & LEN_MASK; +@@ -423,6 +425,7 @@ static int arc_emac_open(struct net_device *ndev) + { + struct arc_emac_priv *priv = netdev_priv(ndev); + struct phy_device *phy_dev = ndev->phydev; ++ struct device *dev = ndev->dev.parent; + int i; + + phy_dev->autoneg = AUTONEG_ENABLE; +@@ -445,9 +448,9 @@ static int arc_emac_open(struct net_device *ndev) + if (unlikely(!rx_buff->skb)) + return -ENOMEM; + +- addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data, ++ addr = dma_map_single(dev, (void *)rx_buff->skb->data, + EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); +- if (dma_mapping_error(&ndev->dev, addr)) { ++ if (dma_mapping_error(dev, addr)) { + netdev_err(ndev, "cannot dma map\n"); + dev_kfree_skb(rx_buff->skb); + return -ENOMEM; +@@ -548,6 +551,7 @@ static void arc_emac_set_rx_mode(struct net_device *ndev) + static void arc_free_tx_queue(struct net_device *ndev) + { + struct arc_emac_priv *priv = netdev_priv(ndev); ++ struct device *dev = ndev->dev.parent; + unsigned int i; + + for (i = 0; i < TX_BD_NUM; i++) { +@@ -555,7 +559,7 @@ static void arc_free_tx_queue(struct net_device *ndev) + struct buffer_state *tx_buff = &priv->tx_buff[i]; + + if (tx_buff->skb) { +- dma_unmap_single(&ndev->dev, ++ dma_unmap_single(dev, + dma_unmap_addr(tx_buff, addr), + dma_unmap_len(tx_buff, len), + DMA_TO_DEVICE); +@@ -579,6 +583,7 @@ static void arc_free_tx_queue(struct net_device *ndev) + static void arc_free_rx_queue(struct net_device *ndev) + { + struct arc_emac_priv *priv = netdev_priv(ndev); ++ struct device *dev = ndev->dev.parent; + unsigned int i; + + for (i = 0; i < RX_BD_NUM; i++) { +@@ -586,7 +591,7 @@ static void arc_free_rx_queue(struct net_device *ndev) + struct buffer_state *rx_buff = &priv->rx_buff[i]; + + if (rx_buff->skb) { +- dma_unmap_single(&ndev->dev, ++ dma_unmap_single(dev, + dma_unmap_addr(rx_buff, addr), + dma_unmap_len(rx_buff, len), + DMA_FROM_DEVICE); +@@ -679,6 +684,7 @@ static netdev_tx_t arc_emac_tx(struct sk_buff *skb, struct net_device *ndev) + unsigned int len, *txbd_curr = &priv->txbd_curr; + struct net_device_stats *stats = &ndev->stats; + __le32 *info = &priv->txbd[*txbd_curr].info; ++ struct device *dev = ndev->dev.parent; + dma_addr_t addr; + + if (skb_padto(skb, ETH_ZLEN)) +@@ -692,10 +698,9 @@ static netdev_tx_t arc_emac_tx(struct sk_buff *skb, struct net_device *ndev) + return NETDEV_TX_BUSY; + } + +- addr = dma_map_single(&ndev->dev, (void *)skb->data, len, +- DMA_TO_DEVICE); ++ addr = dma_map_single(dev, (void *)skb->data, len, DMA_TO_DEVICE); + +- if (unlikely(dma_mapping_error(&ndev->dev, addr))) { ++ if (unlikely(dma_mapping_error(dev, addr))) { + stats->tx_dropped++; + stats->tx_errors++; + dev_kfree_skb_any(skb); +diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c +index acd4a3167ed6aa..88dfcebf2b8739 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c +@@ -78,11 +78,18 @@ static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr) + { + struct enetc_ndev_priv *priv = netdev_priv(ndev); + struct sockaddr *saddr = addr; ++ int err; + + if (!is_valid_ether_addr(saddr->sa_data)) + return -EADDRNOTAVAIL; + +- return enetc_msg_vsi_set_primary_mac_addr(priv, saddr); ++ err = enetc_msg_vsi_set_primary_mac_addr(priv, saddr); ++ if (err) ++ return err; ++ ++ eth_hw_addr_set(ndev, saddr->sa_data); ++ ++ return 0; + } + + static int enetc_vf_set_features(struct net_device *ndev, +diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c +index 67b0bf310daaaf..9a63fbc6940831 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c +@@ -25,8 +25,11 @@ void hnae3_unregister_ae_algo_prepare(struct hnae3_ae_algo *ae_algo) + pci_id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev); + if (!pci_id) + continue; +- if (IS_ENABLED(CONFIG_PCI_IOV)) ++ if (IS_ENABLED(CONFIG_PCI_IOV)) { ++ device_lock(&ae_dev->pdev->dev); + pci_disable_sriov(ae_dev->pdev); ++ device_unlock(&ae_dev->pdev->dev); ++ } + } + } + EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare); +diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h +index a05103e2fb522f..a143440f3db62d 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e.h ++++ b/drivers/net/ethernet/intel/i40e/i40e.h +@@ -776,6 +776,7 @@ enum i40e_filter_state { + I40E_FILTER_ACTIVE, /* Added to switch by FW */ + I40E_FILTER_FAILED, /* Rejected by FW */ + I40E_FILTER_REMOVE, /* To be removed */ ++ I40E_FILTER_NEW_SYNC, /* New, not sent yet, is in i40e_sync_vsi_filters() */ + /* There is no 'removed' state; the filter struct is freed */ + }; + struct i40e_mac_filter { +diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +index 7c5f874ef335a3..503818f0714d4a 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +@@ -105,6 +105,7 @@ static char *i40e_filter_state_string[] = { + "ACTIVE", + "FAILED", + "REMOVE", ++ "NEW_SYNC", + }; + + /** +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index c1f21713ab8d11..bc5da0b8648c1f 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -1233,6 +1233,7 @@ int i40e_count_filters(struct i40e_vsi *vsi) + + hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) { + if (f->state == I40E_FILTER_NEW || ++ f->state == I40E_FILTER_NEW_SYNC || + f->state == I40E_FILTER_ACTIVE) + ++cnt; + } +@@ -1419,6 +1420,8 @@ static int i40e_correct_mac_vlan_filters(struct i40e_vsi *vsi, + + new->f = add_head; + new->state = add_head->state; ++ if (add_head->state == I40E_FILTER_NEW) ++ add_head->state = I40E_FILTER_NEW_SYNC; + + /* Add the new filter to the tmp list */ + hlist_add_head(&new->hlist, tmp_add_list); +@@ -1528,6 +1531,8 @@ static int i40e_correct_vf_mac_vlan_filters(struct i40e_vsi *vsi, + return -ENOMEM; + new_mac->f = add_head; + new_mac->state = add_head->state; ++ if (add_head->state == I40E_FILTER_NEW) ++ add_head->state = I40E_FILTER_NEW_SYNC; + + /* Add the new filter to the tmp list */ + hlist_add_head(&new_mac->hlist, tmp_add_list); +@@ -2417,7 +2422,8 @@ static int + i40e_aqc_broadcast_filter(struct i40e_vsi *vsi, const char *vsi_name, + struct i40e_mac_filter *f) + { +- bool enable = f->state == I40E_FILTER_NEW; ++ bool enable = f->state == I40E_FILTER_NEW || ++ f->state == I40E_FILTER_NEW_SYNC; + struct i40e_hw *hw = &vsi->back->hw; + int aq_ret; + +@@ -2591,6 +2597,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) + + /* Add it to the hash list */ + hlist_add_head(&new->hlist, &tmp_add_list); ++ f->state = I40E_FILTER_NEW_SYNC; + } + + /* Count the number of active (current and new) VLAN +@@ -2742,7 +2749,8 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) + spin_lock_bh(&vsi->mac_filter_hash_lock); + hlist_for_each_entry_safe(new, h, &tmp_add_list, hlist) { + /* Only update the state if we're still NEW */ +- if (new->f->state == I40E_FILTER_NEW) ++ if (new->f->state == I40E_FILTER_NEW || ++ new->f->state == I40E_FILTER_NEW_SYNC) + new->f->state = new->state; + hlist_del(&new->hlist); + netdev_hw_addr_refcnt(new->f, vsi->netdev, -1); +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +index 0106ea3519a01e..b52b77579c7f31 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +@@ -456,7 +456,7 @@ ice_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp, + * + * Returns the number of available flow director filters to this VSI + */ +-static int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi) ++int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi) + { + u16 vsi_num = ice_get_hw_vsi_num(hw, vsi->idx); + u16 num_guar; +diff --git a/drivers/net/ethernet/intel/ice/ice_fdir.h b/drivers/net/ethernet/intel/ice/ice_fdir.h +index d2d40e18ae8aab..32e9258d27d72e 100644 +--- a/drivers/net/ethernet/intel/ice/ice_fdir.h ++++ b/drivers/net/ethernet/intel/ice/ice_fdir.h +@@ -201,6 +201,8 @@ struct ice_fdir_base_pkt { + const u8 *tun_pkt; + }; + ++struct ice_vsi; ++ + enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id); + enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id); + enum ice_status +@@ -214,6 +216,7 @@ enum ice_status + ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, + u8 *pkt, bool frag, bool tun); + int ice_get_fdir_cnt_all(struct ice_hw *hw); ++int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi); + bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input); + bool ice_fdir_has_frag(enum ice_fltr_ptype flow); + struct ice_fdir_fltr * +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +index 412deb36b645b7..2ca8102e8f36e8 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +@@ -744,6 +744,8 @@ static void ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir *fdir) + fdir->fdir_fltr_cnt[flow][0] = 0; + fdir->fdir_fltr_cnt[flow][1] = 0; + } ++ ++ fdir->fdir_fltr_cnt_total = 0; + } + + /** +@@ -1837,6 +1839,7 @@ ice_vc_add_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, + resp->status = status; + resp->flow_id = conf->flow_id; + vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]++; ++ vf->fdir.fdir_fltr_cnt_total++; + + ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret, + (u8 *)resp, len); +@@ -1901,6 +1904,7 @@ ice_vc_del_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, + resp->status = status; + ice_vc_fdir_remove_entry(vf, conf, conf->flow_id); + vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]--; ++ vf->fdir.fdir_fltr_cnt_total--; + + ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret, + (u8 *)resp, len); +@@ -2065,6 +2069,7 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) + struct virtchnl_fdir_add *stat = NULL; + struct virtchnl_fdir_fltr_conf *conf; + enum virtchnl_status_code v_ret; ++ struct ice_vsi *vf_vsi; + struct device *dev; + struct ice_pf *pf; + int is_tun = 0; +@@ -2073,6 +2078,17 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) + + pf = vf->pf; + dev = ice_pf_to_dev(pf); ++ vf_vsi = ice_get_vf_vsi(vf); ++ ++#define ICE_VF_MAX_FDIR_FILTERS 128 ++ if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) || ++ vf->fdir.fdir_fltr_cnt_total >= ICE_VF_MAX_FDIR_FILTERS) { ++ v_ret = VIRTCHNL_STATUS_ERR_PARAM; ++ dev_err(dev, "Max number of FDIR filters for VF %d is reached\n", ++ vf->vf_id); ++ goto err_exit; ++ } ++ + ret = ice_vc_fdir_param_check(vf, fltr->vsi_id); + if (ret) { + v_ret = VIRTCHNL_STATUS_ERR_PARAM; +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h +index f4e629f4c09b54..6258af1ff0aa38 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h +@@ -28,6 +28,7 @@ struct ice_vf_fdir_ctx { + struct ice_vf_fdir { + u16 fdir_fltr_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX]; + int prof_entry_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX]; ++ u16 fdir_fltr_cnt_total; + struct ice_fd_hw_prof **fdir_prof; + + struct idr fdir_rule_idr; +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 4a194f30f4a834..2478caeec763ff 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -3650,6 +3650,7 @@ static int stmmac_request_irq_single(struct net_device *dev) + /* Request the Wake IRQ in case of another line + * is used for WoL + */ ++ priv->wol_irq_disabled = true; + if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) { + ret = request_irq(priv->wol_irq, stmmac_interrupt, + IRQF_SHARED, dev->name, dev); +diff --git a/drivers/net/phy/dp83848.c b/drivers/net/phy/dp83848.c +index 937061acfc613a..351411f0aa6f47 100644 +--- a/drivers/net/phy/dp83848.c ++++ b/drivers/net/phy/dp83848.c +@@ -147,6 +147,8 @@ MODULE_DEVICE_TABLE(mdio, dp83848_tbl); + /* IRQ related */ \ + .config_intr = dp83848_config_intr, \ + .handle_interrupt = dp83848_handle_interrupt, \ ++ \ ++ .flags = PHY_RST_AFTER_CLK_EN, \ + } + + static struct phy_driver dp83848_driver[] = { +diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c +index 7a53bf51964f2b..75ba8b1380322a 100644 +--- a/drivers/pwm/pwm-imx-tpm.c ++++ b/drivers/pwm/pwm-imx-tpm.c +@@ -106,7 +106,9 @@ static int pwm_imx_tpm_round_state(struct pwm_chip *chip, + p->prescale = prescale; + + period_count = (clock_unit + ((1 << prescale) >> 1)) >> prescale; +- p->mod = period_count; ++ if (period_count == 0) ++ return -EINVAL; ++ p->mod = period_count - 1; + + /* calculate real period HW can support */ + tmp = (u64)period_count << prescale; +diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c +index ed06798983f87f..00791a42b8d873 100644 +--- a/drivers/scsi/sd_zbc.c ++++ b/drivers/scsi/sd_zbc.c +@@ -168,8 +168,7 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, + bufsize = min_t(size_t, bufsize, queue_max_segments(q) << PAGE_SHIFT); + + while (bufsize >= SECTOR_SIZE) { +- buf = __vmalloc(bufsize, +- GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY); ++ buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY); + if (buf) { + *buflen = bufsize; + return buf; +diff --git a/drivers/thermal/qcom/lmh.c b/drivers/thermal/qcom/lmh.c +index 36f0e92d92cee3..9006e01e18c207 100644 +--- a/drivers/thermal/qcom/lmh.c ++++ b/drivers/thermal/qcom/lmh.c +@@ -71,7 +71,14 @@ static struct irq_chip lmh_irq_chip = { + static int lmh_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) + { + struct lmh_hw_data *lmh_data = d->host_data; ++ static struct lock_class_key lmh_lock_key; ++ static struct lock_class_key lmh_request_key; + ++ /* ++ * This lock class tells lockdep that GPIO irqs are in a different ++ * category than their parents, so it won't report false recursion. ++ */ ++ irq_set_lockdep_class(irq, &lmh_lock_key, &lmh_request_key); + irq_set_chip_and_handler(irq, &lmh_irq_chip, handle_simple_irq); + irq_set_chip_data(irq, lmh_data); + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 0ca06a3ab71798..f507f055f523c1 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1796,10 +1796,18 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + { + u32 reg; + +- dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & +- DWC3_GUSB2PHYCFG_SUSPHY) || +- (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) & +- DWC3_GUSB3PIPECTL_SUSPHY); ++ if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) { ++ dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & ++ DWC3_GUSB2PHYCFG_SUSPHY) || ++ (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) & ++ DWC3_GUSB3PIPECTL_SUSPHY); ++ /* ++ * TI AM62 platform requires SUSPHY to be ++ * enabled for system suspend to work. ++ */ ++ if (!dwc->susphy_state) ++ dwc3_enable_susphy(dwc, true); ++ } + + switch (dwc->current_dr_role) { + case DWC3_GCTL_PRTCAP_DEVICE: +@@ -1848,15 +1856,6 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + break; + } + +- if (!PMSG_IS_AUTO(msg)) { +- /* +- * TI AM62 platform requires SUSPHY to be +- * enabled for system suspend to work. +- */ +- if (!dwc->susphy_state) +- dwc3_enable_susphy(dwc, true); +- } +- + return 0; + } + +diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c +index f3f76f2ac63f9b..5bdbf58f3b35a6 100644 +--- a/drivers/usb/musb/sunxi.c ++++ b/drivers/usb/musb/sunxi.c +@@ -286,8 +286,6 @@ static int sunxi_musb_exit(struct musb *musb) + if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags)) + sunxi_sram_release(musb->controller->parent); + +- devm_usb_put_phy(glue->dev, glue->xceiv); +- + return 0; + } + +diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c +index bdee78cc4a072a..6e95f0bb00e335 100644 +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -770,11 +770,12 @@ static void edge_bulk_out_data_callback(struct urb *urb) + static void edge_bulk_out_cmd_callback(struct urb *urb) + { + struct edgeport_port *edge_port = urb->context; ++ struct device *dev = &urb->dev->dev; + int status = urb->status; + + atomic_dec(&CmdUrbs); +- dev_dbg(&urb->dev->dev, "%s - FREE URB %p (outstanding %d)\n", +- __func__, urb, atomic_read(&CmdUrbs)); ++ dev_dbg(dev, "%s - FREE URB %p (outstanding %d)\n", __func__, urb, ++ atomic_read(&CmdUrbs)); + + + /* clean up the transfer buffer */ +@@ -784,8 +785,7 @@ static void edge_bulk_out_cmd_callback(struct urb *urb) + usb_free_urb(urb); + + if (status) { +- dev_dbg(&urb->dev->dev, +- "%s - nonzero write bulk status received: %d\n", ++ dev_dbg(dev, "%s - nonzero write bulk status received: %d\n", + __func__, status); + return; + } +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 9d2c8dc14945dc..ec737fcd2c40c2 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -251,6 +251,7 @@ static void option_instat_callback(struct urb *urb); + #define QUECTEL_VENDOR_ID 0x2c7c + /* These Quectel products use Quectel's vendor ID */ + #define QUECTEL_PRODUCT_EC21 0x0121 ++#define QUECTEL_PRODUCT_RG650V 0x0122 + #define QUECTEL_PRODUCT_EM061K_LTA 0x0123 + #define QUECTEL_PRODUCT_EM061K_LMS 0x0124 + #define QUECTEL_PRODUCT_EC25 0x0125 +@@ -1273,6 +1274,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG912Y, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG916Q, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0xff, 0x30) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0, 0) }, + + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, +@@ -2320,6 +2323,9 @@ static const struct usb_device_id option_ids[] = { + { 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_AND_INTERFACE_INFO(0x2cb7, 0x0112, 0xff, 0xff, 0x30) }, /* Fibocom FG132 Diag */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x0112, 0xff, 0xff, 0x40) }, /* Fibocom FG132 AT */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x0112, 0xff, 0, 0) }, /* Fibocom FG132 NMEA */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0115, 0xff), /* Fibocom FM135 (laptop MBIM) */ + .driver_info = RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ +diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c +index 703a9c56355731..061ff754b307bc 100644 +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -166,6 +166,8 @@ static const struct usb_device_id id_table[] = { + {DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */ + {DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */ + {DEVICE_SWI(0x1199, 0x90d2)}, /* Sierra Wireless EM9191 QDL */ ++ {DEVICE_SWI(0x1199, 0x90e4)}, /* Sierra Wireless EM86xx QDL*/ ++ {DEVICE_SWI(0x1199, 0x90e5)}, /* Sierra Wireless EM86xx */ + {DEVICE_SWI(0x1199, 0xc080)}, /* Sierra Wireless EM7590 QDL */ + {DEVICE_SWI(0x1199, 0xc081)}, /* Sierra Wireless EM7590 */ + {DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ +diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c +index 6db7c8ddd51cd0..fb6211efb5d871 100644 +--- a/drivers/usb/typec/ucsi/ucsi_ccg.c ++++ b/drivers/usb/typec/ucsi/ucsi_ccg.c +@@ -436,6 +436,8 @@ static void ucsi_ccg_update_set_new_cam_cmd(struct ucsi_ccg *uc, + + port = uc->orig; + new_cam = UCSI_SET_NEW_CAM_GET_AM(*cmd); ++ if (new_cam >= ARRAY_SIZE(uc->updated)) ++ return; + new_port = &uc->updated[new_cam]; + cam = new_port->linked_idx; + enter_new_mode = UCSI_SET_NEW_CAM_ENTER(*cmd); +diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c +index ca848b1834747c..83c647d2fffe54 100644 +--- a/fs/btrfs/delayed-ref.c ++++ b/fs/btrfs/delayed-ref.c +@@ -608,7 +608,7 @@ static int insert_delayed_ref(struct btrfs_trans_handle *trans, + &href->ref_add_list); + else if (ref->action == BTRFS_DROP_DELAYED_REF) { + ASSERT(!list_empty(&exist->add_list)); +- list_del(&exist->add_list); ++ list_del_init(&exist->add_list); + } else { + ASSERT(0); + } +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 48ade92d4ce8c3..09922258f5a111 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -212,13 +212,18 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) + nfs_fscache_invalidate(inode); + flags &= ~(NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED); + +- nfsi->cache_validity |= flags; +- ++ flags |= nfsi->cache_validity; + if (inode->i_mapping->nrpages == 0) +- nfsi->cache_validity &= ~(NFS_INO_INVALID_DATA | +- NFS_INO_DATA_INVAL_DEFER); +- else if (nfsi->cache_validity & NFS_INO_INVALID_DATA) +- nfsi->cache_validity &= ~NFS_INO_DATA_INVAL_DEFER; ++ flags &= ~NFS_INO_INVALID_DATA; ++ ++ /* pairs with nfs_clear_invalid_mapping()'s smp_load_acquire() */ ++ smp_store_release(&nfsi->cache_validity, flags); ++ ++ if (inode->i_mapping->nrpages == 0 || ++ nfsi->cache_validity & NFS_INO_INVALID_DATA) { ++ nfs_ooo_clear(nfsi); ++ } ++ trace_nfs_set_cache_invalid(inode, 0); + } + EXPORT_SYMBOL_GPL(nfs_set_cache_invalid); + +@@ -691,9 +696,10 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset) + + i_size_write(inode, offset); + /* Optimisation */ +- if (offset == 0) +- NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_DATA | +- NFS_INO_DATA_INVAL_DEFER); ++ if (offset == 0) { ++ NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA; ++ nfs_ooo_clear(NFS_I(inode)); ++ } + NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_SIZE; + + spin_unlock(&inode->i_lock); +@@ -1108,7 +1114,7 @@ void nfs_inode_attach_open_context(struct nfs_open_context *ctx) + + spin_lock(&inode->i_lock); + if (list_empty(&nfsi->open_files) && +- (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER)) ++ nfs_ooo_test(nfsi)) + nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA | + NFS_INO_REVAL_FORCED); + list_add_tail_rcu(&ctx->list, &nfsi->open_files); +@@ -1347,6 +1353,13 @@ int nfs_clear_invalid_mapping(struct address_space *mapping) + nfs_wait_bit_killable, TASK_KILLABLE); + if (ret) + goto out; ++ smp_rmb(); /* pairs with smp_wmb() below */ ++ if (test_bit(NFS_INO_INVALIDATING, bitlock)) ++ continue; ++ /* pairs with nfs_set_cache_invalid()'s smp_store_release() */ ++ if (!(smp_load_acquire(&nfsi->cache_validity) & NFS_INO_INVALID_DATA)) ++ goto out; ++ /* Slow-path that double-checks with spinlock held */ + spin_lock(&inode->i_lock); + if (test_bit(NFS_INO_INVALIDATING, bitlock)) { + spin_unlock(&inode->i_lock); +@@ -1360,8 +1373,8 @@ int nfs_clear_invalid_mapping(struct address_space *mapping) + + set_bit(NFS_INO_INVALIDATING, bitlock); + smp_wmb(); +- nfsi->cache_validity &= +- ~(NFS_INO_INVALID_DATA | NFS_INO_DATA_INVAL_DEFER); ++ nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; ++ nfs_ooo_clear(nfsi); + spin_unlock(&inode->i_lock); + trace_nfs_invalidate_mapping_enter(inode); + ret = nfs_invalidate_mapping(inode, mapping); +@@ -1573,6 +1586,7 @@ void nfs_fattr_init(struct nfs_fattr *fattr) + fattr->gencount = nfs_inc_attr_generation_counter(); + fattr->owner_name = NULL; + fattr->group_name = NULL; ++ fattr->mdsthreshold = NULL; + } + EXPORT_SYMBOL_GPL(nfs_fattr_init); + +@@ -1824,6 +1838,66 @@ static int nfs_inode_finish_partial_attr_update(const struct nfs_fattr *fattr, + return 0; + } + ++static void nfs_ooo_merge(struct nfs_inode *nfsi, ++ u64 start, u64 end) ++{ ++ int i, cnt; ++ ++ if (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER) ++ /* No point merging anything */ ++ return; ++ ++ if (!nfsi->ooo) { ++ nfsi->ooo = kmalloc(sizeof(*nfsi->ooo), GFP_ATOMIC); ++ if (!nfsi->ooo) { ++ nfsi->cache_validity |= NFS_INO_DATA_INVAL_DEFER; ++ return; ++ } ++ nfsi->ooo->cnt = 0; ++ } ++ ++ /* add this range, merging if possible */ ++ cnt = nfsi->ooo->cnt; ++ for (i = 0; i < cnt; i++) { ++ if (end == nfsi->ooo->gap[i].start) ++ end = nfsi->ooo->gap[i].end; ++ else if (start == nfsi->ooo->gap[i].end) ++ start = nfsi->ooo->gap[i].start; ++ else ++ continue; ++ /* Remove 'i' from table and loop to insert the new range */ ++ cnt -= 1; ++ nfsi->ooo->gap[i] = nfsi->ooo->gap[cnt]; ++ i = -1; ++ } ++ if (start != end) { ++ if (cnt >= ARRAY_SIZE(nfsi->ooo->gap)) { ++ nfsi->cache_validity |= NFS_INO_DATA_INVAL_DEFER; ++ kfree(nfsi->ooo); ++ nfsi->ooo = NULL; ++ return; ++ } ++ nfsi->ooo->gap[cnt].start = start; ++ nfsi->ooo->gap[cnt].end = end; ++ cnt += 1; ++ } ++ nfsi->ooo->cnt = cnt; ++} ++ ++static void nfs_ooo_record(struct nfs_inode *nfsi, ++ struct nfs_fattr *fattr) ++{ ++ /* This reply was out-of-order, so record in the ++ * pre/post change id, possibly cancelling ++ * gaps created when iversion was jumpped forward. ++ */ ++ if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) && ++ (fattr->valid & NFS_ATTR_FATTR_PRECHANGE)) ++ nfs_ooo_merge(nfsi, ++ fattr->change_attr, ++ fattr->pre_change_attr); ++} ++ + static int nfs_refresh_inode_locked(struct inode *inode, + struct nfs_fattr *fattr) + { +@@ -1834,8 +1908,12 @@ static int nfs_refresh_inode_locked(struct inode *inode, + + if (attr_cmp > 0 || nfs_inode_finish_partial_attr_update(fattr, inode)) + ret = nfs_update_inode(inode, fattr); +- else if (attr_cmp == 0) +- ret = nfs_check_inode_attributes(inode, fattr); ++ else { ++ nfs_ooo_record(NFS_I(inode), fattr); ++ ++ if (attr_cmp == 0) ++ ret = nfs_check_inode_attributes(inode, fattr); ++ } + + trace_nfs_refresh_inode_exit(inode, ret); + return ret; +@@ -1926,6 +2004,8 @@ int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fa + if (attr_cmp < 0) + return 0; + if ((fattr->valid & NFS_ATTR_FATTR) == 0 || !attr_cmp) { ++ /* Record the pre/post change info before clearing PRECHANGE */ ++ nfs_ooo_record(NFS_I(inode), fattr); + fattr->valid &= ~(NFS_ATTR_FATTR_PRECHANGE + | NFS_ATTR_FATTR_PRESIZE + | NFS_ATTR_FATTR_PREMTIME +@@ -2080,6 +2160,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) + + /* More cache consistency checks */ + if (fattr->valid & NFS_ATTR_FATTR_CHANGE) { ++ if (!have_writers && nfsi->ooo && nfsi->ooo->cnt == 1 && ++ nfsi->ooo->gap[0].end == inode_peek_iversion_raw(inode)) { ++ /* There is one remaining gap that hasn't been ++ * merged into iversion - do that now. ++ */ ++ inode_set_iversion_raw(inode, nfsi->ooo->gap[0].start); ++ kfree(nfsi->ooo); ++ nfsi->ooo = NULL; ++ } + if (!inode_eq_iversion_raw(inode, fattr->change_attr)) { + /* Could it be a race with writeback? */ + if (!(have_writers || have_delegation)) { +@@ -2101,8 +2190,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) + dprintk("NFS: change_attr change on server for file %s/%ld\n", + inode->i_sb->s_id, + inode->i_ino); +- } else if (!have_delegation) +- nfsi->cache_validity |= NFS_INO_DATA_INVAL_DEFER; ++ } else if (!have_delegation) { ++ nfs_ooo_record(nfsi, fattr); ++ nfs_ooo_merge(nfsi, inode_peek_iversion_raw(inode), ++ fattr->change_attr); ++ } + inode_set_iversion_raw(inode, fattr->change_attr); + } + } else { +@@ -2264,6 +2356,7 @@ struct inode *nfs_alloc_inode(struct super_block *sb) + return NULL; + nfsi->flags = 0UL; + nfsi->cache_validity = 0UL; ++ nfsi->ooo = NULL; + #if IS_ENABLED(CONFIG_NFS_V4) + nfsi->nfs4_acl = NULL; + #endif /* CONFIG_NFS_V4 */ +@@ -2276,6 +2369,7 @@ EXPORT_SYMBOL_GPL(nfs_alloc_inode); + + void nfs_free_inode(struct inode *inode) + { ++ kfree(NFS_I(inode)->ooo); + kmem_cache_free(nfs_inode_cachep, NFS_I(inode)); + } + EXPORT_SYMBOL_GPL(nfs_free_inode); +diff --git a/fs/nfs/nfstrace.h b/fs/nfs/nfstrace.h +index 6804ca2efbf997..cbdfe091f56a66 100644 +--- a/fs/nfs/nfstrace.h ++++ b/fs/nfs/nfstrace.h +@@ -162,6 +162,7 @@ DEFINE_NFS_INODE_EVENT_DONE(nfs_writeback_inode_exit); + DEFINE_NFS_INODE_EVENT(nfs_fsync_enter); + DEFINE_NFS_INODE_EVENT_DONE(nfs_fsync_exit); + DEFINE_NFS_INODE_EVENT(nfs_access_enter); ++DEFINE_NFS_INODE_EVENT_DONE(nfs_set_cache_invalid); + + TRACE_EVENT(nfs_access_exit, + TP_PROTO( +diff --git a/fs/nfs/super.c b/fs/nfs/super.c +index 9e672aed359017..f91cb1267b44ec 100644 +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -867,7 +867,15 @@ static int nfs_request_mount(struct fs_context *fc, + * Now ask the mount server to map our export path + * to a file handle. + */ +- status = nfs_mount(&request, ctx->timeo, ctx->retrans); ++ if ((request.protocol == XPRT_TRANSPORT_UDP) == ++ !(ctx->flags & NFS_MOUNT_TCP)) ++ /* ++ * NFS protocol and mount protocol are both UDP or neither UDP ++ * so timeouts are compatible. Use NFS timeouts for MOUNT ++ */ ++ status = nfs_mount(&request, ctx->timeo, ctx->retrans); ++ else ++ status = nfs_mount(&request, NFS_UNSPEC_TIMEO, NFS_UNSPEC_RETRANS); + if (status != 0) { + dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n", + request.hostname, status); +diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c +index c7643409606676..7e097da448cc0f 100644 +--- a/fs/ocfs2/xattr.c ++++ b/fs/ocfs2/xattr.c +@@ -2040,8 +2040,7 @@ static int ocfs2_xa_remove(struct ocfs2_xa_loc *loc, + rc = 0; + ocfs2_xa_cleanup_value_truncate(loc, "removing", + orig_clusters); +- if (rc) +- goto out; ++ goto out; + } + } + +diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c +index 36b7316ef48d38..c6ee7d8439bcc6 100644 +--- a/fs/proc/vmcore.c ++++ b/fs/proc/vmcore.c +@@ -446,10 +446,6 @@ static vm_fault_t mmap_vmcore_fault(struct vm_fault *vmf) + #endif + } + +-static const struct vm_operations_struct vmcore_mmap_ops = { +- .fault = mmap_vmcore_fault, +-}; +- + /** + * vmcore_alloc_buf - allocate buffer in vmalloc memory + * @sizez: size of buffer +@@ -477,6 +473,11 @@ static inline char *vmcore_alloc_buf(size_t size) + * virtually contiguous user-space in ELF layout. + */ + #ifdef CONFIG_MMU ++ ++static const struct vm_operations_struct vmcore_mmap_ops = { ++ .fault = mmap_vmcore_fault, ++}; ++ + /* + * remap_oldmem_pfn_checked - do remap_oldmem_pfn_range replacing all pages + * reported as not being ram with the zero page. +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 6ff6ade229a07b..2ef0e48c89ec48 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -3058,6 +3058,42 @@ static inline void file_end_write(struct file *file) + __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); + } + ++/** ++ * kiocb_start_write - get write access to a superblock for async file io ++ * @iocb: the io context we want to submit the write with ++ * ++ * This is a variant of sb_start_write() for async io submission. ++ * Should be matched with a call to kiocb_end_write(). ++ */ ++static inline void kiocb_start_write(struct kiocb *iocb) ++{ ++ struct inode *inode = file_inode(iocb->ki_filp); ++ ++ sb_start_write(inode->i_sb); ++ /* ++ * Fool lockdep by telling it the lock got released so that it ++ * doesn't complain about the held lock when we return to userspace. ++ */ ++ __sb_writers_release(inode->i_sb, SB_FREEZE_WRITE); ++} ++ ++/** ++ * kiocb_end_write - drop write access to a superblock after async file io ++ * @iocb: the io context we sumbitted the write with ++ * ++ * Should be matched with a call to kiocb_start_write(). ++ */ ++static inline void kiocb_end_write(struct kiocb *iocb) ++{ ++ struct inode *inode = file_inode(iocb->ki_filp); ++ ++ /* ++ * Tell lockdep we inherited freeze protection from submission thread. ++ */ ++ __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); ++ sb_end_write(inode->i_sb); ++} ++ + /* + * This is used for regular files where some users -- especially the + * currently executed binary in a process, previously handled via +diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h +index 886bfa99a6af4c..218e79ba263b2a 100644 +--- a/include/linux/nfs_fs.h ++++ b/include/linux/nfs_fs.h +@@ -189,6 +189,39 @@ struct nfs_inode { + /* Open contexts for shared mmap writes */ + struct list_head open_files; + ++ /* Keep track of out-of-order replies. ++ * The ooo array contains start/end pairs of ++ * numbers from the changeid sequence when ++ * the inode's iversion has been updated. ++ * It also contains end/start pair (i.e. reverse order) ++ * of sections of the changeid sequence that have ++ * been seen in replies from the server. ++ * Normally these should match and when both ++ * A:B and B:A are found in ooo, they are both removed. ++ * And if a reply with A:B causes an iversion update ++ * of A:B, then neither are added. ++ * When a reply has pre_change that doesn't match ++ * iversion, then the changeid pair and any consequent ++ * change in iversion ARE added. Later replies ++ * might fill in the gaps, or possibly a gap is caused ++ * by a change from another client. ++ * When a file or directory is opened, if the ooo table ++ * is not empty, then we assume the gaps were due to ++ * another client and we invalidate the cached data. ++ * ++ * We can only track a limited number of concurrent gaps. ++ * Currently that limit is 16. ++ * We allocate the table on demand. If there is insufficient ++ * memory, then we probably cannot cache the file anyway ++ * so there is no loss. ++ */ ++ struct { ++ int cnt; ++ struct { ++ u64 start, end; ++ } gap[16]; ++ } *ooo; ++ + #if IS_ENABLED(CONFIG_NFS_V4) + struct nfs4_cached_acl *nfs4_acl; + /* NFSv4 state */ +@@ -624,6 +657,20 @@ nfs_fileid_to_ino_t(u64 fileid) + return ino; + } + ++static inline void nfs_ooo_clear(struct nfs_inode *nfsi) ++{ ++ nfsi->cache_validity &= ~NFS_INO_DATA_INVAL_DEFER; ++ kfree(nfsi->ooo); ++ nfsi->ooo = NULL; ++} ++ ++static inline bool nfs_ooo_test(struct nfs_inode *nfsi) ++{ ++ return (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER) || ++ (nfsi->ooo && nfsi->ooo->cnt > 0); ++ ++} ++ + #define NFS_JUKEBOX_RETRY_TIME (5 * HZ) + + +diff --git a/include/linux/tick.h b/include/linux/tick.h +index 9459fef5b85736..9701c571a5cfe9 100644 +--- a/include/linux/tick.h ++++ b/include/linux/tick.h +@@ -252,12 +252,19 @@ static inline void tick_dep_set_task(struct task_struct *tsk, + if (tick_nohz_full_enabled()) + tick_nohz_dep_set_task(tsk, bit); + } ++ + static inline void tick_dep_clear_task(struct task_struct *tsk, + enum tick_dep_bits bit) + { + if (tick_nohz_full_enabled()) + tick_nohz_dep_clear_task(tsk, bit); + } ++ ++static inline void tick_dep_init_task(struct task_struct *tsk) ++{ ++ atomic_set(&tsk->tick_dep_mask, 0); ++} ++ + static inline void tick_dep_set_signal(struct task_struct *tsk, + enum tick_dep_bits bit) + { +@@ -291,6 +298,7 @@ static inline void tick_dep_set_task(struct task_struct *tsk, + enum tick_dep_bits bit) { } + static inline void tick_dep_clear_task(struct task_struct *tsk, + enum tick_dep_bits bit) { } ++static inline void tick_dep_init_task(struct task_struct *tsk) { } + static inline void tick_dep_set_signal(struct task_struct *tsk, + enum tick_dep_bits bit) { } + static inline void tick_dep_clear_signal(struct signal_struct *signal, +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index f1ab0cd987273b..b53099b595cc79 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -2672,17 +2672,12 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, long min) + return ret; + } + +-static void kiocb_end_write(struct io_kiocb *req) ++static void io_req_end_write(struct io_kiocb *req) + { +- /* +- * Tell lockdep we inherited freeze protection from submission +- * thread. +- */ + if (req->flags & REQ_F_ISREG) { +- struct super_block *sb = file_inode(req->file)->i_sb; ++ struct io_rw *rw = &req->rw; + +- __sb_writers_acquired(sb, SB_FREEZE_WRITE); +- sb_end_write(sb); ++ kiocb_end_write(&rw->kiocb); + } + } + +@@ -2742,7 +2737,7 @@ static void io_req_io_end(struct io_kiocb *req) + struct io_rw *rw = &req->rw; + + if (rw->kiocb.ki_flags & IOCB_WRITE) { +- kiocb_end_write(req); ++ io_req_end_write(req); + fsnotify_modify(req->file); + } else { + fsnotify_access(req->file); +@@ -2822,7 +2817,7 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2) + struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb); + + if (kiocb->ki_flags & IOCB_WRITE) +- kiocb_end_write(req); ++ io_req_end_write(req); + if (unlikely(res != req->result)) { + if (res == -EAGAIN && io_rw_should_reissue(req)) { + req->flags |= REQ_F_REISSUE; +@@ -3729,6 +3724,25 @@ static int io_write_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) + return io_prep_rw(req, sqe, WRITE); + } + ++static bool io_kiocb_start_write(struct io_kiocb *req, struct kiocb *kiocb) ++{ ++ struct inode *inode; ++ bool ret; ++ ++ if (!(req->flags & REQ_F_ISREG)) ++ return true; ++ if (!(kiocb->ki_flags & IOCB_NOWAIT)) { ++ kiocb_start_write(kiocb); ++ return true; ++ } ++ ++ inode = file_inode(kiocb->ki_filp); ++ ret = sb_start_write_trylock(inode->i_sb); ++ if (ret) ++ __sb_writers_release(inode->i_sb, SB_FREEZE_WRITE); ++ return ret; ++} ++ + static int io_write(struct io_kiocb *req, unsigned int issue_flags) + { + struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; +@@ -3775,18 +3789,8 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) + if (unlikely(ret)) + goto out_free; + +- /* +- * Open-code file_start_write here to grab freeze protection, +- * which will be released by another thread in +- * io_complete_rw(). Fool lockdep by telling it the lock got +- * released so that it doesn't complain about the held lock when +- * we return to userspace. +- */ +- if (req->flags & REQ_F_ISREG) { +- sb_start_write(file_inode(req->file)->i_sb); +- __sb_writers_release(file_inode(req->file)->i_sb, +- SB_FREEZE_WRITE); +- } ++ if (unlikely(!io_kiocb_start_write(req, kiocb))) ++ goto copy_iov; + kiocb->ki_flags |= IOCB_WRITE; + + if (req->file->f_op->write_iter) +@@ -3822,7 +3826,7 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) + ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false); + if (!ret) { + if (kiocb->ki_flags & IOCB_WRITE) +- kiocb_end_write(req); ++ io_req_end_write(req); + return -EAGAIN; + } + return ret; +diff --git a/kernel/fork.c b/kernel/fork.c +index fec103ae640ffd..23ffcf8a859c5d 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -97,6 +97,7 @@ + #include <linux/scs.h> + #include <linux/io_uring.h> + #include <linux/bpf.h> ++#include <linux/tick.h> + + #include <asm/pgalloc.h> + #include <linux/uaccess.h> +@@ -2126,6 +2127,7 @@ static __latent_entropy struct task_struct *copy_process( + acct_clear_integrals(p); + + posix_cputimers_init(&p->posix_cputimers); ++ tick_dep_init_task(p); + + p->io_context = NULL; + audit_set_context(p, NULL); +diff --git a/kernel/ucount.c b/kernel/ucount.c +index a1d67261501a6d..85d7c19b0b80ad 100644 +--- a/kernel/ucount.c ++++ b/kernel/ucount.c +@@ -315,7 +315,7 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type) + for (iter = ucounts; iter; iter = iter->ns->ucounts) { + long new = atomic_long_add_return(1, &iter->ucount[type]); + if (new < 0 || new > max) +- goto unwind; ++ goto dec_unwind; + if (iter == ucounts) + ret = new; + max = READ_ONCE(iter->ns->ucount_max[type]); +@@ -332,7 +332,6 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type) + dec_unwind: + dec = atomic_long_add_return(-1, &iter->ucount[type]); + WARN_ON_ONCE(dec < 0); +-unwind: + do_dec_rlimit_put_ucounts(ucounts, iter, type); + return 0; + } +diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c +index 8d6bab244c4af2..b2fa4ca2810216 100644 +--- a/net/bridge/br_device.c ++++ b/net/bridge/br_device.c +@@ -38,6 +38,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) + const unsigned char *dest; + u16 vid = 0; + ++ if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) { ++ kfree_skb(skb); ++ return NETDEV_TX_OK; ++ } ++ + memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); + + rcu_read_lock(); +diff --git a/net/core/dst.c b/net/core/dst.c +index 1797c6ebdb8565..6d74b4663085fc 100644 +--- a/net/core/dst.c ++++ b/net/core/dst.c +@@ -108,9 +108,6 @@ struct dst_entry *dst_destroy(struct dst_entry * dst) + child = xdst->child; + } + #endif +- if (!(dst->flags & DST_NOCOUNT)) +- dst_entries_add(dst->ops, -1); +- + if (dst->ops->destroy) + dst->ops->destroy(dst); + dev_put(dst->dev); +@@ -160,6 +157,12 @@ void dst_dev_put(struct dst_entry *dst) + } + EXPORT_SYMBOL(dst_dev_put); + ++static void dst_count_dec(struct dst_entry *dst) ++{ ++ if (!(dst->flags & DST_NOCOUNT)) ++ dst_entries_add(dst->ops, -1); ++} ++ + void dst_release(struct dst_entry *dst) + { + if (dst) { +@@ -169,8 +172,10 @@ void dst_release(struct dst_entry *dst) + if (WARN_ONCE(newrefcnt < 0, "dst_release underflow")) + net_warn_ratelimited("%s: dst:%p refcnt:%d\n", + __func__, dst, newrefcnt); +- if (!newrefcnt) ++ if (!newrefcnt){ ++ dst_count_dec(dst); + call_rcu(&dst->rcu_head, dst_destroy_rcu); ++ } + } + } + EXPORT_SYMBOL(dst_release); +@@ -184,8 +189,10 @@ void dst_release_immediate(struct dst_entry *dst) + if (WARN_ONCE(newrefcnt < 0, "dst_release_immediate underflow")) + net_warn_ratelimited("%s: dst:%p refcnt:%d\n", + __func__, dst, newrefcnt); +- if (!newrefcnt) ++ if (!newrefcnt){ ++ dst_count_dec(dst); + dst_destroy(dst); ++ } + } + } + EXPORT_SYMBOL(dst_release_immediate); +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 13acb84b00c2b0..b5f5ee233b59d2 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -3736,7 +3736,7 @@ enum sctp_disposition sctp_sf_ootb(struct net *net, + } + + ch = (struct sctp_chunkhdr *)ch_end; +- } while (ch_end < skb_tail_pointer(skb)); ++ } while (ch_end + sizeof(*ch) < skb_tail_pointer(skb)); + + if (ootb_shut_ack) + return sctp_sf_shut_8_4_5(net, ep, asoc, type, arg, commands); +diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c +index 19189cf30a72f8..98a229a5cf7773 100644 +--- a/net/vmw_vsock/hyperv_transport.c ++++ b/net/vmw_vsock/hyperv_transport.c +@@ -538,6 +538,7 @@ static void hvs_destruct(struct vsock_sock *vsk) + vmbus_hvsock_device_unregister(chan); + + kfree(hvs); ++ vsk->trans = NULL; + } + + static int hvs_dgram_bind(struct vsock_sock *vsk, struct sockaddr_vm *addr) +diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c +index b490f832439e42..6f67a596b75890 100644 +--- a/net/vmw_vsock/virtio_transport_common.c ++++ b/net/vmw_vsock/virtio_transport_common.c +@@ -812,6 +812,7 @@ void virtio_transport_destruct(struct vsock_sock *vsk) + struct virtio_vsock_sock *vvs = vsk->trans; + + kfree(vvs); ++ vsk->trans = NULL; + } + EXPORT_SYMBOL_GPL(virtio_transport_destruct); + +diff --git a/security/keys/keyring.c b/security/keys/keyring.c +index 5e6a907607530e..1febc2a8abcf66 100644 +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -772,8 +772,11 @@ static bool search_nested_keyrings(struct key *keyring, + for (; slot < ASSOC_ARRAY_FAN_OUT; slot++) { + ptr = READ_ONCE(node->slots[slot]); + +- if (assoc_array_ptr_is_meta(ptr) && node->back_pointer) +- goto descend_to_node; ++ if (assoc_array_ptr_is_meta(ptr)) { ++ if (node->back_pointer || ++ assoc_array_ptr_is_shortcut(ptr)) ++ goto descend_to_node; ++ } + + if (!keyring_ptr_is_keyring(ptr)) + continue; +diff --git a/sound/firewire/tascam/amdtp-tascam.c b/sound/firewire/tascam/amdtp-tascam.c +index 64d66a8025455f..ad185ff3209db3 100644 +--- a/sound/firewire/tascam/amdtp-tascam.c ++++ b/sound/firewire/tascam/amdtp-tascam.c +@@ -244,7 +244,7 @@ int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit, + err = amdtp_stream_init(s, unit, dir, flags, fmt, + process_ctx_payloads, sizeof(struct amdtp_tscm)); + if (err < 0) +- return 0; ++ return err; + + if (dir == AMDTP_OUT_STREAM) { + // Use fixed value for FDF field. +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 3d687d1f7bebb6..8bc0dce59263e1 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -205,8 +205,6 @@ static void cx_auto_shutdown(struct hda_codec *codec) + { + struct conexant_spec *spec = codec->spec; + +- snd_hda_gen_shutup_speakers(codec); +- + /* Turn the problematic codec into D3 to avoid spurious noises + from the internal speaker during (and after) reboot */ + cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, false); +diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c +index 48145f55358802..e3d6258afbac8a 100644 +--- a/sound/soc/stm/stm32_spdifrx.c ++++ b/sound/soc/stm/stm32_spdifrx.c +@@ -947,7 +947,7 @@ static int stm32_spdifrx_remove(struct platform_device *pdev) + { + struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev); + +- if (spdifrx->ctrl_chan) ++ if (!IS_ERR(spdifrx->ctrl_chan)) + dma_release_channel(spdifrx->ctrl_chan); + + if (spdifrx->dmab) +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index ae27e5c57c70e5..4b979218d3b027 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1206,6 +1206,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, + } + break; + case USB_ID(0x1bcf, 0x2283): /* NexiGo N930AF FHD Webcam */ ++ case USB_ID(0x03f0, 0x654a): /* HP 320 FHD Webcam */ + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + usb_audio_info(chip, + "set resolution quirk: cval->res = 16\n"); +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 9d58f8d20f6a5c..e45f3d3e11b434 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -24,6 +24,7 @@ + #include <sound/asoundef.h> + #include <sound/core.h> + #include <sound/control.h> ++#include <sound/hda_verbs.h> + #include <sound/hwdep.h> + #include <sound/info.h> + #include <sound/tlv.h> +@@ -1934,6 +1935,169 @@ static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer) + NULL); + } + ++/* ++ * Dell WD15 dock jack detection ++ * ++ * The WD15 contains an ALC4020 USB audio controller and ALC3263 audio codec ++ * from Realtek. It is a UAC 1 device, and UAC 1 does not support jack ++ * detection. Instead, jack detection works by sending HD Audio commands over ++ * vendor-type USB messages. ++ */ ++ ++#define HDA_VERB_CMD(V, N, D) (((N) << 20) | ((V) << 8) | (D)) ++ ++#define REALTEK_HDA_VALUE 0x0038 ++ ++#define REALTEK_HDA_SET 62 ++#define REALTEK_HDA_GET_OUT 88 ++#define REALTEK_HDA_GET_IN 89 ++ ++#define REALTEK_LINE1 0x1a ++#define REALTEK_VENDOR_REGISTERS 0x20 ++#define REALTEK_HP_OUT 0x21 ++ ++#define REALTEK_CBJ_CTRL2 0x50 ++ ++#define REALTEK_JACK_INTERRUPT_NODE 5 ++ ++#define REALTEK_MIC_FLAG 0x100 ++ ++static int realtek_hda_set(struct snd_usb_audio *chip, u32 cmd) ++{ ++ struct usb_device *dev = chip->dev; ++ __be32 buf = cpu_to_be32(cmd); ++ ++ return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_HDA_SET, ++ USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT, ++ REALTEK_HDA_VALUE, 0, &buf, sizeof(buf)); ++} ++ ++static int realtek_hda_get(struct snd_usb_audio *chip, u32 cmd, u32 *value) ++{ ++ struct usb_device *dev = chip->dev; ++ int err; ++ __be32 buf = cpu_to_be32(cmd); ++ ++ err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_HDA_GET_OUT, ++ USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT, ++ REALTEK_HDA_VALUE, 0, &buf, sizeof(buf)); ++ if (err < 0) ++ return err; ++ err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), REALTEK_HDA_GET_IN, ++ USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_IN, ++ REALTEK_HDA_VALUE, 0, &buf, sizeof(buf)); ++ if (err < 0) ++ return err; ++ ++ *value = be32_to_cpu(buf); ++ return 0; ++} ++ ++static int realtek_ctl_connector_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct usb_mixer_elem_info *cval = kcontrol->private_data; ++ struct snd_usb_audio *chip = cval->head.mixer->chip; ++ u32 pv = kcontrol->private_value; ++ u32 node_id = pv & 0xff; ++ u32 sense; ++ u32 cbj_ctrl2; ++ bool presence; ++ int err; ++ ++ err = snd_usb_lock_shutdown(chip); ++ if (err < 0) ++ return err; ++ err = realtek_hda_get(chip, ++ HDA_VERB_CMD(AC_VERB_GET_PIN_SENSE, node_id, 0), ++ &sense); ++ if (err < 0) ++ goto err; ++ if (pv & REALTEK_MIC_FLAG) { ++ err = realtek_hda_set(chip, ++ HDA_VERB_CMD(AC_VERB_SET_COEF_INDEX, ++ REALTEK_VENDOR_REGISTERS, ++ REALTEK_CBJ_CTRL2)); ++ if (err < 0) ++ goto err; ++ err = realtek_hda_get(chip, ++ HDA_VERB_CMD(AC_VERB_GET_PROC_COEF, ++ REALTEK_VENDOR_REGISTERS, 0), ++ &cbj_ctrl2); ++ if (err < 0) ++ goto err; ++ } ++err: ++ snd_usb_unlock_shutdown(chip); ++ if (err < 0) ++ return err; ++ ++ presence = sense & AC_PINSENSE_PRESENCE; ++ if (pv & REALTEK_MIC_FLAG) ++ presence = presence && (cbj_ctrl2 & 0x0070) == 0x0070; ++ ucontrol->value.integer.value[0] = presence; ++ return 0; ++} ++ ++static const struct snd_kcontrol_new realtek_connector_ctl_ro = { ++ .iface = SNDRV_CTL_ELEM_IFACE_CARD, ++ .name = "", /* will be filled later manually */ ++ .access = SNDRV_CTL_ELEM_ACCESS_READ, ++ .info = snd_ctl_boolean_mono_info, ++ .get = realtek_ctl_connector_get, ++}; ++ ++static int realtek_resume_jack(struct usb_mixer_elem_list *list) ++{ ++ snd_ctl_notify(list->mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, ++ &list->kctl->id); ++ return 0; ++} ++ ++static int realtek_add_jack(struct usb_mixer_interface *mixer, ++ char *name, u32 val) ++{ ++ struct usb_mixer_elem_info *cval; ++ struct snd_kcontrol *kctl; ++ ++ cval = kzalloc(sizeof(*cval), GFP_KERNEL); ++ if (!cval) ++ return -ENOMEM; ++ snd_usb_mixer_elem_init_std(&cval->head, mixer, ++ REALTEK_JACK_INTERRUPT_NODE); ++ cval->head.resume = realtek_resume_jack; ++ cval->val_type = USB_MIXER_BOOLEAN; ++ cval->channels = 1; ++ cval->min = 0; ++ cval->max = 1; ++ kctl = snd_ctl_new1(&realtek_connector_ctl_ro, cval); ++ if (!kctl) { ++ kfree(cval); ++ return -ENOMEM; ++ } ++ kctl->private_value = val; ++ strscpy(kctl->id.name, name, sizeof(kctl->id.name)); ++ kctl->private_free = snd_usb_mixer_elem_free; ++ return snd_usb_mixer_add_control(&cval->head, kctl); ++} ++ ++static int dell_dock_mixer_create(struct usb_mixer_interface *mixer) ++{ ++ int err; ++ ++ err = realtek_add_jack(mixer, "Line Out Jack", REALTEK_LINE1); ++ if (err < 0) ++ return err; ++ err = realtek_add_jack(mixer, "Headphone Jack", REALTEK_HP_OUT); ++ if (err < 0) ++ return err; ++ err = realtek_add_jack(mixer, "Headset Mic Jack", ++ REALTEK_HP_OUT | REALTEK_MIC_FLAG); ++ if (err < 0) ++ return err; ++ return 0; ++} ++ + static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id) + { + u16 buf = 0; +@@ -3272,8 +3436,14 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) + err = snd_soundblaster_e1_switch_create(mixer); + break; + case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */ ++ err = dell_dock_mixer_create(mixer); ++ if (err < 0) ++ break; + err = dell_dock_mixer_init(mixer); + break; ++ case USB_ID(0x0bda, 0x402e): /* Dell WD19 dock */ ++ err = dell_dock_mixer_create(mixer); ++ break; + + case USB_ID(0x2a39, 0x3fd2): /* RME ADI-2 Pro */ + case USB_ID(0x2a39, 0x3fd3): /* RME ADI-2 DAC */ +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 066e972e0e10a2..1d620c2f41a354 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1747,6 +1747,8 @@ struct usb_audio_quirk_flags_table { + + static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + /* Device matches */ ++ DEVICE_FLG(0x03f0, 0x654a, /* HP 320 FHD Webcam */ ++ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x041e, 0x3000, /* Creative SB Extigy */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */ |