diff --git a/android/GKI_VERSION b/android/GKI_VERSION index b8afd9ca8342..ec1af1d442a9 100644 --- a/android/GKI_VERSION +++ b/android/GKI_VERSION @@ -1 +1 @@ -LTS_5.4.254_91f702572a80 +LTS_5.4.254_d43ac48de222 diff --git a/drivers/clk/qcom/gpucc-blair.c b/drivers/clk/qcom/gpucc-blair.c index 8749c0c5fefd..6abd747a9c33 100644 --- a/drivers/clk/qcom/gpucc-blair.c +++ b/drivers/clk/qcom/gpucc-blair.c @@ -441,6 +441,10 @@ static struct clk_regmap *gpu_cc_blair_clocks[] = { [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, }; +static const struct qcom_reset_map gpu_cc_blair_resets[] = { + [GPU_CC_FREQUENCY_LIMITER_IRQ_CLEAR] = { 0x153c, 0 }, +}; + static const struct regmap_config gpu_cc_blair_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -455,6 +459,8 @@ static const struct qcom_cc_desc gpu_cc_blair_desc = { .num_clks = ARRAY_SIZE(gpu_cc_blair_clocks), .clk_regulators = gpu_cc_blair_regulators, .num_clk_regulators = ARRAY_SIZE(gpu_cc_blair_regulators), + .resets = gpu_cc_blair_resets, + .num_resets = ARRAY_SIZE(gpu_cc_blair_resets), }; static const struct of_device_id gpu_cc_blair_match_table[] = { @@ -491,6 +497,8 @@ static int gpu_cc_blair_probe(struct platform_device *pdev) clk_lucid_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); + regmap_write(regmap, 0x1538, 0x0); + ret = qcom_cc_really_probe(pdev, &gpu_cc_blair_desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register GPU CC clocks\n"); diff --git a/drivers/clk/qcom/gpucc-holi.c b/drivers/clk/qcom/gpucc-holi.c index ef05bc2944cc..b549a7fcefa2 100644 --- a/drivers/clk/qcom/gpucc-holi.c +++ b/drivers/clk/qcom/gpucc-holi.c @@ -443,6 +443,10 @@ static struct clk_regmap *gpu_cc_holi_clocks[] = { [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, }; +static const struct qcom_reset_map gpu_cc_holi_resets[] = { + [GPU_CC_FREQUENCY_LIMITER_IRQ_CLEAR] = { 0x153c, 0 }, +}; + static const struct regmap_config gpu_cc_holi_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -455,6 +459,8 @@ static const struct qcom_cc_desc gpu_cc_holi_desc = { .config = &gpu_cc_holi_regmap_config, .clks = gpu_cc_holi_clocks, .num_clks = ARRAY_SIZE(gpu_cc_holi_clocks), + .resets = gpu_cc_holi_resets, + .num_resets = ARRAY_SIZE(gpu_cc_holi_resets), }; static const struct of_device_id gpu_cc_holi_match_table[] = { @@ -496,6 +502,8 @@ static int gpu_cc_holi_probe(struct platform_device *pdev) clk_fabia_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); + regmap_write(regmap, 0x1538, 0x0); + ret = qcom_cc_really_probe(pdev, &gpu_cc_holi_desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register GPU CC clocks\n"); diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index 2633b72f18f7..33fcaabf838d 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -483,6 +483,8 @@ kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, size = kgsl_memdesc_footprint(memdesc); ret = pagetable->pt_ops->mmu_unmap(pagetable, memdesc); + if (ret) + return ret; atomic_dec(&pagetable->stats.entries); atomic_long_sub(size, &pagetable->stats.mapped); diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index ae66f3acba30..d77ec299ae04 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -948,6 +949,9 @@ static void kgsl_contiguous_free(struct kgsl_memdesc *memdesc) if (!memdesc->hostptr) return; + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + atomic_long_sub(memdesc->size, &kgsl_driver.stats.coherent); #ifdef CONFIG_MM_STAT_UNRECLAIMABLE_PAGES @@ -963,9 +967,14 @@ static void kgsl_free_secure_system_pages(struct kgsl_memdesc *memdesc) { int i; struct scatterlist *sg; - int ret = unlock_sgt(memdesc->sgt); + int ret; int order = get_order(PAGE_SIZE); + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + + ret = unlock_sgt(memdesc->sgt); + if (ret) { /* * Unlock of the secure buffer failed. This buffer will @@ -998,7 +1007,12 @@ static void kgsl_free_secure_system_pages(struct kgsl_memdesc *memdesc) static void kgsl_free_secure_pool_pages(struct kgsl_memdesc *memdesc) { - int ret = unlock_sgt(memdesc->sgt); + int ret; + + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + + ret = unlock_sgt(memdesc->sgt); if (ret) { /* @@ -1028,6 +1042,9 @@ static void kgsl_free_pool_pages(struct kgsl_memdesc *memdesc) kgsl_paged_unmap_kernel(memdesc); WARN_ON(memdesc->hostptr); + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + atomic_long_sub(memdesc->size, &kgsl_driver.stats.page_alloc); kgsl_pool_free_pages(memdesc->pages, memdesc->page_count); @@ -1045,6 +1062,9 @@ static void kgsl_free_system_pages(struct kgsl_memdesc *memdesc) kgsl_paged_unmap_kernel(memdesc); WARN_ON(memdesc->hostptr); + if (memdesc->priv & KGSL_MEMDESC_MAPPED) + return; + atomic_long_sub(memdesc->size, &kgsl_driver.stats.page_alloc); for (i = 0; i < memdesc->page_count; i++) { diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index 04ef2286efc6..5694d18b43d5 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -350,7 +350,7 @@ session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt *pkt, memcpy(&bufreq[idx], buf_req, sizeof(*bufreq)); idx++; - if (idx > HFI_BUFFER_TYPE_MAX) + if (idx >= HFI_BUFFER_TYPE_MAX) return HFI_ERR_SESSION_INVALID_PARAMETER; req_bytes -= sizeof(struct hfi_buffer_requirements); diff --git a/drivers/soc/qcom/hgsl/hgsl_sync.c b/drivers/soc/qcom/hgsl/hgsl_sync.c index 0b8a7fd6a1d5..5efc7c948c87 100644 --- a/drivers/soc/qcom/hgsl/hgsl_sync.c +++ b/drivers/soc/qcom/hgsl/hgsl_sync.c @@ -275,14 +275,16 @@ int hgsl_isync_timeline_create(struct hgsl_priv *priv, idr_preload(GFP_KERNEL); spin_lock(&priv->isync_timeline_lock); idr = idr_alloc(&priv->isync_timeline_idr, timeline, 1, 0, GFP_NOWAIT); - spin_unlock(&priv->isync_timeline_lock); - idr_preload_end(); - if (idr > 0) { timeline->id = idr; *timeline_id = idr; ret = 0; - } else + } + spin_unlock(&priv->isync_timeline_lock); + idr_preload_end(); + + /* allocate IDR failed */ + if (ret != 0) kfree(timeline); return ret; diff --git a/drivers/soc/qcom/qmi_encdec.c b/drivers/soc/qcom/qmi_encdec.c index 331d67fb95ed..afc0764c560b 100644 --- a/drivers/soc/qcom/qmi_encdec.c +++ b/drivers/soc/qcom/qmi_encdec.c @@ -427,6 +427,7 @@ static int qmi_encode(struct qmi_elem_info *ei_array, void *out_buf, * @buf_src: Buffer containing the elements in QMI wire format. * @elem_len: Number of elements to be decoded. * @elem_size: Size of a single instance of the element to be decoded. + * @src_len: Source buffer length. * * This function decodes the "elem_len" number of elements in QMI wire format, * each of size "elem_size" bytes from the source buffer "buf_src" and stores @@ -437,10 +438,13 @@ static int qmi_encode(struct qmi_elem_info *ei_array, void *out_buf, * Return: The total size of the decoded data elements, in bytes. */ static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src, - u32 elem_len, u32 elem_size) + u32 elem_len, u32 elem_size, u32 src_len) { u32 i, rc = 0; + if (elem_len * elem_size > src_len) + return -EINVAL; + for (i = 0; i < elem_len; i++) { QMI_ENCDEC_DECODE_N_BYTES(buf_dst, buf_src, elem_size); rc += elem_size; @@ -458,6 +462,7 @@ static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src, * @tlv_len: Total size of the encoded inforation corresponding to * this struct element. * @dec_level: Depth of the nested structure from the main structure. + * @src_len: Source buffer length. * * This function decodes the "elem_len" number of elements in QMI wire format, * each of size "(tlv_len/elem_len)" bytes from the source buffer "buf_src" @@ -471,16 +476,20 @@ static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src, static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array, void *buf_dst, const void *buf_src, u32 elem_len, u32 tlv_len, - int dec_level) + int dec_level, u32 src_len) { int i, rc, decoded_bytes = 0; struct qmi_elem_info *temp_ei = ei_array; + if (tlv_len > src_len) + return -EINVAL; + for (i = 0; i < elem_len && decoded_bytes < tlv_len; i++) { rc = qmi_decode(temp_ei->ei_array, buf_dst, buf_src, tlv_len - decoded_bytes, dec_level); if (rc < 0) return rc; + buf_src = buf_src + rc; buf_dst = buf_dst + temp_ei->elem_size; decoded_bytes += rc; @@ -505,6 +514,7 @@ static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array, * @tlv_len: Total size of the encoded inforation corresponding to * this string element. * @dec_level: Depth of the string element from the main structure. + * @src_len: Source buffer length. * * This function decodes the string element of maximum length * "ei_array->elem_len" from the source buffer "buf_src" and puts it into @@ -516,7 +526,7 @@ static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array, */ static int qmi_decode_string_elem(struct qmi_elem_info *ei_array, void *buf_dst, const void *buf_src, - u32 tlv_len, int dec_level) + u32 tlv_len, int dec_level, u32 src_len) { int rc; int decoded_bytes = 0; @@ -530,7 +540,10 @@ static int qmi_decode_string_elem(struct qmi_elem_info *ei_array, string_len_sz = temp_ei->elem_len <= U8_MAX ? sizeof(u8) : sizeof(u16); rc = qmi_decode_basic_elem(&string_len, buf_src, - 1, string_len_sz); + 1, string_len_sz, src_len); + if (rc < 0) + return rc; + decoded_bytes += rc; } @@ -545,7 +558,11 @@ static int qmi_decode_string_elem(struct qmi_elem_info *ei_array, } rc = qmi_decode_basic_elem(buf_dst, buf_src + decoded_bytes, - string_len, temp_ei->elem_size); + string_len, temp_ei->elem_size, + src_len - decoded_bytes); + if (rc < 0) + return rc; + *((char *)buf_dst + string_len) = '\0'; decoded_bytes += rc; @@ -611,6 +628,9 @@ static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct, if (dec_level == 1) { tlv_pointer = buf_src; + if (decoded_bytes + TLV_TYPE_SIZE + TLV_LEN_SIZE > in_buf_len) + return -EINVAL; + QMI_ENCDEC_DECODE_TLV(&tlv_type, &tlv_len, tlv_pointer); buf_src += (TLV_TYPE_SIZE + TLV_LEN_SIZE); @@ -643,7 +663,11 @@ static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct, data_len_sz = temp_ei->elem_size == sizeof(u8) ? sizeof(u8) : sizeof(u16); rc = qmi_decode_basic_elem(&data_len_value, buf_src, - 1, data_len_sz); + 1, data_len_sz, + in_buf_len - decoded_bytes); + if (rc < 0) + return rc; + memcpy(buf_dst, &data_len_value, sizeof(u32)); temp_ei = temp_ei + 1; buf_dst = out_c_struct + temp_ei->offset; @@ -670,24 +694,32 @@ static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct, case QMI_SIGNED_4_BYTE_ENUM: rc = qmi_decode_basic_elem(buf_dst, buf_src, data_len_value, - temp_ei->elem_size); + temp_ei->elem_size, + in_buf_len - decoded_bytes); + if (rc < 0) + return rc; + UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc); break; case QMI_STRUCT: rc = qmi_decode_struct_elem(temp_ei, buf_dst, buf_src, data_len_value, tlv_len, - dec_level + 1); + dec_level + 1, + in_buf_len - decoded_bytes); if (rc < 0) return rc; + UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc); break; case QMI_STRING: rc = qmi_decode_string_elem(temp_ei, buf_dst, buf_src, - tlv_len, dec_level); + tlv_len, dec_level, + in_buf_len - decoded_bytes); if (rc < 0) return rc; + UPDATE_DECODE_VARIABLES(buf_src, decoded_bytes, rc); break; diff --git a/include/dt-bindings/clock/qcom,gpucc-blair.h b/include/dt-bindings/clock/qcom,gpucc-blair.h index c9fc5e5cc854..4f2472215e87 100644 --- a/include/dt-bindings/clock/qcom,gpucc-blair.h +++ b/include/dt-bindings/clock/qcom,gpucc-blair.h @@ -31,4 +31,7 @@ #define GPU_CC_RBCPR_CLK_SRC 21 #define GPU_CC_SLEEP_CLK 22 +/* GPU_CC resets */ +#define GPU_CC_FREQUENCY_LIMITER_IRQ_CLEAR 0 + #endif diff --git a/include/dt-bindings/clock/qcom,gpucc-holi.h b/include/dt-bindings/clock/qcom,gpucc-holi.h index 9d7a282238e3..3f0344ad767f 100644 --- a/include/dt-bindings/clock/qcom,gpucc-holi.h +++ b/include/dt-bindings/clock/qcom,gpucc-holi.h @@ -27,4 +27,7 @@ #define CX_GDSC 0 #define GX_GDSC 1 +/* GPU_CC resets */ +#define GPU_CC_FREQUENCY_LIMITER_IRQ_CLEAR 0 + #endif