diff options
author | Mike Pagano <mpagano@gentoo.org> | 2024-09-08 07:05:11 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2024-09-08 07:05:11 -0400 |
commit | a965b43020306cd4562bffa7f427356df8ab29de (patch) | |
tree | cf92ec02567c98a7ad198c97f60c12d21424619f | |
parent | dtrace patch for 6.10.X (CTF, modules.builtin.objs) p3 (diff) | |
download | linux-patches-6.10-12.tar.gz linux-patches-6.10-12.tar.bz2 linux-patches-6.10-12.zip |
Linux patch 6.10.96.10-12
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1008_linux-6.10.9.patch | 7005 |
2 files changed, 7009 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 574cd30b..20bc0dd9 100644 --- a/0000_README +++ b/0000_README @@ -75,6 +75,10 @@ Patch: 1007_linux-6.10.8.patch From: https://www.kernel.org Desc: Linux 6.10.8 +Patch: 1008_linux-6.10.9.patch +From: https://www.kernel.org +Desc: Linux 6.10.9 + Patch: 1510_fs-enable-link-security-restrictions-by-default.patch From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/ Desc: Enable link security restrictions by default. diff --git a/1008_linux-6.10.9.patch b/1008_linux-6.10.9.patch new file mode 100644 index 00000000..d0922587 --- /dev/null +++ b/1008_linux-6.10.9.patch @@ -0,0 +1,7005 @@ +diff --git a/Documentation/locking/hwspinlock.rst b/Documentation/locking/hwspinlock.rst +index 6f03713b70039..2ffaa3cbd63f1 100644 +--- a/Documentation/locking/hwspinlock.rst ++++ b/Documentation/locking/hwspinlock.rst +@@ -85,6 +85,17 @@ is already free). + + Should be called from a process context (might sleep). + ++:: ++ ++ int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id); ++ ++After verifying the owner of the hwspinlock, release a previously acquired ++hwspinlock; returns 0 on success, or an appropriate error code on failure ++(e.g. -EOPNOTSUPP if the bust operation is not defined for the specific ++hwspinlock). ++ ++Should be called from a process context (might sleep). ++ + :: + + int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout); +diff --git a/Makefile b/Makefile +index 2e5ac6ab3d476..5945cce6b0663 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 10 +-SUBLEVEL = 8 ++SUBLEVEL = 9 + EXTRAVERSION = + NAME = Baby Opossum Posse + +diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts +index 7d03316c279df..9f72e748c8041 100644 +--- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts ++++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts +@@ -173,6 +173,20 @@ vreg_edp_3p3: regulator-edp-3p3 { + regulator-always-on; + regulator-boot-on; + }; ++ ++ vreg_nvme: regulator-nvme { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "VREG_NVME_3P3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&nvme_reg_en>; ++ }; + }; + + &apps_rsc { +@@ -644,6 +658,12 @@ &mdss_dp3_phy { + }; + + &pcie4 { ++ perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; ++ wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; ++ ++ pinctrl-0 = <&pcie4_default>; ++ pinctrl-names = "default"; ++ + status = "okay"; + }; + +@@ -655,6 +675,14 @@ &pcie4_phy { + }; + + &pcie6a { ++ perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; ++ wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; ++ ++ vddpe-3v3-supply = <&vreg_nvme>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie6a_default>; ++ + status = "okay"; + }; + +@@ -804,6 +832,59 @@ kybd_default: kybd-default-state { + bias-disable; + }; + ++ nvme_reg_en: nvme-reg-en-state { ++ pins = "gpio18"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ pcie4_default: pcie4-default-state { ++ clkreq-n-pins { ++ pins = "gpio147"; ++ function = "pcie4_clk"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ perst-n-pins { ++ pins = "gpio146"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ wake-n-pins { ++ pins = "gpio148"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ }; ++ ++ pcie6a_default: pcie6a-default-state { ++ clkreq-n-pins { ++ pins = "gpio153"; ++ function = "pcie6a_clk"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ perst-n-pins { ++ pins = "gpio152"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-down; ++ }; ++ ++ wake-n-pins { ++ pins = "gpio154"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ }; ++ + tpad_default: tpad-default-state { + pins = "gpio3"; + function = "gpio"; +diff --git a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts +index 2d7dedb7e30f2..f90177a662b7d 100644 +--- a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts ++++ b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts +@@ -59,6 +59,20 @@ vreg_edp_3p3: regulator-edp-3p3 { + regulator-always-on; + regulator-boot-on; + }; ++ ++ vreg_nvme: regulator-nvme { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "VREG_NVME_3P3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&nvme_reg_en>; ++ }; + }; + + &apps_rsc { +@@ -455,6 +469,12 @@ &mdss_dp3_phy { + }; + + &pcie4 { ++ perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; ++ wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; ++ ++ pinctrl-0 = <&pcie4_default>; ++ pinctrl-names = "default"; ++ + status = "okay"; + }; + +@@ -466,6 +486,14 @@ &pcie4_phy { + }; + + &pcie6a { ++ perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; ++ wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; ++ ++ vddpe-3v3-supply = <&vreg_nvme>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie6a_default>; ++ + status = "okay"; + }; + +@@ -528,6 +556,59 @@ edp_reg_en: edp-reg-en-state { + drive-strength = <16>; + bias-disable; + }; ++ ++ nvme_reg_en: nvme-reg-en-state { ++ pins = "gpio18"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ pcie4_default: pcie4-default-state { ++ clkreq-n-pins { ++ pins = "gpio147"; ++ function = "pcie4_clk"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ perst-n-pins { ++ pins = "gpio146"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ wake-n-pins { ++ pins = "gpio148"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ }; ++ ++ pcie6a_default: pcie6a-default-state { ++ clkreq-n-pins { ++ pins = "gpio153"; ++ function = "pcie6a_clk"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ ++ perst-n-pins { ++ pins = "gpio152"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-down; ++ }; ++ ++ wake-n-pins { ++ pins = "gpio154"; ++ function = "gpio"; ++ drive-strength = <2>; ++ bias-pull-up; ++ }; ++ }; + }; + + &uart21 { +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index 44df3f11e7319..7b4940530b462 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -462,7 +462,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) + switch (c->x86_model) { + case 0x00 ... 0x2f: + case 0x40 ... 0x4f: +- case 0x70 ... 0x7f: ++ case 0x60 ... 0x7f: + setup_force_cpu_cap(X86_FEATURE_ZEN5); + break; + default: +diff --git a/block/blk-integrity.c b/block/blk-integrity.c +index ccbeb6dfa87a4..8dd8a0126274b 100644 +--- a/block/blk-integrity.c ++++ b/block/blk-integrity.c +@@ -397,8 +397,6 @@ void blk_integrity_unregister(struct gendisk *disk) + if (!bi->profile) + return; + +- /* ensure all bios are off the integrity workqueue */ +- blk_flush_integrity(); + blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue); + memset(bi, 0, sizeof(*bi)); + } +diff --git a/crypto/ecc.c b/crypto/ecc.c +index fe761256e335b..dd48d9928a210 100644 +--- a/crypto/ecc.c ++++ b/crypto/ecc.c +@@ -78,7 +78,7 @@ void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, + /* diff > 0: not enough input bytes: set most significant digits to 0 */ + if (diff > 0) { + ndigits -= diff; +- memset(&out[ndigits - 1], 0, diff * sizeof(u64)); ++ memset(&out[ndigits], 0, diff * sizeof(u64)); + } + + if (o) { +diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c +index 094cf2a2ca3cd..14b1d88997cbe 100644 +--- a/drivers/base/regmap/regmap-spi.c ++++ b/drivers/base/regmap/regmap-spi.c +@@ -122,8 +122,7 @@ static const struct regmap_bus *regmap_get_spi_bus(struct spi_device *spi, + return ERR_PTR(-ENOMEM); + + max_msg_size = spi_max_message_size(spi); +- reg_reserve_size = config->reg_bits / BITS_PER_BYTE +- + config->pad_bits / BITS_PER_BYTE; ++ reg_reserve_size = (config->reg_bits + config->pad_bits) / BITS_PER_BYTE; + if (max_size + reg_reserve_size > max_msg_size) + max_size -= reg_reserve_size; + +diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c +index 3b4f6bfb2f4cf..b87fd127aa433 100644 +--- a/drivers/cpufreq/scmi-cpufreq.c ++++ b/drivers/cpufreq/scmi-cpufreq.c +@@ -63,9 +63,9 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy, + unsigned int target_freq) + { + struct scmi_data *priv = policy->driver_data; ++ unsigned long freq = target_freq; + +- if (!perf_ops->freq_set(ph, priv->domain_id, +- target_freq * 1000, true)) ++ if (!perf_ops->freq_set(ph, priv->domain_id, freq * 1000, true)) + return target_freq; + + return 0; +diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c +index 11ad4ffdce0d4..84f5f30d5dddb 100644 +--- a/drivers/crypto/stm32/stm32-cryp.c ++++ b/drivers/crypto/stm32/stm32-cryp.c +@@ -11,6 +11,7 @@ + #include <crypto/internal/des.h> + #include <crypto/internal/skcipher.h> + #include <crypto/scatterwalk.h> ++#include <linux/bottom_half.h> + #include <linux/clk.h> + #include <linux/delay.h> + #include <linux/err.h> +@@ -1665,8 +1666,11 @@ static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg) + it_mask &= ~IMSCR_OUT; + stm32_cryp_write(cryp, cryp->caps->imsc, it_mask); + +- if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) ++ if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) { ++ local_bh_disable(); + stm32_cryp_finish_req(cryp, 0); ++ local_bh_enable(); ++ } + + return IRQ_HANDLED; + } +diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c +index a8e3615235b8e..041f549c8c990 100644 +--- a/drivers/dma/altera-msgdma.c ++++ b/drivers/dma/altera-msgdma.c +@@ -233,7 +233,7 @@ static void msgdma_free_descriptor(struct msgdma_device *mdev, + struct msgdma_sw_desc *child, *next; + + mdev->desc_free_cnt++; +- list_add_tail(&desc->node, &mdev->free_list); ++ list_move_tail(&desc->node, &mdev->free_list); + list_for_each_entry_safe(child, next, &desc->tx_list, node) { + mdev->desc_free_cnt++; + list_move_tail(&child->node, &mdev->free_list); +@@ -583,17 +583,16 @@ static void msgdma_issue_pending(struct dma_chan *chan) + static void msgdma_chan_desc_cleanup(struct msgdma_device *mdev) + { + struct msgdma_sw_desc *desc, *next; ++ unsigned long irqflags; + + list_for_each_entry_safe(desc, next, &mdev->done_list, node) { + struct dmaengine_desc_callback cb; + +- list_del(&desc->node); +- + dmaengine_desc_get_callback(&desc->async_tx, &cb); + if (dmaengine_desc_callback_valid(&cb)) { +- spin_unlock(&mdev->lock); ++ spin_unlock_irqrestore(&mdev->lock, irqflags); + dmaengine_desc_callback_invoke(&cb, NULL); +- spin_lock(&mdev->lock); ++ spin_lock_irqsave(&mdev->lock, irqflags); + } + + /* Run any dependencies, then free the descriptor */ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c +index c50202215f6b1..9baee7c246b6d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c +@@ -534,7 +534,7 @@ int amdgpu_aca_get_error_data(struct amdgpu_device *adev, struct aca_handle *han + if (aca_handle_is_valid(handle)) + return -EOPNOTSUPP; + +- if (!(BIT(type) & handle->mask)) ++ if ((type < 0) || (!(BIT(type) & handle->mask))) + return 0; + + return __aca_get_error_data(adev, handle, type, err_data, qctx); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c +index a4d65973bf7cf..80771b1480fff 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c +@@ -100,6 +100,7 @@ struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock) + amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); + amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); + amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); ++ res.clock = clock; + + return res; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +index 48ad0c04aa72b..e675e4815650b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +@@ -415,6 +415,10 @@ static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain, + "Called with userptr BO")) + return -EINVAL; + ++ /* bo has been pinned, not need validate it */ ++ if (bo->tbo.pin_count) ++ return 0; ++ + amdgpu_bo_placement_from_domain(bo, domain); + + ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); +@@ -2712,7 +2716,7 @@ static int confirm_valid_user_pages_locked(struct amdkfd_process_info *process_i + + /* keep mem without hmm range at userptr_inval_list */ + if (!mem->range) +- continue; ++ continue; + + /* Only check mem with hmm range associated */ + valid = amdgpu_ttm_tt_get_user_pages_done( +@@ -2957,9 +2961,6 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu * + if (!attachment->is_mapped) + continue; + +- if (attachment->bo_va->base.bo->tbo.pin_count) +- continue; +- + kfd_mem_dmaunmap_attachment(mem, attachment); + ret = update_gpuvm_pte(mem, attachment, &sync_obj); + if (ret) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +index 52b12c1718eb0..7dc102f0bc1d3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +@@ -1484,6 +1484,8 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev, + (u32)le32_to_cpu(*((u32 *)reg_data + j)); + j++; + } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { ++ if (i == 0) ++ continue; + reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = + reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1]; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +index b8280be6225d9..c3d89088123db 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +@@ -213,6 +213,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, + struct amdgpu_firmware_info *ucode; + + id = fw_type_convert(cgs_device, type); ++ if (id >= AMDGPU_UCODE_ID_MAXIMUM) ++ return -EINVAL; ++ + ucode = &adev->firmware.ucode[id]; + if (ucode->fw == NULL) + return -EINVAL; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 89cf9ac6da174..d24d7a1086240 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -5012,7 +5012,8 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) + shadow = vmbo->shadow; + + /* No need to recover an evicted BO */ +- if (shadow->tbo.resource->mem_type != TTM_PL_TT || ++ if (!shadow->tbo.resource || ++ shadow->tbo.resource->mem_type != TTM_PL_TT || + shadow->tbo.resource->start == AMDGPU_BO_INVALID_OFFSET || + shadow->parent->tbo.resource->mem_type != TTM_PL_VRAM) + continue; +@@ -5726,7 +5727,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, + * to put adev in the 1st position. + */ + INIT_LIST_HEAD(&device_list); +- if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) { ++ if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1) && hive) { + list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { + list_add_tail(&tmp_adev->reset_list, &device_list); + if (adev->shutdown) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +index f1b08893765cf..1ea55ee4796e0 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +@@ -1597,7 +1597,7 @@ static int amdgpu_discovery_get_mall_info(struct amdgpu_device *adev) + break; + case 2: + mall_size_per_umc = le32_to_cpu(mall_info->v2.mall_size_per_umc); +- adev->gmc.mall_size = mall_size_per_umc * adev->gmc.num_umc; ++ adev->gmc.mall_size = (uint64_t)mall_size_per_umc * adev->gmc.num_umc; + break; + default: + dev_err(adev->dev, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c +index e71768661ca8d..09a34c7258e22 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c +@@ -179,7 +179,7 @@ static int __amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr, + * Returns the number of bytes read/written; -errno on error. + */ + static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr, +- u8 *eeprom_buf, u16 buf_size, bool read) ++ u8 *eeprom_buf, u32 buf_size, bool read) + { + const struct i2c_adapter_quirks *quirks = i2c_adap->quirks; + u16 limit; +@@ -225,7 +225,7 @@ static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr, + + int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap, + u32 eeprom_addr, u8 *eeprom_buf, +- u16 bytes) ++ u32 bytes) + { + return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes, + true); +@@ -233,7 +233,7 @@ int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap, + + int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap, + u32 eeprom_addr, u8 *eeprom_buf, +- u16 bytes) ++ u32 bytes) + { + return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes, + false); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h +index 6935adb2be1f1..8083b8253ef43 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h +@@ -28,10 +28,10 @@ + + int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap, + u32 eeprom_addr, u8 *eeprom_buf, +- u16 bytes); ++ u32 bytes); + + int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap, + u32 eeprom_addr, u8 *eeprom_buf, +- u16 bytes); ++ u32 bytes); + + #endif +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +index c623e23049d1d..a6ddffbf8b4df 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +@@ -34,6 +34,7 @@ + #include <asm/set_memory.h> + #endif + #include "amdgpu.h" ++#include "amdgpu_reset.h" + #include <drm/drm_drv.h> + #include <drm/ttm/ttm_tt.h> + +@@ -408,7 +409,10 @@ void amdgpu_gart_invalidate_tlb(struct amdgpu_device *adev) + return; + + mb(); +- amdgpu_device_flush_hdp(adev, NULL); ++ if (down_read_trylock(&adev->reset_domain->sem)) { ++ amdgpu_device_flush_hdp(adev, NULL); ++ up_read(&adev->reset_domain->sem); ++ } + for_each_set_bit(i, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS) + amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0); + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +index a0ea6fe8d0606..977cde6d13626 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -623,25 +623,32 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + switch (type) { + case AMD_IP_BLOCK_TYPE_GFX: + ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX, &inst_mask); ++ if (ret) ++ return ret; + count = hweight32(inst_mask); + break; + case AMD_IP_BLOCK_TYPE_SDMA: + ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_SDMA, &inst_mask); ++ if (ret) ++ return ret; + count = hweight32(inst_mask); + break; + case AMD_IP_BLOCK_TYPE_JPEG: + ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_VCN, &inst_mask); ++ if (ret) ++ return ret; + count = hweight32(inst_mask) * adev->jpeg.num_jpeg_rings; + break; + case AMD_IP_BLOCK_TYPE_VCN: + ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_VCN, &inst_mask); ++ if (ret) ++ return ret; + count = hweight32(inst_mask); + break; + default: + return -EINVAL; + } +- if (ret) +- return ret; ++ + return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +index cef9dd0a012b5..b3df27ce76634 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +@@ -1375,6 +1375,9 @@ static void psp_xgmi_reflect_topology_info(struct psp_context *psp, + uint8_t dst_num_links = node_info.num_links; + + hive = amdgpu_get_xgmi_hive(psp->adev); ++ if (WARN_ON(!hive)) ++ return; ++ + list_for_each_entry(mirror_adev, &hive->device_list, gmc.xgmi.head) { + struct psp_xgmi_topology_info *mirror_top_info; + int j; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index 0c4ee06451e9c..7ba90c5974ed3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -2112,6 +2112,7 @@ static void amdgpu_ras_interrupt_umc_handler(struct ras_manager *obj, + /* Let IP handle its data, maybe we need get the output + * from the callback to update the error type/count, etc + */ ++ amdgpu_ras_set_fed(obj->adev, true); + ret = data->cb(obj->adev, &err_data, entry); + /* ue will trigger an interrupt, and in that case + * we need do a reset to recovery the whole system. +@@ -4504,3 +4505,21 @@ int amdgpu_ras_reserve_page(struct amdgpu_device *adev, uint64_t pfn) + + return ret; + } ++ ++void amdgpu_ras_event_log_print(struct amdgpu_device *adev, u64 event_id, ++ const char *fmt, ...) ++{ ++ struct va_format vaf; ++ va_list args; ++ ++ va_start(args, fmt); ++ vaf.fmt = fmt; ++ vaf.va = &args; ++ ++ if (amdgpu_ras_event_id_is_valid(adev, event_id)) ++ dev_printk(KERN_INFO, adev->dev, "{%llu}%pV", event_id, &vaf); ++ else ++ dev_printk(KERN_INFO, adev->dev, "%pV", &vaf); ++ ++ va_end(args); ++} +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +index 7021c4a66fb5e..18d20f6faa5fc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +@@ -67,13 +67,8 @@ struct amdgpu_iv_entry; + /* The high three bits indicates socketid */ + #define AMDGPU_RAS_GET_FEATURES(val) ((val) & ~AMDGPU_RAS_FEATURES_SOCKETID_MASK) + +-#define RAS_EVENT_LOG(_adev, _id, _fmt, ...) \ +-do { \ +- if (amdgpu_ras_event_id_is_valid((_adev), (_id))) \ +- dev_info((_adev)->dev, "{%llu}" _fmt, (_id), ##__VA_ARGS__); \ +- else \ +- dev_info((_adev)->dev, _fmt, ##__VA_ARGS__); \ +-} while (0) ++#define RAS_EVENT_LOG(adev, id, fmt, ...) \ ++ amdgpu_ras_event_log_print((adev), (id), (fmt), ##__VA_ARGS__) + + enum amdgpu_ras_block { + AMDGPU_RAS_BLOCK__UMC = 0, +@@ -956,4 +951,8 @@ int amdgpu_ras_put_poison_req(struct amdgpu_device *adev, + enum amdgpu_ras_block block, uint16_t pasid, + pasid_notify pasid_fn, void *data, uint32_t reset); + ++__printf(3, 4) ++void amdgpu_ras_event_log_print(struct amdgpu_device *adev, u64 event_id, ++ const char *fmt, ...); ++ + #endif +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +index 88ffb15e25ccc..e6344a6b0a9f6 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +@@ -354,7 +354,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, + ring->max_dw = max_dw; + ring->hw_prio = hw_prio; + +- if (!ring->no_scheduler) { ++ if (!ring->no_scheduler && ring->funcs->type < AMDGPU_HW_IP_NUM) { + hw_ip = ring->funcs->type; + num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds; + adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] = +@@ -475,8 +475,9 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) + { + struct amdgpu_ring *ring = file_inode(f)->i_private; +- int r, i; + uint32_t value, result, early[3]; ++ loff_t i; ++ int r; + + if (*pos & 3 || size & 3) + return -EINVAL; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c +index 8ed0e073656f8..41ebe690eeffa 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c +@@ -135,6 +135,10 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __u + mutex_unlock(&psp->securedisplay_context.mutex); + break; + case 2: ++ if (size < 3 || phy_id >= TA_SECUREDISPLAY_MAX_PHY) { ++ dev_err(adev->dev, "Invalid input: %s\n", str); ++ return -EINVAL; ++ } + mutex_lock(&psp->securedisplay_context.mutex); + psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, + TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +index 972a58f0f4924..2359d1d602751 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +@@ -395,6 +395,8 @@ static void amdgpu_virt_add_bad_page(struct amdgpu_device *adev, + else + vram_usage_va = adev->mman.drv_vram_usage_va; + ++ memset(&bp, 0, sizeof(bp)); ++ + if (bp_block_size) { + bp_cnt = bp_block_size / sizeof(uint64_t); + for (bp_idx = 0; bp_idx < bp_cnt; bp_idx++) { +@@ -583,7 +585,7 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev) + } + vf2pf_info->checksum = + amd_sriov_msg_checksum( +- vf2pf_info, vf2pf_info->header.size, 0, 0); ++ vf2pf_info, sizeof(*vf2pf_info), 0, 0); + + return 0; + } +@@ -600,7 +602,7 @@ static void amdgpu_virt_update_vf2pf_work_item(struct work_struct *work) + amdgpu_sriov_runtime(adev) && !amdgpu_in_reset(adev)) { + amdgpu_ras_set_fed(adev, true); + if (amdgpu_reset_domain_schedule(adev->reset_domain, +- &adev->virt.flr_work)) ++ &adev->kfd.reset_work)) + return; + else + dev_err(adev->dev, "Failed to queue work! at %s", __func__); +@@ -975,6 +977,9 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f + return 0; + } + ++ if (amdgpu_device_skip_hw_access(adev)) ++ return 0; ++ + reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[xcc_id]; + scratch_reg0 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg0; + scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1; +@@ -1051,6 +1056,9 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev, + { + u32 rlcg_flag; + ++ if (amdgpu_device_skip_hw_access(adev)) ++ return; ++ + if (!amdgpu_sriov_runtime(adev) && + amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, true, &rlcg_flag)) { + amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag, xcc_id); +@@ -1068,6 +1076,9 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev, + { + u32 rlcg_flag; + ++ if (amdgpu_device_skip_hw_access(adev)) ++ return 0; ++ + if (!amdgpu_sriov_runtime(adev) && + amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, false, &rlcg_flag)) + return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag, xcc_id); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +index 6c30eceec8965..f91cc149d06c8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +@@ -31,6 +31,8 @@ + #include "amdgpu_atomfirmware.h" + #include "atom.h" + ++#define AMDGPU_MAX_SG_SEGMENT_SIZE (2UL << 30) ++ + struct amdgpu_vram_reservation { + u64 start; + u64 size; +@@ -518,9 +520,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man, + else + min_block_size = mgr->default_page_size; + +- /* Limit maximum size to 2GiB due to SG table limitations */ +- size = min(remaining_size, 2ULL << 30); +- ++ size = remaining_size; + if ((size >= (u64)pages_per_block << PAGE_SHIFT) && + !(size & (((u64)pages_per_block << PAGE_SHIFT) - 1))) + min_block_size = (u64)pages_per_block << PAGE_SHIFT; +@@ -660,7 +660,7 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, + amdgpu_res_first(res, offset, length, &cursor); + while (cursor.remaining) { + num_entries++; +- amdgpu_res_next(&cursor, cursor.size); ++ amdgpu_res_next(&cursor, min(cursor.size, AMDGPU_MAX_SG_SEGMENT_SIZE)); + } + + r = sg_alloc_table(*sgt, num_entries, GFP_KERNEL); +@@ -680,7 +680,7 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, + amdgpu_res_first(res, offset, length, &cursor); + for_each_sgtable_sg((*sgt), sg, i) { + phys_addr_t phys = cursor.start + adev->gmc.aper_base; +- size_t size = cursor.size; ++ unsigned long size = min(cursor.size, AMDGPU_MAX_SG_SEGMENT_SIZE); + dma_addr_t addr; + + addr = dma_map_resource(dev, phys, size, dir, +@@ -693,7 +693,7 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, + sg_dma_address(sg) = addr; + sg_dma_len(sg) = size; + +- amdgpu_res_next(&cursor, cursor.size); ++ amdgpu_res_next(&cursor, size); + } + + return 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +index dd2ec48cf5c26..4a14f9c1bfe89 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +@@ -434,6 +434,9 @@ static ssize_t amdgpu_xgmi_show_connected_port_num(struct device *dev, + } + } + ++ if (i == top->num_nodes) ++ return -EINVAL; ++ + for (i = 0; i < top->num_nodes; i++) { + for (j = 0; j < top->nodes[i].num_links; j++) + /* node id in sysfs starts from 1 rather than 0 so +1 here */ +diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +index d4e2aed2efa33..2c9a0aa41e2d5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c ++++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +@@ -501,6 +501,12 @@ static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr, + + if (mode == AMDGPU_AUTO_COMPUTE_PARTITION_MODE) { + mode = __aqua_vanjaram_get_auto_mode(xcp_mgr); ++ if (mode == AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE) { ++ dev_err(adev->dev, ++ "Invalid config, no compatible compute partition mode found, available memory partitions: %d", ++ adev->gmc.num_mem_partitions); ++ return -EINVAL; ++ } + } else if (!__aqua_vanjaram_is_valid_mode(xcp_mgr, mode)) { + dev_err(adev->dev, + "Invalid compute partition mode requested, requested: %s, available memory partitions: %d", +diff --git a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c +index 5dfab80ffff21..cd298556f7a60 100644 +--- a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c ++++ b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c +@@ -70,6 +70,8 @@ static u32 df_v1_7_get_hbm_channel_number(struct amdgpu_device *adev) + int fb_channel_number; + + fb_channel_number = adev->df.funcs->get_fb_channel_number(adev); ++ if (fb_channel_number >= ARRAY_SIZE(df_v1_7_channel_number)) ++ fb_channel_number = 0; + + return df_v1_7_channel_number[fb_channel_number]; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c +index da6bb9022b804..4c8f9772437b5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c ++++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c +@@ -187,7 +187,7 @@ static int jpeg_v4_0_5_hw_init(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + struct amdgpu_ring *ring; +- int r, i; ++ int i, r = 0; + + // TODO: Enable ring test with DPG support + if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) { +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c +index 92432cd2c0c7b..9689e2b5d4e51 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c +@@ -544,7 +544,7 @@ static int mmhub_v1_7_set_clockgating(struct amdgpu_device *adev, + + static void mmhub_v1_7_get_clockgating(struct amdgpu_device *adev, u64 *flags) + { +- int data, data1; ++ u32 data, data1; + + if (amdgpu_sriov_vf(adev)) + *flags = 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c +index 02fd45261399c..a0cc8e218ca1e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c +@@ -671,7 +671,7 @@ static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev, + + static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u64 *flags) + { +- int data, data1; ++ u32 data, data1; + + if (amdgpu_sriov_vf(adev)) + *flags = 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c +index 238ea40c24500..d7c3178254973 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c +@@ -560,7 +560,7 @@ static int mmhub_v3_3_set_clockgating(struct amdgpu_device *adev, + + static void mmhub_v3_3_get_clockgating(struct amdgpu_device *adev, u64 *flags) + { +- int data; ++ u32 data; + + if (amdgpu_sriov_vf(adev)) + *flags = 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c +index 1b7da4aff2b8f..ff1b58e446892 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c +@@ -657,7 +657,7 @@ static int mmhub_v9_4_set_clockgating(struct amdgpu_device *adev, + + static void mmhub_v9_4_get_clockgating(struct amdgpu_device *adev, u64 *flags) + { +- int data, data1; ++ u32 data, data1; + + if (amdgpu_sriov_vf(adev)) + *flags = 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +index 19986ff6a48d7..e326d6f06ca92 100644 +--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c ++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +@@ -387,7 +387,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device + else + WREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl); + +- if (!ras->disable_ras_err_cnt_harvest) { ++ if (ras && !ras->disable_ras_err_cnt_harvest && obj) { + /* + * clear error status after ras_controller_intr + * according to hw team and count ue number +@@ -418,6 +418,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device + /* ras_controller_int is dedicated for nbif ras error, + * not the global interrupt for sync flood + */ ++ amdgpu_ras_set_fed(adev, true); + amdgpu_ras_reset_gpu(adev); + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +index fbd3f7a582c12..55465b8a3df6c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +@@ -229,8 +229,6 @@ static int vcn_v5_0_0_hw_fini(void *handle) + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + if (adev->vcn.harvest_config & (1 << i)) + continue; +- +- amdgpu_irq_put(adev, &adev->vcn.inst[i].irq, 0); + } + + return 0; +@@ -1232,22 +1230,6 @@ static int vcn_v5_0_0_set_powergating_state(void *handle, enum amd_powergating_s + return ret; + } + +-/** +- * vcn_v5_0_0_set_interrupt_state - set VCN block interrupt state +- * +- * @adev: amdgpu_device pointer +- * @source: interrupt sources +- * @type: interrupt types +- * @state: interrupt states +- * +- * Set VCN block interrupt state +- */ +-static int vcn_v5_0_0_set_interrupt_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source, +- unsigned type, enum amdgpu_interrupt_state state) +-{ +- return 0; +-} +- + /** + * vcn_v5_0_0_process_interrupt - process VCN block interrupt + * +@@ -1293,7 +1275,6 @@ static int vcn_v5_0_0_process_interrupt(struct amdgpu_device *adev, struct amdgp + } + + static const struct amdgpu_irq_src_funcs vcn_v5_0_0_irq_funcs = { +- .set = vcn_v5_0_0_set_interrupt_state, + .process = vcn_v5_0_0_process_interrupt, + }; + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h +index 300634b9f6683..a8ca7ecb6d271 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h +@@ -42,8 +42,6 @@ + #define CRAT_OEMTABLEID_LENGTH 8 + #define CRAT_RESERVED_LENGTH 6 + +-#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1) +- + /* Compute Unit flags */ + #define COMPUTE_UNIT_CPU (1 << 0) /* Create Virtual CRAT for CPU */ + #define COMPUTE_UNIT_GPU (1 << 1) /* Create Virtual CRAT for GPU */ +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +index d889e3545120a..6c2f6a26c479c 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +@@ -103,7 +103,8 @@ void debug_event_write_work_handler(struct work_struct *work) + struct kfd_process, + debug_event_workarea); + +- kernel_write(process->dbg_ev_file, &write_data, 1, &pos); ++ if (process->debug_trap_enabled && process->dbg_ev_file) ++ kernel_write(process->dbg_ev_file, &write_data, 1, &pos); + } + + /* update process/device/queue exception status, write to descriptor +@@ -645,6 +646,7 @@ int kfd_dbg_trap_disable(struct kfd_process *target) + else if (target->runtime_info.runtime_state != DEBUG_RUNTIME_STATE_DISABLED) + target->runtime_info.runtime_state = DEBUG_RUNTIME_STATE_ENABLED; + ++ cancel_work_sync(&target->debug_event_workarea); + fput(target->dbg_ev_file); + target->dbg_ev_file = NULL; + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +index e1c21d2506112..78dde62fb04ad 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +@@ -164,7 +164,7 @@ static void event_interrupt_poison_consumption_v9(struct kfd_node *dev, + case SOC15_IH_CLIENTID_SE3SH: + case SOC15_IH_CLIENTID_UTCL2: + block = AMDGPU_RAS_BLOCK__GFX; +- reset = AMDGPU_RAS_GPU_RESET_MODE2_RESET; ++ reset = AMDGPU_RAS_GPU_RESET_MODE1_RESET; + break; + case SOC15_IH_CLIENTID_VMC: + case SOC15_IH_CLIENTID_VMC1: +@@ -177,7 +177,7 @@ static void event_interrupt_poison_consumption_v9(struct kfd_node *dev, + case SOC15_IH_CLIENTID_SDMA3: + case SOC15_IH_CLIENTID_SDMA4: + block = AMDGPU_RAS_BLOCK__SDMA; +- reset = AMDGPU_RAS_GPU_RESET_MODE2_RESET; ++ reset = AMDGPU_RAS_GPU_RESET_MODE1_RESET; + break; + default: + dev_warn(dev->adev->dev, +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +index 4858112f9a53b..a5bdc3258ae54 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +@@ -28,6 +28,7 @@ + #include "kfd_priv.h" + #include "kfd_kernel_queue.h" + #include "amdgpu_amdkfd.h" ++#include "amdgpu_reset.h" + + static inline struct process_queue_node *get_queue_by_qid( + struct process_queue_manager *pqm, unsigned int qid) +@@ -87,8 +88,12 @@ void kfd_process_dequeue_from_device(struct kfd_process_device *pdd) + return; + + dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd); +- if (dev->kfd->shared_resources.enable_mes) +- amdgpu_mes_flush_shader_debugger(dev->adev, pdd->proc_ctx_gpu_addr); ++ if (dev->kfd->shared_resources.enable_mes && ++ down_read_trylock(&dev->adev->reset_domain->sem)) { ++ amdgpu_mes_flush_shader_debugger(dev->adev, ++ pdd->proc_ctx_gpu_addr); ++ up_read(&dev->adev->reset_domain->sem); ++ } + pdd->already_dequeued = true; + } + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +index bc9eb847ecfe7..1d271ecc386f0 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +@@ -958,8 +958,7 @@ static void kfd_update_system_properties(void) + dev = list_last_entry(&topology_device_list, + struct kfd_topology_device, list); + if (dev) { +- sys_props.platform_id = +- (*((uint64_t *)dev->oem_id)) & CRAT_OEMID_64BIT_MASK; ++ sys_props.platform_id = dev->oem_id64; + sys_props.platform_oem = *((uint64_t *)dev->oem_table_id); + sys_props.platform_rev = dev->oem_revision; + } +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h +index 27386ce9a021d..2d1c9d771bef2 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h +@@ -154,7 +154,10 @@ struct kfd_topology_device { + struct attribute attr_gpuid; + struct attribute attr_name; + struct attribute attr_props; +- uint8_t oem_id[CRAT_OEMID_LENGTH]; ++ union { ++ uint8_t oem_id[CRAT_OEMID_LENGTH]; ++ uint64_t oem_id64; ++ }; + uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH]; + uint32_t oem_revision; + }; +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 8d4ad15b8e171..382a41c5b5152 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -594,12 +594,14 @@ static void dm_crtc_high_irq(void *interrupt_params) + if (!acrtc) + return; + +- if (acrtc->wb_pending) { +- if (acrtc->wb_conn) { +- spin_lock_irqsave(&acrtc->wb_conn->job_lock, flags); ++ if (acrtc->wb_conn) { ++ spin_lock_irqsave(&acrtc->wb_conn->job_lock, flags); ++ ++ if (acrtc->wb_pending) { + job = list_first_entry_or_null(&acrtc->wb_conn->job_queue, + struct drm_writeback_job, + list_entry); ++ acrtc->wb_pending = false; + spin_unlock_irqrestore(&acrtc->wb_conn->job_lock, flags); + + if (job) { +@@ -617,8 +619,7 @@ static void dm_crtc_high_irq(void *interrupt_params) + acrtc->dm_irq_params.stream, 0); + } + } else +- DRM_ERROR("%s: no amdgpu_crtc wb_conn\n", __func__); +- acrtc->wb_pending = false; ++ spin_unlock_irqrestore(&acrtc->wb_conn->job_lock, flags); + } + + vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc); +@@ -4129,8 +4130,11 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) + } + + #ifdef AMD_PRIVATE_COLOR +- if (amdgpu_dm_create_color_properties(adev)) ++ if (amdgpu_dm_create_color_properties(adev)) { ++ dc_state_release(state->context); ++ kfree(state); + return -ENOMEM; ++ } + #endif + + r = amdgpu_dm_audio_init(adev); +@@ -4466,7 +4470,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) + + /* There is one primary plane per CRTC */ + primary_planes = dm->dc->caps.max_streams; +- ASSERT(primary_planes <= AMDGPU_MAX_PLANES); ++ if (primary_planes > AMDGPU_MAX_PLANES) { ++ DRM_ERROR("DM: Plane nums out of 6 planes\n"); ++ return -EINVAL; ++ } + + /* + * Initialize primary planes, implicit planes for legacy IOCTLS. +@@ -4584,17 +4591,17 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) + } + } + ++ if (link_cnt > MAX_LINKS) { ++ DRM_ERROR( ++ "KMS: Cannot support more than %d display indexes\n", ++ MAX_LINKS); ++ goto fail; ++ } ++ + /* loops over all connectors on the board */ + for (i = 0; i < link_cnt; i++) { + struct dc_link *link = NULL; + +- if (i > AMDGPU_DM_MAX_DISPLAY_INDEX) { +- DRM_ERROR( +- "KMS: Cannot support more than %d display indexes\n", +- AMDGPU_DM_MAX_DISPLAY_INDEX); +- continue; +- } +- + link = dc_get_link_at_index(dm->dc, i); + + if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) { +@@ -8639,15 +8646,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + bundle->stream_update.vrr_infopacket = + &acrtc_state->stream->vrr_infopacket; + } +- } else if (cursor_update && acrtc_state->active_planes > 0 && +- acrtc_attach->base.state->event) { +- drm_crtc_vblank_get(pcrtc); +- ++ } else if (cursor_update && acrtc_state->active_planes > 0) { + spin_lock_irqsave(&pcrtc->dev->event_lock, flags); +- +- acrtc_attach->event = acrtc_attach->base.state->event; +- acrtc_attach->base.state->event = NULL; +- ++ if (acrtc_attach->base.state->event) { ++ drm_crtc_vblank_get(pcrtc); ++ acrtc_attach->event = acrtc_attach->base.state->event; ++ acrtc_attach->base.state->event = NULL; ++ } + spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); + } + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +index 09519b7abf67b..5c9d32dff8538 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +@@ -50,7 +50,7 @@ + + #define AMDGPU_DM_MAX_NUM_EDP 2 + +-#define AMDGPU_DMUB_NOTIFICATION_MAX 5 ++#define AMDGPU_DMUB_NOTIFICATION_MAX 6 + + #define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID 0x00001A + #define AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40 +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +index bc16db69a6636..3bacf470f7c5b 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +@@ -665,6 +665,9 @@ static enum bp_result get_ss_info_v3_1( + ss_table_header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base, + DATA_TABLES(ASIC_InternalSS_Info), + struct_size(ss_table_header_include, asSpreadSpectrum, 1))); ++ if (!ss_table_header_include) ++ return BP_RESULT_UNSUPPORTED; ++ + table_size = + (le16_to_cpu(ss_table_header_include->sHeader.usStructureSize) + - sizeof(ATOM_COMMON_TABLE_HEADER)) +@@ -1034,6 +1037,8 @@ static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1( + &bp->base, + DATA_TABLES(ASIC_InternalSS_Info), + struct_size(header, asSpreadSpectrum, 1))); ++ if (!header) ++ return result; + + memset(info, 0, sizeof(struct spread_spectrum_info)); + +@@ -1107,6 +1112,8 @@ static enum bp_result get_ss_info_from_ss_info_table( + get_atom_data_table_revision(header, &revision); + + tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info)); ++ if (!tbl) ++ return result; + + if (1 != revision.major || 2 > revision.minor) + return result; +@@ -1634,6 +1641,8 @@ static uint32_t get_ss_entry_number_from_ss_info_tbl( + + tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, + DATA_TABLES(SS_Info)); ++ if (!tbl) ++ return number; + + if (1 != revision.major || 2 > revision.minor) + return number; +@@ -1716,6 +1725,8 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1( + &bp->base, + DATA_TABLES(ASIC_InternalSS_Info), + struct_size(header_include, asSpreadSpectrum, 1))); ++ if (!header_include) ++ return 0; + + size = (le16_to_cpu(header_include->sHeader.usStructureSize) + - sizeof(ATOM_COMMON_TABLE_HEADER)) +@@ -1755,6 +1766,9 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1( + header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base, + DATA_TABLES(ASIC_InternalSS_Info), + struct_size(header_include, asSpreadSpectrum, 1))); ++ if (!header_include) ++ return number; ++ + size = (le16_to_cpu(header_include->sHeader.usStructureSize) - + sizeof(ATOM_COMMON_TABLE_HEADER)) / + sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); +@@ -2551,8 +2565,8 @@ static enum bp_result construct_integrated_info( + + /* Sort voltage table from low to high*/ + if (result == BP_RESULT_OK) { +- uint32_t i; +- uint32_t j; ++ int32_t i; ++ int32_t j; + + for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { + for (j = i; j > 0; --j) { +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index 9fe0020bcb9c2..c8c8587a059d9 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -2920,8 +2920,11 @@ static enum bp_result construct_integrated_info( + struct atom_common_table_header *header; + struct atom_data_revision revision; + +- uint32_t i; +- uint32_t j; ++ int32_t i; ++ int32_t j; ++ ++ if (!info) ++ return result; + + if (info && DATA_TABLES(integratedsysteminfo)) { + header = GET_IMAGE(struct atom_common_table_header, +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +index 5ef0879f6ad9c..aea4bb46856ef 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +@@ -484,7 +484,8 @@ static void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_sm + ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; + + /* Modify previous watermark range to cover up to max */ +- ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; ++ if (num_valid_sets > 0) ++ ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; + } + num_valid_sets++; + } +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 236876d95185b..da237f718dbdd 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1421,6 +1421,7 @@ struct dc *dc_create(const struct dc_init_data *init_params) + return NULL; + + if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) { ++ dc->caps.linear_pitch_alignment = 64; + if (!dc_construct_ctx(dc, init_params)) + goto destruct_dc; + } else { +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +index c6c35037bdb8b..dfdfe22d9e851 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +@@ -37,6 +37,9 @@ + #include "dce/dce_i2c.h" + struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index) + { ++ if (link_index >= MAX_LINKS) ++ return NULL; ++ + return dc->links[link_index]; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +index 8ed599324693e..786b56e96a816 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +@@ -2283,6 +2283,9 @@ void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state) + state->stream_status[stream_idx].mall_stream_config.paired_stream); + otg_master = resource_get_otg_master_for_stream( + &state->res_ctx, state->streams[phantom_stream_idx]); ++ if (!otg_master) ++ continue; ++ + resource_log_pipe_for_stream(dc, state, otg_master, stream_idx); + } + } +@@ -3508,7 +3511,7 @@ static bool acquire_otg_master_pipe_for_stream( + if (pool->dpps[pipe_idx]) + pipe_ctx->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst; + +- if (pipe_idx >= pool->timing_generator_count) { ++ if (pipe_idx >= pool->timing_generator_count && pool->timing_generator_count != 0) { + int tg_inst = pool->timing_generator_count - 1; + + pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst]; +@@ -4669,6 +4672,9 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream, + + enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) + { ++ if (dc == NULL || stream == NULL) ++ return DC_ERROR_UNEXPECTED; ++ + struct dc_link *link = stream->link; + struct timing_generator *tg = dc->res_pool->timing_generators[0]; + enum dc_status res = DC_OK; +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c b/drivers/gpu/drm/amd/display/dc/core/dc_state.c +index 52a1cfc5feed8..502740f6fb2ce 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c +@@ -191,7 +191,7 @@ static void init_state(struct dc *dc, struct dc_state *state) + struct dc_state *dc_state_create(struct dc *dc, struct dc_state_create_params *params) + { + #ifdef CONFIG_DRM_AMD_DC_FP +- struct dml2_configuration_options *dml2_opt = &dc->dml2_options; ++ struct dml2_configuration_options dml2_opt = dc->dml2_options; + #endif + struct dc_state *state = kvzalloc(sizeof(struct dc_state), + GFP_KERNEL); +@@ -205,11 +205,11 @@ struct dc_state *dc_state_create(struct dc *dc, struct dc_state_create_params *p + + #ifdef CONFIG_DRM_AMD_DC_FP + if (dc->debug.using_dml2) { +- dml2_opt->use_clock_dc_limits = false; +- dml2_create(dc, dml2_opt, &state->bw_ctx.dml2); ++ dml2_opt.use_clock_dc_limits = false; ++ dml2_create(dc, &dml2_opt, &state->bw_ctx.dml2); + +- dml2_opt->use_clock_dc_limits = true; +- dml2_create(dc, dml2_opt, &state->bw_ctx.dml2_dc_power_source); ++ dml2_opt.use_clock_dc_limits = true; ++ dml2_create(dc, &dml2_opt, &state->bw_ctx.dml2_dc_power_source); + } + #endif + +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c +index b851fc65f5b7c..5c2d6642633d9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c +@@ -258,7 +258,7 @@ bool dmub_abm_set_pipe(struct abm *abm, + { + union dmub_rb_cmd cmd; + struct dc_context *dc = abm->ctx; +- uint32_t ramping_boundary = 0xFFFF; ++ uint8_t ramping_boundary = 0xFF; + + memset(&cmd, 0, sizeof(cmd)); + cmd.abm_set_pipe.header.type = DMUB_CMD__ABM; +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c +index 09cf54586fd5d..424669632b3b9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c +@@ -102,7 +102,8 @@ static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, + break; + } + +- fsleep(500); ++ /* must *not* be fsleep - this can be called from high irq levels */ ++ udelay(500); + } + + /* assert if max retry hit */ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c +index 994fb732a7cb7..a0d437f0ce2ba 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c +@@ -690,6 +690,9 @@ static void wbscl_set_scaler_filter( + int pair; + uint16_t odd_coef, even_coef; + ++ if (!filter) ++ return; ++ + for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) { + for (pair = 0; pair < tap_pairs; pair++) { + even_coef = filter[phase * taps + 2 * pair]; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c +index 58dd3c5bbff09..4677eb485f945 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c +@@ -940,7 +940,7 @@ static uint8_t dccg35_get_other_enabled_symclk_fe(struct dccg *dccg, uint32_t st + /* for DPMST, this backend could be used by multiple front end. + only disable the backend if this stream_enc_ins is the last active stream enc connected to this back_end*/ + uint8_t i; +- for (i = 0; i != link_enc_inst && i < sizeof(fe_clk_en); i++) { ++ for (i = 0; i != link_enc_inst && i < ARRAY_SIZE(fe_clk_en); i++) { + if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst) + num_enabled_symclk_fe++; + } +diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c +index 0c4a8fe8e5ca6..f1cde1e4265f3 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c +@@ -1453,10 +1453,9 @@ void dcn_bw_update_from_pplib_fclks( + ASSERT(fclks->num_levels); + + vmin0p65_idx = 0; +- vmid0p72_idx = fclks->num_levels - +- (fclks->num_levels > 2 ? 3 : (fclks->num_levels > 1 ? 2 : 1)); +- vnom0p8_idx = fclks->num_levels - (fclks->num_levels > 1 ? 2 : 1); +- vmax0p9_idx = fclks->num_levels - 1; ++ vmid0p72_idx = fclks->num_levels > 2 ? fclks->num_levels - 3 : 0; ++ vnom0p8_idx = fclks->num_levels > 1 ? fclks->num_levels - 2 : 0; ++ vmax0p9_idx = fclks->num_levels > 0 ? fclks->num_levels - 1 : 0; + + dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = + 32 * (fclks->data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c +index e2bcd205aa936..8da97a96b1ceb 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c +@@ -304,6 +304,16 @@ void dcn302_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p + dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; + } + ++ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL]. ++ * MAX_NUM_DPM_LVL is 8. ++ * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES]. ++ * DC__VOLTAGE_STATES is 40. ++ */ ++ if (num_states > MAX_NUM_DPM_LVL) { ++ ASSERT(0); ++ return; ++ } ++ + dcn3_02_soc.num_states = num_states; + for (i = 0; i < dcn3_02_soc.num_states; i++) { + dcn3_02_soc.clock_limits[i].state = i; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c +index 3f02bb806d421..e968870a4b810 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c +@@ -310,6 +310,16 @@ void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p + dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; + } + ++ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL]. ++ * MAX_NUM_DPM_LVL is 8. ++ * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES]. ++ * DC__VOLTAGE_STATES is 40. ++ */ ++ if (num_states > MAX_NUM_DPM_LVL) { ++ ASSERT(0); ++ return; ++ } ++ + dcn3_03_soc.num_states = num_states; + for (i = 0; i < dcn3_03_soc.num_states; i++) { + dcn3_03_soc.clock_limits[i].state = i; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +index f6fe0a64beacf..ebcf5ece209a4 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +@@ -3232,6 +3232,16 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa + dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; + } + ++ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL]. ++ * MAX_NUM_DPM_LVL is 8. ++ * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES]. ++ * DC__VOLTAGE_STATES is 40. ++ */ ++ if (num_states > MAX_NUM_DPM_LVL) { ++ ASSERT(0); ++ return; ++ } ++ + dcn3_2_soc.num_states = num_states; + for (i = 0; i < dcn3_2_soc.num_states; i++) { + dcn3_2_soc.clock_limits[i].state = i; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c +index ff4d795c79664..4297402bdab39 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c +@@ -803,6 +803,16 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p + dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; + } + ++ /* bw_params->clk_table.entries[MAX_NUM_DPM_LVL]. ++ * MAX_NUM_DPM_LVL is 8. ++ * dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES]. ++ * DC__VOLTAGE_STATES is 40. ++ */ ++ if (num_states > MAX_NUM_DPM_LVL) { ++ ASSERT(0); ++ return; ++ } ++ + dcn3_21_soc.num_states = num_states; + for (i = 0; i < dcn3_21_soc.num_states; i++) { + dcn3_21_soc.clock_limits[i].state = i; +diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +index 9a3ded3111952..85453bbb4f9b1 100644 +--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c ++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +@@ -1099,8 +1099,13 @@ void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib) + + // Total Available Pipes Support Check + for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { +- total_pipes += mode_lib->vba.DPPPerPlane[k]; + pipe_idx = get_pipe_idx(mode_lib, k); ++ if (pipe_idx == -1) { ++ ASSERT(0); ++ continue; // skip inactive planes ++ } ++ total_pipes += mode_lib->vba.DPPPerPlane[k]; ++ + if (mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz > 0.0) + mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz; + else +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +index 663c17f52779c..f344478e9bd47 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +@@ -56,7 +56,7 @@ struct gpio_service *dal_gpio_service_create( + struct dc_context *ctx) + { + struct gpio_service *service; +- uint32_t index_of_id; ++ int32_t index_of_id; + + service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL); + +@@ -112,7 +112,7 @@ struct gpio_service *dal_gpio_service_create( + return service; + + failure_2: +- while (index_of_id) { ++ while (index_of_id > 0) { + --index_of_id; + kfree(service->busyness[index_of_id]); + } +@@ -239,6 +239,9 @@ static bool is_pin_busy( + enum gpio_id id, + uint32_t en) + { ++ if (id == GPIO_ID_UNKNOWN) ++ return false; ++ + return service->busyness[id][en]; + } + +@@ -247,6 +250,9 @@ static void set_pin_busy( + enum gpio_id id, + uint32_t en) + { ++ if (id == GPIO_ID_UNKNOWN) ++ return; ++ + service->busyness[id][en] = true; + } + +@@ -255,6 +261,9 @@ static void set_pin_free( + enum gpio_id id, + uint32_t en) + { ++ if (id == GPIO_ID_UNKNOWN) ++ return; ++ + service->busyness[id][en] = false; + } + +@@ -263,7 +272,7 @@ enum gpio_result dal_gpio_service_lock( + enum gpio_id id, + uint32_t en) + { +- if (!service->busyness[id]) { ++ if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_OPEN_FAILED; + } +@@ -277,7 +286,7 @@ enum gpio_result dal_gpio_service_unlock( + enum gpio_id id, + uint32_t en) + { +- if (!service->busyness[id]) { ++ if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_OPEN_FAILED; + } +diff --git a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c +index 99e17c164ce7b..1d3e8f0b915b6 100644 +--- a/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c ++++ b/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c +@@ -128,13 +128,21 @@ static bool hdmi_14_process_transaction( + const uint8_t hdcp_i2c_addr_link_primary = 0x3a; /* 0x74 >> 1*/ + const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/ + struct i2c_command i2c_command; +- uint8_t offset = hdcp_i2c_offsets[message_info->msg_id]; ++ uint8_t offset; + struct i2c_payload i2c_payloads[] = { +- { true, 0, 1, &offset }, ++ { true, 0, 1, 0 }, + /* actual hdcp payload, will be filled later, zeroed for now*/ + { 0 } + }; + ++ if (message_info->msg_id == HDCP_MESSAGE_ID_INVALID) { ++ DC_LOG_ERROR("%s: Invalid message_info msg_id - %d\n", __func__, message_info->msg_id); ++ return false; ++ } ++ ++ offset = hdcp_i2c_offsets[message_info->msg_id]; ++ i2c_payloads[0].data = &offset; ++ + switch (message_info->link) { + case HDCP_LINK_SECONDARY: + i2c_payloads[0].address = hdcp_i2c_addr_link_secondary; +@@ -308,6 +316,11 @@ static bool dp_11_process_transaction( + struct dc_link *link, + struct hdcp_protection_message *message_info) + { ++ if (message_info->msg_id == HDCP_MESSAGE_ID_INVALID) { ++ DC_LOG_ERROR("%s: Invalid message_info msg_id - %d\n", __func__, message_info->msg_id); ++ return false; ++ } ++ + return dpcd_access_helper( + link, + message_info->length, +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c +index 6be846635a798..59f46df015511 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c +@@ -95,8 +95,11 @@ static bool gpu_addr_to_uma(struct dce_hwseq *hwseq, + } else if (hwseq->fb_offset.quad_part <= addr->quad_part && + addr->quad_part <= hwseq->uma_top.quad_part) { + is_in_uma = true; ++ } else if (addr->quad_part == 0) { ++ is_in_uma = false; + } else { + is_in_uma = false; ++ BREAK_TO_DEBUGGER(); + } + return is_in_uma; + } +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c +index 804be977ea47b..3de65a9f0e6f2 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c +@@ -142,7 +142,7 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, + { + union dmub_rb_cmd cmd; + struct dc_context *dc = abm->ctx; +- uint32_t ramping_boundary = 0xFFFF; ++ uint8_t ramping_boundary = 0xFF; + + memset(&cmd, 0, sizeof(cmd)); + cmd.abm_set_pipe.header.type = DMUB_CMD__ABM; +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +index dcced89c07b38..f829ff82797e7 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +@@ -1077,7 +1077,8 @@ void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context, + continue; + + if ((!cur_pipe->plane_state && new_pipe->plane_state) || +- (!cur_pipe->stream && new_pipe->stream)) { ++ (!cur_pipe->stream && new_pipe->stream) || ++ (cur_pipe->stream != new_pipe->stream && new_pipe->stream)) { + // New pipe addition + for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++) { + if (j == PG_HUBP && new_pipe->plane_res.hubp) +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +index d487dfcd219b0..a3df1b55e48b7 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +@@ -534,7 +534,7 @@ static bool decide_fallback_link_setting_max_bw_policy( + struct dc_link_settings *cur, + enum link_training_result training_result) + { +- uint8_t cur_idx = 0, next_idx; ++ uint32_t cur_idx = 0, next_idx; + bool found = false; + + if (training_result == LINK_TRAINING_ABORT) +@@ -914,21 +914,17 @@ bool link_decide_link_settings(struct dc_stream_state *stream, + + memset(link_setting, 0, sizeof(*link_setting)); + +- /* if preferred is specified through AMDDP, use it, if it's enough +- * to drive the mode +- */ +- if (link->preferred_link_setting.lane_count != +- LANE_COUNT_UNKNOWN && +- link->preferred_link_setting.link_rate != +- LINK_RATE_UNKNOWN) { ++ if (dc_is_dp_signal(stream->signal) && ++ link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN && ++ link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) { ++ /* if preferred is specified through AMDDP, use it, if it's enough ++ * to drive the mode ++ */ + *link_setting = link->preferred_link_setting; +- return true; +- } +- +- /* MST doesn't perform link training for now +- * TODO: add MST specific link training routine +- */ +- if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { ++ } else if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { ++ /* MST doesn't perform link training for now ++ * TODO: add MST specific link training routine ++ */ + decide_mst_link_settings(link, link_setting); + } else if (link->connector_signal == SIGNAL_TYPE_EDP) { + /* enable edp link optimization for DSC eDP case */ +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +index 1818970b8eaf7..b8e704dbe9567 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +@@ -914,10 +914,10 @@ static enum dc_status configure_lttpr_mode_non_transparent( + /* Driver does not need to train the first hop. Skip DPCD read and clear + * AUX_RD_INTERVAL for DPTX-to-DPIA hop. + */ +- if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) ++ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && repeater_cnt > 0 && repeater_cnt < MAX_REPEATER_CNT) + link->dpcd_caps.lttpr_caps.aux_rd_interval[--repeater_cnt] = 0; + +- for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) { ++ for (repeater_id = repeater_cnt; repeater_id > 0 && repeater_id < MAX_REPEATER_CNT; repeater_id--) { + aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 + + ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1)); + core_link_read_dpcd( +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c +index a72c898b64fab..584b9295a12af 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c +@@ -165,6 +165,7 @@ static void dpcd_extend_address_range( + *out_address = new_addr_range.start; + *out_size = ADDRESS_RANGE_SIZE(new_addr_range.start, new_addr_range.end); + *out_data = kcalloc(*out_size, sizeof(**out_data), GFP_KERNEL); ++ ASSERT(*out_data); + } + } + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +index 56ee45e12b461..a73d3c6ef4258 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +@@ -1538,6 +1538,7 @@ struct resource_pool *dce83_create_resource_pool( + if (dce83_construct(num_virtual_links, dc, pool)) + return &pool->base; + ++ kfree(pool); + BREAK_TO_DEBUGGER(); + return NULL; + } +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +index d4c3e2754f516..5d1801dce2730 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +@@ -1864,6 +1864,7 @@ static struct clock_source *dcn30_clock_source_create( + return &clk_src->base; + } + ++ kfree(clk_src); + BREAK_TO_DEBUGGER(); + return NULL; + } +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c +index ff50f43e4c000..da73e842c55c8 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c +@@ -1660,8 +1660,8 @@ static struct clock_source *dcn31_clock_source_create( + return &clk_src->base; + } + +- BREAK_TO_DEBUGGER(); + kfree(clk_src); ++ BREAK_TO_DEBUGGER(); + return NULL; + } + +@@ -1821,8 +1821,8 @@ static struct clock_source *dcn30_clock_source_create( + return &clk_src->base; + } + +- BREAK_TO_DEBUGGER(); + kfree(clk_src); ++ BREAK_TO_DEBUGGER(); + return NULL; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +index 2df8a742516c8..915d68cc04e9c 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +@@ -785,6 +785,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .ips2_entry_delay_us = 800, + .disable_dmub_reallow_idle = false, + .static_screen_wait_frames = 2, ++ .disable_timeout = true, + }; + + static const struct dc_panel_config panel_config_defaults = { +@@ -1716,6 +1717,7 @@ static struct clock_source *dcn35_clock_source_create( + return &clk_src->base; + } + ++ kfree(clk_src); + BREAK_TO_DEBUGGER(); + return NULL; + } +diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +index ddf9560ab7722..b7bd0f36125a4 100644 +--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +@@ -1696,6 +1696,7 @@ static struct clock_source *dcn35_clock_source_create( + return &clk_src->base; + } + ++ kfree(clk_src); + BREAK_TO_DEBUGGER(); + return NULL; + } +diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c +index 70e63aeb8f89b..a330827f900c3 100644 +--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c ++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c +@@ -459,7 +459,7 @@ uint32_t dmub_dcn35_get_current_time(struct dmub_srv *dmub) + void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data) + { + uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset; +- uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled; ++ uint32_t is_traceport_enabled, is_cw6_enabled; + + if (!dmub || !diag_data) + return; +@@ -510,9 +510,6 @@ void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti + REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled); + diag_data->is_traceport_en = is_traceport_enabled; + +- REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled); +- diag_data->is_cw0_enabled = is_cw0_enabled; +- + REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); + diag_data->is_cw6_enabled = is_cw6_enabled; + +diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +index 8e9caae7c9559..1b2df97226a3f 100644 +--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c ++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +@@ -156,11 +156,16 @@ static enum mod_hdcp_status read(struct mod_hdcp *hdcp, + uint32_t cur_size = 0; + uint32_t data_offset = 0; + +- if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) { ++ if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID || ++ msg_id >= MOD_HDCP_MESSAGE_ID_MAX) + return MOD_HDCP_STATUS_DDC_FAILURE; +- } + + if (is_dp_hdcp(hdcp)) { ++ int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) / ++ sizeof(hdcp_dpcd_addrs[0]); ++ if (msg_id >= num_dpcd_addrs) ++ return MOD_HDCP_STATUS_DDC_FAILURE; ++ + while (buf_len > 0) { + cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); + success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle, +@@ -175,6 +180,11 @@ static enum mod_hdcp_status read(struct mod_hdcp *hdcp, + data_offset += cur_size; + } + } else { ++ int num_i2c_offsets = sizeof(hdcp_i2c_offsets) / ++ sizeof(hdcp_i2c_offsets[0]); ++ if (msg_id >= num_i2c_offsets) ++ return MOD_HDCP_STATUS_DDC_FAILURE; ++ + success = hdcp->config.ddc.funcs.read_i2c( + hdcp->config.ddc.handle, + HDCP_I2C_ADDR, +@@ -219,11 +229,16 @@ static enum mod_hdcp_status write(struct mod_hdcp *hdcp, + uint32_t cur_size = 0; + uint32_t data_offset = 0; + +- if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) { ++ if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID || ++ msg_id >= MOD_HDCP_MESSAGE_ID_MAX) + return MOD_HDCP_STATUS_DDC_FAILURE; +- } + + if (is_dp_hdcp(hdcp)) { ++ int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) / ++ sizeof(hdcp_dpcd_addrs[0]); ++ if (msg_id >= num_dpcd_addrs) ++ return MOD_HDCP_STATUS_DDC_FAILURE; ++ + while (buf_len > 0) { + cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); + success = hdcp->config.ddc.funcs.write_dpcd( +@@ -239,6 +254,11 @@ static enum mod_hdcp_status write(struct mod_hdcp *hdcp, + data_offset += cur_size; + } + } else { ++ int num_i2c_offsets = sizeof(hdcp_i2c_offsets) / ++ sizeof(hdcp_i2c_offsets[0]); ++ if (msg_id >= num_i2c_offsets) ++ return MOD_HDCP_STATUS_DDC_FAILURE; ++ + hdcp->buf[0] = hdcp_i2c_offsets[msg_id]; + memmove(&hdcp->buf[1], buf, buf_len); + success = hdcp->config.ddc.funcs.write_i2c( +diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +index f531ce1d2b1dc..a71c6117d7e54 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +@@ -99,7 +99,7 @@ static void pp_swctf_delayed_work_handler(struct work_struct *work) + struct amdgpu_device *adev = hwmgr->adev; + struct amdgpu_dpm_thermal *range = + &adev->pm.dpm.thermal; +- uint32_t gpu_temperature, size; ++ uint32_t gpu_temperature, size = sizeof(gpu_temperature); + int ret; + + /* +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +index f4bd8e9357e22..18f00038d8441 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +@@ -30,9 +30,8 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr) + { + int result; + unsigned int i; +- unsigned int table_entries; + struct pp_power_state *state; +- int size; ++ int size, table_entries; + + if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL) + return 0; +@@ -40,15 +39,19 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr) + if (hwmgr->hwmgr_func->get_power_state_size == NULL) + return 0; + +- hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr); ++ table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr); + +- hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) + ++ size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) + + sizeof(struct pp_power_state); + +- if (table_entries == 0 || size == 0) { ++ if (table_entries <= 0 || size == 0) { + pr_warn("Please check whether power state management is supported on this asic\n"); ++ hwmgr->num_ps = 0; ++ hwmgr->ps_size = 0; + return 0; + } ++ hwmgr->num_ps = table_entries; ++ hwmgr->ps_size = size; + + hwmgr->ps = kcalloc(table_entries, size, GFP_KERNEL); + if (hwmgr->ps == NULL) +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +index b1b4c09c34671..b56298d9da98f 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +@@ -73,8 +73,9 @@ static int atomctrl_retrieve_ac_timing( + j++; + } else if ((table->mc_reg_address[i].uc_pre_reg_data & + LOW_NIBBLE_MASK) == DATA_EQU_PREV) { +- table->mc_reg_table_entry[num_ranges].mc_data[i] = +- table->mc_reg_table_entry[num_ranges].mc_data[i-1]; ++ if (i) ++ table->mc_reg_table_entry[num_ranges].mc_data[i] = ++ table->mc_reg_table_entry[num_ranges].mc_data[i-1]; + } + } + num_ranges++; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +index 02ba68d7c6546..f62381b189ade 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +@@ -1036,7 +1036,9 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, + + switch (type) { + case PP_SCLK: +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now); ++ if (ret) ++ return ret; + + /* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */ + if (now == data->gfx_max_freq_limit/100) +@@ -1057,7 +1059,9 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, + i == 2 ? "*" : ""); + break; + case PP_MCLK: +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now); ++ if (ret) ++ return ret; + + for (i = 0; i < mclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", +@@ -1550,7 +1554,10 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr, + } + + if (input[0] == 0) { +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); ++ if (ret) ++ return ret; ++ + if (input[1] < min_freq) { + pr_err("Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", + input[1], min_freq); +@@ -1558,7 +1565,10 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr, + } + smu10_data->gfx_actual_soft_min_freq = input[1]; + } else if (input[0] == 1) { +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); ++ if (ret) ++ return ret; ++ + if (input[1] > max_freq) { + pr_err("Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", + input[1], max_freq); +@@ -1573,10 +1583,15 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr, + pr_err("Input parameter number not correct\n"); + return -EINVAL; + } +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); +- ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); ++ if (ret) ++ return ret; + smu10_data->gfx_actual_soft_min_freq = min_freq; ++ ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); ++ if (ret) ++ return ret; ++ + smu10_data->gfx_actual_soft_max_freq = max_freq; + } else if (type == PP_OD_COMMIT_DPM_TABLE) { + if (size != 0) { +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index f1c369945ac5d..bc27a70a1224f 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -5641,7 +5641,7 @@ static int smu7_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint + mode = input[size]; + switch (mode) { + case PP_SMC_POWER_PROFILE_CUSTOM: +- if (size < 8 && size != 0) ++ if (size != 8 && size != 0) + return -EINVAL; + /* If only CUSTOM is passed in, use the saved values. Check + * that we actually have a CUSTOM profile by ensuring that +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +index eb744401e0567..7e11974208732 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +@@ -584,6 +584,7 @@ static int smu8_init_uvd_limit(struct pp_hwmgr *hwmgr) + hwmgr->dyn_state.uvd_clock_voltage_dependency_table; + unsigned long clock = 0; + uint32_t level; ++ int ret; + + if (NULL == table || table->count <= 0) + return -EINVAL; +@@ -591,7 +592,9 @@ static int smu8_init_uvd_limit(struct pp_hwmgr *hwmgr) + data->uvd_dpm.soft_min_clk = 0; + data->uvd_dpm.hard_min_clk = 0; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxUvdLevel, &level); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxUvdLevel, &level); ++ if (ret) ++ return ret; + + if (level < table->count) + clock = table->entries[level].vclk; +@@ -611,6 +614,7 @@ static int smu8_init_vce_limit(struct pp_hwmgr *hwmgr) + hwmgr->dyn_state.vce_clock_voltage_dependency_table; + unsigned long clock = 0; + uint32_t level; ++ int ret; + + if (NULL == table || table->count <= 0) + return -EINVAL; +@@ -618,7 +622,9 @@ static int smu8_init_vce_limit(struct pp_hwmgr *hwmgr) + data->vce_dpm.soft_min_clk = 0; + data->vce_dpm.hard_min_clk = 0; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxEclkLevel, &level); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxEclkLevel, &level); ++ if (ret) ++ return ret; + + if (level < table->count) + clock = table->entries[level].ecclk; +@@ -638,6 +644,7 @@ static int smu8_init_acp_limit(struct pp_hwmgr *hwmgr) + hwmgr->dyn_state.acp_clock_voltage_dependency_table; + unsigned long clock = 0; + uint32_t level; ++ int ret; + + if (NULL == table || table->count <= 0) + return -EINVAL; +@@ -645,7 +652,9 @@ static int smu8_init_acp_limit(struct pp_hwmgr *hwmgr) + data->acp_dpm.soft_min_clk = 0; + data->acp_dpm.hard_min_clk = 0; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxAclkLevel, &level); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxAclkLevel, &level); ++ if (ret) ++ return ret; + + if (level < table->count) + clock = table->entries[level].acpclk; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +index f4acdb2267416..ff605063d7ef0 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +@@ -354,13 +354,13 @@ static int vega10_odn_initial_default_setting(struct pp_hwmgr *hwmgr) + return 0; + } + +-static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) ++static int vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) + { + struct vega10_hwmgr *data = hwmgr->backend; +- int i; + uint32_t sub_vendor_id, hw_revision; + uint32_t top32, bottom32; + struct amdgpu_device *adev = hwmgr->adev; ++ int ret, i; + + vega10_initialize_power_tune_defaults(hwmgr); + +@@ -485,9 +485,12 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) + if (data->registry_data.vr0hot_enabled) + data->smu_features[GNLD_VR0HOT].supported = true; + +- smum_send_msg_to_smc(hwmgr, ++ ret = smum_send_msg_to_smc(hwmgr, + PPSMC_MSG_GetSmuVersion, + &hwmgr->smu_version); ++ if (ret) ++ return ret; ++ + /* ACG firmware has major version 5 */ + if ((hwmgr->smu_version & 0xff000000) == 0x5000000) + data->smu_features[GNLD_ACG].supported = true; +@@ -505,10 +508,16 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) + data->smu_features[GNLD_PCC_LIMIT].supported = true; + + /* Get the SN to turn into a Unique ID */ +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); ++ if (ret) ++ return ret; ++ ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); ++ if (ret) ++ return ret; + + adev->unique_id = ((uint64_t)bottom32 << 32) | top32; ++ return 0; + } + + #ifdef PPLIB_VEGA10_EVV_SUPPORT +@@ -882,7 +891,9 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + + vega10_set_features_platform_caps(hwmgr); + +- vega10_init_dpm_defaults(hwmgr); ++ result = vega10_init_dpm_defaults(hwmgr); ++ if (result) ++ return result; + + #ifdef PPLIB_VEGA10_EVV_SUPPORT + /* Get leakage voltage based on leakage ID. */ +@@ -2350,15 +2361,20 @@ static int vega10_acg_enable(struct pp_hwmgr *hwmgr) + { + struct vega10_hwmgr *data = hwmgr->backend; + uint32_t agc_btc_response; ++ int ret; + + if (data->smu_features[GNLD_ACG].supported) { + if (0 == vega10_enable_smc_features(hwmgr, true, + data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_bitmap)) + data->smu_features[GNLD_DPM_PREFETCHER].enabled = true; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitializeAcg, NULL); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitializeAcg, NULL); ++ if (ret) ++ return ret; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc, &agc_btc_response); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc, &agc_btc_response); ++ if (ret) ++ agc_btc_response = 0; + + if (1 == agc_btc_response) { + if (1 == data->acg_loop_state) +@@ -2571,8 +2587,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) + } + } + +- pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC, ++ result = pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC, + VOLTAGE_OBJ_SVID2, &voltage_table); ++ PP_ASSERT_WITH_CODE(!result, ++ "Failed to get voltage table!", ++ return result); + pp_table->MaxVidStep = voltage_table.max_vid_step; + + pp_table->GfxDpmVoltageMode = +@@ -3910,11 +3929,14 @@ static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr, + uint32_t *query) + { + uint32_t value; ++ int ret; + + if (!query) + return -EINVAL; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr, &value); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr, &value); ++ if (ret) ++ return ret; + + /* SMC returning actual watts, keep consistent with legacy asics, low 8 bit as 8 fractional bits */ + *query = value << 8; +@@ -4810,14 +4832,16 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width; + PPTable_t *pptable = &(data->smc_state_table.pp_table); + +- int i, now, size = 0, count = 0; ++ int i, ret, now, size = 0, count = 0; + + switch (type) { + case PP_SCLK: + if (data->registry_data.sclk_dpm_key_disabled) + break; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex, &now); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex, &now); ++ if (ret) ++ break; + + if (hwmgr->pp_one_vf && + (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)) +@@ -4833,7 +4857,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + if (data->registry_data.mclk_dpm_key_disabled) + break; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now); ++ if (ret) ++ break; + + for (i = 0; i < mclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", +@@ -4844,7 +4870,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + if (data->registry_data.socclk_dpm_key_disabled) + break; + +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now); ++ if (ret) ++ break; + + for (i = 0; i < soc_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", +@@ -4855,8 +4883,10 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, + if (data->registry_data.dcefclk_dpm_key_disabled) + break; + +- smum_send_msg_to_smc_with_parameter(hwmgr, ++ ret = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now); ++ if (ret) ++ break; + + for (i = 0; i < dcef_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +index c223e3a6bfca5..10fd4e9f016cd 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +@@ -293,12 +293,12 @@ static int vega12_set_features_platform_caps(struct pp_hwmgr *hwmgr) + return 0; + } + +-static void vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr) ++static int vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr) + { + struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); + struct amdgpu_device *adev = hwmgr->adev; + uint32_t top32, bottom32; +- int i; ++ int i, ret; + + data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id = + FEATURE_DPM_PREFETCHER_BIT; +@@ -364,10 +364,16 @@ static void vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr) + } + + /* Get the SN to turn into a Unique ID */ +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); ++ if (ret) ++ return ret; ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); ++ if (ret) ++ return ret; + + adev->unique_id = ((uint64_t)bottom32 << 32) | top32; ++ ++ return 0; + } + + static int vega12_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr) +@@ -410,7 +416,11 @@ static int vega12_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + + vega12_set_features_platform_caps(hwmgr); + +- vega12_init_dpm_defaults(hwmgr); ++ result = vega12_init_dpm_defaults(hwmgr); ++ if (result) { ++ pr_err("%s failed\n", __func__); ++ return result; ++ } + + /* Parse pptable data read from VBIOS */ + vega12_set_private_data_based_on_pptable(hwmgr); +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +index f9efb0bad8072..baf251fe5d828 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +@@ -328,12 +328,12 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr) + return 0; + } + +-static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr) ++static int vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr) + { + struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); + struct amdgpu_device *adev = hwmgr->adev; + uint32_t top32, bottom32; +- int i; ++ int i, ret; + + data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id = + FEATURE_DPM_PREFETCHER_BIT; +@@ -404,10 +404,17 @@ static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr) + } + + /* Get the SN to turn into a Unique ID */ +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); +- smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); ++ if (ret) ++ return ret; ++ ++ ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); ++ if (ret) ++ return ret; + + adev->unique_id = ((uint64_t)bottom32 << 32) | top32; ++ ++ return 0; + } + + static int vega20_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr) +@@ -427,6 +434,7 @@ static int vega20_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + { + struct vega20_hwmgr *data; + struct amdgpu_device *adev = hwmgr->adev; ++ int result; + + data = kzalloc(sizeof(struct vega20_hwmgr), GFP_KERNEL); + if (data == NULL) +@@ -452,8 +460,11 @@ static int vega20_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + + vega20_set_features_platform_caps(hwmgr); + +- vega20_init_dpm_defaults(hwmgr); +- ++ result = vega20_init_dpm_defaults(hwmgr); ++ if (result) { ++ pr_err("%s failed\n", __func__); ++ return result; ++ } + /* Parse pptable data read from VBIOS */ + vega20_set_private_data_based_on_pptable(hwmgr); + +@@ -4091,9 +4102,11 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui + if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { + struct vega20_hwmgr *data = + (struct vega20_hwmgr *)(hwmgr->backend); +- if (size == 0 && !data->is_custom_profile_set) ++ ++ if (size != 10 && size != 0) + return -EINVAL; +- if (size < 10 && size != 0) ++ ++ if (size == 0 && !data->is_custom_profile_set) + return -EINVAL; + + result = vega20_get_activity_monitor_coeff(hwmgr, +@@ -4155,6 +4168,8 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui + activity_monitor.Fclk_PD_Data_error_coeff = input[8]; + activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9]; + break; ++ default: ++ return -EINVAL; + } + + result = vega20_set_activity_monitor_coeff(hwmgr, +diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c +index a70d738966490..f9c0f117725dd 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c +@@ -130,13 +130,17 @@ int vega10_get_enabled_smc_features(struct pp_hwmgr *hwmgr, + uint64_t *features_enabled) + { + uint32_t enabled_features; ++ int ret; + + if (features_enabled == NULL) + return -EINVAL; + +- smum_send_msg_to_smc(hwmgr, ++ ret = smum_send_msg_to_smc(hwmgr, + PPSMC_MSG_GetEnabledSmuFeatures, + &enabled_features); ++ if (ret) ++ return ret; ++ + *features_enabled = enabled_features; + + return 0; +diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +index d9700a3f28d2f..e58220a7ee2f7 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h ++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +@@ -298,5 +298,9 @@ int smu_v13_0_enable_uclk_shadow(struct smu_context *smu, bool enable); + + int smu_v13_0_set_wbrf_exclusion_ranges(struct smu_context *smu, + struct freq_band_range *exclusion_ranges); ++ ++int smu_v13_0_get_boot_freq_by_index(struct smu_context *smu, ++ enum smu_clk_type clk_type, ++ uint32_t *value); + #endif + #endif +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +index 6d334a2aff672..623f6052f97ed 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +@@ -1416,6 +1416,9 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu, + + if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) && + (smu->smc_fw_version >= 0x360d00)) { ++ if (size != 10) ++ return -EINVAL; ++ + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, + WORKLOAD_PPLIB_CUSTOM_BIT, +@@ -1449,6 +1452,8 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu, + activity_monitor.Mem_PD_Data_error_coeff = input[8]; + activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; + break; ++ default: ++ return -EINVAL; + } + + ret = smu_cmn_update_table(smu, +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +index 5a68d365967f7..01039cdd456b0 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +@@ -1219,19 +1219,22 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu, + value); + } + +-static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type) ++static int navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type) + { + PPTable_t *pptable = smu->smu_table.driver_pptable; + DpmDescriptor_t *dpm_desc = NULL; +- uint32_t clk_index = 0; ++ int clk_index = 0; + + clk_index = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_CLK, + clk_type); ++ if (clk_index < 0) ++ return clk_index; ++ + dpm_desc = &pptable->DpmDescriptor[clk_index]; + + /* 0 - Fine grained DPM, 1 - Discrete DPM */ +- return dpm_desc->SnapToDiscrete == 0; ++ return dpm_desc->SnapToDiscrete == 0 ? 1 : 0; + } + + static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap) +@@ -1287,7 +1290,11 @@ static int navi10_emit_clk_levels(struct smu_context *smu, + if (ret) + return ret; + +- if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { ++ ret = navi10_is_support_fine_grained_dpm(smu, clk_type); ++ if (ret < 0) ++ return ret; ++ ++ if (!ret) { + for (i = 0; i < count; i++) { + ret = smu_v11_0_get_dpm_freq_by_index(smu, + clk_type, i, &value); +@@ -1496,7 +1503,11 @@ static int navi10_print_clk_levels(struct smu_context *smu, + if (ret) + return size; + +- if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { ++ ret = navi10_is_support_fine_grained_dpm(smu, clk_type); ++ if (ret < 0) ++ return ret; ++ ++ if (!ret) { + for (i = 0; i < count; i++) { + ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value); + if (ret) +@@ -1665,7 +1676,11 @@ static int navi10_force_clk_levels(struct smu_context *smu, + case SMU_UCLK: + case SMU_FCLK: + /* There is only 2 levels for fine grained DPM */ +- if (navi10_is_support_fine_grained_dpm(smu, clk_type)) { ++ ret = navi10_is_support_fine_grained_dpm(smu, clk_type); ++ if (ret < 0) ++ return ret; ++ ++ if (ret) { + soft_max_level = (soft_max_level >= 1 ? 1 : 0); + soft_min_level = (soft_min_level >= 1 ? 1 : 0); + } +@@ -2006,6 +2021,8 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u + } + + if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { ++ if (size != 10) ++ return -EINVAL; + + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, +@@ -2049,6 +2066,8 @@ static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, u + activity_monitor.Mem_PD_Data_error_coeff = input[8]; + activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; + break; ++ default: ++ return -EINVAL; + } + + ret = smu_cmn_update_table(smu, +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +index e426f457a017f..d5a21d7836cc6 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +@@ -1722,6 +1722,8 @@ static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long * + } + + if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { ++ if (size != 10) ++ return -EINVAL; + + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, +@@ -1765,6 +1767,8 @@ static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long * + activity_monitor->Mem_PD_Data_error_coeff = input[8]; + activity_monitor->Mem_PD_Data_error_rate_coeff = input[9]; + break; ++ default: ++ return -EINVAL; + } + + ret = smu_cmn_update_table(smu, +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +index 379e44eb0019d..22737b11b1bfb 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +@@ -976,6 +976,18 @@ static int vangogh_get_dpm_ultimate_freq(struct smu_context *smu, + } + } + if (min) { ++ ret = vangogh_get_profiling_clk_mask(smu, ++ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK, ++ NULL, ++ NULL, ++ &mclk_mask, ++ &fclk_mask, ++ &soc_mask); ++ if (ret) ++ goto failed; ++ ++ vclk_mask = dclk_mask = 0; ++ + switch (clk_type) { + case SMU_UCLK: + case SMU_MCLK: +@@ -2450,6 +2462,8 @@ static u32 vangogh_set_gfxoff_residency(struct smu_context *smu, bool start) + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_LogGfxOffResidency, + start, &residency); ++ if (ret) ++ return ret; + + if (!start) + adev->gfx.gfx_off_residency = residency; +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +index ce941fbb9cfbe..a22eb6bbb05ed 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +@@ -1886,7 +1886,8 @@ static int aldebaran_mode2_reset(struct smu_context *smu) + + index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, + SMU_MSG_GfxDeviceDriverReset); +- ++ if (index < 0 ) ++ return -EINVAL; + mutex_lock(&smu->message_lock); + if (smu->smc_fw_version >= 0x00441400) { + ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index, SMU_RESET_MODE_2); +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +index b63ad9cb24bfd..933fe93c8d1e6 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +@@ -1559,22 +1559,9 @@ int smu_v13_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type c + uint32_t clock_limit; + + if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) { +- switch (clk_type) { +- case SMU_MCLK: +- case SMU_UCLK: +- clock_limit = smu->smu_table.boot_values.uclk; +- break; +- case SMU_GFXCLK: +- case SMU_SCLK: +- clock_limit = smu->smu_table.boot_values.gfxclk; +- break; +- case SMU_SOCCLK: +- clock_limit = smu->smu_table.boot_values.socclk; +- break; +- default: +- clock_limit = 0; +- break; +- } ++ ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit); ++ if (ret) ++ return ret; + + /* clock in Mhz unit */ + if (min) +@@ -1894,6 +1881,40 @@ int smu_v13_0_set_power_source(struct smu_context *smu, + NULL); + } + ++int smu_v13_0_get_boot_freq_by_index(struct smu_context *smu, ++ enum smu_clk_type clk_type, ++ uint32_t *value) ++{ ++ int ret = 0; ++ ++ switch (clk_type) { ++ case SMU_MCLK: ++ case SMU_UCLK: ++ *value = smu->smu_table.boot_values.uclk; ++ break; ++ case SMU_FCLK: ++ *value = smu->smu_table.boot_values.fclk; ++ break; ++ case SMU_GFXCLK: ++ case SMU_SCLK: ++ *value = smu->smu_table.boot_values.gfxclk; ++ break; ++ case SMU_SOCCLK: ++ *value = smu->smu_table.boot_values.socclk; ++ break; ++ case SMU_VCLK: ++ *value = smu->smu_table.boot_values.vclk; ++ break; ++ case SMU_DCLK: ++ *value = smu->smu_table.boot_values.dclk; ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ + int smu_v13_0_get_dpm_freq_by_index(struct smu_context *smu, + enum smu_clk_type clk_type, uint16_t level, + uint32_t *value) +@@ -1905,7 +1926,7 @@ int smu_v13_0_get_dpm_freq_by_index(struct smu_context *smu, + return -EINVAL; + + if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) +- return 0; ++ return smu_v13_0_get_boot_freq_by_index(smu, clk_type, value); + + clk_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_CLK, +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +index 1e09d5f2d82fe..f7e756ca36dcd 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +@@ -2495,6 +2495,9 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, + } + + if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { ++ if (size != 9) ++ return -EINVAL; ++ + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, + WORKLOAD_PPLIB_CUSTOM_BIT, +@@ -2526,6 +2529,8 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, + activity_monitor->Fclk_PD_Data_error_coeff = input[7]; + activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8]; + break; ++ default: ++ return -EINVAL; + } + + ret = smu_cmn_update_table(smu, +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +index b6257f34a7c65..b081ae3e8f43c 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +@@ -758,31 +758,9 @@ static int smu_v13_0_4_get_dpm_ultimate_freq(struct smu_context *smu, + int ret = 0; + + if (!smu_v13_0_4_clk_dpm_is_enabled(smu, clk_type)) { +- switch (clk_type) { +- case SMU_MCLK: +- case SMU_UCLK: +- clock_limit = smu->smu_table.boot_values.uclk; +- break; +- case SMU_FCLK: +- clock_limit = smu->smu_table.boot_values.fclk; +- break; +- case SMU_GFXCLK: +- case SMU_SCLK: +- clock_limit = smu->smu_table.boot_values.gfxclk; +- break; +- case SMU_SOCCLK: +- clock_limit = smu->smu_table.boot_values.socclk; +- break; +- case SMU_VCLK: +- clock_limit = smu->smu_table.boot_values.vclk; +- break; +- case SMU_DCLK: +- clock_limit = smu->smu_table.boot_values.dclk; +- break; +- default: +- clock_limit = 0; +- break; +- } ++ ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit); ++ if (ret) ++ return ret; + + /* clock in Mhz unit */ + if (min) +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c +index 218f209c37756..59854465d7115 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c +@@ -733,31 +733,9 @@ static int smu_v13_0_5_get_dpm_ultimate_freq(struct smu_context *smu, + int ret = 0; + + if (!smu_v13_0_5_clk_dpm_is_enabled(smu, clk_type)) { +- switch (clk_type) { +- case SMU_MCLK: +- case SMU_UCLK: +- clock_limit = smu->smu_table.boot_values.uclk; +- break; +- case SMU_FCLK: +- clock_limit = smu->smu_table.boot_values.fclk; +- break; +- case SMU_GFXCLK: +- case SMU_SCLK: +- clock_limit = smu->smu_table.boot_values.gfxclk; +- break; +- case SMU_SOCCLK: +- clock_limit = smu->smu_table.boot_values.socclk; +- break; +- case SMU_VCLK: +- clock_limit = smu->smu_table.boot_values.vclk; +- break; +- case SMU_DCLK: +- clock_limit = smu->smu_table.boot_values.dclk; +- break; +- default: +- clock_limit = 0; +- break; +- } ++ ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit); ++ if (ret) ++ return ret; + + /* clock in Mhz unit */ + if (min) +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +index 4d3eca2fc3f11..f4469d001d7c4 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +@@ -2333,6 +2333,8 @@ static int smu_v13_0_6_mode2_reset(struct smu_context *smu) + + index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, + SMU_MSG_GfxDeviceDriverReset); ++ if (index < 0) ++ return index; + + mutex_lock(&smu->message_lock); + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +index e996a0a4d33e1..4f98869e02848 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +@@ -2450,6 +2450,8 @@ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *inp + } + + if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { ++ if (size != 8) ++ return -EINVAL; + + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, +@@ -2478,6 +2480,8 @@ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *inp + activity_monitor->Fclk_MinActiveFreq = input[6]; + activity_monitor->Fclk_BoosterFreq = input[7]; + break; ++ default: ++ return -EINVAL; + } + + ret = smu_cmn_update_table(smu, +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +index d8bcf765a8038..5917c88cc87d6 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +@@ -867,31 +867,9 @@ static int yellow_carp_get_dpm_ultimate_freq(struct smu_context *smu, + int ret = 0; + + if (!yellow_carp_clk_dpm_is_enabled(smu, clk_type)) { +- switch (clk_type) { +- case SMU_MCLK: +- case SMU_UCLK: +- clock_limit = smu->smu_table.boot_values.uclk; +- break; +- case SMU_FCLK: +- clock_limit = smu->smu_table.boot_values.fclk; +- break; +- case SMU_GFXCLK: +- case SMU_SCLK: +- clock_limit = smu->smu_table.boot_values.gfxclk; +- break; +- case SMU_SOCCLK: +- clock_limit = smu->smu_table.boot_values.socclk; +- break; +- case SMU_VCLK: +- clock_limit = smu->smu_table.boot_values.vclk; +- break; +- case SMU_DCLK: +- clock_limit = smu->smu_table.boot_values.dclk; +- break; +- default: +- clock_limit = 0; +- break; +- } ++ ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit); ++ if (ret) ++ return ret; + + /* clock in Mhz unit */ + if (min) +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +index 90703f4542aba..06b65159f7b4a 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +@@ -1364,6 +1364,9 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu, + } + + if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { ++ if (size != 9) ++ return -EINVAL; ++ + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, + WORKLOAD_PPLIB_CUSTOM_BIT, +@@ -1395,6 +1398,8 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu, + activity_monitor->Fclk_PD_Data_error_coeff = input[7]; + activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8]; + break; ++ default: ++ return -EINVAL; + } + + ret = smu_cmn_update_table(smu, +diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c +index 166f9a3e9622d..332f0aa50fee4 100644 +--- a/drivers/gpu/drm/bridge/tc358767.c ++++ b/drivers/gpu/drm/bridge/tc358767.c +@@ -2135,7 +2135,7 @@ static irqreturn_t tc_irq_handler(int irq, void *arg) + dev_err(tc->dev, "syserr %x\n", stat); + } + +- if (tc->hpd_pin >= 0 && tc->bridge.dev) { ++ if (tc->hpd_pin >= 0 && tc->bridge.dev && tc->aux.drm_dev) { + /* + * H is triggered when the GPIO goes high. + * +diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c +index 28abe9aa99ca5..584d109330ab1 100644 +--- a/drivers/gpu/drm/drm_bridge.c ++++ b/drivers/gpu/drm/drm_bridge.c +@@ -353,13 +353,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, + bridge->encoder = NULL; + list_del(&bridge->chain_node); + +-#ifdef CONFIG_OF + DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n", + bridge->of_node, encoder->name, ret); +-#else +- DRM_ERROR("failed to attach bridge to encoder %s: %d\n", +- encoder->name, ret); +-#endif + + return ret; + } +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index 117237d3528bd..618b045230336 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -631,6 +631,17 @@ static void drm_fb_helper_add_damage_clip(struct drm_fb_helper *helper, u32 x, u + static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y, + u32 width, u32 height) + { ++ /* ++ * This function may be invoked by panic() to flush the frame ++ * buffer, where all CPUs except the panic CPU are stopped. ++ * During the following schedule_work(), the panic CPU needs ++ * the worker_pool lock, which might be held by a stopped CPU, ++ * causing schedule_work() and panic() to block. Return early on ++ * oops_in_progress to prevent this blocking. ++ */ ++ if (oops_in_progress) ++ return; ++ + drm_fb_helper_add_damage_clip(helper, x, y, width, height); + + schedule_work(&helper->damage_work); +diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c +index 3860a8ce1e2d4..903f4bfea7e83 100644 +--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c ++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c +@@ -414,6 +414,12 @@ static const struct dmi_system_id orientation_data[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"), + }, + .driver_data = (void *)&lcd1600x2560_leftside_up, ++ }, { /* OrangePi Neo */ ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "OrangePi"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "NEO-01"), ++ }, ++ .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* Samsung GalaxyBook 10.6 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c +index 815dfe30492b6..b43ac61201f31 100644 +--- a/drivers/gpu/drm/meson/meson_plane.c ++++ b/drivers/gpu/drm/meson/meson_plane.c +@@ -534,6 +534,7 @@ int meson_plane_create(struct meson_drm *priv) + struct meson_plane *meson_plane; + struct drm_plane *plane; + const uint64_t *format_modifiers = format_modifiers_default; ++ int ret; + + meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane), + GFP_KERNEL); +@@ -548,12 +549,16 @@ int meson_plane_create(struct meson_drm *priv) + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + format_modifiers = format_modifiers_afbc_g12a; + +- drm_universal_plane_init(priv->drm, plane, 0xFF, +- &meson_plane_funcs, +- supported_drm_formats, +- ARRAY_SIZE(supported_drm_formats), +- format_modifiers, +- DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); ++ ret = drm_universal_plane_init(priv->drm, plane, 0xFF, ++ &meson_plane_funcs, ++ supported_drm_formats, ++ ARRAY_SIZE(supported_drm_formats), ++ format_modifiers, ++ DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); ++ if (ret) { ++ devm_kfree(priv->drm->dev, meson_plane); ++ return ret; ++ } + + drm_plane_helper_add(plane, &meson_plane_helper_funcs); + +diff --git a/drivers/gpu/drm/xe/xe_force_wake.h b/drivers/gpu/drm/xe/xe_force_wake.h +index 83cb157da7cc6..a2577672f4e3e 100644 +--- a/drivers/gpu/drm/xe/xe_force_wake.h ++++ b/drivers/gpu/drm/xe/xe_force_wake.h +@@ -24,14 +24,25 @@ static inline int + xe_force_wake_ref(struct xe_force_wake *fw, + enum xe_force_wake_domains domain) + { +- xe_gt_assert(fw->gt, domain); ++ xe_gt_assert(fw->gt, domain != XE_FORCEWAKE_ALL); + return fw->domains[ffs(domain) - 1].ref; + } + ++/** ++ * xe_force_wake_assert_held - asserts domain is awake ++ * @fw : xe_force_wake structure ++ * @domain: xe_force_wake_domains apart from XE_FORCEWAKE_ALL ++ * ++ * xe_force_wake_assert_held() is designed to confirm a particular ++ * forcewake domain's wakefulness; it doesn't verify the wakefulness of ++ * multiple domains. Make sure the caller doesn't input multiple ++ * domains(XE_FORCEWAKE_ALL) as a parameter. ++ */ + static inline void + xe_force_wake_assert_held(struct xe_force_wake *fw, + enum xe_force_wake_domains domain) + { ++ xe_gt_assert(fw->gt, domain != XE_FORCEWAKE_ALL); + xe_gt_assert(fw->gt, fw->awake_domains & domain); + } + +diff --git a/drivers/gpu/drm/xe/xe_gt_ccs_mode.c b/drivers/gpu/drm/xe/xe_gt_ccs_mode.c +index 396aeb5b99242..a34c9a24dafc7 100644 +--- a/drivers/gpu/drm/xe/xe_gt_ccs_mode.c ++++ b/drivers/gpu/drm/xe/xe_gt_ccs_mode.c +@@ -68,8 +68,8 @@ static void __xe_gt_apply_ccs_mode(struct xe_gt *gt, u32 num_engines) + + xe_mmio_write32(gt, CCS_MODE, mode); + +- xe_gt_info(gt, "CCS_MODE=%x config:%08x, num_engines:%d, num_slices:%d\n", +- mode, config, num_engines, num_slices); ++ xe_gt_dbg(gt, "CCS_MODE=%x config:%08x, num_engines:%d, num_slices:%d\n", ++ mode, config, num_engines, num_slices); + } + + void xe_gt_apply_ccs_mode(struct xe_gt *gt) +diff --git a/drivers/gpu/drm/xe/xe_gt_topology.c b/drivers/gpu/drm/xe/xe_gt_topology.c +index 3733e7a6860d3..d224ed1b5c0f9 100644 +--- a/drivers/gpu/drm/xe/xe_gt_topology.c ++++ b/drivers/gpu/drm/xe/xe_gt_topology.c +@@ -108,7 +108,9 @@ gen_l3_mask_from_pattern(struct xe_device *xe, xe_l3_bank_mask_t dst, + { + unsigned long bit; + +- xe_assert(xe, fls(mask) <= patternbits); ++ xe_assert(xe, find_last_bit(pattern, XE_MAX_L3_BANK_MASK_BITS) < patternbits || ++ bitmap_empty(pattern, XE_MAX_L3_BANK_MASK_BITS)); ++ xe_assert(xe, !mask || patternbits * (__fls(mask) + 1) <= XE_MAX_L3_BANK_MASK_BITS); + for_each_set_bit(bit, &mask, 32) { + xe_l3_bank_mask_t shifted_pattern = {}; + +diff --git a/drivers/gpu/drm/xe/xe_guc_relay.c b/drivers/gpu/drm/xe/xe_guc_relay.c +index c0a2d8d5d3b3c..b49137ea6d843 100644 +--- a/drivers/gpu/drm/xe/xe_guc_relay.c ++++ b/drivers/gpu/drm/xe/xe_guc_relay.c +@@ -757,7 +757,14 @@ static void relay_process_incoming_action(struct xe_guc_relay *relay) + + static bool relay_needs_worker(struct xe_guc_relay *relay) + { +- return !list_empty(&relay->incoming_actions); ++ bool is_empty; ++ ++ spin_lock(&relay->lock); ++ is_empty = list_empty(&relay->incoming_actions); ++ spin_unlock(&relay->lock); ++ ++ return !is_empty; ++ + } + + static void relay_kick_worker(struct xe_guc_relay *relay) +diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c +index e48285c81bf57..0a496612c810f 100644 +--- a/drivers/gpu/drm/xe/xe_guc_submit.c ++++ b/drivers/gpu/drm/xe/xe_guc_submit.c +@@ -1551,6 +1551,11 @@ static void deregister_exec_queue(struct xe_guc *guc, struct xe_exec_queue *q) + q->guc->id, + }; + ++ xe_gt_assert(guc_to_gt(guc), exec_queue_destroyed(q)); ++ xe_gt_assert(guc_to_gt(guc), exec_queue_registered(q)); ++ xe_gt_assert(guc_to_gt(guc), !exec_queue_pending_disable(q)); ++ xe_gt_assert(guc_to_gt(guc), !exec_queue_pending_enable(q)); ++ + trace_xe_exec_queue_deregister(q); + + xe_guc_ct_send_g2h_handler(&guc->ct, action, ARRAY_SIZE(action)); +diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c +index bb815dbde63a6..daf0d15354fea 100644 +--- a/drivers/gpu/drm/xe/xe_hwmon.c ++++ b/drivers/gpu/drm/xe/xe_hwmon.c +@@ -551,12 +551,17 @@ xe_hwmon_curr_is_visible(const struct xe_hwmon *hwmon, u32 attr, int channel) + { + u32 uval; + ++ /* hwmon sysfs attribute of current available only for package */ ++ if (channel != CHANNEL_PKG) ++ return 0; ++ + switch (attr) { + case hwmon_curr_crit: +- case hwmon_curr_label: +- if (channel == CHANNEL_PKG) + return (xe_hwmon_pcode_read_i1(hwmon->gt, &uval) || + (uval & POWER_SETUP_I1_WATTS)) ? 0 : 0644; ++ case hwmon_curr_label: ++ return (xe_hwmon_pcode_read_i1(hwmon->gt, &uval) || ++ (uval & POWER_SETUP_I1_WATTS)) ? 0 : 0444; + break; + default: + return 0; +diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c +index 198f5c2189cb4..208649436fdb3 100644 +--- a/drivers/gpu/drm/xe/xe_migrate.c ++++ b/drivers/gpu/drm/xe/xe_migrate.c +@@ -69,7 +69,7 @@ struct xe_migrate { + + #define MAX_PREEMPTDISABLE_TRANSFER SZ_8M /* Around 1ms. */ + #define MAX_CCS_LIMITED_TRANSFER SZ_4M /* XE_PAGE_SIZE * (FIELD_MAX(XE2_CCS_SIZE_MASK) + 1) */ +-#define NUM_KERNEL_PDE 17 ++#define NUM_KERNEL_PDE 15 + #define NUM_PT_SLOTS 32 + #define LEVEL0_PAGE_TABLE_ENCODE_SIZE SZ_2M + #define MAX_NUM_PTE 512 +@@ -137,10 +137,11 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m, + struct xe_device *xe = tile_to_xe(tile); + u16 pat_index = xe->pat.idx[XE_CACHE_WB]; + u8 id = tile->id; +- u32 num_entries = NUM_PT_SLOTS, num_level = vm->pt_root[id]->level; ++ u32 num_entries = NUM_PT_SLOTS, num_level = vm->pt_root[id]->level, ++ num_setup = num_level + 1; + u32 map_ofs, level, i; + struct xe_bo *bo, *batch = tile->mem.kernel_bb_pool->bo; +- u64 entry; ++ u64 entry, pt30_ofs; + + /* Can't bump NUM_PT_SLOTS too high */ + BUILD_BUG_ON(NUM_PT_SLOTS > SZ_2M/XE_PAGE_SIZE); +@@ -160,10 +161,12 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m, + if (IS_ERR(bo)) + return PTR_ERR(bo); + +- entry = vm->pt_ops->pde_encode_bo(bo, bo->size - XE_PAGE_SIZE, pat_index); ++ /* PT31 reserved for 2M identity map */ ++ pt30_ofs = bo->size - 2 * XE_PAGE_SIZE; ++ entry = vm->pt_ops->pde_encode_bo(bo, pt30_ofs, pat_index); + xe_pt_write(xe, &vm->pt_root[id]->bo->vmap, 0, entry); + +- map_ofs = (num_entries - num_level) * XE_PAGE_SIZE; ++ map_ofs = (num_entries - num_setup) * XE_PAGE_SIZE; + + /* Map the entire BO in our level 0 pt */ + for (i = 0, level = 0; i < num_entries; level++) { +@@ -234,7 +237,7 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m, + } + + /* Write PDE's that point to our BO. */ +- for (i = 0; i < num_entries - num_level; i++) { ++ for (i = 0; i < map_ofs / PAGE_SIZE; i++) { + entry = vm->pt_ops->pde_encode_bo(bo, (u64)i * XE_PAGE_SIZE, + pat_index); + +@@ -252,28 +255,54 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m, + /* Identity map the entire vram at 256GiB offset */ + if (IS_DGFX(xe)) { + u64 pos, ofs, flags; ++ /* XXX: Unclear if this should be usable_size? */ ++ u64 vram_limit = xe->mem.vram.actual_physical_size + ++ xe->mem.vram.dpa_base; + + level = 2; + ofs = map_ofs + XE_PAGE_SIZE * level + 256 * 8; + flags = vm->pt_ops->pte_encode_addr(xe, 0, pat_index, level, + true, 0); + ++ xe_assert(xe, IS_ALIGNED(xe->mem.vram.usable_size, SZ_2M)); ++ + /* +- * Use 1GB pages, it shouldn't matter the physical amount of +- * vram is less, when we don't access it. ++ * Use 1GB pages when possible, last chunk always use 2M ++ * pages as mixing reserved memory (stolen, WOCPM) with a single ++ * mapping is not allowed on certain platforms. + */ +- for (pos = xe->mem.vram.dpa_base; +- pos < xe->mem.vram.actual_physical_size + xe->mem.vram.dpa_base; +- pos += SZ_1G, ofs += 8) ++ for (pos = xe->mem.vram.dpa_base; pos < vram_limit; ++ pos += SZ_1G, ofs += 8) { ++ if (pos + SZ_1G >= vram_limit) { ++ u64 pt31_ofs = bo->size - XE_PAGE_SIZE; ++ ++ entry = vm->pt_ops->pde_encode_bo(bo, pt31_ofs, ++ pat_index); ++ xe_map_wr(xe, &bo->vmap, ofs, u64, entry); ++ ++ flags = vm->pt_ops->pte_encode_addr(xe, 0, ++ pat_index, ++ level - 1, ++ true, 0); ++ ++ for (ofs = pt31_ofs; pos < vram_limit; ++ pos += SZ_2M, ofs += 8) ++ xe_map_wr(xe, &bo->vmap, ofs, u64, pos | flags); ++ break; /* Ensure pos == vram_limit assert correct */ ++ } ++ + xe_map_wr(xe, &bo->vmap, ofs, u64, pos | flags); ++ } ++ ++ xe_assert(xe, pos == vram_limit); + } + + /* + * Example layout created above, with root level = 3: + * [PT0...PT7]: kernel PT's for copy/clear; 64 or 4KiB PTE's + * [PT8]: Kernel PT for VM_BIND, 4 KiB PTE's +- * [PT9...PT28]: Userspace PT's for VM_BIND, 4 KiB PTE's +- * [PT29 = PDE 0] [PT30 = PDE 1] [PT31 = PDE 2] ++ * [PT9...PT27]: Userspace PT's for VM_BIND, 4 KiB PTE's ++ * [PT28 = PDE 0] [PT29 = PDE 1] [PT30 = PDE 2] [PT31 = 2M vram identity map] + * + * This makes the lowest part of the VM point to the pagetables. + * Hence the lowest 2M in the vm should point to itself, with a few writes +diff --git a/drivers/gpu/drm/xe/xe_pcode.c b/drivers/gpu/drm/xe/xe_pcode.c +index a5e7da8cf9441..9c4eefdf66428 100644 +--- a/drivers/gpu/drm/xe/xe_pcode.c ++++ b/drivers/gpu/drm/xe/xe_pcode.c +@@ -10,6 +10,7 @@ + + #include <drm/drm_managed.h> + ++#include "xe_assert.h" + #include "xe_device.h" + #include "xe_gt.h" + #include "xe_mmio.h" +@@ -124,6 +125,8 @@ static int pcode_try_request(struct xe_gt *gt, u32 mbox, + { + int slept, wait = 10; + ++ xe_gt_assert(gt, timeout_us > 0); ++ + for (slept = 0; slept < timeout_us; slept += wait) { + if (locked) + *status = pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true, +@@ -169,6 +172,8 @@ int xe_pcode_request(struct xe_gt *gt, u32 mbox, u32 request, + u32 status; + int ret; + ++ xe_gt_assert(gt, timeout_base_ms <= 3); ++ + mutex_lock(>->pcode.lock); + + ret = pcode_try_request(gt, mbox, request, reply_mask, reply, &status, +@@ -188,7 +193,6 @@ int xe_pcode_request(struct xe_gt *gt, u32 mbox, u32 request, + */ + drm_err(>_to_xe(gt)->drm, + "PCODE timeout, retrying with preemption disabled\n"); +- drm_WARN_ON_ONCE(>_to_xe(gt)->drm, timeout_base_ms > 1); + preempt_disable(); + ret = pcode_try_request(gt, mbox, request, reply_mask, reply, &status, + true, 50 * 1000, true); +diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c +index 8092312c0a877..6cad35e7f1828 100644 +--- a/drivers/hwmon/k10temp.c ++++ b/drivers/hwmon/k10temp.c +@@ -153,8 +153,9 @@ static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval) + + static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval) + { +- amd_smn_read(amd_pci_dev_to_node_id(pdev), +- ZEN_REPORTED_TEMP_CTRL_BASE, regval); ++ if (amd_smn_read(amd_pci_dev_to_node_id(pdev), ++ ZEN_REPORTED_TEMP_CTRL_BASE, regval)) ++ *regval = 0; + } + + static long get_raw_temp(struct k10temp_data *data) +@@ -205,6 +206,7 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, + long *val) + { + struct k10temp_data *data = dev_get_drvdata(dev); ++ int ret = -EOPNOTSUPP; + u32 regval; + + switch (attr) { +@@ -221,13 +223,17 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, + *val = 0; + break; + case 2 ... 13: /* Tccd{1-12} */ +- amd_smn_read(amd_pci_dev_to_node_id(data->pdev), +- ZEN_CCD_TEMP(data->ccd_offset, channel - 2), +- ®val); ++ ret = amd_smn_read(amd_pci_dev_to_node_id(data->pdev), ++ ZEN_CCD_TEMP(data->ccd_offset, channel - 2), ++ ®val); ++ ++ if (ret) ++ return ret; ++ + *val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000; + break; + default: +- return -EOPNOTSUPP; ++ return ret; + } + break; + case hwmon_temp_max: +@@ -243,7 +249,7 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, + - ((regval >> 24) & 0xf)) * 500 + 52000; + break; + default: +- return -EOPNOTSUPP; ++ return ret; + } + return 0; + } +@@ -381,8 +387,20 @@ static void k10temp_get_ccd_support(struct pci_dev *pdev, + int i; + + for (i = 0; i < limit; i++) { +- amd_smn_read(amd_pci_dev_to_node_id(pdev), +- ZEN_CCD_TEMP(data->ccd_offset, i), ®val); ++ /* ++ * Ignore inaccessible CCDs. ++ * ++ * Some systems will return a register value of 0, and the TEMP_VALID ++ * bit check below will naturally fail. ++ * ++ * Other systems will return a PCI_ERROR_RESPONSE (0xFFFFFFFF) for ++ * the register value. And this will incorrectly pass the TEMP_VALID ++ * bit check. ++ */ ++ if (amd_smn_read(amd_pci_dev_to_node_id(pdev), ++ ZEN_CCD_TEMP(data->ccd_offset, i), ®val)) ++ continue; ++ + if (regval & ZEN_CCD_TEMP_VALID) + data->show_temp |= BIT(TCCD_BIT(i)); + } +diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c +index 0c0a932c00f35..6505261e60686 100644 +--- a/drivers/hwspinlock/hwspinlock_core.c ++++ b/drivers/hwspinlock/hwspinlock_core.c +@@ -305,6 +305,34 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) + } + EXPORT_SYMBOL_GPL(__hwspin_unlock); + ++/** ++ * hwspin_lock_bust() - bust a specific hwspinlock ++ * @hwlock: a previously-acquired hwspinlock which we want to bust ++ * @id: identifier of the remote lock holder, if applicable ++ * ++ * This function will bust a hwspinlock that was previously acquired as ++ * long as the current owner of the lock matches the id given by the caller. ++ * ++ * Context: Process context. ++ * ++ * Returns: 0 on success, or -EINVAL if the hwspinlock does not exist, or ++ * the bust operation fails, and -EOPNOTSUPP if the bust operation is not ++ * defined for the hwspinlock. ++ */ ++int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id) ++{ ++ if (WARN_ON(!hwlock)) ++ return -EINVAL; ++ ++ if (!hwlock->bank->ops->bust) { ++ pr_err("bust operation not defined\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ return hwlock->bank->ops->bust(hwlock, id); ++} ++EXPORT_SYMBOL_GPL(hwspin_lock_bust); ++ + /** + * of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id + * @hwlock_spec: hwlock specifier as found in the device tree +diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h +index 29892767bb7a0..f298fc0ee5adb 100644 +--- a/drivers/hwspinlock/hwspinlock_internal.h ++++ b/drivers/hwspinlock/hwspinlock_internal.h +@@ -21,6 +21,8 @@ struct hwspinlock_device; + * @trylock: make a single attempt to take the lock. returns 0 on + * failure and true on success. may _not_ sleep. + * @unlock: release the lock. always succeed. may _not_ sleep. ++ * @bust: optional, platform-specific bust handler, called by hwspinlock ++ * core to bust a specific lock. + * @relax: optional, platform-specific relax handler, called by hwspinlock + * core while spinning on a lock, between two successive + * invocations of @trylock. may _not_ sleep. +@@ -28,6 +30,7 @@ struct hwspinlock_device; + struct hwspinlock_ops { + int (*trylock)(struct hwspinlock *lock); + void (*unlock)(struct hwspinlock *lock); ++ int (*bust)(struct hwspinlock *lock, unsigned int id); + void (*relax)(struct hwspinlock *lock); + }; + +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index fa7cc051b4c49..2f185b3869495 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -758,9 +758,11 @@ static ssize_t iio_read_channel_info(struct device *dev, + INDIO_MAX_RAW_ELEMENTS, + vals, &val_len, + this_attr->address); +- else ++ else if (indio_dev->info->read_raw) + ret = indio_dev->info->read_raw(indio_dev, this_attr->c, + &vals[0], &vals[1], this_attr->address); ++ else ++ return -EINVAL; + + if (ret < 0) + return ret; +@@ -842,6 +844,9 @@ static ssize_t iio_read_channel_info_avail(struct device *dev, + int length; + int type; + ++ if (!indio_dev->info->read_avail) ++ return -EINVAL; ++ + ret = indio_dev->info->read_avail(indio_dev, this_attr->c, + &vals, &type, &length, + this_attr->address); +diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c +index 910c1f14abd55..a64f8fbac597e 100644 +--- a/drivers/iio/industrialio-event.c ++++ b/drivers/iio/industrialio-event.c +@@ -285,6 +285,9 @@ static ssize_t iio_ev_state_store(struct device *dev, + if (ret < 0) + return ret; + ++ if (!indio_dev->info->write_event_config) ++ return -EINVAL; ++ + ret = indio_dev->info->write_event_config(indio_dev, + this_attr->c, iio_ev_attr_type(this_attr), + iio_ev_attr_dir(this_attr), val); +@@ -300,6 +303,9 @@ static ssize_t iio_ev_state_show(struct device *dev, + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int val; + ++ if (!indio_dev->info->read_event_config) ++ return -EINVAL; ++ + val = indio_dev->info->read_event_config(indio_dev, + this_attr->c, iio_ev_attr_type(this_attr), + iio_ev_attr_dir(this_attr)); +@@ -318,6 +324,9 @@ static ssize_t iio_ev_value_show(struct device *dev, + int val, val2, val_arr[2]; + int ret; + ++ if (!indio_dev->info->read_event_value) ++ return -EINVAL; ++ + ret = indio_dev->info->read_event_value(indio_dev, + this_attr->c, iio_ev_attr_type(this_attr), + iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr), +diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c +index 485e6fc44a04c..39cf26d69d17a 100644 +--- a/drivers/iio/inkern.c ++++ b/drivers/iio/inkern.c +@@ -543,6 +543,7 @@ EXPORT_SYMBOL_GPL(devm_iio_channel_get_all); + static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, + enum iio_chan_info_enum info) + { ++ const struct iio_info *iio_info = chan->indio_dev->info; + int unused; + int vals[INDIO_MAX_RAW_ELEMENTS]; + int ret; +@@ -554,15 +555,18 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, + if (!iio_channel_has_info(chan->channel, info)) + return -EINVAL; + +- if (chan->indio_dev->info->read_raw_multi) { +- ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev, +- chan->channel, INDIO_MAX_RAW_ELEMENTS, +- vals, &val_len, info); ++ if (iio_info->read_raw_multi) { ++ ret = iio_info->read_raw_multi(chan->indio_dev, ++ chan->channel, ++ INDIO_MAX_RAW_ELEMENTS, ++ vals, &val_len, info); + *val = vals[0]; + *val2 = vals[1]; ++ } else if (iio_info->read_raw) { ++ ret = iio_info->read_raw(chan->indio_dev, ++ chan->channel, val, val2, info); + } else { +- ret = chan->indio_dev->info->read_raw(chan->indio_dev, +- chan->channel, val, val2, info); ++ return -EINVAL; + } + + return ret; +@@ -750,11 +754,15 @@ static int iio_channel_read_avail(struct iio_channel *chan, + const int **vals, int *type, int *length, + enum iio_chan_info_enum info) + { ++ const struct iio_info *iio_info = chan->indio_dev->info; ++ + if (!iio_channel_has_available(chan->channel, info)) + return -EINVAL; + +- return chan->indio_dev->info->read_avail(chan->indio_dev, chan->channel, +- vals, type, length, info); ++ if (iio_info->read_avail) ++ return iio_info->read_avail(chan->indio_dev, chan->channel, ++ vals, type, length, info); ++ return -EINVAL; + } + + int iio_read_avail_channel_attribute(struct iio_channel *chan, +@@ -917,8 +925,12 @@ EXPORT_SYMBOL_GPL(iio_get_channel_type); + static int iio_channel_write(struct iio_channel *chan, int val, int val2, + enum iio_chan_info_enum info) + { +- return chan->indio_dev->info->write_raw(chan->indio_dev, +- chan->channel, val, val2, info); ++ const struct iio_info *iio_info = chan->indio_dev->info; ++ ++ if (iio_info->write_raw) ++ return iio_info->write_raw(chan->indio_dev, ++ chan->channel, val, val2, info); ++ return -EINVAL; + } + + int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2, +diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c +index 16a24a05fc2a6..bafd210dd43e8 100644 +--- a/drivers/infiniband/hw/efa/efa_com.c ++++ b/drivers/infiniband/hw/efa/efa_com.c +@@ -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-2024 Amazon.com, Inc. or its affiliates. All rights reserved. + */ + + #include "efa_com.h" +@@ -406,8 +406,8 @@ static struct efa_comp_ctx *efa_com_submit_admin_cmd(struct efa_com_admin_queue + return comp_ctx; + } + +-static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq, +- struct efa_admin_acq_entry *cqe) ++static int efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq, ++ struct efa_admin_acq_entry *cqe) + { + struct efa_comp_ctx *comp_ctx; + u16 cmd_id; +@@ -416,11 +416,11 @@ static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *a + EFA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID); + + comp_ctx = efa_com_get_comp_ctx(aq, cmd_id, false); +- if (!comp_ctx) { ++ if (comp_ctx->status != EFA_CMD_SUBMITTED) { + ibdev_err(aq->efa_dev, +- "comp_ctx is NULL. Changing the admin queue running state\n"); +- clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state); +- return; ++ "Received completion with unexpected command id[%d], sq producer: %d, sq consumer: %d, cq consumer: %d\n", ++ cmd_id, aq->sq.pc, aq->sq.cc, aq->cq.cc); ++ return -EINVAL; + } + + comp_ctx->status = EFA_CMD_COMPLETED; +@@ -428,14 +428,17 @@ static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *a + + if (!test_bit(EFA_AQ_STATE_POLLING_BIT, &aq->state)) + complete(&comp_ctx->wait_event); ++ ++ return 0; + } + + static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq) + { + struct efa_admin_acq_entry *cqe; + u16 queue_size_mask; +- u16 comp_num = 0; ++ u16 comp_cmds = 0; + u8 phase; ++ int err; + u16 ci; + + queue_size_mask = aq->depth - 1; +@@ -453,10 +456,12 @@ static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq) + * phase bit was validated + */ + dma_rmb(); +- efa_com_handle_single_admin_completion(aq, cqe); ++ err = efa_com_handle_single_admin_completion(aq, cqe); ++ if (!err) ++ comp_cmds++; + ++ aq->cq.cc++; + ci++; +- comp_num++; + if (ci == aq->depth) { + ci = 0; + phase = !phase; +@@ -465,10 +470,9 @@ static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq) + cqe = &aq->cq.entries[ci]; + } + +- aq->cq.cc += comp_num; + aq->cq.phase = phase; +- aq->sq.cc += comp_num; +- atomic64_add(comp_num, &aq->stats.completed_cmd); ++ aq->sq.cc += comp_cmds; ++ atomic64_add(comp_cmds, &aq->stats.completed_cmd); + } + + static int efa_com_comp_status_to_errno(u8 comp_status) +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index d435b6a6c295d..13c2c11cfdf64 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -687,16 +687,26 @@ static int uvc_parse_streaming(struct uvc_device *dev, + goto error; + } + +- size = nformats * sizeof(*format) + nframes * sizeof(*frame) ++ /* ++ * Allocate memory for the formats, the frames and the intervals, ++ * plus any required padding to guarantee that everything has the ++ * correct alignment. ++ */ ++ size = nformats * sizeof(*format); ++ size = ALIGN(size, __alignof__(*frame)) + nframes * sizeof(*frame); ++ size = ALIGN(size, __alignof__(*interval)) + + nintervals * sizeof(*interval); ++ + format = kzalloc(size, GFP_KERNEL); +- if (format == NULL) { ++ if (!format) { + ret = -ENOMEM; + goto error; + } + +- frame = (struct uvc_frame *)&format[nformats]; +- interval = (u32 *)&frame[nframes]; ++ frame = (void *)format + nformats * sizeof(*format); ++ frame = PTR_ALIGN(frame, __alignof__(*frame)); ++ interval = (void *)frame + nframes * sizeof(*frame); ++ interval = PTR_ALIGN(interval, __alignof__(*interval)); + + streaming->formats = format; + streaming->nformats = 0; +diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c +index ee3475bed37fa..1ff94affbaf3a 100644 +--- a/drivers/media/v4l2-core/v4l2-cci.c ++++ b/drivers/media/v4l2-core/v4l2-cci.c +@@ -23,6 +23,15 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err) + u8 buf[8]; + int ret; + ++ /* ++ * TODO: Fix smatch. Assign *val to 0 here in order to avoid ++ * failing a smatch check on caller when the caller proceeds to ++ * read *val without initialising it on caller's side. *val is set ++ * to a valid value whenever this function returns 0 but smatch ++ * can't figure that out currently. ++ */ ++ *val = 0; ++ + if (err && *err) + return *err; + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index cdc84a27a04ed..0138f77eaeed0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -2369,7 +2369,8 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq + if (flush) + mlx5e_shampo_flush_skb(rq, cqe, match); + free_hd_entry: +- mlx5e_free_rx_shampo_hd_entry(rq, header_index); ++ if (likely(head_size)) ++ mlx5e_free_rx_shampo_hd_entry(rq, header_index); + mpwrq_cqe_out: + if (likely(wi->consumed_strides < rq->mpwqe.num_strides)) + return; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c +index 042ca03491243..d1db04baa1fa6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c +@@ -7,7 +7,7 @@ + /* don't try to optimize STE allocation if the stack is too constaraining */ + #define DR_RULE_MAX_STES_OPTIMIZED 0 + #else +-#define DR_RULE_MAX_STES_OPTIMIZED 5 ++#define DR_RULE_MAX_STES_OPTIMIZED 2 + #endif + #define DR_RULE_MAX_STE_CHAIN_OPTIMIZED (DR_RULE_MAX_STES_OPTIMIZED + DR_ACTION_MAX_STES) + +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +index 1837a30ba08ac..f64d18949f68b 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +@@ -242,7 +242,7 @@ static int ionic_request_irq(struct ionic_lif *lif, struct ionic_qcq *qcq) + name = dev_name(dev); + + snprintf(intr->name, sizeof(intr->name), +- "%s-%s-%s", IONIC_DRV_NAME, name, q->name); ++ "%.5s-%.16s-%.8s", IONIC_DRV_NAME, name, q->name); + + return devm_request_irq(dev, intr->vector, ionic_isr, + 0, intr->name, &qcq->napi); +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index cfda32047cffb..4823dbdf54656 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1432,6 +1432,7 @@ static const struct usb_device_id products[] = { + {QMI_QUIRK_SET_DTR(0x1546, 0x1312, 4)}, /* u-blox LARA-R6 01B */ + {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */ + {QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */ ++ {QMI_FIXED_INTF(0x2dee, 0x4d22, 5)}, /* MeiG Smart SRM825L */ + + /* 4. Gobi 1000 devices */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index f32e017b62e9b..21bd0c127b05a 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3172,6 +3172,9 @@ static int virtnet_send_rx_ctrl_coal_vq_cmd(struct virtnet_info *vi, + { + int err; + ++ if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL)) ++ return -EOPNOTSUPP; ++ + err = virtnet_send_ctrl_coal_vq_cmd(vi, rxq2vq(queue), + max_usecs, max_packets); + if (err) +@@ -3189,6 +3192,9 @@ static int virtnet_send_tx_ctrl_coal_vq_cmd(struct virtnet_info *vi, + { + int err; + ++ if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL)) ++ return -EOPNOTSUPP; ++ + err = virtnet_send_ctrl_coal_vq_cmd(vi, txq2vq(queue), + max_usecs, max_packets); + if (err) +diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c +index d4a243b64f6c3..aa160e6fe24f1 100644 +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -2293,7 +2293,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, + struct qmi_txn txn; + const u8 *temp = data; + void __iomem *bdf_addr = NULL; +- int ret; ++ int ret = 0; + u32 remaining = len; + + req = kzalloc(sizeof(*req), GFP_KERNEL); +diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c +index 1d287ed25a949..3cdc4c51d6dfe 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -4058,7 +4058,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) + struct ath12k_dp *dp = &ab->dp; + struct htt_rx_ring_tlv_filter tlv_filter = {0}; + u32 ring_id; +- int ret; ++ int ret = 0; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + int i; + +diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c +index 5484112859a66..6d1ebbba17d9b 100644 +--- a/drivers/net/wireless/ath/ath12k/qmi.c ++++ b/drivers/net/wireless/ath/ath12k/qmi.c +@@ -2538,7 +2538,7 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab, + struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {}; + struct qmi_txn txn; + const u8 *temp = data; +- int ret; ++ int ret = 0; + u32 remaining = len; + + req = kzalloc(sizeof(*req), GFP_KERNEL); +diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +index 751a125a1566f..893b21fcaf87c 100644 +--- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c ++++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +@@ -230,8 +230,7 @@ static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char *buf, + .data = { NULL, }, + }; + +- if (fwrt->ops && fwrt->ops->fw_running && +- !fwrt->ops->fw_running(fwrt->ops_ctx)) ++ if (!iwl_trans_fw_running(fwrt->trans)) + return -EIO; + + if (count < header_size + 1 || count > 1024 * 4) +diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +index 9122f9a1260ae..d201440066ea9 100644 +--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h ++++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +@@ -19,7 +19,6 @@ + struct iwl_fw_runtime_ops { + void (*dump_start)(void *ctx); + void (*dump_end)(void *ctx); +- bool (*fw_running)(void *ctx); + int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd); + bool (*d3_debug_enable)(void *ctx); + }; +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c +index 92ac6cc40faa7..61b5648d3ab07 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c +@@ -504,17 +504,27 @@ iwl_mvm_get_puncturing_factor(const struct ieee80211_bss_conf *link_conf) + static unsigned int + iwl_mvm_get_chan_load(struct ieee80211_bss_conf *link_conf) + { ++ struct ieee80211_vif *vif = link_conf->vif; + struct iwl_mvm_vif_link_info *mvm_link = + iwl_mvm_vif_from_mac80211(link_conf->vif)->link[link_conf->link_id]; + const struct element *bss_load_elem; + const struct ieee80211_bss_load_elem *bss_load; + enum nl80211_band band = link_conf->chanreq.oper.chan->band; ++ const struct cfg80211_bss_ies *ies; + unsigned int chan_load; + u32 chan_load_by_us; + + rcu_read_lock(); +- bss_load_elem = ieee80211_bss_get_elem(link_conf->bss, +- WLAN_EID_QBSS_LOAD); ++ if (ieee80211_vif_link_active(vif, link_conf->link_id)) ++ ies = rcu_dereference(link_conf->bss->beacon_ies); ++ else ++ ies = rcu_dereference(link_conf->bss->ies); ++ ++ if (ies) ++ bss_load_elem = cfg80211_find_elem(WLAN_EID_QBSS_LOAD, ++ ies->data, ies->len); ++ else ++ bss_load_elem = NULL; + + /* If there isn't BSS Load element, take the defaults */ + if (!bss_load_elem || +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +index 1380ae5155f35..498afbe4ee6be 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +@@ -770,11 +770,6 @@ static void iwl_mvm_fwrt_dump_end(void *ctx) + mutex_unlock(&mvm->mutex); + } + +-static bool iwl_mvm_fwrt_fw_running(void *ctx) +-{ +- return iwl_mvm_firmware_running(ctx); +-} +- + static int iwl_mvm_fwrt_send_hcmd(void *ctx, struct iwl_host_cmd *host_cmd) + { + struct iwl_mvm *mvm = (struct iwl_mvm *)ctx; +@@ -795,7 +790,6 @@ static bool iwl_mvm_d3_debug_enable(void *ctx) + static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { + .dump_start = iwl_mvm_fwrt_dump_start, + .dump_end = iwl_mvm_fwrt_dump_end, +- .fw_running = iwl_mvm_fwrt_fw_running, + .send_hcmd = iwl_mvm_fwrt_send_hcmd, + .d3_debug_enable = iwl_mvm_d3_debug_enable, + }; +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c b/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c +index f49e3c98b1ba4..991dc875a7ead 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c +@@ -208,6 +208,7 @@ static void setup_link_conf(struct kunit *test) + bss_load->channel_util = params->channel_util; + + rcu_assign_pointer(bss.ies, ies); ++ rcu_assign_pointer(bss.beacon_ies, ies); + } + + static void test_link_grading(struct kunit *test) +diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c +index 99896d85d2f81..5fc2faa9ba5a7 100644 +--- a/drivers/net/wireless/realtek/rtw89/ser.c ++++ b/drivers/net/wireless/realtek/rtw89/ser.c +@@ -308,9 +308,13 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + + static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta) + { +- struct rtw89_vif *rtwvif = (struct rtw89_vif *)data; +- struct rtw89_dev *rtwdev = rtwvif->rtwdev; ++ struct rtw89_vif *target_rtwvif = (struct rtw89_vif *)data; + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ struct rtw89_vif *rtwvif = rtwsta->rtwvif; ++ struct rtw89_dev *rtwdev = rtwvif->rtwdev; ++ ++ if (rtwvif != target_rtwvif) ++ return; + + if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) + rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam); +diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c +index 6dfdda59f3283..643115f74092d 100644 +--- a/drivers/pci/controller/dwc/pcie-al.c ++++ b/drivers/pci/controller/dwc/pcie-al.c +@@ -242,18 +242,24 @@ static struct pci_ops al_child_pci_ops = { + .write = pci_generic_config_write, + }; + +-static void al_pcie_config_prepare(struct al_pcie *pcie) ++static int al_pcie_config_prepare(struct al_pcie *pcie) + { + struct al_pcie_target_bus_cfg *target_bus_cfg; + struct dw_pcie_rp *pp = &pcie->pci->pp; + unsigned int ecam_bus_mask; ++ struct resource_entry *ft; + u32 cfg_control_offset; ++ struct resource *bus; + u8 subordinate_bus; + u8 secondary_bus; + u32 cfg_control; + u32 reg; +- struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res; + ++ ft = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS); ++ if (!ft) ++ return -ENODEV; ++ ++ bus = ft->res; + target_bus_cfg = &pcie->target_bus_cfg; + + ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1; +@@ -287,6 +293,8 @@ static void al_pcie_config_prepare(struct al_pcie *pcie) + FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus); + + al_pcie_controller_writel(pcie, cfg_control_offset, reg); ++ ++ return 0; + } + + static int al_pcie_host_init(struct dw_pcie_rp *pp) +@@ -305,7 +313,9 @@ static int al_pcie_host_init(struct dw_pcie_rp *pp) + if (rc) + return rc; + +- al_pcie_config_prepare(pcie); ++ rc = al_pcie_config_prepare(pcie); ++ if (rc) ++ return rc; + + return 0; + } +diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c +index 4438f3b4b5ef9..60f866f1e6d78 100644 +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -1670,6 +1670,7 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) + seq_printf(s, "pin %d (%s) ", pin, desc->name); + + #ifdef CONFIG_GPIOLIB ++ gdev = NULL; + gpio_num = -1; + list_for_each_entry(range, &pctldev->gpio_ranges, node) { + if ((pin >= range->pin_base) && +diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +index 60be78da9f529..389602e4d7ab3 100644 +--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c ++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +@@ -2583,8 +2583,10 @@ static int rzg2l_pinctrl_suspend_noirq(struct device *dev) + rzg2l_pinctrl_pm_setup_dedicated_regs(pctrl, true); + + for (u8 i = 0; i < 2; i++) { +- cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i)); +- cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i)); ++ if (regs->sd_ch) ++ cache->sd_ch[i] = readb(pctrl->base + SD_CH(regs->sd_ch, i)); ++ if (regs->eth_poc) ++ cache->eth_poc[i] = readb(pctrl->base + ETH_POC(regs->eth_poc, i)); + } + + cache->qspi = readb(pctrl->base + QSPI); +@@ -2615,8 +2617,10 @@ static int rzg2l_pinctrl_resume_noirq(struct device *dev) + writeb(cache->qspi, pctrl->base + QSPI); + writeb(cache->eth_mode, pctrl->base + ETH_MODE); + for (u8 i = 0; i < 2; i++) { +- writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i)); +- writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i)); ++ if (regs->sd_ch) ++ writeb(cache->sd_ch[i], pctrl->base + SD_CH(regs->sd_ch, i)); ++ if (regs->eth_poc) ++ writeb(cache->eth_poc[i], pctrl->base + ETH_POC(regs->eth_poc, i)); + } + + rzg2l_pinctrl_pm_setup_pfc(pctrl); +diff --git a/drivers/platform/chrome/cros_ec_lpc_mec.c b/drivers/platform/chrome/cros_ec_lpc_mec.c +index 0d9c79b270ce2..63b6b261b8e58 100644 +--- a/drivers/platform/chrome/cros_ec_lpc_mec.c ++++ b/drivers/platform/chrome/cros_ec_lpc_mec.c +@@ -10,13 +10,65 @@ + + #include "cros_ec_lpc_mec.h" + ++#define ACPI_LOCK_DELAY_MS 500 ++ + /* + * This mutex must be held while accessing the EMI unit. We can't rely on the + * EC mutex because memmap data may be accessed without it being held. + */ + static DEFINE_MUTEX(io_mutex); ++/* ++ * An alternative mutex to be used when the ACPI AML code may also ++ * access memmap data. When set, this mutex is used in preference to ++ * io_mutex. ++ */ ++static acpi_handle aml_mutex; ++ + static u16 mec_emi_base, mec_emi_end; + ++/** ++ * cros_ec_lpc_mec_lock() - Acquire mutex for EMI ++ * ++ * @return: Negative error code, or zero for success ++ */ ++static int cros_ec_lpc_mec_lock(void) ++{ ++ bool success; ++ ++ if (!aml_mutex) { ++ mutex_lock(&io_mutex); ++ return 0; ++ } ++ ++ success = ACPI_SUCCESS(acpi_acquire_mutex(aml_mutex, ++ NULL, ACPI_LOCK_DELAY_MS)); ++ if (!success) ++ return -EBUSY; ++ ++ return 0; ++} ++ ++/** ++ * cros_ec_lpc_mec_unlock() - Release mutex for EMI ++ * ++ * @return: Negative error code, or zero for success ++ */ ++static int cros_ec_lpc_mec_unlock(void) ++{ ++ bool success; ++ ++ if (!aml_mutex) { ++ mutex_unlock(&io_mutex); ++ return 0; ++ } ++ ++ success = ACPI_SUCCESS(acpi_release_mutex(aml_mutex, NULL)); ++ if (!success) ++ return -EBUSY; ++ ++ return 0; ++} ++ + /** + * cros_ec_lpc_mec_emi_write_address() - Initialize EMI at a given address. + * +@@ -77,6 +129,7 @@ u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, + int io_addr; + u8 sum = 0; + enum cros_ec_lpc_mec_emi_access_mode access, new_access; ++ int ret; + + /* Return checksum of 0 if window is not initialized */ + WARN_ON(mec_emi_base == 0 || mec_emi_end == 0); +@@ -92,7 +145,9 @@ u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, + else + access = ACCESS_TYPE_LONG_AUTO_INCREMENT; + +- mutex_lock(&io_mutex); ++ ret = cros_ec_lpc_mec_lock(); ++ if (ret) ++ return ret; + + /* Initialize I/O at desired address */ + cros_ec_lpc_mec_emi_write_address(offset, access); +@@ -134,7 +189,9 @@ u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, + } + + done: +- mutex_unlock(&io_mutex); ++ ret = cros_ec_lpc_mec_unlock(); ++ if (ret) ++ return ret; + + return sum; + } +@@ -146,3 +203,18 @@ void cros_ec_lpc_mec_init(unsigned int base, unsigned int end) + mec_emi_end = end; + } + EXPORT_SYMBOL(cros_ec_lpc_mec_init); ++ ++int cros_ec_lpc_mec_acpi_mutex(struct acpi_device *adev, const char *pathname) ++{ ++ int status; ++ ++ if (!adev) ++ return -ENOENT; ++ ++ status = acpi_get_handle(adev->handle, pathname, &aml_mutex); ++ if (ACPI_FAILURE(status)) ++ return -ENOENT; ++ ++ return 0; ++} ++EXPORT_SYMBOL(cros_ec_lpc_mec_acpi_mutex); +diff --git a/drivers/platform/chrome/cros_ec_lpc_mec.h b/drivers/platform/chrome/cros_ec_lpc_mec.h +index 9d0521b23e8ae..3f3af37e58a50 100644 +--- a/drivers/platform/chrome/cros_ec_lpc_mec.h ++++ b/drivers/platform/chrome/cros_ec_lpc_mec.h +@@ -8,6 +8,8 @@ + #ifndef __CROS_EC_LPC_MEC_H + #define __CROS_EC_LPC_MEC_H + ++#include <linux/acpi.h> ++ + enum cros_ec_lpc_mec_emi_access_mode { + /* 8-bit access */ + ACCESS_TYPE_BYTE = 0x0, +@@ -45,6 +47,15 @@ enum cros_ec_lpc_mec_io_type { + */ + void cros_ec_lpc_mec_init(unsigned int base, unsigned int end); + ++/** ++ * cros_ec_lpc_mec_acpi_mutex() - Find and set ACPI mutex for MEC ++ * ++ * @adev: Parent ACPI device ++ * @pathname: Name of AML mutex ++ * @return: Negative error code, or zero for success ++ */ ++int cros_ec_lpc_mec_acpi_mutex(struct acpi_device *adev, const char *pathname); ++ + /** + * cros_ec_lpc_mec_in_range() - Determine if addresses are in MEC EMI range. + * +diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c +index 2d6e2558863c5..8f1f719befa3e 100644 +--- a/drivers/platform/x86/amd/pmf/core.c ++++ b/drivers/platform/x86/amd/pmf/core.c +@@ -41,6 +41,7 @@ + #define AMD_CPU_ID_RMB 0x14b5 + #define AMD_CPU_ID_PS 0x14e8 + #define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 ++#define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT 0x1122 + + #define PMF_MSG_DELAY_MIN_US 50 + #define RESPONSE_REGISTER_LOOP_MAX 20000 +@@ -249,6 +250,7 @@ static const struct pci_device_id pmf_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RMB) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_ROOT) }, + { } + }; + +@@ -382,6 +384,7 @@ static const struct acpi_device_id amd_pmf_acpi_ids[] = { + {"AMDI0102", 0}, + {"AMDI0103", 0}, + {"AMDI0105", 0}, ++ {"AMDI0107", 0}, + { } + }; + MODULE_DEVICE_TABLE(acpi, amd_pmf_acpi_ids); +diff --git a/drivers/platform/x86/amd/pmf/pmf-quirks.c b/drivers/platform/x86/amd/pmf/pmf-quirks.c +index 0b2eb0ae85feb..460444cda1b29 100644 +--- a/drivers/platform/x86/amd/pmf/pmf-quirks.c ++++ b/drivers/platform/x86/amd/pmf/pmf-quirks.c +@@ -29,6 +29,14 @@ static const struct dmi_system_id fwbug_list[] = { + }, + .driver_data = &quirk_no_sps_bug, + }, ++ { ++ .ident = "ROG Ally X", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "RC72LA"), ++ }, ++ .driver_data = &quirk_no_sps_bug, ++ }, + {} + }; + +@@ -48,4 +56,3 @@ void amd_pmf_quirks_init(struct amd_pmf_dev *dev) + dmi_id->ident); + } + } +- +diff --git a/drivers/ras/amd/atl/dehash.c b/drivers/ras/amd/atl/dehash.c +index 4ea46262c4f58..d4ee7ecabaeee 100644 +--- a/drivers/ras/amd/atl/dehash.c ++++ b/drivers/ras/amd/atl/dehash.c +@@ -12,41 +12,10 @@ + + #include "internal.h" + +-/* +- * Verify the interleave bits are correct in the different interleaving +- * settings. +- * +- * If @num_intlv_dies and/or @num_intlv_sockets are 1, it means the +- * respective interleaving is disabled. +- */ +-static inline bool map_bits_valid(struct addr_ctx *ctx, u8 bit1, u8 bit2, +- u8 num_intlv_dies, u8 num_intlv_sockets) +-{ +- if (!(ctx->map.intlv_bit_pos == bit1 || ctx->map.intlv_bit_pos == bit2)) { +- pr_debug("Invalid interleave bit: %u", ctx->map.intlv_bit_pos); +- return false; +- } +- +- if (ctx->map.num_intlv_dies > num_intlv_dies) { +- pr_debug("Invalid number of interleave dies: %u", ctx->map.num_intlv_dies); +- return false; +- } +- +- if (ctx->map.num_intlv_sockets > num_intlv_sockets) { +- pr_debug("Invalid number of interleave sockets: %u", ctx->map.num_intlv_sockets); +- return false; +- } +- +- return true; +-} +- + static int df2_dehash_addr(struct addr_ctx *ctx) + { + u8 hashed_bit, intlv_bit, intlv_bit_pos; + +- if (!map_bits_valid(ctx, 8, 9, 1, 1)) +- return -EINVAL; +- + intlv_bit_pos = ctx->map.intlv_bit_pos; + intlv_bit = !!(BIT_ULL(intlv_bit_pos) & ctx->ret_addr); + +@@ -67,9 +36,6 @@ static int df3_dehash_addr(struct addr_ctx *ctx) + bool hash_ctl_64k, hash_ctl_2M, hash_ctl_1G; + u8 hashed_bit, intlv_bit, intlv_bit_pos; + +- if (!map_bits_valid(ctx, 8, 9, 1, 1)) +- return -EINVAL; +- + hash_ctl_64k = FIELD_GET(DF3_HASH_CTL_64K, ctx->map.ctl); + hash_ctl_2M = FIELD_GET(DF3_HASH_CTL_2M, ctx->map.ctl); + hash_ctl_1G = FIELD_GET(DF3_HASH_CTL_1G, ctx->map.ctl); +@@ -171,9 +137,6 @@ static int df4_dehash_addr(struct addr_ctx *ctx) + bool hash_ctl_64k, hash_ctl_2M, hash_ctl_1G; + u8 hashed_bit, intlv_bit; + +- if (!map_bits_valid(ctx, 8, 8, 1, 2)) +- return -EINVAL; +- + hash_ctl_64k = FIELD_GET(DF4_HASH_CTL_64K, ctx->map.ctl); + hash_ctl_2M = FIELD_GET(DF4_HASH_CTL_2M, ctx->map.ctl); + hash_ctl_1G = FIELD_GET(DF4_HASH_CTL_1G, ctx->map.ctl); +@@ -247,9 +210,6 @@ static int df4p5_dehash_addr(struct addr_ctx *ctx) + u8 hashed_bit, intlv_bit; + u64 rehash_vector; + +- if (!map_bits_valid(ctx, 8, 8, 1, 2)) +- return -EINVAL; +- + hash_ctl_64k = FIELD_GET(DF4_HASH_CTL_64K, ctx->map.ctl); + hash_ctl_2M = FIELD_GET(DF4_HASH_CTL_2M, ctx->map.ctl); + hash_ctl_1G = FIELD_GET(DF4_HASH_CTL_1G, ctx->map.ctl); +@@ -360,9 +320,6 @@ static int mi300_dehash_addr(struct addr_ctx *ctx) + bool hashed_bit, intlv_bit, test_bit; + u8 num_intlv_bits, base_bit, i; + +- if (!map_bits_valid(ctx, 8, 8, 4, 1)) +- return -EINVAL; +- + hash_ctl_4k = FIELD_GET(DF4p5_HASH_CTL_4K, ctx->map.ctl); + hash_ctl_64k = FIELD_GET(DF4_HASH_CTL_64K, ctx->map.ctl); + hash_ctl_2M = FIELD_GET(DF4_HASH_CTL_2M, ctx->map.ctl); +diff --git a/drivers/ras/amd/atl/map.c b/drivers/ras/amd/atl/map.c +index 8b908e8d7495f..04419923f0884 100644 +--- a/drivers/ras/amd/atl/map.c ++++ b/drivers/ras/amd/atl/map.c +@@ -642,6 +642,79 @@ static int get_global_map_data(struct addr_ctx *ctx) + return 0; + } + ++/* ++ * Verify the interleave bits are correct in the different interleaving ++ * settings. ++ * ++ * If @num_intlv_dies and/or @num_intlv_sockets are 1, it means the ++ * respective interleaving is disabled. ++ */ ++static inline bool map_bits_valid(struct addr_ctx *ctx, u8 bit1, u8 bit2, ++ u8 num_intlv_dies, u8 num_intlv_sockets) ++{ ++ if (!(ctx->map.intlv_bit_pos == bit1 || ctx->map.intlv_bit_pos == bit2)) { ++ pr_debug("Invalid interleave bit: %u", ctx->map.intlv_bit_pos); ++ return false; ++ } ++ ++ if (ctx->map.num_intlv_dies > num_intlv_dies) { ++ pr_debug("Invalid number of interleave dies: %u", ctx->map.num_intlv_dies); ++ return false; ++ } ++ ++ if (ctx->map.num_intlv_sockets > num_intlv_sockets) { ++ pr_debug("Invalid number of interleave sockets: %u", ctx->map.num_intlv_sockets); ++ return false; ++ } ++ ++ return true; ++} ++ ++static int validate_address_map(struct addr_ctx *ctx) ++{ ++ switch (ctx->map.intlv_mode) { ++ case DF2_2CHAN_HASH: ++ case DF3_COD4_2CHAN_HASH: ++ case DF3_COD2_4CHAN_HASH: ++ case DF3_COD1_8CHAN_HASH: ++ if (!map_bits_valid(ctx, 8, 9, 1, 1)) ++ goto err; ++ break; ++ ++ case DF4_NPS4_2CHAN_HASH: ++ case DF4_NPS2_4CHAN_HASH: ++ case DF4_NPS1_8CHAN_HASH: ++ case DF4p5_NPS4_2CHAN_1K_HASH: ++ case DF4p5_NPS4_2CHAN_2K_HASH: ++ case DF4p5_NPS2_4CHAN_1K_HASH: ++ case DF4p5_NPS2_4CHAN_2K_HASH: ++ case DF4p5_NPS1_8CHAN_1K_HASH: ++ case DF4p5_NPS1_8CHAN_2K_HASH: ++ case DF4p5_NPS1_16CHAN_1K_HASH: ++ case DF4p5_NPS1_16CHAN_2K_HASH: ++ if (!map_bits_valid(ctx, 8, 8, 1, 2)) ++ goto err; ++ break; ++ ++ case MI3_HASH_8CHAN: ++ case MI3_HASH_16CHAN: ++ case MI3_HASH_32CHAN: ++ if (!map_bits_valid(ctx, 8, 8, 4, 1)) ++ goto err; ++ break; ++ ++ /* Nothing to do for modes that don't need special validation checks. */ ++ default: ++ break; ++ } ++ ++ return 0; ++ ++err: ++ atl_debug(ctx, "Inconsistent address map"); ++ return -EINVAL; ++} ++ + static void dump_address_map(struct dram_addr_map *map) + { + u8 i; +@@ -678,5 +751,9 @@ int get_address_map(struct addr_ctx *ctx) + + dump_address_map(&ctx->map); + ++ ret = validate_address_map(ctx); ++ if (ret) ++ return ret; ++ + return ret; + } +diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c +index abf7b371b8604..e744c07507eed 100644 +--- a/drivers/remoteproc/mtk_scp.c ++++ b/drivers/remoteproc/mtk_scp.c +@@ -117,8 +117,8 @@ static void scp_ipi_handler(struct mtk_scp *scp) + return; + } + +- memset(scp->share_buf, 0, scp_sizes->ipi_share_buffer_size); + memcpy_fromio(scp->share_buf, &rcv_obj->share_buf, len); ++ memset(&scp->share_buf[len], 0, scp_sizes->ipi_share_buffer_size - len); + handler(scp->share_buf, len, ipi_desc[id].priv); + scp_ipi_unlock(scp, id); + +diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c +index 54d8005d40a34..8458bcfe9e19e 100644 +--- a/drivers/remoteproc/qcom_q6v5_pas.c ++++ b/drivers/remoteproc/qcom_q6v5_pas.c +@@ -52,6 +52,7 @@ struct adsp_data { + const char *ssr_name; + const char *sysmon_name; + int ssctl_id; ++ unsigned int smem_host_id; + + int region_assign_idx; + int region_assign_count; +@@ -81,6 +82,7 @@ struct qcom_adsp { + int lite_pas_id; + unsigned int minidump_id; + int crash_reason_smem; ++ unsigned int smem_host_id; + bool decrypt_shutdown; + const char *info_name; + +@@ -399,6 +401,9 @@ static int adsp_stop(struct rproc *rproc) + if (handover) + qcom_pas_handover(&adsp->q6v5); + ++ if (adsp->smem_host_id) ++ ret = qcom_smem_bust_hwspin_lock_by_host(adsp->smem_host_id); ++ + return ret; + } + +@@ -727,6 +732,7 @@ static int adsp_probe(struct platform_device *pdev) + adsp->pas_id = desc->pas_id; + adsp->lite_pas_id = desc->lite_pas_id; + adsp->info_name = desc->sysmon_name; ++ adsp->smem_host_id = desc->smem_host_id; + adsp->decrypt_shutdown = desc->decrypt_shutdown; + adsp->region_assign_idx = desc->region_assign_idx; + adsp->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count); +@@ -1196,6 +1202,7 @@ static const struct adsp_data sm8550_adsp_resource = { + .ssr_name = "lpass", + .sysmon_name = "adsp", + .ssctl_id = 0x14, ++ .smem_host_id = 2, + }; + + static const struct adsp_data sm8550_cdsp_resource = { +@@ -1216,6 +1223,7 @@ static const struct adsp_data sm8550_cdsp_resource = { + .ssr_name = "cdsp", + .sysmon_name = "cdsp", + .ssctl_id = 0x17, ++ .smem_host_id = 5, + }; + + static const struct adsp_data sm8550_mpss_resource = { +@@ -1236,6 +1244,7 @@ static const struct adsp_data sm8550_mpss_resource = { + .ssr_name = "mpss", + .sysmon_name = "modem", + .ssctl_id = 0x12, ++ .smem_host_id = 1, + .region_assign_idx = 2, + .region_assign_count = 1, + .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, +@@ -1275,6 +1284,7 @@ static const struct adsp_data sm8650_cdsp_resource = { + .ssr_name = "cdsp", + .sysmon_name = "cdsp", + .ssctl_id = 0x17, ++ .smem_host_id = 5, + .region_assign_idx = 2, + .region_assign_count = 1, + .region_assign_shared = true, +@@ -1299,6 +1309,7 @@ static const struct adsp_data sm8650_mpss_resource = { + .ssr_name = "mpss", + .sysmon_name = "modem", + .ssctl_id = 0x12, ++ .smem_host_id = 1, + .region_assign_idx = 2, + .region_assign_count = 3, + .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, +diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c +index 7191fa0c087f2..50039e983ebaa 100644 +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -359,6 +359,32 @@ static struct qcom_smem *__smem; + /* Timeout (ms) for the trylock of remote spinlocks */ + #define HWSPINLOCK_TIMEOUT 1000 + ++/* The qcom hwspinlock id is always plus one from the smem host id */ ++#define SMEM_HOST_ID_TO_HWSPINLOCK_ID(__x) ((__x) + 1) ++ ++/** ++ * qcom_smem_bust_hwspin_lock_by_host() - bust the smem hwspinlock for a host ++ * @host: remote processor id ++ * ++ * Busts the hwspin_lock for the given smem host id. This helper is intended ++ * for remoteproc drivers that manage remoteprocs with an equivalent smem ++ * driver instance in the remote firmware. Drivers can force a release of the ++ * smem hwspin_lock if the rproc unexpectedly goes into a bad state. ++ * ++ * Context: Process context. ++ * ++ * Returns: 0 on success, otherwise negative errno. ++ */ ++int qcom_smem_bust_hwspin_lock_by_host(unsigned int host) ++{ ++ /* This function is for remote procs, so ignore SMEM_HOST_APPS */ ++ if (host == SMEM_HOST_APPS || host >= SMEM_HOST_COUNT) ++ return -EINVAL; ++ ++ return hwspin_lock_bust(__smem->hwlock, SMEM_HOST_ID_TO_HWSPINLOCK_ID(host)); ++} ++EXPORT_SYMBOL_GPL(qcom_smem_bust_hwspin_lock_by_host); ++ + /** + * qcom_smem_is_available() - Check if SMEM is available + * +diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c +index 77e9738e42f60..6910b4d4c427b 100644 +--- a/drivers/spi/spi-hisi-kunpeng.c ++++ b/drivers/spi/spi-hisi-kunpeng.c +@@ -495,6 +495,7 @@ static int hisi_spi_probe(struct platform_device *pdev) + host->transfer_one = hisi_spi_transfer_one; + host->handle_err = hisi_spi_handle_err; + host->dev.fwnode = dev->fwnode; ++ host->min_speed_hz = DIV_ROUND_UP(host->max_speed_hz, CLK_DIV_MAX); + + hisi_spi_hw_init(hs); + +diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c +index 88211ccdfbd62..5be6113e7c80f 100644 +--- a/drivers/thermal/thermal_sysfs.c ++++ b/drivers/thermal/thermal_sysfs.c +@@ -150,7 +150,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, + if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip_id) != 1) + return -EINVAL; + +- return sprintf(buf, "%d\n", tz->trips[trip_id].trip.temperature); ++ return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.temperature)); + } + + static ssize_t +@@ -174,7 +174,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, + trip = &tz->trips[trip_id].trip; + + if (hyst != trip->hysteresis) { +- trip->hysteresis = hyst; ++ WRITE_ONCE(trip->hysteresis, hyst); + + thermal_zone_trip_updated(tz, trip); + } +@@ -194,7 +194,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, + if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) + return -EINVAL; + +- return sprintf(buf, "%d\n", tz->trips[trip_id].trip.hysteresis); ++ return sprintf(buf, "%d\n", READ_ONCE(tz->trips[trip_id].trip.hysteresis)); + } + + static ssize_t +diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c +index 49e63db685172..b4e7411b2fe74 100644 +--- a/drivers/thermal/thermal_trip.c ++++ b/drivers/thermal/thermal_trip.c +@@ -152,7 +152,7 @@ void thermal_zone_set_trip_temp(struct thermal_zone_device *tz, + if (trip->temperature == temp) + return; + +- trip->temperature = temp; ++ WRITE_ONCE(trip->temperature, temp); + thermal_notify_tz_trip_change(tz, trip); + + if (temp == THERMAL_TEMP_INVALID) { +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 5864d65448ce5..91bfdc17eedb3 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -2412,7 +2412,17 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba) + return err; + } + ++ /* ++ * The UFSHCI 3.0 specification does not define MCQ_SUPPORT and ++ * LSDB_SUPPORT, but [31:29] as reserved bits with reset value 0s, which ++ * means we can simply read values regardless of version. ++ */ + hba->mcq_sup = FIELD_GET(MASK_MCQ_SUPPORT, hba->capabilities); ++ /* ++ * 0h: legacy single doorbell support is available ++ * 1h: indicate that legacy single doorbell support has been removed ++ */ ++ hba->lsdb_sup = !FIELD_GET(MASK_LSDB_SUPPORT, hba->capabilities); + if (!hba->mcq_sup) + return 0; + +@@ -6550,7 +6560,8 @@ static void ufshcd_err_handler(struct work_struct *work) + if (ufshcd_err_handling_should_stop(hba)) + goto skip_err_handling; + +- if (hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) { ++ if ((hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) && ++ !hba->force_reset) { + bool ret; + + spin_unlock_irqrestore(hba->host->host_lock, flags); +@@ -10456,6 +10467,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + } + + if (!is_mcq_supported(hba)) { ++ if (!hba->lsdb_sup) { ++ dev_err(hba->dev, "%s: failed to initialize (legacy doorbell mode not supported)\n", ++ __func__); ++ err = -EINVAL; ++ goto out_disable; ++ } + err = scsi_add_host(host, hba->dev); + if (err) { + dev_err(hba->dev, "scsi_add_host failed\n"); +diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h +index c4d103db9d0f8..f66224a270bc6 100644 +--- a/drivers/usb/typec/ucsi/ucsi.h ++++ b/drivers/usb/typec/ucsi/ucsi.h +@@ -496,7 +496,7 @@ ucsi_register_displayport(struct ucsi_connector *con, + bool override, int offset, + struct typec_altmode_desc *desc) + { +- return NULL; ++ return typec_port_register_altmode(con->port, desc); + } + + static inline void +diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c +index fc01b31bbb875..6338d818bc8bc 100644 +--- a/drivers/usb/usbip/stub_rx.c ++++ b/drivers/usb/usbip/stub_rx.c +@@ -144,53 +144,62 @@ static int tweak_set_configuration_cmd(struct urb *urb) + if (err && err != -ENODEV) + dev_err(&sdev->udev->dev, "can't set config #%d, error %d\n", + config, err); +- return 0; ++ return err; + } + + static int tweak_reset_device_cmd(struct urb *urb) + { + struct stub_priv *priv = (struct stub_priv *) urb->context; + struct stub_device *sdev = priv->sdev; ++ int err; + + dev_info(&urb->dev->dev, "usb_queue_reset_device\n"); + +- if (usb_lock_device_for_reset(sdev->udev, NULL) < 0) { ++ err = usb_lock_device_for_reset(sdev->udev, NULL); ++ if (err < 0) { + dev_err(&urb->dev->dev, "could not obtain lock to reset device\n"); +- return 0; ++ return err; + } +- usb_reset_device(sdev->udev); ++ err = usb_reset_device(sdev->udev); + usb_unlock_device(sdev->udev); + +- return 0; ++ return err; + } + + /* + * clear_halt, set_interface, and set_configuration require special tricks. ++ * Returns 1 if request was tweaked, 0 otherwise. + */ +-static void tweak_special_requests(struct urb *urb) ++static int tweak_special_requests(struct urb *urb) + { ++ int err; ++ + if (!urb || !urb->setup_packet) +- return; ++ return 0; + + if (usb_pipetype(urb->pipe) != PIPE_CONTROL) +- return; ++ return 0; + + if (is_clear_halt_cmd(urb)) + /* tweak clear_halt */ +- tweak_clear_halt_cmd(urb); ++ err = tweak_clear_halt_cmd(urb); + + else if (is_set_interface_cmd(urb)) + /* tweak set_interface */ +- tweak_set_interface_cmd(urb); ++ err = tweak_set_interface_cmd(urb); + + else if (is_set_configuration_cmd(urb)) + /* tweak set_configuration */ +- tweak_set_configuration_cmd(urb); ++ err = tweak_set_configuration_cmd(urb); + + else if (is_reset_device_cmd(urb)) +- tweak_reset_device_cmd(urb); +- else ++ err = tweak_reset_device_cmd(urb); ++ else { + usbip_dbg_stub_rx("no need to tweak\n"); ++ return 0; ++ } ++ ++ return !err; + } + + /* +@@ -468,6 +477,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, + int support_sg = 1; + int np = 0; + int ret, i; ++ int is_tweaked; + + if (pipe == -1) + return; +@@ -580,8 +590,11 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, + priv->urbs[i]->pipe = pipe; + priv->urbs[i]->complete = stub_complete; + +- /* no need to submit an intercepted request, but harmless? */ +- tweak_special_requests(priv->urbs[i]); ++ /* ++ * all URBs belong to a single PDU, so a global is_tweaked flag is ++ * enough ++ */ ++ is_tweaked = tweak_special_requests(priv->urbs[i]); + + masking_bogus_flags(priv->urbs[i]); + } +@@ -594,22 +607,32 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, + + /* urb is now ready to submit */ + for (i = 0; i < priv->num_urbs; i++) { +- ret = usb_submit_urb(priv->urbs[i], GFP_KERNEL); ++ if (!is_tweaked) { ++ ret = usb_submit_urb(priv->urbs[i], GFP_KERNEL); + +- if (ret == 0) +- usbip_dbg_stub_rx("submit urb ok, seqnum %u\n", +- pdu->base.seqnum); +- else { +- dev_err(&udev->dev, "submit_urb error, %d\n", ret); +- usbip_dump_header(pdu); +- usbip_dump_urb(priv->urbs[i]); ++ if (ret == 0) ++ usbip_dbg_stub_rx("submit urb ok, seqnum %u\n", ++ pdu->base.seqnum); ++ else { ++ dev_err(&udev->dev, "submit_urb error, %d\n", ret); ++ usbip_dump_header(pdu); ++ usbip_dump_urb(priv->urbs[i]); + ++ /* ++ * Pessimistic. ++ * This connection will be discarded. ++ */ ++ usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT); ++ break; ++ } ++ } else { + /* +- * Pessimistic. +- * This connection will be discarded. ++ * An identical URB was already submitted in ++ * tweak_special_requests(). Skip submitting this URB to not ++ * duplicate the request. + */ +- usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT); +- break; ++ priv->urbs[i]->status = 0; ++ stub_complete(priv->urbs[i]); + } + } + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 39d22693e47b6..c2f48fc159e5a 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -1586,6 +1586,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode, + locked_page, &cached, + clear_bits, + page_ops); ++ btrfs_qgroup_free_data(inode, NULL, start, cur_alloc_size, NULL); + start += cur_alloc_size; + } + +@@ -1599,6 +1600,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode, + clear_bits |= EXTENT_CLEAR_DATA_RESV; + extent_clear_unlock_delalloc(inode, start, end, locked_page, + &cached, clear_bits, page_ops); ++ btrfs_qgroup_free_data(inode, NULL, start, cur_alloc_size, NULL); + } + return ret; + } +@@ -2269,6 +2271,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, + EXTENT_DO_ACCOUNTING, PAGE_UNLOCK | + PAGE_START_WRITEBACK | + PAGE_END_WRITEBACK); ++ btrfs_qgroup_free_data(inode, NULL, cur_offset, end - cur_offset + 1, NULL); + } + btrfs_free_path(path); + return ret; +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index d7caa3732f074..731d7d562db1a 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -1648,14 +1648,20 @@ static void scrub_reset_stripe(struct scrub_stripe *stripe) + } + } + ++static u32 stripe_length(const struct scrub_stripe *stripe) ++{ ++ ASSERT(stripe->bg); ++ ++ return min(BTRFS_STRIPE_LEN, ++ stripe->bg->start + stripe->bg->length - stripe->logical); ++} ++ + static void scrub_submit_extent_sector_read(struct scrub_ctx *sctx, + struct scrub_stripe *stripe) + { + struct btrfs_fs_info *fs_info = stripe->bg->fs_info; + struct btrfs_bio *bbio = NULL; +- unsigned int nr_sectors = min(BTRFS_STRIPE_LEN, stripe->bg->start + +- stripe->bg->length - stripe->logical) >> +- fs_info->sectorsize_bits; ++ unsigned int nr_sectors = stripe_length(stripe) >> fs_info->sectorsize_bits; + u64 stripe_len = BTRFS_STRIPE_LEN; + int mirror = stripe->mirror_num; + int i; +@@ -1729,9 +1735,7 @@ static void scrub_submit_initial_read(struct scrub_ctx *sctx, + { + struct btrfs_fs_info *fs_info = sctx->fs_info; + struct btrfs_bio *bbio; +- unsigned int nr_sectors = min(BTRFS_STRIPE_LEN, stripe->bg->start + +- stripe->bg->length - stripe->logical) >> +- fs_info->sectorsize_bits; ++ unsigned int nr_sectors = stripe_length(stripe) >> fs_info->sectorsize_bits; + int mirror = stripe->mirror_num; + + ASSERT(stripe->bg); +@@ -1871,6 +1875,9 @@ static int flush_scrub_stripes(struct scrub_ctx *sctx) + stripe = &sctx->stripes[i]; + + wait_scrub_stripe_io(stripe); ++ spin_lock(&sctx->stat_lock); ++ sctx->stat.last_physical = stripe->physical + stripe_length(stripe); ++ spin_unlock(&sctx->stat_lock); + scrub_reset_stripe(stripe); + } + out: +@@ -2139,7 +2146,9 @@ static int scrub_simple_mirror(struct scrub_ctx *sctx, + cur_physical, &found_logical); + if (ret > 0) { + /* No more extent, just update the accounting */ ++ spin_lock(&sctx->stat_lock); + sctx->stat.last_physical = physical + logical_length; ++ spin_unlock(&sctx->stat_lock); + ret = 0; + break; + } +@@ -2336,6 +2345,10 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, + stripe_logical += chunk_logical; + ret = scrub_raid56_parity_stripe(sctx, scrub_dev, bg, + map, stripe_logical); ++ spin_lock(&sctx->stat_lock); ++ sctx->stat.last_physical = min(physical + BTRFS_STRIPE_LEN, ++ physical_end); ++ spin_unlock(&sctx->stat_lock); + if (ret) + goto out; + goto next; +diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c +index 897e19790522d..de1c063bc39db 100644 +--- a/fs/btrfs/tree-checker.c ++++ b/fs/btrfs/tree-checker.c +@@ -1272,6 +1272,19 @@ static void extent_err(const struct extent_buffer *eb, int slot, + va_end(args); + } + ++static bool is_valid_dref_root(u64 rootid) ++{ ++ /* ++ * The following tree root objectids are allowed to have a data backref: ++ * - subvolume trees ++ * - data reloc tree ++ * - tree root ++ * For v1 space cache ++ */ ++ return is_fstree(rootid) || rootid == BTRFS_DATA_RELOC_TREE_OBJECTID || ++ rootid == BTRFS_ROOT_TREE_OBJECTID; ++} ++ + static int check_extent_item(struct extent_buffer *leaf, + struct btrfs_key *key, int slot, + struct btrfs_key *prev_key) +@@ -1424,6 +1437,8 @@ static int check_extent_item(struct extent_buffer *leaf, + struct btrfs_extent_data_ref *dref; + struct btrfs_shared_data_ref *sref; + u64 seq; ++ u64 dref_root; ++ u64 dref_objectid; + u64 dref_offset; + u64 inline_offset; + u8 inline_type; +@@ -1467,11 +1482,26 @@ static int check_extent_item(struct extent_buffer *leaf, + */ + case BTRFS_EXTENT_DATA_REF_KEY: + dref = (struct btrfs_extent_data_ref *)(&iref->offset); ++ dref_root = btrfs_extent_data_ref_root(leaf, dref); ++ dref_objectid = btrfs_extent_data_ref_objectid(leaf, dref); + dref_offset = btrfs_extent_data_ref_offset(leaf, dref); + seq = hash_extent_data_ref( + btrfs_extent_data_ref_root(leaf, dref), + btrfs_extent_data_ref_objectid(leaf, dref), + btrfs_extent_data_ref_offset(leaf, dref)); ++ if (unlikely(!is_valid_dref_root(dref_root))) { ++ extent_err(leaf, slot, ++ "invalid data ref root value %llu", ++ dref_root); ++ return -EUCLEAN; ++ } ++ if (unlikely(dref_objectid < BTRFS_FIRST_FREE_OBJECTID || ++ dref_objectid > BTRFS_LAST_FREE_OBJECTID)) { ++ extent_err(leaf, slot, ++ "invalid data ref objectid value %llu", ++ dref_root); ++ return -EUCLEAN; ++ } + if (unlikely(!IS_ALIGNED(dref_offset, + fs_info->sectorsize))) { + extent_err(leaf, slot, +@@ -1610,6 +1640,8 @@ static int check_extent_data_ref(struct extent_buffer *leaf, + return -EUCLEAN; + } + for (; ptr < end; ptr += sizeof(*dref)) { ++ u64 root; ++ u64 objectid; + u64 offset; + + /* +@@ -1617,7 +1649,22 @@ static int check_extent_data_ref(struct extent_buffer *leaf, + * overflow from the leaf due to hash collisions. + */ + dref = (struct btrfs_extent_data_ref *)ptr; ++ root = btrfs_extent_data_ref_root(leaf, dref); ++ objectid = btrfs_extent_data_ref_objectid(leaf, dref); + offset = btrfs_extent_data_ref_offset(leaf, dref); ++ if (unlikely(!is_valid_dref_root(root))) { ++ extent_err(leaf, slot, ++ "invalid extent data backref root value %llu", ++ root); ++ return -EUCLEAN; ++ } ++ if (unlikely(objectid < BTRFS_FIRST_FREE_OBJECTID || ++ objectid > BTRFS_LAST_FREE_OBJECTID)) { ++ extent_err(leaf, slot, ++ "invalid extent data backref objectid value %llu", ++ root); ++ return -EUCLEAN; ++ } + if (unlikely(!IS_ALIGNED(offset, leaf->fs_info->sectorsize))) { + extent_err(leaf, slot, + "invalid extent data backref offset, have %llu expect aligned to %u", +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index 5556ab491368d..92fda31c68cdc 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -4154,7 +4154,7 @@ extern struct kmem_cache *f2fs_inode_entry_slab; + * inline.c + */ + bool f2fs_may_inline_data(struct inode *inode); +-bool f2fs_sanity_check_inline_data(struct inode *inode); ++bool f2fs_sanity_check_inline_data(struct inode *inode, struct page *ipage); + bool f2fs_may_inline_dentry(struct inode *inode); + void f2fs_do_read_inline_data(struct folio *folio, struct page *ipage); + void f2fs_truncate_inline_inode(struct inode *inode, +diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c +index 215daa71dc18a..cca7d448e55cb 100644 +--- a/fs/f2fs/inline.c ++++ b/fs/f2fs/inline.c +@@ -33,11 +33,29 @@ bool f2fs_may_inline_data(struct inode *inode) + return !f2fs_post_read_required(inode); + } + +-bool f2fs_sanity_check_inline_data(struct inode *inode) ++static bool inode_has_blocks(struct inode *inode, struct page *ipage) ++{ ++ struct f2fs_inode *ri = F2FS_INODE(ipage); ++ int i; ++ ++ if (F2FS_HAS_BLOCKS(inode)) ++ return true; ++ ++ for (i = 0; i < DEF_NIDS_PER_INODE; i++) { ++ if (ri->i_nid[i]) ++ return true; ++ } ++ return false; ++} ++ ++bool f2fs_sanity_check_inline_data(struct inode *inode, struct page *ipage) + { + if (!f2fs_has_inline_data(inode)) + return false; + ++ if (inode_has_blocks(inode, ipage)) ++ return false; ++ + if (!support_inline_data(inode)) + return true; + +diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c +index ed629dabbfda4..57da02bfa823e 100644 +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -347,7 +347,7 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page) + } + } + +- if (f2fs_sanity_check_inline_data(inode)) { ++ if (f2fs_sanity_check_inline_data(inode, node_page)) { + f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix", + __func__, inode->i_ino, inode->i_mode); + return false; +diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c +index aa9cf01028489..52556b6bae6b1 100644 +--- a/fs/gfs2/quota.c ++++ b/fs/gfs2/quota.c +@@ -75,9 +75,6 @@ + #define GFS2_QD_HASH_SIZE BIT(GFS2_QD_HASH_SHIFT) + #define GFS2_QD_HASH_MASK (GFS2_QD_HASH_SIZE - 1) + +-#define QC_CHANGE 0 +-#define QC_SYNC 1 +- + /* Lock order: qd_lock -> bucket lock -> qd->lockref.lock -> lru lock */ + /* -> sd_bitmap_lock */ + static DEFINE_SPINLOCK(qd_lock); +@@ -710,7 +707,7 @@ static int sort_qd(const void *a, const void *b) + return 0; + } + +-static void do_qc(struct gfs2_quota_data *qd, s64 change, int qc_type) ++static void do_qc(struct gfs2_quota_data *qd, s64 change) + { + struct gfs2_sbd *sdp = qd->qd_sbd; + struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); +@@ -735,18 +732,16 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change, int qc_type) + qd->qd_change = x; + spin_unlock(&qd_lock); + +- if (qc_type == QC_CHANGE) { +- if (!test_and_set_bit(QDF_CHANGE, &qd->qd_flags)) { +- qd_hold(qd); +- slot_hold(qd); +- } +- } else { ++ if (!x) { + gfs2_assert_warn(sdp, test_bit(QDF_CHANGE, &qd->qd_flags)); + clear_bit(QDF_CHANGE, &qd->qd_flags); + qc->qc_flags = 0; + qc->qc_id = 0; + slot_put(qd); + qd_put(qd); ++ } else if (!test_and_set_bit(QDF_CHANGE, &qd->qd_flags)) { ++ qd_hold(qd); ++ slot_hold(qd); + } + + if (change < 0) /* Reset quiet flag if we freed some blocks */ +@@ -992,7 +987,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) + if (error) + goto out_end_trans; + +- do_qc(qd, -qd->qd_change_sync, QC_SYNC); ++ do_qc(qd, -qd->qd_change_sync); + set_bit(QDF_REFRESH, &qd->qd_flags); + } + +@@ -1312,7 +1307,7 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, + + if (qid_eq(qd->qd_id, make_kqid_uid(uid)) || + qid_eq(qd->qd_id, make_kqid_gid(gid))) { +- do_qc(qd, change, QC_CHANGE); ++ do_qc(qd, change); + } + } + } +diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c +index af4758d8d894c..551efd7820ad8 100644 +--- a/fs/gfs2/util.c ++++ b/fs/gfs2/util.c +@@ -99,12 +99,12 @@ int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, + */ + int gfs2_freeze_lock_shared(struct gfs2_sbd *sdp) + { ++ int flags = LM_FLAG_NOEXP | GL_EXACT; + int error; + +- error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, +- LM_FLAG_NOEXP | GL_EXACT, ++ error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, flags, + &sdp->sd_freeze_gh); +- if (error) ++ if (error && error != GLR_TRYFAILED) + fs_err(sdp, "can't lock the freeze glock: %d\n", error); + return error; + } +diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c +index ff69ae24c4e89..272c8a1dab3c2 100644 +--- a/fs/notify/fsnotify.c ++++ b/fs/notify/fsnotify.c +@@ -117,17 +117,13 @@ void fsnotify_sb_free(struct super_block *sb) + * parent cares. Thus when an event happens on a child it can quickly tell + * if there is a need to find a parent and send the event to the parent. + */ +-void __fsnotify_update_child_dentry_flags(struct inode *inode) ++void fsnotify_set_children_dentry_flags(struct inode *inode) + { + struct dentry *alias; +- int watched; + + if (!S_ISDIR(inode->i_mode)) + return; + +- /* determine if the children should tell inode about their events */ +- watched = fsnotify_inode_watches_children(inode); +- + spin_lock(&inode->i_lock); + /* run all of the dentries associated with this inode. Since this is a + * directory, there damn well better only be one item on this list */ +@@ -143,10 +139,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) + continue; + + spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); +- if (watched) +- child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; +- else +- child->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; ++ child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; + spin_unlock(&child->d_lock); + } + spin_unlock(&alias->d_lock); +@@ -154,6 +147,24 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) + spin_unlock(&inode->i_lock); + } + ++/* ++ * Lazily clear false positive PARENT_WATCHED flag for child whose parent had ++ * stopped watching children. ++ */ ++static void fsnotify_clear_child_dentry_flag(struct inode *pinode, ++ struct dentry *dentry) ++{ ++ spin_lock(&dentry->d_lock); ++ /* ++ * d_lock is a sufficient barrier to prevent observing a non-watched ++ * parent state from before the fsnotify_set_children_dentry_flags() ++ * or fsnotify_update_flags() call that had set PARENT_WATCHED. ++ */ ++ if (!fsnotify_inode_watches_children(pinode)) ++ dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; ++ spin_unlock(&dentry->d_lock); ++} ++ + /* Are inode/sb/mount interested in parent and name info with this event? */ + static bool fsnotify_event_needs_parent(struct inode *inode, __u32 mnt_mask, + __u32 mask) +@@ -228,7 +239,7 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, + p_inode = parent->d_inode; + p_mask = fsnotify_inode_watches_children(p_inode); + if (unlikely(parent_watched && !p_mask)) +- __fsnotify_update_child_dentry_flags(p_inode); ++ fsnotify_clear_child_dentry_flag(p_inode, dentry); + + /* + * Include parent/name in notification either if some notification +diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h +index 2d059f789ee35..663759ed6fbc1 100644 +--- a/fs/notify/fsnotify.h ++++ b/fs/notify/fsnotify.h +@@ -93,7 +93,7 @@ static inline void fsnotify_clear_marks_by_sb(struct super_block *sb) + * update the dentry->d_flags of all of inode's children to indicate if inode cares + * about events that happen to its children. + */ +-extern void __fsnotify_update_child_dentry_flags(struct inode *inode); ++extern void fsnotify_set_children_dentry_flags(struct inode *inode); + + extern struct kmem_cache *fsnotify_mark_connector_cachep; + +diff --git a/fs/notify/mark.c b/fs/notify/mark.c +index c3eefa70633c4..5e170e7130886 100644 +--- a/fs/notify/mark.c ++++ b/fs/notify/mark.c +@@ -250,6 +250,24 @@ static void *__fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) + return fsnotify_update_iref(conn, want_iref); + } + ++static bool fsnotify_conn_watches_children( ++ struct fsnotify_mark_connector *conn) ++{ ++ if (conn->type != FSNOTIFY_OBJ_TYPE_INODE) ++ return false; ++ ++ return fsnotify_inode_watches_children(fsnotify_conn_inode(conn)); ++} ++ ++static void fsnotify_conn_set_children_dentry_flags( ++ struct fsnotify_mark_connector *conn) ++{ ++ if (conn->type != FSNOTIFY_OBJ_TYPE_INODE) ++ return; ++ ++ fsnotify_set_children_dentry_flags(fsnotify_conn_inode(conn)); ++} ++ + /* + * Calculate mask of events for a list of marks. The caller must make sure + * connector and connector->obj cannot disappear under us. Callers achieve +@@ -258,15 +276,23 @@ static void *__fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) + */ + void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) + { ++ bool update_children; ++ + if (!conn) + return; + + spin_lock(&conn->lock); ++ update_children = !fsnotify_conn_watches_children(conn); + __fsnotify_recalc_mask(conn); ++ update_children &= fsnotify_conn_watches_children(conn); + spin_unlock(&conn->lock); +- if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) +- __fsnotify_update_child_dentry_flags( +- fsnotify_conn_inode(conn)); ++ /* ++ * Set children's PARENT_WATCHED flags only if parent started watching. ++ * When parent stops watching, we clear false positive PARENT_WATCHED ++ * flags lazily in __fsnotify_parent(). ++ */ ++ if (update_children) ++ fsnotify_conn_set_children_dentry_flags(conn); + } + + /* Free all connectors queued for freeing once SRCU period ends */ +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 062b86a4936fd..9f5bc41433c15 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -950,7 +950,8 @@ int smb2_query_path_info(const unsigned int xid, + cmds[num_cmds++] = SMB2_OP_GET_REPARSE; + + oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, +- FILE_READ_ATTRIBUTES | FILE_READ_EA, ++ FILE_READ_ATTRIBUTES | ++ FILE_READ_EA | SYNCHRONIZE, + FILE_OPEN, create_options | + OPEN_REPARSE_POINT, ACL_NO_MODE); + cifs_get_readable_path(tcon, full_path, &cfile); +@@ -1258,7 +1259,8 @@ int smb2_query_reparse_point(const unsigned int xid, + cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); + + cifs_get_readable_path(tcon, full_path, &cfile); +- oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_READ_ATTRIBUTES, ++ oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, ++ FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE, + FILE_OPEN, OPEN_REPARSE_POINT, ACL_NO_MODE); + rc = smb2_compound_op(xid, tcon, cifs_sb, + full_path, &oparms, &in_iov, +diff --git a/include/clocksource/timer-xilinx.h b/include/clocksource/timer-xilinx.h +index c0f56fe6d22ae..d116f18de899c 100644 +--- a/include/clocksource/timer-xilinx.h ++++ b/include/clocksource/timer-xilinx.h +@@ -41,7 +41,7 @@ struct regmap; + struct xilinx_timer_priv { + struct regmap *map; + struct clk *clk; +- u32 max; ++ u64 max; + }; + + /** +diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h +index 4dd6143db2716..8be029bc50b1e 100644 +--- a/include/linux/fsnotify_backend.h ++++ b/include/linux/fsnotify_backend.h +@@ -594,12 +594,14 @@ static inline __u32 fsnotify_parent_needed_mask(__u32 mask) + + static inline int fsnotify_inode_watches_children(struct inode *inode) + { ++ __u32 parent_mask = READ_ONCE(inode->i_fsnotify_mask); ++ + /* FS_EVENT_ON_CHILD is set if the inode may care */ +- if (!(inode->i_fsnotify_mask & FS_EVENT_ON_CHILD)) ++ if (!(parent_mask & FS_EVENT_ON_CHILD)) + return 0; + /* this inode might care about child events, does it care about the + * specific set of events that can happen on a child? */ +- return inode->i_fsnotify_mask & FS_EVENTS_POSS_ON_CHILD; ++ return parent_mask & FS_EVENTS_POSS_ON_CHILD; + } + + /* +@@ -613,7 +615,7 @@ static inline void fsnotify_update_flags(struct dentry *dentry) + /* + * Serialisation of setting PARENT_WATCHED on the dentries is provided + * by d_lock. If inotify_inode_watched changes after we have taken +- * d_lock, the following __fsnotify_update_child_dentry_flags call will ++ * d_lock, the following fsnotify_set_children_dentry_flags call will + * find our entry, so it will spin until we complete here, and update + * us with the new state. + */ +diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h +index bfe7c1f1ac6d1..f0231dbc47771 100644 +--- a/include/linux/hwspinlock.h ++++ b/include/linux/hwspinlock.h +@@ -68,6 +68,7 @@ int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int, + int __hwspin_trylock(struct hwspinlock *, int, unsigned long *); + void __hwspin_unlock(struct hwspinlock *, int, unsigned long *); + int of_hwspin_lock_get_id_byname(struct device_node *np, const char *name); ++int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id); + int devm_hwspin_lock_free(struct device *dev, struct hwspinlock *hwlock); + struct hwspinlock *devm_hwspin_lock_request(struct device *dev); + struct hwspinlock *devm_hwspin_lock_request_specific(struct device *dev, +@@ -127,6 +128,11 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) + { + } + ++static inline int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id) ++{ ++ return 0; ++} ++ + static inline int of_hwspin_lock_get_id(struct device_node *np, int index) + { + return 0; +diff --git a/include/linux/i2c.h b/include/linux/i2c.h +index 424acb98c7c26..c11624a3d9c04 100644 +--- a/include/linux/i2c.h ++++ b/include/linux/i2c.h +@@ -1053,7 +1053,7 @@ static inline int of_i2c_get_board_info(struct device *dev, + struct acpi_resource; + struct acpi_resource_i2c_serialbus; + +-#if IS_ENABLED(CONFIG_ACPI) ++#if IS_REACHABLE(CONFIG_ACPI) && IS_REACHABLE(CONFIG_I2C) + bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares, + struct acpi_resource_i2c_serialbus **i2c); + int i2c_acpi_client_count(struct acpi_device *adev); +diff --git a/include/linux/soc/qcom/smem.h b/include/linux/soc/qcom/smem.h +index a36a3b9d4929e..03187bc958518 100644 +--- a/include/linux/soc/qcom/smem.h ++++ b/include/linux/soc/qcom/smem.h +@@ -14,4 +14,6 @@ phys_addr_t qcom_smem_virt_to_phys(void *p); + + int qcom_smem_get_soc_id(u32 *id); + ++int qcom_smem_bust_hwspin_lock_by_host(unsigned int host); ++ + #endif +diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h +index 2a536eea9424e..5b43d220243de 100644 +--- a/include/net/inet_timewait_sock.h ++++ b/include/net/inet_timewait_sock.h +@@ -93,8 +93,10 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, + struct inet_timewait_death_row *dr, + const int state); + +-void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, +- struct inet_hashinfo *hashinfo); ++void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw, ++ struct sock *sk, ++ struct inet_hashinfo *hashinfo, ++ int timeo); + + void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo, + bool rearm); +diff --git a/include/net/ip.h b/include/net/ip.h +index 6d735e00d3f3e..c5606cadb1a55 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -506,8 +506,7 @@ static inline unsigned int ip_skb_dst_mtu(struct sock *sk, + return mtu - lwtunnel_headroom(skb_dst(skb)->lwtstate, mtu); + } + +-struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx, +- int fc_mx_len, ++struct dst_metrics *ip_fib_metrics_init(struct nlattr *fc_mx, int fc_mx_len, + struct netlink_ext_ack *extack); + static inline void ip_fib_metrics_put(struct dst_metrics *fib_metrics) + { +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 32815a40dea16..45bbb54e42e85 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -1216,7 +1216,7 @@ extern struct tcp_congestion_ops tcp_reno; + + struct tcp_congestion_ops *tcp_ca_find(const char *name); + struct tcp_congestion_ops *tcp_ca_find_key(u32 key); +-u32 tcp_ca_get_key_by_name(struct net *net, const char *name, bool *ecn_ca); ++u32 tcp_ca_get_key_by_name(const char *name, bool *ecn_ca); + #ifdef CONFIG_INET + char *tcp_ca_get_name_by_key(u32 key, char *buffer); + #else +diff --git a/include/sound/ump_convert.h b/include/sound/ump_convert.h +index 28c364c63245d..d099ae27f8491 100644 +--- a/include/sound/ump_convert.h ++++ b/include/sound/ump_convert.h +@@ -13,6 +13,7 @@ struct ump_cvt_to_ump_bank { + unsigned char cc_nrpn_msb, cc_nrpn_lsb; + unsigned char cc_data_msb, cc_data_lsb; + unsigned char cc_bank_msb, cc_bank_lsb; ++ bool cc_data_msb_set, cc_data_lsb_set; + }; + + /* context for converting from MIDI1 byte stream to UMP packet */ +diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h +index d965e4d1277e6..52f0094a8c083 100644 +--- a/include/ufs/ufshcd.h ++++ b/include/ufs/ufshcd.h +@@ -1074,6 +1074,7 @@ struct ufs_hba { + bool ext_iid_sup; + bool scsi_host_added; + bool mcq_sup; ++ bool lsdb_sup; + bool mcq_enabled; + struct ufshcd_res_info res[RES_MAX]; + void __iomem *mcq_base; +diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h +index 385e1c6b8d604..22ba85e81d8c9 100644 +--- a/include/ufs/ufshci.h ++++ b/include/ufs/ufshci.h +@@ -75,6 +75,7 @@ enum { + MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000, + MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000, + MASK_CRYPTO_SUPPORT = 0x10000000, ++ MASK_LSDB_SUPPORT = 0x20000000, + MASK_MCQ_SUPPORT = 0x40000000, + }; + +diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c +index a6e3792b15f8a..d570535342cb7 100644 +--- a/kernel/dma/debug.c ++++ b/kernel/dma/debug.c +@@ -416,8 +416,11 @@ static unsigned long long phys_addr(struct dma_debug_entry *entry) + * dma_active_cacheline entry to track per event. dma_map_sg(), on the + * other hand, consumes a single dma_debug_entry, but inserts 'nents' + * entries into the tree. ++ * ++ * Use __GFP_NOWARN because the printk from an OOM, to netconsole, could end ++ * up right back in the DMA debugging code, leading to a deadlock. + */ +-static RADIX_TREE(dma_active_cacheline, GFP_ATOMIC); ++static RADIX_TREE(dma_active_cacheline, GFP_ATOMIC | __GFP_NOWARN); + static DEFINE_SPINLOCK(radix_lock); + #define ACTIVE_CACHELINE_MAX_OVERLAP ((1 << RADIX_TREE_MAX_TAGS) - 1) + #define CACHELINE_PER_PAGE_SHIFT (PAGE_SHIFT - L1_CACHE_SHIFT) +diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h +index bae7925c497fe..179f60ca03130 100644 +--- a/kernel/rcu/tree.h ++++ b/kernel/rcu/tree.h +@@ -223,7 +223,6 @@ struct rcu_data { + struct swait_queue_head nocb_state_wq; /* For offloading state changes */ + struct task_struct *nocb_gp_kthread; + raw_spinlock_t nocb_lock; /* Guard following pair of fields. */ +- atomic_t nocb_lock_contended; /* Contention experienced. */ + int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */ + struct timer_list nocb_timer; /* Enforce finite deferral. */ + unsigned long nocb_gp_adv_time; /* Last call_rcu() CB adv (jiffies). */ +diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h +index 3f85577bddd4e..2d9eed2bf7509 100644 +--- a/kernel/rcu/tree_nocb.h ++++ b/kernel/rcu/tree_nocb.h +@@ -91,8 +91,7 @@ module_param(nocb_nobypass_lim_per_jiffy, int, 0); + + /* + * Acquire the specified rcu_data structure's ->nocb_bypass_lock. If the +- * lock isn't immediately available, increment ->nocb_lock_contended to +- * flag the contention. ++ * lock isn't immediately available, perform minimal sanity check. + */ + static void rcu_nocb_bypass_lock(struct rcu_data *rdp) + __acquires(&rdp->nocb_bypass_lock) +@@ -100,29 +99,12 @@ static void rcu_nocb_bypass_lock(struct rcu_data *rdp) + lockdep_assert_irqs_disabled(); + if (raw_spin_trylock(&rdp->nocb_bypass_lock)) + return; +- atomic_inc(&rdp->nocb_lock_contended); ++ /* ++ * Contention expected only when local enqueue collide with ++ * remote flush from kthreads. ++ */ + WARN_ON_ONCE(smp_processor_id() != rdp->cpu); +- smp_mb__after_atomic(); /* atomic_inc() before lock. */ + raw_spin_lock(&rdp->nocb_bypass_lock); +- smp_mb__before_atomic(); /* atomic_dec() after lock. */ +- atomic_dec(&rdp->nocb_lock_contended); +-} +- +-/* +- * Spinwait until the specified rcu_data structure's ->nocb_lock is +- * not contended. Please note that this is extremely special-purpose, +- * relying on the fact that at most two kthreads and one CPU contend for +- * this lock, and also that the two kthreads are guaranteed to have frequent +- * grace-period-duration time intervals between successive acquisitions +- * of the lock. This allows us to use an extremely simple throttling +- * mechanism, and further to apply it only to the CPU doing floods of +- * call_rcu() invocations. Don't try this at home! +- */ +-static void rcu_nocb_wait_contended(struct rcu_data *rdp) +-{ +- WARN_ON_ONCE(smp_processor_id() != rdp->cpu); +- while (WARN_ON_ONCE(atomic_read(&rdp->nocb_lock_contended))) +- cpu_relax(); + } + + /* +@@ -510,7 +492,6 @@ static bool rcu_nocb_try_bypass(struct rcu_data *rdp, struct rcu_head *rhp, + } + + // We need to use the bypass. +- rcu_nocb_wait_contended(rdp); + rcu_nocb_bypass_lock(rdp); + ncbs = rcu_cblist_n_cbs(&rdp->nocb_bypass); + rcu_segcblist_inc_len(&rdp->cblist); /* Must precede enqueue. */ +@@ -1678,12 +1659,11 @@ static void show_rcu_nocb_state(struct rcu_data *rdp) + + sprintf(bufw, "%ld", rsclp->gp_seq[RCU_WAIT_TAIL]); + sprintf(bufr, "%ld", rsclp->gp_seq[RCU_NEXT_READY_TAIL]); +- pr_info(" CB %d^%d->%d %c%c%c%c%c%c F%ld L%ld C%d %c%c%s%c%s%c%c q%ld %c CPU %d%s\n", ++ pr_info(" CB %d^%d->%d %c%c%c%c%c F%ld L%ld C%d %c%c%s%c%s%c%c q%ld %c CPU %d%s\n", + rdp->cpu, rdp->nocb_gp_rdp->cpu, + nocb_next_rdp ? nocb_next_rdp->cpu : -1, + "kK"[!!rdp->nocb_cb_kthread], + "bB"[raw_spin_is_locked(&rdp->nocb_bypass_lock)], +- "cC"[!!atomic_read(&rdp->nocb_lock_contended)], + "lL"[raw_spin_is_locked(&rdp->nocb_lock)], + "sS"[!!rdp->nocb_cb_sleep], + ".W"[swait_active(&rdp->nocb_cb_wq)], +diff --git a/mm/filemap.c b/mm/filemap.c +index 657bcd887fdb8..3577f94f69d97 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -4221,7 +4221,7 @@ int filemap_invalidate_inode(struct inode *inode, bool flush, + } + + /* Wait for writeback to complete on all folios and discard. */ +- truncate_inode_pages_range(mapping, start, end); ++ invalidate_inode_pages2_range(mapping, start / PAGE_SIZE, end / PAGE_SIZE); + + unlock: + filemap_invalidate_unlock(mapping); +diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c +index 251a57cf58223..deb52d7d31b48 100644 +--- a/net/dccp/minisocks.c ++++ b/net/dccp/minisocks.c +@@ -59,11 +59,10 @@ void dccp_time_wait(struct sock *sk, int state, int timeo) + * we complete the initialization. + */ + local_bh_disable(); +- inet_twsk_schedule(tw, timeo); + /* Linkage updates. + * Note that access to tw after this point is illegal. + */ +- inet_twsk_hashdance(tw, sk, &dccp_hashinfo); ++ inet_twsk_hashdance_schedule(tw, sk, &dccp_hashinfo, timeo); + local_bh_enable(); + } else { + /* Sorry, if we're out of memory, just CLOSE this +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index 8956026bc0a2c..2b57cd2b96e2a 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -1030,7 +1030,7 @@ bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi) + bool ecn_ca = false; + + nla_strscpy(tmp, nla, sizeof(tmp)); +- val = tcp_ca_get_key_by_name(fi->fib_net, tmp, &ecn_ca); ++ val = tcp_ca_get_key_by_name(tmp, &ecn_ca); + } else { + if (nla_len(nla) != sizeof(u32)) + return false; +@@ -1459,8 +1459,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, + fi = kzalloc(struct_size(fi, fib_nh, nhs), GFP_KERNEL); + if (!fi) + goto failure; +- fi->fib_metrics = ip_fib_metrics_init(fi->fib_net, cfg->fc_mx, +- cfg->fc_mx_len, extack); ++ fi->fib_metrics = ip_fib_metrics_init(cfg->fc_mx, cfg->fc_mx_len, extack); + if (IS_ERR(fi->fib_metrics)) { + err = PTR_ERR(fi->fib_metrics); + kfree(fi); +diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c +index e28075f0006e3..628d33a41ce5f 100644 +--- a/net/ipv4/inet_timewait_sock.c ++++ b/net/ipv4/inet_timewait_sock.c +@@ -96,9 +96,13 @@ static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw, + * Enter the time wait state. This is called with locally disabled BH. + * Essentially we whip up a timewait bucket, copy the relevant info into it + * from the SK, and mess with hash chains and list linkage. ++ * ++ * The caller must not access @tw anymore after this function returns. + */ +-void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, +- struct inet_hashinfo *hashinfo) ++void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw, ++ struct sock *sk, ++ struct inet_hashinfo *hashinfo, ++ int timeo) + { + const struct inet_sock *inet = inet_sk(sk); + const struct inet_connection_sock *icsk = inet_csk(sk); +@@ -129,26 +133,33 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, + + spin_lock(lock); + ++ /* Step 2: Hash TW into tcp ehash chain */ + inet_twsk_add_node_rcu(tw, &ehead->chain); + + /* Step 3: Remove SK from hash chain */ + if (__sk_nulls_del_node_init_rcu(sk)) + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + +- spin_unlock(lock); + ++ /* Ensure above writes are committed into memory before updating the ++ * refcount. ++ * Provides ordering vs later refcount_inc(). ++ */ ++ smp_wmb(); + /* tw_refcnt is set to 3 because we have : + * - one reference for bhash chain. + * - one reference for ehash chain. + * - one reference for timer. +- * We can use atomic_set() because prior spin_lock()/spin_unlock() +- * committed into memory all tw fields. + * Also note that after this point, we lost our implicit reference + * so we are not allowed to use tw anymore. + */ + refcount_set(&tw->tw_refcnt, 3); ++ ++ inet_twsk_schedule(tw, timeo); ++ ++ spin_unlock(lock); + } +-EXPORT_SYMBOL_GPL(inet_twsk_hashdance); ++EXPORT_SYMBOL_GPL(inet_twsk_hashdance_schedule); + + static void tw_timer_handler(struct timer_list *t) + { +@@ -217,7 +228,34 @@ EXPORT_SYMBOL_GPL(inet_twsk_alloc); + */ + void inet_twsk_deschedule_put(struct inet_timewait_sock *tw) + { +- if (del_timer_sync(&tw->tw_timer)) ++ struct inet_hashinfo *hashinfo = tw->tw_dr->hashinfo; ++ spinlock_t *lock = inet_ehash_lockp(hashinfo, tw->tw_hash); ++ ++ /* inet_twsk_purge() walks over all sockets, including tw ones, ++ * and removes them via inet_twsk_deschedule_put() after a ++ * refcount_inc_not_zero(). ++ * ++ * inet_twsk_hashdance_schedule() must (re)init the refcount before ++ * arming the timer, i.e. inet_twsk_purge can obtain a reference to ++ * a twsk that did not yet schedule the timer. ++ * ++ * The ehash lock synchronizes these two: ++ * After acquiring the lock, the timer is always scheduled (else ++ * timer_shutdown returns false), because hashdance_schedule releases ++ * the ehash lock only after completing the timer initialization. ++ * ++ * Without grabbing the ehash lock, we get: ++ * 1) cpu x sets twsk refcount to 3 ++ * 2) cpu y bumps refcount to 4 ++ * 3) cpu y calls inet_twsk_deschedule_put() and shuts timer down ++ * 4) cpu x tries to start timer, but mod_timer is a noop post-shutdown ++ * -> timer refcount is never decremented. ++ */ ++ spin_lock(lock); ++ /* Makes sure hashdance_schedule() has completed */ ++ spin_unlock(lock); ++ ++ if (timer_shutdown_sync(&tw->tw_timer)) + inet_twsk_kill(tw); + inet_twsk_put(tw); + } +diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c +index 0e3ee1532848c..8ddac1f595ed8 100644 +--- a/net/ipv4/metrics.c ++++ b/net/ipv4/metrics.c +@@ -7,7 +7,7 @@ + #include <net/net_namespace.h> + #include <net/tcp.h> + +-static int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, ++static int ip_metrics_convert(struct nlattr *fc_mx, + int fc_mx_len, u32 *metrics, + struct netlink_ext_ack *extack) + { +@@ -31,7 +31,7 @@ static int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, + char tmp[TCP_CA_NAME_MAX]; + + nla_strscpy(tmp, nla, sizeof(tmp)); +- val = tcp_ca_get_key_by_name(net, tmp, &ecn_ca); ++ val = tcp_ca_get_key_by_name(tmp, &ecn_ca); + if (val == TCP_CA_UNSPEC) { + NL_SET_ERR_MSG(extack, "Unknown tcp congestion algorithm"); + return -EINVAL; +@@ -63,7 +63,7 @@ static int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, + return 0; + } + +-struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx, ++struct dst_metrics *ip_fib_metrics_init(struct nlattr *fc_mx, + int fc_mx_len, + struct netlink_ext_ack *extack) + { +@@ -77,7 +77,7 @@ struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx, + if (unlikely(!fib_metrics)) + return ERR_PTR(-ENOMEM); + +- err = ip_metrics_convert(net, fc_mx, fc_mx_len, fib_metrics->metrics, ++ err = ip_metrics_convert(fc_mx, fc_mx_len, fib_metrics->metrics, + extack); + if (!err) { + refcount_set(&fib_metrics->refcnt, 1); +diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c +index 28ffcfbeef14e..48617d99abb0d 100644 +--- a/net/ipv4/tcp_cong.c ++++ b/net/ipv4/tcp_cong.c +@@ -46,8 +46,7 @@ void tcp_set_ca_state(struct sock *sk, const u8 ca_state) + } + + /* Must be called with rcu lock held */ +-static struct tcp_congestion_ops *tcp_ca_find_autoload(struct net *net, +- const char *name) ++static struct tcp_congestion_ops *tcp_ca_find_autoload(const char *name) + { + struct tcp_congestion_ops *ca = tcp_ca_find(name); + +@@ -178,7 +177,7 @@ int tcp_update_congestion_control(struct tcp_congestion_ops *ca, struct tcp_cong + return ret; + } + +-u32 tcp_ca_get_key_by_name(struct net *net, const char *name, bool *ecn_ca) ++u32 tcp_ca_get_key_by_name(const char *name, bool *ecn_ca) + { + const struct tcp_congestion_ops *ca; + u32 key = TCP_CA_UNSPEC; +@@ -186,7 +185,7 @@ u32 tcp_ca_get_key_by_name(struct net *net, const char *name, bool *ecn_ca) + might_sleep(); + + rcu_read_lock(); +- ca = tcp_ca_find_autoload(net, name); ++ ca = tcp_ca_find_autoload(name); + if (ca) { + key = ca->key; + *ecn_ca = ca->flags & TCP_CONG_NEEDS_ECN; +@@ -283,7 +282,7 @@ int tcp_set_default_congestion_control(struct net *net, const char *name) + int ret; + + rcu_read_lock(); +- ca = tcp_ca_find_autoload(net, name); ++ ca = tcp_ca_find_autoload(name); + if (!ca) { + ret = -ENOENT; + } else if (!bpf_try_module_get(ca, ca->owner)) { +@@ -421,7 +420,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, + if (!load) + ca = tcp_ca_find(name); + else +- ca = tcp_ca_find_autoload(sock_net(sk), name); ++ ca = tcp_ca_find_autoload(name); + + /* No change asking for existing value */ + if (ca == icsk->icsk_ca_ops) { +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 8f8f93716ff85..da0f502553991 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -116,6 +116,7 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) + const struct inet_timewait_sock *tw = inet_twsk(sktw); + const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw); + struct tcp_sock *tp = tcp_sk(sk); ++ int ts_recent_stamp; + + if (reuse == 2) { + /* Still does not detect *everything* that goes through +@@ -154,10 +155,11 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) + If TW bucket has been already destroyed we fall back to VJ's scheme + and use initial timestamp retrieved from peer table. + */ +- if (tcptw->tw_ts_recent_stamp && ++ ts_recent_stamp = READ_ONCE(tcptw->tw_ts_recent_stamp); ++ if (ts_recent_stamp && + (!twp || (reuse && time_after32(ktime_get_seconds(), +- tcptw->tw_ts_recent_stamp)))) { +- /* inet_twsk_hashdance() sets sk_refcnt after putting twsk ++ ts_recent_stamp)))) { ++ /* inet_twsk_hashdance_schedule() sets sk_refcnt after putting twsk + * and releasing the bucket lock. + */ + if (unlikely(!refcount_inc_not_zero(&sktw->sk_refcnt))) +@@ -180,8 +182,8 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) + if (!seq) + seq = 1; + WRITE_ONCE(tp->write_seq, seq); +- tp->rx_opt.ts_recent = tcptw->tw_ts_recent; +- tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; ++ tp->rx_opt.ts_recent = READ_ONCE(tcptw->tw_ts_recent); ++ tp->rx_opt.ts_recent_stamp = ts_recent_stamp; + } + + return 1; +@@ -1066,7 +1068,7 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) + tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, + tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, + tcp_tw_tsval(tcptw), +- tcptw->tw_ts_recent, ++ READ_ONCE(tcptw->tw_ts_recent), + tw->tw_bound_dev_if, &key, + tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0, + tw->tw_tos, +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index 0fbebf6266e91..d5da3ec8f846e 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -101,16 +101,18 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, + struct tcp_options_received tmp_opt; + struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); + bool paws_reject = false; ++ int ts_recent_stamp; + + tmp_opt.saw_tstamp = 0; +- if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { ++ ts_recent_stamp = READ_ONCE(tcptw->tw_ts_recent_stamp); ++ if (th->doff > (sizeof(*th) >> 2) && ts_recent_stamp) { + tcp_parse_options(twsk_net(tw), skb, &tmp_opt, 0, NULL); + + if (tmp_opt.saw_tstamp) { + if (tmp_opt.rcv_tsecr) + tmp_opt.rcv_tsecr -= tcptw->tw_ts_offset; +- tmp_opt.ts_recent = tcptw->tw_ts_recent; +- tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; ++ tmp_opt.ts_recent = READ_ONCE(tcptw->tw_ts_recent); ++ tmp_opt.ts_recent_stamp = ts_recent_stamp; + paws_reject = tcp_paws_reject(&tmp_opt, th->rst); + } + } +@@ -152,8 +154,10 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, + twsk_rcv_nxt_update(tcptw, TCP_SKB_CB(skb)->end_seq); + + if (tmp_opt.saw_tstamp) { +- tcptw->tw_ts_recent_stamp = ktime_get_seconds(); +- tcptw->tw_ts_recent = tmp_opt.rcv_tsval; ++ WRITE_ONCE(tcptw->tw_ts_recent_stamp, ++ ktime_get_seconds()); ++ WRITE_ONCE(tcptw->tw_ts_recent, ++ tmp_opt.rcv_tsval); + } + + inet_twsk_reschedule(tw, TCP_TIMEWAIT_LEN); +@@ -197,8 +201,10 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, + } + + if (tmp_opt.saw_tstamp) { +- tcptw->tw_ts_recent = tmp_opt.rcv_tsval; +- tcptw->tw_ts_recent_stamp = ktime_get_seconds(); ++ WRITE_ONCE(tcptw->tw_ts_recent, ++ tmp_opt.rcv_tsval); ++ WRITE_ONCE(tcptw->tw_ts_recent_stamp, ++ ktime_get_seconds()); + } + + inet_twsk_put(tw); +@@ -225,7 +231,7 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, + if (th->syn && !th->rst && !th->ack && !paws_reject && + (after(TCP_SKB_CB(skb)->seq, tcptw->tw_rcv_nxt) || + (tmp_opt.saw_tstamp && +- (s32)(tcptw->tw_ts_recent - tmp_opt.rcv_tsval) < 0))) { ++ (s32)(READ_ONCE(tcptw->tw_ts_recent) - tmp_opt.rcv_tsval) < 0))) { + u32 isn = tcptw->tw_snd_nxt + 65535 + 2; + if (isn == 0) + isn++; +@@ -344,11 +350,10 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) + * we complete the initialization. + */ + local_bh_disable(); +- inet_twsk_schedule(tw, timeo); + /* Linkage updates. + * Note that access to tw after this point is illegal. + */ +- inet_twsk_hashdance(tw, sk, net->ipv4.tcp_death_row.hashinfo); ++ inet_twsk_hashdance_schedule(tw, sk, net->ipv4.tcp_death_row.hashinfo, timeo); + local_bh_enable(); + } else { + /* Sorry, if we're out of memory, just CLOSE this +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index c9a9506b714d7..a9644a8edb960 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3764,7 +3764,7 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg, + if (!rt) + goto out; + +- rt->fib6_metrics = ip_fib_metrics_init(net, cfg->fc_mx, cfg->fc_mx_len, ++ rt->fib6_metrics = ip_fib_metrics_init(cfg->fc_mx, cfg->fc_mx_len, + extack); + if (IS_ERR(rt->fib6_metrics)) { + err = PTR_ERR(rt->fib6_metrics); +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 3385faf1d5dcb..66f6fe5afb030 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1196,9 +1196,9 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) + tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, + tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, + tcp_tw_tsval(tcptw), +- tcptw->tw_ts_recent, tw->tw_bound_dev_if, &key, +- tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority, +- tw->tw_txhash); ++ READ_ONCE(tcptw->tw_ts_recent), tw->tw_bound_dev_if, ++ &key, tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), ++ tw->tw_priority, tw->tw_txhash); + + #ifdef CONFIG_TCP_AO + out: +diff --git a/net/mac80211/main.c b/net/mac80211/main.c +index 7ba329ebdda91..e44b2a26354b5 100644 +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -337,6 +337,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, + + might_sleep(); + ++ WARN_ON_ONCE(ieee80211_vif_is_mld(&sdata->vif)); ++ + if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + return; + +@@ -369,7 +371,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, + if (changed & ~BSS_CHANGED_VIF_CFG_FLAGS) { + u64 ch = changed & ~BSS_CHANGED_VIF_CFG_FLAGS; + +- /* FIXME: should be for each link */ + trace_drv_link_info_changed(local, sdata, &sdata->vif.bss_conf, + changed); + if (local->ops->link_info_changed) +diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c +index 9f02ee5f08beb..34e5acff39351 100644 +--- a/net/wireless/ibss.c ++++ b/net/wireless/ibss.c +@@ -3,7 +3,7 @@ + * Some IBSS support code for cfg80211. + * + * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> +- * Copyright (C) 2020-2023 Intel Corporation ++ * Copyright (C) 2020-2024 Intel Corporation + */ + + #include <linux/etherdevice.h> +@@ -94,6 +94,9 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, + + lockdep_assert_held(&rdev->wiphy.mtx); + ++ if (wdev->cac_started) ++ return -EBUSY; ++ + if (wdev->u.ibss.ssid_len) + return -EALREADY; + +diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c +index 83306979fbe21..aaca65b66af48 100644 +--- a/net/wireless/mesh.c ++++ b/net/wireless/mesh.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* + * Portions +- * Copyright (C) 2022-2023 Intel Corporation ++ * Copyright (C) 2022-2024 Intel Corporation + */ + #include <linux/ieee80211.h> + #include <linux/export.h> +@@ -127,6 +127,9 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, + if (!rdev->ops->join_mesh) + return -EOPNOTSUPP; + ++ if (wdev->cac_started) ++ return -EBUSY; ++ + if (!setup->chandef.chan) { + /* if no channel explicitly given, use preset channel */ + setup->chandef = wdev->u.mesh.preset_chandef; +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index c2829d673bc76..967bc4935b4ed 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -5965,6 +5965,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) + if (!rdev->ops->start_ap) + return -EOPNOTSUPP; + ++ if (wdev->cac_started) ++ return -EBUSY; ++ + if (wdev->links[link_id].ap.beacon_interval) + return -EALREADY; + +@@ -9957,6 +9960,17 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, + + flush_delayed_work(&rdev->dfs_update_channels_wk); + ++ switch (wdev->iftype) { ++ case NL80211_IFTYPE_AP: ++ case NL80211_IFTYPE_P2P_GO: ++ case NL80211_IFTYPE_MESH_POINT: ++ case NL80211_IFTYPE_ADHOC: ++ break; ++ default: ++ /* caution - see cfg80211_beaconing_iface_active() below */ ++ return -EINVAL; ++ } ++ + wiphy_lock(wiphy); + + dfs_region = reg_get_dfs_region(wiphy); +@@ -9987,12 +10001,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, + goto unlock; + } + +- if (netif_carrier_ok(dev)) { +- err = -EBUSY; +- goto unlock; +- } +- +- if (wdev->cac_started) { ++ if (cfg80211_beaconing_iface_active(wdev) || wdev->cac_started) { + err = -EBUSY; + goto unlock; + } +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 292b530a6dd31..64c779788a646 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -1604,7 +1604,7 @@ struct cfg80211_bss *__cfg80211_get_bss(struct wiphy *wiphy, + } + EXPORT_SYMBOL(__cfg80211_get_bss); + +-static void rb_insert_bss(struct cfg80211_registered_device *rdev, ++static bool rb_insert_bss(struct cfg80211_registered_device *rdev, + struct cfg80211_internal_bss *bss) + { + struct rb_node **p = &rdev->bss_tree.rb_node; +@@ -1620,7 +1620,7 @@ static void rb_insert_bss(struct cfg80211_registered_device *rdev, + + if (WARN_ON(!cmp)) { + /* will sort of leak this BSS */ +- return; ++ return false; + } + + if (cmp < 0) +@@ -1631,6 +1631,7 @@ static void rb_insert_bss(struct cfg80211_registered_device *rdev, + + rb_link_node(&bss->rbn, parent, p); + rb_insert_color(&bss->rbn, &rdev->bss_tree); ++ return true; + } + + static struct cfg80211_internal_bss * +@@ -1657,6 +1658,34 @@ rb_find_bss(struct cfg80211_registered_device *rdev, + return NULL; + } + ++static void cfg80211_insert_bss(struct cfg80211_registered_device *rdev, ++ struct cfg80211_internal_bss *bss) ++{ ++ lockdep_assert_held(&rdev->bss_lock); ++ ++ if (!rb_insert_bss(rdev, bss)) ++ return; ++ list_add_tail(&bss->list, &rdev->bss_list); ++ rdev->bss_entries++; ++} ++ ++static void cfg80211_rehash_bss(struct cfg80211_registered_device *rdev, ++ struct cfg80211_internal_bss *bss) ++{ ++ lockdep_assert_held(&rdev->bss_lock); ++ ++ rb_erase(&bss->rbn, &rdev->bss_tree); ++ if (!rb_insert_bss(rdev, bss)) { ++ list_del(&bss->list); ++ if (!list_empty(&bss->hidden_list)) ++ list_del_init(&bss->hidden_list); ++ if (!list_empty(&bss->pub.nontrans_list)) ++ list_del_init(&bss->pub.nontrans_list); ++ rdev->bss_entries--; ++ } ++ rdev->bss_generation++; ++} ++ + static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev, + struct cfg80211_internal_bss *new) + { +@@ -1969,9 +1998,7 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev, + bss_ref_get(rdev, bss_from_pub(tmp->pub.transmitted_bss)); + } + +- list_add_tail(&new->list, &rdev->bss_list); +- rdev->bss_entries++; +- rb_insert_bss(rdev, new); ++ cfg80211_insert_bss(rdev, new); + found = new; + } + +@@ -3354,19 +3381,14 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev, + if (!WARN_ON(!__cfg80211_unlink_bss(rdev, new))) + rdev->bss_generation++; + } +- +- rb_erase(&cbss->rbn, &rdev->bss_tree); +- rb_insert_bss(rdev, cbss); +- rdev->bss_generation++; ++ cfg80211_rehash_bss(rdev, cbss); + + list_for_each_entry_safe(nontrans_bss, tmp, + &cbss->pub.nontrans_list, + nontrans_list) { + bss = bss_from_pub(nontrans_bss); + bss->pub.channel = chan; +- rb_erase(&bss->rbn, &rdev->bss_tree); +- rb_insert_bss(rdev, bss); +- rdev->bss_generation++; ++ cfg80211_rehash_bss(rdev, bss); + } + + done: +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index bcfea073e3f2e..01b923d97a446 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -1692,6 +1692,10 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent) + struct aa_profile *p; + p = aa_deref_parent(profile); + dent = prof_dir(p); ++ if (!dent) { ++ error = -ENOENT; ++ goto fail2; ++ } + /* adding to parent that previously didn't have children */ + dent = aafs_create_dir("profiles", dent); + if (IS_ERR(dent)) +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 081129be5b62c..ab939e6449e41 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -4456,7 +4456,7 @@ static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb, + rcu_read_unlock(); + + if (hskp == NULL) +- rc = netlbl_req_setattr(req, &skp->smk_netlabel); ++ rc = netlbl_req_setattr(req, &ssp->smk_out->smk_netlabel); + else + netlbl_req_delattr(req); + +diff --git a/sound/core/seq/seq_ports.h b/sound/core/seq/seq_ports.h +index b111382f697aa..9e36738c0dd04 100644 +--- a/sound/core/seq/seq_ports.h ++++ b/sound/core/seq/seq_ports.h +@@ -7,6 +7,7 @@ + #define __SND_SEQ_PORTS_H + + #include <sound/seq_kernel.h> ++#include <sound/ump_convert.h> + #include "seq_lock.h" + + /* list of 'exported' ports */ +@@ -42,17 +43,6 @@ struct snd_seq_port_subs_info { + int (*close)(void *private_data, struct snd_seq_port_subscribe *info); + }; + +-/* context for converting from legacy control event to UMP packet */ +-struct snd_seq_ump_midi2_bank { +- bool rpn_set; +- bool nrpn_set; +- bool bank_set; +- unsigned char cc_rpn_msb, cc_rpn_lsb; +- unsigned char cc_nrpn_msb, cc_nrpn_lsb; +- unsigned char cc_data_msb, cc_data_lsb; +- unsigned char cc_bank_msb, cc_bank_lsb; +-}; +- + struct snd_seq_client_port { + + struct snd_seq_addr addr; /* client/port number */ +@@ -88,7 +78,7 @@ struct snd_seq_client_port { + unsigned char ump_group; + + #if IS_ENABLED(CONFIG_SND_SEQ_UMP) +- struct snd_seq_ump_midi2_bank midi2_bank[16]; /* per channel */ ++ struct ump_cvt_to_ump_bank midi2_bank[16]; /* per channel */ + #endif + }; + +diff --git a/sound/core/seq/seq_ump_convert.c b/sound/core/seq/seq_ump_convert.c +index d9dacfbe4a9ae..4dd540cbb1cbb 100644 +--- a/sound/core/seq/seq_ump_convert.c ++++ b/sound/core/seq/seq_ump_convert.c +@@ -368,7 +368,7 @@ static int cvt_ump_midi1_to_midi2(struct snd_seq_client *dest, + struct snd_seq_ump_event ev_cvt; + const union snd_ump_midi1_msg *midi1 = (const union snd_ump_midi1_msg *)event->ump; + union snd_ump_midi2_msg *midi2 = (union snd_ump_midi2_msg *)ev_cvt.ump; +- struct snd_seq_ump_midi2_bank *cc; ++ struct ump_cvt_to_ump_bank *cc; + + ev_cvt = *event; + memset(&ev_cvt.ump, 0, sizeof(ev_cvt.ump)); +@@ -789,28 +789,45 @@ static int paf_ev_to_ump_midi2(const struct snd_seq_event *event, + return 1; + } + ++static void reset_rpn(struct ump_cvt_to_ump_bank *cc) ++{ ++ cc->rpn_set = 0; ++ cc->nrpn_set = 0; ++ cc->cc_rpn_msb = cc->cc_rpn_lsb = 0; ++ cc->cc_data_msb = cc->cc_data_lsb = 0; ++ cc->cc_data_msb_set = cc->cc_data_lsb_set = 0; ++} ++ + /* set up the MIDI2 RPN/NRPN packet data from the parsed info */ +-static void fill_rpn(struct snd_seq_ump_midi2_bank *cc, +- union snd_ump_midi2_msg *data, +- unsigned char channel) ++static int fill_rpn(struct ump_cvt_to_ump_bank *cc, ++ union snd_ump_midi2_msg *data, ++ unsigned char channel, ++ bool flush) + { ++ if (!(cc->cc_data_lsb_set || cc->cc_data_msb_set)) ++ return 0; // skip ++ /* when not flushing, wait for complete data set */ ++ if (!flush && (!cc->cc_data_lsb_set || !cc->cc_data_msb_set)) ++ return 0; // skip ++ + if (cc->rpn_set) { + data->rpn.status = UMP_MSG_STATUS_RPN; + data->rpn.bank = cc->cc_rpn_msb; + data->rpn.index = cc->cc_rpn_lsb; +- cc->rpn_set = 0; +- cc->cc_rpn_msb = cc->cc_rpn_lsb = 0; +- } else { ++ } else if (cc->nrpn_set) { + data->rpn.status = UMP_MSG_STATUS_NRPN; + data->rpn.bank = cc->cc_nrpn_msb; + data->rpn.index = cc->cc_nrpn_lsb; +- cc->nrpn_set = 0; +- cc->cc_nrpn_msb = cc->cc_nrpn_lsb = 0; ++ } else { ++ return 0; // skip + } ++ + data->rpn.data = upscale_14_to_32bit((cc->cc_data_msb << 7) | + cc->cc_data_lsb); + data->rpn.channel = channel; +- cc->cc_data_msb = cc->cc_data_lsb = 0; ++ ++ reset_rpn(cc); ++ return 1; + } + + /* convert CC event to MIDI 2.0 UMP */ +@@ -822,29 +839,39 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event, + unsigned char channel = event->data.control.channel & 0x0f; + unsigned char index = event->data.control.param & 0x7f; + unsigned char val = event->data.control.value & 0x7f; +- struct snd_seq_ump_midi2_bank *cc = &dest_port->midi2_bank[channel]; ++ struct ump_cvt_to_ump_bank *cc = &dest_port->midi2_bank[channel]; ++ int ret; + + /* process special CC's (bank/rpn/nrpn) */ + switch (index) { + case UMP_CC_RPN_MSB: ++ ret = fill_rpn(cc, data, channel, true); + cc->rpn_set = 1; + cc->cc_rpn_msb = val; +- return 0; // skip ++ if (cc->cc_rpn_msb == 0x7f && cc->cc_rpn_lsb == 0x7f) ++ reset_rpn(cc); ++ return ret; + case UMP_CC_RPN_LSB: ++ ret = fill_rpn(cc, data, channel, true); + cc->rpn_set = 1; + cc->cc_rpn_lsb = val; +- return 0; // skip ++ if (cc->cc_rpn_msb == 0x7f && cc->cc_rpn_lsb == 0x7f) ++ reset_rpn(cc); ++ return ret; + case UMP_CC_NRPN_MSB: ++ ret = fill_rpn(cc, data, channel, true); + cc->nrpn_set = 1; + cc->cc_nrpn_msb = val; +- return 0; // skip ++ return ret; + case UMP_CC_NRPN_LSB: ++ ret = fill_rpn(cc, data, channel, true); + cc->nrpn_set = 1; + cc->cc_nrpn_lsb = val; +- return 0; // skip ++ return ret; + case UMP_CC_DATA: ++ cc->cc_data_msb_set = 1; + cc->cc_data_msb = val; +- return 0; // skip ++ return fill_rpn(cc, data, channel, false); + case UMP_CC_BANK_SELECT: + cc->bank_set = 1; + cc->cc_bank_msb = val; +@@ -854,11 +881,9 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event, + cc->cc_bank_lsb = val; + return 0; // skip + case UMP_CC_DATA_LSB: ++ cc->cc_data_lsb_set = 1; + cc->cc_data_lsb = val; +- if (!(cc->rpn_set || cc->nrpn_set)) +- return 0; // skip +- fill_rpn(cc, data, channel); +- return 1; ++ return fill_rpn(cc, data, channel, false); + } + + data->cc.status = status; +@@ -887,7 +912,7 @@ static int pgm_ev_to_ump_midi2(const struct snd_seq_event *event, + unsigned char status) + { + unsigned char channel = event->data.control.channel & 0x0f; +- struct snd_seq_ump_midi2_bank *cc = &dest_port->midi2_bank[channel]; ++ struct ump_cvt_to_ump_bank *cc = &dest_port->midi2_bank[channel]; + + data->pg.status = status; + data->pg.channel = channel; +@@ -924,8 +949,9 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event, + { + unsigned char channel = event->data.control.channel & 0x0f; + unsigned char index = event->data.control.param & 0x7f; +- struct snd_seq_ump_midi2_bank *cc = &dest_port->midi2_bank[channel]; ++ struct ump_cvt_to_ump_bank *cc = &dest_port->midi2_bank[channel]; + unsigned char msb, lsb; ++ int ret; + + msb = (event->data.control.value >> 7) & 0x7f; + lsb = event->data.control.value & 0x7f; +@@ -939,28 +965,27 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event, + cc->cc_bank_lsb = lsb; + return 0; // skip + case UMP_CC_RPN_MSB: +- cc->cc_rpn_msb = msb; +- fallthrough; + case UMP_CC_RPN_LSB: +- cc->rpn_set = 1; ++ ret = fill_rpn(cc, data, channel, true); ++ cc->cc_rpn_msb = msb; + cc->cc_rpn_lsb = lsb; +- return 0; // skip ++ cc->rpn_set = 1; ++ if (cc->cc_rpn_msb == 0x7f && cc->cc_rpn_lsb == 0x7f) ++ reset_rpn(cc); ++ return ret; + case UMP_CC_NRPN_MSB: +- cc->cc_nrpn_msb = msb; +- fallthrough; + case UMP_CC_NRPN_LSB: ++ ret = fill_rpn(cc, data, channel, true); ++ cc->cc_nrpn_msb = msb; + cc->nrpn_set = 1; + cc->cc_nrpn_lsb = lsb; +- return 0; // skip ++ return ret; + case UMP_CC_DATA: +- cc->cc_data_msb = msb; +- fallthrough; + case UMP_CC_DATA_LSB: ++ cc->cc_data_msb_set = cc->cc_data_lsb_set = 1; ++ cc->cc_data_msb = msb; + cc->cc_data_lsb = lsb; +- if (!(cc->rpn_set || cc->nrpn_set)) +- return 0; // skip +- fill_rpn(cc, data, channel); +- return 1; ++ return fill_rpn(cc, data, channel, false); + } + + data->cc.status = UMP_MSG_STATUS_CC; +diff --git a/sound/core/ump_convert.c b/sound/core/ump_convert.c +index f67c44c83fde4..0fe13d0316568 100644 +--- a/sound/core/ump_convert.c ++++ b/sound/core/ump_convert.c +@@ -287,25 +287,42 @@ static int cvt_legacy_system_to_ump(struct ump_cvt_to_ump *cvt, + return 4; + } + +-static void fill_rpn(struct ump_cvt_to_ump_bank *cc, +- union snd_ump_midi2_msg *midi2) ++static void reset_rpn(struct ump_cvt_to_ump_bank *cc) + { ++ cc->rpn_set = 0; ++ cc->nrpn_set = 0; ++ cc->cc_rpn_msb = cc->cc_rpn_lsb = 0; ++ cc->cc_data_msb = cc->cc_data_lsb = 0; ++ cc->cc_data_msb_set = cc->cc_data_lsb_set = 0; ++} ++ ++static int fill_rpn(struct ump_cvt_to_ump_bank *cc, ++ union snd_ump_midi2_msg *midi2, ++ bool flush) ++{ ++ if (!(cc->cc_data_lsb_set || cc->cc_data_msb_set)) ++ return 0; // skip ++ /* when not flushing, wait for complete data set */ ++ if (!flush && (!cc->cc_data_lsb_set || !cc->cc_data_msb_set)) ++ return 0; // skip ++ + if (cc->rpn_set) { + midi2->rpn.status = UMP_MSG_STATUS_RPN; + midi2->rpn.bank = cc->cc_rpn_msb; + midi2->rpn.index = cc->cc_rpn_lsb; +- cc->rpn_set = 0; +- cc->cc_rpn_msb = cc->cc_rpn_lsb = 0; +- } else { ++ } else if (cc->nrpn_set) { + midi2->rpn.status = UMP_MSG_STATUS_NRPN; + midi2->rpn.bank = cc->cc_nrpn_msb; + midi2->rpn.index = cc->cc_nrpn_lsb; +- cc->nrpn_set = 0; +- cc->cc_nrpn_msb = cc->cc_nrpn_lsb = 0; ++ } else { ++ return 0; // skip + } ++ + midi2->rpn.data = upscale_14_to_32bit((cc->cc_data_msb << 7) | + cc->cc_data_lsb); +- cc->cc_data_msb = cc->cc_data_lsb = 0; ++ ++ reset_rpn(cc); ++ return 1; + } + + /* convert to a MIDI 1.0 Channel Voice message */ +@@ -318,6 +335,7 @@ static int cvt_legacy_cmd_to_ump(struct ump_cvt_to_ump *cvt, + struct ump_cvt_to_ump_bank *cc; + union snd_ump_midi2_msg *midi2 = (union snd_ump_midi2_msg *)data; + unsigned char status, channel; ++ int ret; + + BUILD_BUG_ON(sizeof(union snd_ump_midi1_msg) != 4); + BUILD_BUG_ON(sizeof(union snd_ump_midi2_msg) != 8); +@@ -358,24 +376,33 @@ static int cvt_legacy_cmd_to_ump(struct ump_cvt_to_ump *cvt, + case UMP_MSG_STATUS_CC: + switch (buf[1]) { + case UMP_CC_RPN_MSB: ++ ret = fill_rpn(cc, midi2, true); + cc->rpn_set = 1; + cc->cc_rpn_msb = buf[2]; +- return 0; // skip ++ if (cc->cc_rpn_msb == 0x7f && cc->cc_rpn_lsb == 0x7f) ++ reset_rpn(cc); ++ return ret; + case UMP_CC_RPN_LSB: ++ ret = fill_rpn(cc, midi2, true); + cc->rpn_set = 1; + cc->cc_rpn_lsb = buf[2]; +- return 0; // skip ++ if (cc->cc_rpn_msb == 0x7f && cc->cc_rpn_lsb == 0x7f) ++ reset_rpn(cc); ++ return ret; + case UMP_CC_NRPN_MSB: ++ ret = fill_rpn(cc, midi2, true); + cc->nrpn_set = 1; + cc->cc_nrpn_msb = buf[2]; +- return 0; // skip ++ return ret; + case UMP_CC_NRPN_LSB: ++ ret = fill_rpn(cc, midi2, true); + cc->nrpn_set = 1; + cc->cc_nrpn_lsb = buf[2]; +- return 0; // skip ++ return ret; + case UMP_CC_DATA: ++ cc->cc_data_msb_set = 1; + cc->cc_data_msb = buf[2]; +- return 0; // skip ++ return fill_rpn(cc, midi2, false); + case UMP_CC_BANK_SELECT: + cc->bank_set = 1; + cc->cc_bank_msb = buf[2]; +@@ -385,12 +412,9 @@ static int cvt_legacy_cmd_to_ump(struct ump_cvt_to_ump *cvt, + cc->cc_bank_lsb = buf[2]; + return 0; // skip + case UMP_CC_DATA_LSB: ++ cc->cc_data_lsb_set = 1; + cc->cc_data_lsb = buf[2]; +- if (cc->rpn_set || cc->nrpn_set) +- fill_rpn(cc, midi2); +- else +- return 0; // skip +- break; ++ return fill_rpn(cc, midi2, false); + default: + midi2->cc.index = buf[1]; + midi2->cc.data = upscale_7_to_32bit(buf[2]); +diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c +index f64d9dc197a31..9cff87dfbecbb 100644 +--- a/sound/pci/hda/hda_generic.c ++++ b/sound/pci/hda/hda_generic.c +@@ -4955,6 +4955,69 @@ void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on) + } + EXPORT_SYMBOL_GPL(snd_hda_gen_stream_pm); + ++/* forcibly mute the speaker output without caching; return true if updated */ ++static bool force_mute_output_path(struct hda_codec *codec, hda_nid_t nid) ++{ ++ if (!nid) ++ return false; ++ if (!nid_has_mute(codec, nid, HDA_OUTPUT)) ++ return false; /* no mute, skip */ ++ if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & ++ snd_hda_codec_amp_read(codec, nid, 1, HDA_OUTPUT, 0) & ++ HDA_AMP_MUTE) ++ return false; /* both channels already muted, skip */ ++ ++ /* direct amp update without caching */ ++ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, ++ AC_AMP_SET_OUTPUT | AC_AMP_SET_LEFT | ++ AC_AMP_SET_RIGHT | HDA_AMP_MUTE); ++ return true; ++} ++ ++/** ++ * snd_hda_gen_shutup_speakers - Forcibly mute the speaker outputs ++ * @codec: the HDA codec ++ * ++ * Forcibly mute the speaker outputs, to be called at suspend or shutdown. ++ * ++ * The mute state done by this function isn't cached, hence the original state ++ * will be restored at resume. ++ * ++ * Return true if the mute state has been changed. ++ */ ++bool snd_hda_gen_shutup_speakers(struct hda_codec *codec) ++{ ++ struct hda_gen_spec *spec = codec->spec; ++ const int *paths; ++ const struct nid_path *path; ++ int i, p, num_paths; ++ bool updated = false; ++ ++ /* if already powered off, do nothing */ ++ if (!snd_hdac_is_power_on(&codec->core)) ++ return false; ++ ++ if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) { ++ paths = spec->out_paths; ++ num_paths = spec->autocfg.line_outs; ++ } else { ++ paths = spec->speaker_paths; ++ num_paths = spec->autocfg.speaker_outs; ++ } ++ ++ for (i = 0; i < num_paths; i++) { ++ path = snd_hda_get_path_from_idx(codec, paths[i]); ++ if (!path) ++ continue; ++ for (p = 0; p < path->depth; p++) ++ if (force_mute_output_path(codec, path->path[p])) ++ updated = true; ++ } ++ ++ return updated; ++} ++EXPORT_SYMBOL_GPL(snd_hda_gen_shutup_speakers); ++ + /** + * snd_hda_gen_parse_auto_config - Parse the given BIOS configuration and + * set up the hda_gen_spec +diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h +index 8f5ecf740c491..08544601b4ce2 100644 +--- a/sound/pci/hda/hda_generic.h ++++ b/sound/pci/hda/hda_generic.h +@@ -353,5 +353,6 @@ int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec, + int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec, + int (*callback)(struct led_classdev *, + enum led_brightness)); ++bool snd_hda_gen_shutup_speakers(struct hda_codec *codec); + + #endif /* __SOUND_HDA_GENERIC_H */ +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 4472923ba694b..f030669243f9a 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -205,6 +205,8 @@ 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/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index d597e59863ee3..f6c1dbd0ebcf5 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -220,6 +220,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "21J6"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "21M3"), ++ } ++ }, + { + .driver_data = &acp6x_card, + .matches = { +@@ -430,6 +437,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_BOARD_NAME, "8A3E"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "HP"), ++ DMI_MATCH(DMI_BOARD_NAME, "8B27"), ++ } ++ }, + { + .driver_data = &acp6x_card, + .matches = { +diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c +index 6a4e42e5e35b9..e620af9b864cb 100644 +--- a/sound/soc/codecs/es8326.c ++++ b/sound/soc/codecs/es8326.c +@@ -825,6 +825,8 @@ static void es8326_jack_detect_handler(struct work_struct *work) + es8326_disable_micbias(es8326->component); + if (es8326->jack->status & SND_JACK_HEADPHONE) { + dev_dbg(comp->dev, "Report hp remove event\n"); ++ snd_soc_jack_report(es8326->jack, 0, ++ SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2); + snd_soc_jack_report(es8326->jack, 0, SND_JACK_HEADSET); + /* mute adc when mic path switch */ + regmap_write(es8326->regmap, ES8326_ADC1_SRC, 0x44); +diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh +index c0ba79a8ad6da..a4762c49a8786 100755 +--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh +@@ -420,12 +420,17 @@ reset_with_fail() + fi + } + ++start_events() ++{ ++ mptcp_lib_events "${ns1}" "${evts_ns1}" evts_ns1_pid ++ mptcp_lib_events "${ns2}" "${evts_ns2}" evts_ns2_pid ++} ++ + reset_with_events() + { + reset "${1}" || return 1 + +- mptcp_lib_events "${ns1}" "${evts_ns1}" evts_ns1_pid +- mptcp_lib_events "${ns2}" "${evts_ns2}" evts_ns2_pid ++ start_events + } + + reset_with_tcp_filter() +@@ -3333,6 +3338,36 @@ userspace_pm_chk_get_addr() + fi + } + ++# $1: ns ; $2: event type ; $3: count ++chk_evt_nr() ++{ ++ local ns=${1} ++ local evt_name="${2}" ++ local exp="${3}" ++ ++ local evts="${evts_ns1}" ++ local evt="${!evt_name}" ++ local count ++ ++ evt_name="${evt_name:16}" # without MPTCP_LIB_EVENT_ ++ [ "${ns}" == "ns2" ] && evts="${evts_ns2}" ++ ++ print_check "event ${ns} ${evt_name} (${exp})" ++ ++ if [[ "${evt_name}" = "LISTENER_"* ]] && ++ ! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then ++ print_skip "event not supported" ++ return ++ fi ++ ++ count=$(grep -cw "type:${evt}" "${evts}") ++ if [ "${count}" != "${exp}" ]; then ++ fail_test "got ${count} events, expected ${exp}" ++ else ++ print_ok ++ fi ++} ++ + userspace_tests() + { + # userspace pm type prevents add_addr +@@ -3572,6 +3607,7 @@ endpoint_tests() + + if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT && + mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then ++ start_events + pm_nl_set_limits $ns1 0 3 + pm_nl_set_limits $ns2 0 3 + pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow +@@ -3623,9 +3659,129 @@ endpoint_tests() + + mptcp_lib_kill_wait $tests_pid + ++ kill_events_pids ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_CREATED 1 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_ESTABLISHED 1 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_ANNOUNCED 0 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_REMOVED 4 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_ESTABLISHED 6 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_CLOSED 4 ++ ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_CREATED 1 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_ESTABLISHED 1 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_ANNOUNCED 0 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_REMOVED 0 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_ESTABLISHED 6 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 5 # one has been closed before estab ++ + chk_join_nr 6 6 6 + chk_rm_nr 4 4 + fi ++ ++ # remove and re-add ++ if reset_with_events "delete re-add signal" && ++ mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then ++ pm_nl_set_limits $ns1 0 3 ++ pm_nl_set_limits $ns2 3 3 ++ pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal ++ # broadcast IP: no packet for this address will be received on ns1 ++ pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal ++ pm_nl_add_endpoint $ns1 10.0.1.1 id 42 flags signal ++ test_linkfail=4 speed=5 \ ++ run_tests $ns1 $ns2 10.0.1.1 & ++ local tests_pid=$! ++ ++ wait_mpj $ns2 ++ pm_nl_check_endpoint "creation" \ ++ $ns1 10.0.2.1 id 1 flags signal ++ chk_subflow_nr "before delete" 2 ++ chk_mptcp_info subflows 1 subflows 1 ++ ++ pm_nl_del_endpoint $ns1 1 10.0.2.1 ++ pm_nl_del_endpoint $ns1 2 224.0.0.1 ++ sleep 0.5 ++ chk_subflow_nr "after delete" 1 ++ chk_mptcp_info subflows 0 subflows 0 ++ ++ pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal ++ pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal ++ wait_mpj $ns2 ++ chk_subflow_nr "after re-add" 3 ++ chk_mptcp_info subflows 2 subflows 2 ++ ++ pm_nl_del_endpoint $ns1 42 10.0.1.1 ++ sleep 0.5 ++ chk_subflow_nr "after delete ID 0" 2 ++ chk_mptcp_info subflows 2 subflows 2 ++ ++ pm_nl_add_endpoint $ns1 10.0.1.1 id 99 flags signal ++ wait_mpj $ns2 ++ chk_subflow_nr "after re-add ID 0" 3 ++ chk_mptcp_info subflows 3 subflows 3 ++ ++ pm_nl_del_endpoint $ns1 99 10.0.1.1 ++ sleep 0.5 ++ chk_subflow_nr "after re-delete ID 0" 2 ++ chk_mptcp_info subflows 2 subflows 2 ++ ++ pm_nl_add_endpoint $ns1 10.0.1.1 id 88 flags signal ++ wait_mpj $ns2 ++ chk_subflow_nr "after re-re-add ID 0" 3 ++ chk_mptcp_info subflows 3 subflows 3 ++ mptcp_lib_kill_wait $tests_pid ++ ++ kill_events_pids ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_CREATED 1 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_ESTABLISHED 1 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_ANNOUNCED 0 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_REMOVED 0 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_ESTABLISHED 5 ++ chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_CLOSED 3 ++ ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_CREATED 1 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_ESTABLISHED 1 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_ANNOUNCED 6 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_REMOVED 4 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_ESTABLISHED 5 ++ chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 3 ++ ++ chk_join_nr 5 5 5 ++ chk_add_nr 6 6 ++ chk_rm_nr 4 3 invert ++ fi ++ ++ # flush and re-add ++ if reset_with_tcp_filter "flush re-add" ns2 10.0.3.2 REJECT OUTPUT && ++ mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then ++ pm_nl_set_limits $ns1 0 2 ++ pm_nl_set_limits $ns2 1 2 ++ # broadcast IP: no packet for this address will be received on ns1 ++ pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal ++ pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow ++ test_linkfail=4 speed=20 \ ++ run_tests $ns1 $ns2 10.0.1.1 & ++ local tests_pid=$! ++ ++ wait_attempt_fail $ns2 ++ chk_subflow_nr "before flush" 1 ++ chk_mptcp_info subflows 0 subflows 0 ++ ++ pm_nl_flush_endpoint $ns2 ++ pm_nl_flush_endpoint $ns1 ++ wait_rm_addr $ns2 0 ++ ip netns exec "${ns2}" ${iptables} -D OUTPUT -s "10.0.3.2" -p tcp -j REJECT ++ pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow ++ wait_mpj $ns2 ++ pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal ++ wait_mpj $ns2 ++ mptcp_lib_kill_wait $tests_pid ++ ++ chk_join_nr 2 2 2 ++ chk_add_nr 2 2 ++ chk_rm_nr 1 0 invert ++ fi + } + + # [$1: error message] +diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh +index 6ffa9b7a3260d..e299090eb0426 100644 +--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh +@@ -9,10 +9,14 @@ readonly KSFT_SKIP=4 + readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}" + + # These variables are used in some selftests, read-only ++declare -rx MPTCP_LIB_EVENT_CREATED=1 # MPTCP_EVENT_CREATED ++declare -rx MPTCP_LIB_EVENT_ESTABLISHED=2 # MPTCP_EVENT_ESTABLISHED ++declare -rx MPTCP_LIB_EVENT_CLOSED=3 # MPTCP_EVENT_CLOSED + declare -rx MPTCP_LIB_EVENT_ANNOUNCED=6 # MPTCP_EVENT_ANNOUNCED + declare -rx MPTCP_LIB_EVENT_REMOVED=7 # MPTCP_EVENT_REMOVED + declare -rx MPTCP_LIB_EVENT_SUB_ESTABLISHED=10 # MPTCP_EVENT_SUB_ESTABLISHED + declare -rx MPTCP_LIB_EVENT_SUB_CLOSED=11 # MPTCP_EVENT_SUB_CLOSED ++declare -rx MPTCP_LIB_EVENT_SUB_PRIORITY=13 # MPTCP_EVENT_SUB_PRIORITY + declare -rx MPTCP_LIB_EVENT_LISTENER_CREATED=15 # MPTCP_EVENT_LISTENER_CREATED + declare -rx MPTCP_LIB_EVENT_LISTENER_CLOSED=16 # MPTCP_EVENT_LISTENER_CLOSED + |