From 5bd1b3e226972e0ecf9d5a095544a17d9d252fed Mon Sep 17 00:00:00 2001 From: raghavendra ambadas Date: Mon, 8 Oct 2018 14:46:33 +0530 Subject: [PATCH 01/75] msm: mdss: Fix potential null pointer dereference Add NULL checks before accessing potential null pointers. Change-Id: Ibdecaa7664c21a0acf57a3dd2c473f7407520f6b Signed-off-by: Raghavendra Ambadas --- drivers/video/fbdev/msm/mdss_mdp_overlay.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 34001ab35e55..676bbfa89211 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -6375,6 +6375,15 @@ void mdss_mdp_footswitch_ctrl_handler(bool on) static void mdss_mdp_signal_retire_fence(struct msm_fb_data_type *mfd, int retire_cnt) { + struct mdss_overlay_private *mdp5_data; + + if (!mfd) + return; + + mdp5_data = mfd_to_mdp5_data(mfd); + if (!mdp5_data->ctl || !mdp5_data->ctl->ops.remove_vsync_handler) + return; + __vsync_retire_signal(mfd, retire_cnt); pr_debug("Signaled (%d) pending retire fence\n", retire_cnt); } From 539ae5515fececf08b44ca8f75002447322ea00f Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Wed, 15 Nov 2017 09:57:15 -0800 Subject: [PATCH 02/75] dwc3: gadget: Take copy of dwc->gadget_driver before releasing lock gadget_driver can become null if gadget_stop is called while any other gadget callbacks are in progress. As gadget callbacks needs to release spinlock before the callback, store the local copy of gadget_driver to avoid the race with gadget_stop. Change-Id: I7f0cbf9af3e3b286f2826647f08215f29f699de1 Signed-off-by: Mayank Rana Signed-off-by: Vijayavardhan Vennapusa --- drivers/usb/dwc3/gadget.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f6117ac0e301..9c4345313f1e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2674,41 +2674,55 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, static void dwc3_disconnect_gadget(struct dwc3 *dwc) { + struct usb_gadget_driver *gadget_driver; + if (dwc->gadget_driver && dwc->gadget_driver->disconnect) { + gadget_driver = dwc->gadget_driver; spin_unlock(&dwc->lock); - dwc->gadget_driver->disconnect(&dwc->gadget); + dbg_event(0xFF, "DISCONNECT", 0); + gadget_driver->disconnect(&dwc->gadget); spin_lock(&dwc->lock); } } static void dwc3_suspend_gadget(struct dwc3 *dwc) { + struct usb_gadget_driver *gadget_driver; + if (dwc->gadget_driver && dwc->gadget_driver->suspend) { + gadget_driver = dwc->gadget_driver; spin_unlock(&dwc->lock); dbg_event(0xFF, "SUSPEND", 0); - dwc->gadget_driver->suspend(&dwc->gadget); + gadget_driver->suspend(&dwc->gadget); spin_lock(&dwc->lock); } } static void dwc3_resume_gadget(struct dwc3 *dwc) { + struct usb_gadget_driver *gadget_driver; + if (dwc->gadget_driver && dwc->gadget_driver->resume) { + gadget_driver = dwc->gadget_driver; spin_unlock(&dwc->lock); dbg_event(0xFF, "RESUME", 0); - dwc->gadget_driver->resume(&dwc->gadget); + gadget_driver->resume(&dwc->gadget); spin_lock(&dwc->lock); } } static void dwc3_reset_gadget(struct dwc3 *dwc) { + struct usb_gadget_driver *gadget_driver; + if (!dwc->gadget_driver) return; if (dwc->gadget.speed != USB_SPEED_UNKNOWN) { + gadget_driver = dwc->gadget_driver; spin_unlock(&dwc->lock); - usb_gadget_udc_reset(&dwc->gadget, dwc->gadget_driver); + dbg_event(0xFF, "UDC RESET", 0); + usb_gadget_udc_reset(&dwc->gadget, gadget_driver); spin_lock(&dwc->lock); } } From 1d6109e0e97e9e7a077f4776e05e955d226422d9 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Thu, 10 Jan 2019 15:26:50 +0800 Subject: [PATCH 03/75] ipc: Implement FIFO queue to fix sequence inconsistency The SVA history buffer is out of order if there are more than 2 continuous RX buffer done from GLINK. Implement FIFO to ensure sequence consistency. Change-Id: If70e2d0160e8f3140d621298b0db03bd89ba88ba Signed-off-by: Xiaojun Sang --- drivers/soc/qcom/wcd-dsp-glink.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/soc/qcom/wcd-dsp-glink.c b/drivers/soc/qcom/wcd-dsp-glink.c index 50cef91ad5a4..9093dfefcc83 100644 --- a/drivers/soc/qcom/wcd-dsp-glink.c +++ b/drivers/soc/qcom/wcd-dsp-glink.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -109,6 +109,8 @@ struct wdsp_glink_priv { /* Respone buffer related */ u8 rsp_cnt; struct wdsp_glink_rsp_que rsp[RESP_QUEUE_SIZE]; + u8 write_idx; + u8 read_idx; struct completion rsp_complete; struct mutex rsp_mutex; @@ -202,13 +204,19 @@ static void wdsp_glink_notify_rx(void *handle, const void *priv, mutex_lock(&wpriv->rsp_mutex); rsp_cnt = wpriv->rsp_cnt; if (rsp_cnt >= RESP_QUEUE_SIZE) { - dev_err(wpriv->dev, "%s: Resp Queue is Full\n", __func__); - rsp_cnt = 0; + dev_err(wpriv->dev, "%s: Resp Queue is Full. Ignore latest and keep oldest.\n", + __func__); + mutex_unlock(&wpriv->rsp_mutex); + glink_rx_done(handle, ptr, true); + return; } - dev_dbg(wpriv->dev, "%s: copy into buffer %d\n", __func__, rsp_cnt); + dev_dbg(wpriv->dev, "%s: rsp_cnt = %d copy into buffer %d\n", + __func__, rsp_cnt, wpriv->write_idx); - memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, size); - wpriv->rsp[rsp_cnt].buf_size = size; + memcpy(wpriv->rsp[wpriv->write_idx].buf, rx_buf, size); + wpriv->rsp[wpriv->write_idx].buf_size = size; + + wpriv->write_idx = (wpriv->write_idx + 1) % RESP_QUEUE_SIZE; wpriv->rsp_cnt = ++rsp_cnt; mutex_unlock(&wpriv->rsp_mutex); @@ -781,10 +789,11 @@ static ssize_t wdsp_glink_read(struct file *file, char __user *buf, mutex_lock(&wpriv->rsp_mutex); if (wpriv->rsp_cnt) { wpriv->rsp_cnt--; - dev_dbg(wpriv->dev, "%s: read from buffer %d\n", - __func__, wpriv->rsp_cnt); + dev_dbg(wpriv->dev, "%s: rsp_cnt=%d read from buffer %d\n", + __func__, wpriv->rsp_cnt, wpriv->read_idx); - rsp = &wpriv->rsp[wpriv->rsp_cnt]; + rsp = &wpriv->rsp[wpriv->read_idx]; + wpriv->read_idx = (wpriv->read_idx + 1) % RESP_QUEUE_SIZE; if (count < rsp->buf_size) { ret1 = copy_to_user(buf, &rsp->buf, count); /* Return the number of bytes copied */ From 329c3ba349d74d0908a4bb2882f87d58eb10b14a Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 20 Dec 2018 13:56:48 +0530 Subject: [PATCH 04/75] msm: vidc: ensure codec count is in supported session range Ensure the count of supported encoder and decoder returned from firmware are within the range of supported sessions Change-Id: If3eae7bc82dc8302444e2e4104fb6ae3cfbfed5a Signed-off-by: Dikshita Agarwal Signed-off-by: Vasantha Balla --- .../media/platform/msm/vidc/hfi_response_handler.c | 12 +++++++++++- drivers/media/platform/msm/vidc/vidc_hfi_api.h | 5 ++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index 3835a2e45882..6d2af94a784b 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -603,6 +603,11 @@ static int hfi_fill_codec_info(u8 *data_ptr, vidc_get_hal_codec((1 << i) & codecs); capability->domain = vidc_get_hal_domain(HFI_VIDEO_DOMAIN_DECODER); + if (codec_count == VIDC_MAX_DECODE_SESSIONS) { + dprintk(VIDC_ERR, + "Max supported decoder sessions reached"); + break; + } } } codecs = sys_init_done->enc_codec_supported; @@ -614,6 +619,11 @@ static int hfi_fill_codec_info(u8 *data_ptr, vidc_get_hal_codec((1 << i) & codecs); capability->domain = vidc_get_hal_domain(HFI_VIDEO_DOMAIN_ENCODER); + if (codec_count == VIDC_MAX_SESSIONS) { + dprintk(VIDC_ERR, + "Max supported sessions reached"); + break; + } } } sys_init_done->codec_count = codec_count; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h index d946b035b284..bb817498d0e4 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -66,6 +66,9 @@ /* 16 encoder and 16 decoder sessions */ #define VIDC_MAX_SESSIONS 32 +#define VIDC_MAX_DECODE_SESSIONS 16 +#define VIDC_MAX_ENCODE_SESSIONS 16 + enum vidc_status { VIDC_ERR_NONE = 0x0, From 412b07f4dae740aa64463dabcc9029003b1646ab Mon Sep 17 00:00:00 2001 From: Vijayanand Jitta Date: Sun, 27 Jan 2019 22:36:16 +0530 Subject: [PATCH 05/75] iommu: dma-mapping-fast: Add a check for count in fast_smmu_alloc In fast_smmu_alloc size_t variable size is type casted to int variable count, this variable count can get truncated and can result in memory corruption during unmap, make count as size_t and also add a check for count as sg_alloc_table_from_pages accepts unsigned int value for count. Change-Id: I4780a554c5c062fd9dd229e5cc0ac804b1ba31d8 Signed-off-by: Vijayanand Jitta --- drivers/iommu/dma-mapping-fast.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/dma-mapping-fast.c b/drivers/iommu/dma-mapping-fast.c index 0881d68f34d8..66c2abd358f8 100644 --- a/drivers/iommu/dma-mapping-fast.c +++ b/drivers/iommu/dma-mapping-fast.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017,2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -513,12 +513,22 @@ static void *fast_smmu_alloc(struct device *dev, size_t size, av8l_fast_iopte *ptep; unsigned long flags; struct sg_mapping_iter miter; - unsigned int count = ALIGN(size, SZ_4K) >> PAGE_SHIFT; + size_t count = ALIGN(size, SZ_4K) >> PAGE_SHIFT; int prot = IOMMU_READ | IOMMU_WRITE; /* TODO: extract from attrs */ bool is_coherent = is_dma_coherent(dev, attrs); pgprot_t remap_prot = __get_dma_pgprot(attrs, PAGE_KERNEL, is_coherent); struct page **pages; + /* + * sg_alloc_table_from_pages accepts unsigned int value for count + * so check count doesn't exceed UINT_MAX. + */ + + if (count > UINT_MAX) { + dev_err(dev, "count: %zx exceeds UNIT_MAX\n", count); + return NULL; + } + prot = __get_iommu_pgprot(attrs, prot, is_coherent); *handle = DMA_ERROR_CODE; From 7fef9d4e2d507ee493059290d7ec5ebba5a9c3b7 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Fri, 17 Nov 2017 15:04:28 +0530 Subject: [PATCH 06/75] msm: vidc: Add memory barrier after queue header update Add memory barrier after updating queue header variables to ensure main memory is updated so that video hardware reads the updated header values. CRs-Fixed: 2135048 Change-Id: I1a2778bee16c9093284c4d33980e6985c279f499 Signed-off-by: Vikash Garodia Signed-off-by: Sanjay Singh --- drivers/media/platform/msm/vidc/venus_hfi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 20f02ce46029..d43fd8ef514b 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -501,6 +501,11 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, if (queue->qhdr_read_idx == queue->qhdr_write_idx) { queue->qhdr_rx_req = receive_request; + /* + * mb() to ensure qhdr is updated in main memory + * so that venus reads the updated header values + */ + mb(); *pb_tx_req_is_set = 0; dprintk(VIDC_DBG, "%s queue is empty, rx_req = %u, tx_req = %u, read_idx = %u\n", @@ -548,6 +553,11 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, queue->qhdr_rx_req = 0; else queue->qhdr_rx_req = receive_request; + /* + * mb() to ensure qhdr is updated in main memory + * so that venus reads the updated header values + */ + mb(); *pb_tx_req_is_set = (1 == queue->qhdr_tx_req) ? 1 : 0; From 2eae84f039304bfbfa80920a9d43b1f5abe746ca Mon Sep 17 00:00:00 2001 From: Sanjay Singh Date: Wed, 9 Jan 2019 16:11:36 +0530 Subject: [PATCH 07/75] msm: vidc: Correct error handling for allocation failure cases In error handling, trying to free memory which is not yet allocated. Fix is added to correct this error handling. Change-Id: I4e91a95f7ebd9132141d8686ae2bdfaed3a9a8c1 Signed-off-by: Sanjay Singh Signed-off-by: Vasantha Balla --- drivers/media/platform/msm/vidc/msm_vidc_common.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index ee3cfb88855c..c3f558b4334e 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1478,7 +1478,7 @@ void validate_output_buffers(struct msm_vidc_inst *inst) } mutex_lock(&inst->outputbufs.lock); list_for_each_entry(binfo, &inst->outputbufs.list, list) { - if (binfo->buffer_ownership != DRIVER) { + if (binfo && binfo->buffer_ownership != DRIVER) { dprintk(VIDC_DBG, "This buffer is with FW %pa\n", &binfo->handle->device_addr); @@ -3175,8 +3175,7 @@ static int set_output_buffers(struct msm_vidc_inst *inst, if (!handle) { dprintk(VIDC_ERR, "Failed to allocate output memory\n"); - rc = -ENOMEM; - goto err_no_mem; + return -ENOMEM; } rc = msm_comm_smem_cache_operations(inst, handle, SMEM_CACHE_CLEAN, -1); @@ -3228,10 +3227,9 @@ static int set_output_buffers(struct msm_vidc_inst *inst, } return rc; fail_set_buffers: - msm_comm_smem_free(inst, handle); -err_no_mem: kfree(binfo); fail_kzalloc: + msm_comm_smem_free(inst, handle); return rc; } From b6376f2b6ddc78c26660fe6eb095c405e5a5ce60 Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Mon, 14 Jan 2019 13:54:44 +0530 Subject: [PATCH 08/75] msm: vidc: fix KCFI errors Fix errors reported after enabling Kernel Control Flow Integrity (KCFI) on kernel code. This is a security mechanism that disallows changes to the original control flow of a compiled binary. Change-Id: I1e1e901c5889d9928411dc785da88e1eac378560 Signed-off-by: Govindaraj Rajagopal Signed-off-by: Sanjay Singh --- .../platform/msm/vidc/hfi_response_handler.c | 53 ++++++++++++------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index 6d2af94a784b..15f6490d4a9e 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -316,9 +316,10 @@ static int hfi_process_session_error(u32 device_id, } static int hfi_process_event_notify(u32 device_id, - struct hfi_msg_event_notify_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_event_notify_packet *pkt = _pkt; dprintk(VIDC_DBG, "Received: EVENT_NOTIFY\n"); if (pkt->size < sizeof(struct hfi_msg_event_notify_packet)) { @@ -357,9 +358,10 @@ static int hfi_process_event_notify(u32 device_id, } static int hfi_process_sys_init_done(u32 device_id, - struct hfi_msg_sys_init_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_sys_init_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; enum vidc_status status = VIDC_ERR_NONE; @@ -396,9 +398,10 @@ err_no_prop: } static int hfi_process_sys_rel_resource_done(u32 device_id, - struct hfi_msg_sys_release_resource_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_sys_release_resource_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; enum vidc_status status = VIDC_ERR_NONE; u32 pkt_size; @@ -1221,9 +1224,10 @@ static void hfi_process_sess_get_prop_buf_req( } static int hfi_process_session_prop_info(u32 device_id, - struct hfi_msg_session_property_info_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_session_property_info_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; struct hfi_profile_level profile_level = {0}; enum hal_h264_entropy entropy = {0}; @@ -1296,9 +1300,10 @@ static int hfi_process_session_prop_info(u32 device_id, } static int hfi_process_session_init_done(u32 device_id, - struct hfi_msg_sys_session_init_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_sys_session_init_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; struct vidc_hal_session_init_done session_init_done = { {0} }; @@ -1330,9 +1335,10 @@ static int hfi_process_session_init_done(u32 device_id, } static int hfi_process_session_load_res_done(u32 device_id, - struct hfi_msg_session_load_resources_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_session_load_resources_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%#x]\n", pkt->session_id); @@ -1359,9 +1365,10 @@ static int hfi_process_session_load_res_done(u32 device_id, } static int hfi_process_session_flush_done(u32 device_id, - struct hfi_msg_session_flush_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_session_flush_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n", @@ -1404,9 +1411,10 @@ static int hfi_process_session_flush_done(u32 device_id, } static int hfi_process_session_etb_done(u32 device_id, - struct hfi_msg_session_empty_buffer_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; struct msm_vidc_cb_data_done data_done = {0}; struct hfi_picture_type *hfi_picture_type = NULL; @@ -1455,9 +1463,10 @@ static int hfi_process_session_etb_done(u32 device_id, } static int hfi_process_session_ftb_done( - u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, + u32 device_id, void *_pkt, struct msm_vidc_cb_info *info) { + struct vidc_hal_msg_pkt_hdr *msg_hdr = _pkt; struct msm_vidc_cb_data_done data_done = {0}; bool is_decoder = false, is_encoder = false; @@ -1582,9 +1591,10 @@ static int hfi_process_session_ftb_done( } static int hfi_process_session_start_done(u32 device_id, - struct hfi_msg_session_start_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_session_start_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%#x]\n", @@ -1610,9 +1620,10 @@ static int hfi_process_session_start_done(u32 device_id, } static int hfi_process_session_stop_done(u32 device_id, - struct hfi_msg_session_stop_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_session_stop_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%#x]\n", @@ -1639,9 +1650,10 @@ static int hfi_process_session_stop_done(u32 device_id, } static int hfi_process_session_rel_res_done(u32 device_id, - struct hfi_msg_session_release_resources_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_session_release_resources_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%#x]\n", @@ -1668,9 +1680,10 @@ static int hfi_process_session_rel_res_done(u32 device_id, } static int hfi_process_session_rel_buf_done(u32 device_id, - struct hfi_msg_session_release_buffers_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_session_release_buffers_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; if (!pkt || pkt->size < @@ -1703,9 +1716,10 @@ static int hfi_process_session_rel_buf_done(u32 device_id, } static int hfi_process_session_end_done(u32 device_id, - struct hfi_msg_sys_session_end_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_sys_session_end_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id); @@ -1730,9 +1744,10 @@ static int hfi_process_session_end_done(u32 device_id, } static int hfi_process_session_abort_done(u32 device_id, - struct hfi_msg_sys_session_abort_done_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_sys_session_abort_done_packet *pkt = _pkt; struct msm_vidc_cb_cmd_done cmd_done = {0}; dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%#x]\n", @@ -1837,9 +1852,10 @@ static void hfi_process_sys_get_prop_image_version( } static int hfi_process_sys_property_info(u32 device_id, - struct hfi_msg_sys_property_info_packet *pkt, + void *_pkt, struct msm_vidc_cb_info *info) { + struct hfi_msg_sys_property_info_packet *pkt = _pkt; if (!pkt) { dprintk(VIDC_ERR, "%s: invalid param\n", __func__); return -EINVAL; @@ -1871,7 +1887,7 @@ static int hfi_process_sys_property_info(u32 device_id, } static int hfi_process_ignore(u32 device_id, - struct vidc_hal_msg_pkt_hdr *msg_hdr, + void *_pkt, struct msm_vidc_cb_info *info) { *info = (struct msm_vidc_cb_info) { @@ -1955,5 +1971,6 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, break; } - return pkt_func ? pkt_func(device_id, msg_hdr, info) : -ENOTSUPP; + return pkt_func ? + pkt_func(device_id, (void *)msg_hdr, info) : -ENOTSUPP; } From 13fbdf9d9ad74608e8f7bf8fc353e565ef154c4b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 12 Sep 2018 23:57:48 -1000 Subject: [PATCH 09/75] mm: get rid of vmacache_flush_all() entirely commit 7a9cdebdcc17e426fb5287e4a82db1dfe86339b2 upstream. Jann Horn points out that the vmacache_flush_all() function is not only potentially expensive, it's buggy too. It also happens to be entirely unnecessary, because the sequence number overflow case can be avoided by simply making the sequence number be 64-bit. That doesn't even grow the data structures in question, because the other adjacent fields are already 64-bit. So simplify the whole thing by just making the sequence number overflow case go away entirely, which gets rid of all the complications and makes the code faster too. Win-win. [ Oleg Nesterov points out that the VMACACHE_FULL_FLUSHES statistics also just goes away entirely with this ] Change-Id: Ib485c9f33638e844f2378a1ec376e64200d30fd2 Reported-by: Jann Horn Suggested-by: Will Deacon Acked-by: Davidlohr Bueso Cc: Oleg Nesterov Cc: stable@kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Git-commit: 84580567f1f856d2c7a610273315852e345bc3ac Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Srinivasarao P --- include/linux/mm_types.h | 2 +- include/linux/sched.h | 2 +- include/linux/vm_event_item.h | 1 - include/linux/vmacache.h | 5 ----- mm/debug.c | 4 ++-- mm/vmacache.c | 38 ----------------------------------- 6 files changed, 4 insertions(+), 48 deletions(-) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index fe0a5de1eda5..29c17fae9bbf 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -404,7 +404,7 @@ struct kioctx_table; struct mm_struct { struct vm_area_struct *mmap; /* list of VMAs */ struct rb_root mm_rb; - u32 vmacache_seqnum; /* per-thread vmacache */ + u64 vmacache_seqnum; /* per-thread vmacache */ #ifdef CONFIG_MMU unsigned long (*get_unmapped_area) (struct file *filp, unsigned long addr, unsigned long len, diff --git a/include/linux/sched.h b/include/linux/sched.h index 5fe8c3dfd60f..8f6894c6e83c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1726,7 +1726,7 @@ struct task_struct { struct mm_struct *mm, *active_mm; /* per-thread vma caching */ - u32 vmacache_seqnum; + u64 vmacache_seqnum; struct vm_area_struct *vmacache[VMACACHE_SIZE]; #if defined(SPLIT_RSS_COUNTING) struct task_rss_stat rss_stat; diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index 056b4e5830a6..d31afe5d790d 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -89,7 +89,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PGPGOUTCLEAN, PSWPIN, PSWPOUT, #ifdef CONFIG_DEBUG_VM_VMACACHE VMACACHE_FIND_CALLS, VMACACHE_FIND_HITS, - VMACACHE_FULL_FLUSHES, #endif NR_VM_EVENT_ITEMS }; diff --git a/include/linux/vmacache.h b/include/linux/vmacache.h index c3fa0fd43949..4f58ff2dacd6 100644 --- a/include/linux/vmacache.h +++ b/include/linux/vmacache.h @@ -15,7 +15,6 @@ static inline void vmacache_flush(struct task_struct *tsk) memset(tsk->vmacache, 0, sizeof(tsk->vmacache)); } -extern void vmacache_flush_all(struct mm_struct *mm); extern void vmacache_update(unsigned long addr, struct vm_area_struct *newvma); extern struct vm_area_struct *vmacache_find(struct mm_struct *mm, unsigned long addr); @@ -29,10 +28,6 @@ extern struct vm_area_struct *vmacache_find_exact(struct mm_struct *mm, static inline void vmacache_invalidate(struct mm_struct *mm) { mm->vmacache_seqnum++; - - /* deal with overflows */ - if (unlikely(mm->vmacache_seqnum == 0)) - vmacache_flush_all(mm); } #endif /* __LINUX_VMACACHE_H */ diff --git a/mm/debug.c b/mm/debug.c index 3621385c09ac..89ac083ea504 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -184,7 +184,7 @@ EXPORT_SYMBOL(dump_vma); void dump_mm(const struct mm_struct *mm) { - pr_emerg("mm %p mmap %p seqnum %d task_size %lu\n" + pr_emerg("mm %p mmap %p seqnum %llu task_size %lu\n" #ifdef CONFIG_MMU "get_unmapped_area %p\n" #endif @@ -214,7 +214,7 @@ void dump_mm(const struct mm_struct *mm) #endif "%s", /* This is here to hold the comma */ - mm, mm->mmap, mm->vmacache_seqnum, mm->task_size, + mm, mm->mmap, (long long) mm->vmacache_seqnum, mm->task_size, #ifdef CONFIG_MMU mm->get_unmapped_area, #endif diff --git a/mm/vmacache.c b/mm/vmacache.c index fd09dc9c6812..9c8ff3d4eda9 100644 --- a/mm/vmacache.c +++ b/mm/vmacache.c @@ -5,44 +5,6 @@ #include #include -/* - * Flush vma caches for threads that share a given mm. - * - * The operation is safe because the caller holds the mmap_sem - * exclusively and other threads accessing the vma cache will - * have mmap_sem held at least for read, so no extra locking - * is required to maintain the vma cache. - */ -void vmacache_flush_all(struct mm_struct *mm) -{ - struct task_struct *g, *p; - - count_vm_vmacache_event(VMACACHE_FULL_FLUSHES); - - /* - * Single threaded tasks need not iterate the entire - * list of process. We can avoid the flushing as well - * since the mm's seqnum was increased and don't have - * to worry about other threads' seqnum. Current's - * flush will occur upon the next lookup. - */ - if (atomic_read(&mm->mm_users) == 1) - return; - - rcu_read_lock(); - for_each_process_thread(g, p) { - /* - * Only flush the vmacache pointers as the - * mm seqnum is already set and curr's will - * be set upon invalidation when the next - * lookup is done. - */ - if (mm == p->mm) - vmacache_flush(p); - } - rcu_read_unlock(); -} - /* * This task may be accessing a foreign mm via (for example) * get_user_pages()->find_vma(). The vmacache is task-local and this From 38f4fba64da54671b5bfb4c2b406fa65247176ce Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Fri, 5 Oct 2018 15:52:03 -0700 Subject: [PATCH 10/75] mm/vmstat.c: fix outdated vmstat_text 7a9cdebdcc17 ("mm: get rid of vmacache_flush_all() entirely") removed the VMACACHE_FULL_FLUSHES statistics, but didn't remove the corresponding entry in vmstat_text. This causes an out-of-bounds access in vmstat_show(). Luckily this only affects kernels with CONFIG_DEBUG_VM_VMACACHE=y, which is probably very rare. Change-Id: Ia4f5f0327d58a7831aff010949fa31bfd56139dc Link: http://lkml.kernel.org/r/20181001143138.95119-1-jannh@google.com Fixes: 7a9cdebdcc17 ("mm: get rid of vmacache_flush_all() entirely") Signed-off-by: Jann Horn Reviewed-by: Kees Cook Reviewed-by: Andrew Morton Acked-by: Michal Hocko Acked-by: Roman Gushchin Cc: Davidlohr Bueso Cc: Oleg Nesterov Cc: Christoph Lameter Cc: Kemi Wang Cc: Andy Lutomirski Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Git-commit: 28e2c4bb99aa40f9d5f07ac130cbc4da0ea93079 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Srinivasarao P --- mm/vmstat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mm/vmstat.c b/mm/vmstat.c index 9ab13e3be5df..d1cebdc8d3c8 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -872,7 +872,6 @@ const char * const vmstat_text[] = { #ifdef CONFIG_DEBUG_VM_VMACACHE "vmacache_find_calls", "vmacache_find_hits", - "vmacache_full_flushes", #endif #endif /* CONFIG_VM_EVENTS_COUNTERS */ }; From 979cdd6f6e26da14aa95e2e7e116f9af72b122dc Mon Sep 17 00:00:00 2001 From: Vinayak Menon Date: Thu, 31 Jan 2019 20:47:07 +0530 Subject: [PATCH 11/75] ion: fix system secure force alloc Even when ION_FLAG_POOL_FORCE_ALLOC is set for secure alloc, alloc_from_pool_preferred tries to get the pages from pool first. In case if it enters split_page_from_secure_pool, free_buffer_page can end up calling __free_pages on the page from pool which is hyp assigned, resulting in issues for e.g. a fault if page poisoning is enabled. Change-Id: I68759dc17551a5705693506a5c137977d429fe36 Signed-off-by: Vinayak Menon --- drivers/staging/android/ion/ion_system_heap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 403dadea5bb2..126f45ac5bf9 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -2,7 +2,7 @@ * drivers/staging/android/ion/ion_system_heap.c * * Copyright (C) 2011 Google, Inc. - * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -270,6 +270,9 @@ static struct page_info *alloc_from_pool_preferred( struct page_info *info; int i; + if (buffer->flags & ION_FLAG_POOL_FORCE_ALLOC) + goto force_alloc; + info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) return NULL; @@ -301,6 +304,7 @@ static struct page_info *alloc_from_pool_preferred( } kfree(info); +force_alloc: return alloc_largest_available(heap, buffer, size, max_order); } From e18e27735c68de652f8a68e9c40c92ec0b0c8a9e Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Sat, 12 Jan 2019 00:32:22 +0530 Subject: [PATCH 12/75] msm: vidc: Ensure validity of shared Q indices Video driver and firmware communicates over shared queue. The queue header has the indices which synchronizes the read and write between the driver and firmware modules. This change ensures that the indices are within the valid range before accessing them. CRs-fixed: 2345481 Change-Id: I8da6bb4218a5b8ec0e2e2c7b87f6cc9eec21bd16 Signed-off-by: Vikash Garodia Signed-off-by: Paras Nagda Signed-off-by: Vasantha Balla --- drivers/media/platform/msm/vidc/venus_hfi.c | 68 +++++++++++++-------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index d43fd8ef514b..1ec06cb07523 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -328,7 +328,7 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, { struct hfi_queue_header *queue; u32 packet_size_in_words, new_write_idx; - u32 empty_space, read_idx; + u32 empty_space, read_idx, write_idx; u32 *write_ptr; if (!qinfo || !packet) { @@ -351,16 +351,18 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, } packet_size_in_words = (*(u32 *)packet) >> 2; - if (!packet_size_in_words) { - dprintk(VIDC_ERR, "Zero packet size\n"); + if (!packet_size_in_words || packet_size_in_words > + qinfo->q_array.mem_size>>2) { + dprintk(VIDC_ERR, "Invalid packet size\n"); return -ENODATA; } read_idx = queue->qhdr_read_idx; + write_idx = queue->qhdr_write_idx; - empty_space = (queue->qhdr_write_idx >= read_idx) ? - (queue->qhdr_q_size - (queue->qhdr_write_idx - read_idx)) : - (read_idx - queue->qhdr_write_idx); + empty_space = (write_idx >= read_idx) ? + ((qinfo->q_array.mem_size>>2) - (write_idx - read_idx)) : + (read_idx - write_idx); if (empty_space <= packet_size_in_words) { queue->qhdr_tx_req = 1; dprintk(VIDC_ERR, "Insufficient size (%d) to write (%d)\n", @@ -370,13 +372,20 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, queue->qhdr_tx_req = 0; - new_write_idx = (queue->qhdr_write_idx + packet_size_in_words); + new_write_idx = write_idx + packet_size_in_words; write_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + - (queue->qhdr_write_idx << 2)); - if (new_write_idx < queue->qhdr_q_size) { + (write_idx << 2)); + if (write_ptr < (u32 *)qinfo->q_array.align_virtual_addr || + write_ptr > (u32 *)(qinfo->q_array.align_virtual_addr + + qinfo->q_array.mem_size)) { + dprintk(VIDC_ERR, "Invalid write index"); + return -ENODATA; + } + + if (new_write_idx < (qinfo->q_array.mem_size >> 2)) { memcpy(write_ptr, packet, packet_size_in_words << 2); } else { - new_write_idx -= queue->qhdr_q_size; + new_write_idx -= qinfo->q_array.mem_size >> 2; memcpy(write_ptr, packet, (packet_size_in_words - new_write_idx) << 2); memcpy((void *)qinfo->q_array.align_virtual_addr, @@ -468,7 +477,8 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, u32 packet_size_in_words, new_read_idx; u32 *read_ptr; u32 receive_request = 0; - int rc = 0; + u32 read_idx, write_idx; + int rc = 0; if (!qinfo || !packet || !pb_tx_req_is_set) { dprintk(VIDC_ERR, "Invalid Params\n"); @@ -499,7 +509,10 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, if (queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_MSG_Q) receive_request = 1; - if (queue->qhdr_read_idx == queue->qhdr_write_idx) { + read_idx = queue->qhdr_read_idx; + write_idx = queue->qhdr_write_idx; + + if (read_idx == write_idx) { queue->qhdr_rx_req = receive_request; /* * mb() to ensure qhdr is updated in main memory @@ -516,21 +529,28 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, } read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + - (queue->qhdr_read_idx << 2)); + (read_idx << 2)); + if (read_ptr < (u32 *)qinfo->q_array.align_virtual_addr || + read_ptr > (u32 *)(qinfo->q_array.align_virtual_addr + + qinfo->q_array.mem_size - sizeof(*read_ptr))) { + dprintk(VIDC_ERR, "Invalid read index\n"); + return -ENODATA; + } + packet_size_in_words = (*read_ptr) >> 2; if (!packet_size_in_words) { dprintk(VIDC_ERR, "Zero packet size\n"); return -ENODATA; } - new_read_idx = queue->qhdr_read_idx + packet_size_in_words; - if (((packet_size_in_words << 2) <= VIDC_IFACEQ_VAR_HUGE_PKT_SIZE) - && queue->qhdr_read_idx <= queue->qhdr_q_size) { - if (new_read_idx < queue->qhdr_q_size) { + new_read_idx = read_idx + packet_size_in_words; + if (((packet_size_in_words << 2) <= VIDC_IFACEQ_VAR_HUGE_PKT_SIZE) && + read_idx <= (qinfo->q_array.mem_size >> 2)) { + if (new_read_idx < (qinfo->q_array.mem_size >> 2)) { memcpy(packet, read_ptr, packet_size_in_words << 2); } else { - new_read_idx -= queue->qhdr_q_size; + new_read_idx -= (qinfo->q_array.mem_size >> 2); memcpy(packet, read_ptr, (packet_size_in_words - new_read_idx) << 2); memcpy(packet + ((packet_size_in_words - @@ -541,15 +561,13 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, } else { dprintk(VIDC_WARN, "BAD packet received, read_idx: %#x, pkt_size: %d\n", - queue->qhdr_read_idx, packet_size_in_words << 2); + read_idx, packet_size_in_words << 2); dprintk(VIDC_WARN, "Dropping this packet\n"); - new_read_idx = queue->qhdr_write_idx; + new_read_idx = write_idx; rc = -ENODATA; } - queue->qhdr_read_idx = new_read_idx; - - if (queue->qhdr_read_idx != queue->qhdr_write_idx) + if (new_read_idx != write_idx) queue->qhdr_rx_req = 0; else queue->qhdr_rx_req = receive_request; @@ -559,6 +577,8 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, */ mb(); + queue->qhdr_read_idx = new_read_idx; + *pb_tx_req_is_set = (1 == queue->qhdr_tx_req) ? 1 : 0; if (msm_vidc_debug & VIDC_PKT) { From 3f49920e675513430394423d4cb78bccb61cb07e Mon Sep 17 00:00:00 2001 From: Deepak Kumar Singh Date: Mon, 4 Feb 2019 18:16:49 +0530 Subject: [PATCH 13/75] soc: qcom: Validate read and write index before calculating ptr Currently we are not validating read and write index of tx and rx fifo's before calculating ptr, this can lead to out-of-bound access. The patch adds proper check for the same. CR-Fixed: 2355425 Change-Id: I7b158e94ae743a90ac364783fe31914ca0fa582b Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/glink_smem_native_xprt.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c index c78c8a00aa21..8b8b404c6ee8 100644 --- a/drivers/soc/qcom/glink_smem_native_xprt.c +++ b/drivers/soc/qcom/glink_smem_native_xprt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -446,6 +446,9 @@ static int fifo_read(struct edge_info *einfo, void *_data, int len) uint32_t fifo_size = einfo->rx_fifo_size; uint32_t n; + if (read_index >= fifo_size || write_index >= fifo_size) + return 0; + while (len) { ptr = einfo->rx_fifo + read_index; if (read_index <= write_index) @@ -489,6 +492,9 @@ static uint32_t fifo_write_body(struct edge_info *einfo, const void *_data, uint32_t fifo_size = einfo->tx_fifo_size; uint32_t n; + if (read_index >= fifo_size || *write_index >= fifo_size) + return 0; + while (len) { ptr = einfo->tx_fifo + *write_index; if (*write_index < read_index) { From 42a7efc865a858a35c142e829154f8c02dd8d03a Mon Sep 17 00:00:00 2001 From: Vijayanand Jitta Date: Wed, 13 Feb 2019 14:21:41 +0530 Subject: [PATCH 14/75] iommu: iommu-debug: don't pass null character to copy_to_user Doing a cat on pte,test_virt_addr from adb shell prints a null character as well which is at the end of the string this is not required so, don't pass this null character to copy_to_user. Change-Id: I8d9120f64d1df84a704379eb00bd239fc7059e9e Signed-off-by: Vijayanand Jitta --- drivers/iommu/iommu-debug.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c index 629b9158a3cb..7c02babe7807 100644 --- a/drivers/iommu/iommu-debug.c +++ b/drivers/iommu/iommu-debug.c @@ -1403,7 +1403,7 @@ static ssize_t iommu_debug_virt_addr_read(struct file *file, char __user *ubuf, else snprintf(buf, 100, "0x%pK\n", virt_addr); - buflen = min(count, strlen(buf)+1); + buflen = min(count, strlen(buf)); if (copy_to_user(ubuf, buf, buflen)) { pr_err("Couldn't copy_to_user\n"); retval = -EFAULT; @@ -1527,7 +1527,7 @@ static ssize_t iommu_debug_pte_read(struct file *file, char __user *ubuf, else snprintf(buf, 100, "pte=%016llx\n", pte); - buflen = min(count, strlen(buf)+1); + buflen = min(count, strlen(buf)); if (copy_to_user(ubuf, buf, buflen)) { pr_err("Couldn't copy_to_user\n"); retval = -EFAULT; @@ -1596,7 +1596,7 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf, snprintf(buf, 100, "%pa\n", &phys); } - buflen = min(count, strlen(buf)+1); + buflen = min(count, strlen(buf)); if (copy_to_user(ubuf, buf, buflen)) { pr_err("Couldn't copy_to_user\n"); retval = -EFAULT; @@ -1649,7 +1649,7 @@ static ssize_t iommu_debug_dma_atos_read(struct file *file, char __user *ubuf, else snprintf(buf, 100, "%pa\n", &phys); - buflen = min(count, strlen(buf)+1); + buflen = min(count, strlen(buf)); if (copy_to_user(ubuf, buf, buflen)) { pr_err("Couldn't copy_to_user\n"); retval = -EFAULT; @@ -1880,7 +1880,7 @@ static ssize_t iommu_debug_dma_map_read(struct file *file, char __user *ubuf, iova = ddev->iova; snprintf(buf, 100, "%pa\n", &iova); - buflen = min(count, strlen(buf)+1); + buflen = min(count, strlen(buf)); if (copy_to_user(ubuf, buf, buflen)) { pr_err("Couldn't copy_to_user\n"); retval = -EFAULT; From 8c12285cf306db81780d74069e1064cbac59ae63 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Mon, 4 Feb 2019 11:22:49 +0530 Subject: [PATCH 15/75] dsp: asm: Add check for num_channels before calling q6asm_map_channels Channel_mapping array size varies for different commands. Add check for num_channels before calling q6asm_map_channels. Change-Id: Iccbcfe82f716fc0ffe0a26b1779dcaa1c3cb805b Signed-off-by: Rohit kumar --- sound/soc/msm/qdsp6v2/q6asm.c | 85 ++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 3f90347d491c..de2cc07a4ab0 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -3973,6 +3973,12 @@ int q6asm_open_shared_io(struct audio_client *ac, if (!ac || !config) return -EINVAL; + if (config->channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, + config->channels); + return -EINVAL; + } + bufsz = config->bufsz; bufcnt = config->bufcnt; num_watermarks = 0; @@ -4432,6 +4438,13 @@ int q6asm_set_encdec_chan_map(struct audio_client *ac, int rc = 0; pr_debug("%s: Session %d, num_channels = %d\n", __func__, ac->session, num_channels); + + if (num_channels > MAX_CHAN_MAP_CHANNELS) { + pr_err("%s: Invalid channel count %d\n", __func__, + num_channels); + return -EINVAL; + } + q6asm_add_hdr(ac, &chan_map.hdr, sizeof(chan_map), TRUE); atomic_set(&ac->cmd_state, -1); chan_map.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM; @@ -4510,6 +4523,12 @@ static int q6asm_enc_cfg_blk_pcm_v5(struct audio_client *ac, goto fail_cmd; } + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V2) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -4612,6 +4631,12 @@ int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac, goto fail_cmd; } + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -4711,6 +4736,12 @@ int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac, goto fail_cmd; } + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -4793,6 +4824,11 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac, return -EINVAL; } + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__, ac->session, rate, channels); @@ -4985,9 +5021,13 @@ int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac, struct asm_multi_channel_pcm_enc_cfg_v2 enc_cfg; u8 *channel_mapping; u32 frames_per_buf = 0; - int rc = 0; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__, ac->session, rate, channels); @@ -5535,6 +5575,11 @@ static int __q6asm_media_format_block_pcm(struct audio_client *ac, u8 *channel_mapping; int rc = 0; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate, channels); @@ -5617,6 +5662,11 @@ static int __q6asm_media_format_block_pcm_v3(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -5700,6 +5750,11 @@ static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -5888,6 +5943,11 @@ static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac, u8 *channel_mapping; int rc = 0; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate, channels); @@ -5955,6 +6015,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -6026,6 +6091,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -6099,6 +6169,12 @@ static int __q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac, u8 *channel_mapping; int rc; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V2) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + rc = -EINVAL; + goto fail_cmd; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__, ac->session, rate, channels, bits_per_sample, sample_word_size); @@ -6290,6 +6366,11 @@ int q6asm_media_format_block_gen_compr(struct audio_client *ac, u8 *channel_mapping; int rc = 0; + if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) { + pr_err("%s: Invalid channel count %d\n", __func__, channels); + return -EINVAL; + } + pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]\n", __func__, ac->session, rate, channels, bits_per_sample); From e8629a0959f7f35a0b72d7f27132a4057a9e104d Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 1 Mar 2019 13:16:39 +0530 Subject: [PATCH 16/75] qdsp6v2: apr: check for packet size to header size comparison Check if packet size is large enough to hold the header. Change-Id: I7261f8111d8b5f4f7c181e469de248a732242d64 Signed-off-by: Vatsal Bucha --- drivers/soc/qcom/qdsp6v2/apr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c index 8cd86915be98..d8e95e08177f 100644 --- a/drivers/soc/qcom/qdsp6v2/apr.c +++ b/drivers/soc/qcom/qdsp6v2/apr.c @@ -601,6 +601,12 @@ void apr_cb_func(void *buf, int len, void *priv) pr_err("APR: Wrong paket size\n"); return; } + + if (hdr->pkt_size < hdr_size) { + pr_err("APR: Packet size less than header size\n"); + return; + } + msg_type = hdr->hdr_field; msg_type = (msg_type >> 0x08) & 0x0003; if (msg_type >= APR_MSG_TYPE_MAX && msg_type != APR_BASIC_RSP_RESULT) { From 5557ce5cc847aeb8ed1671c303a3273aaf2f1ede Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 25 Feb 2019 12:01:05 +0530 Subject: [PATCH 17/75] asoc: codecs: Fix out of bound register access For TX5 MUX registers, offset is not followed in TXn order. Update driver to read/write correct register offset when TX5 MUX registers access. CRs-Fixed: 2218938 Change-Id: I8958b6cd1847967cbd37e7145c9f3909b0b8853b Signed-off-by: Laxminath Kasam --- sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c index a80ac1d18298..dba4f8b48197 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -40,6 +40,7 @@ #define CF_MIN_3DB_75HZ 0x1 #define CF_MIN_3DB_150HZ 0x2 +#define DEC_SVA 5 #define MSM_DIG_CDC_VERSION_ENTRY_SIZE 32 static unsigned long rx_digital_gain_reg[] = { @@ -213,6 +214,9 @@ static int msm_dig_cdc_put_dec_enum(struct snd_kcontrol *kcontrol, tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + 32 * (decimator - 1); + if (decimator == DEC_SVA) + tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL; + snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel); ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); @@ -939,7 +943,7 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w, 32 * (decimator - 1); tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL + 32 * (decimator - 1); - if (decimator == 5) { + if (decimator == DEC_SVA) { tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG; tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL; } @@ -1250,15 +1254,19 @@ static void sdm660_tx_mute_update_callback(struct work_struct *work) dig_cdc = tx_mute_dwork->dig_cdc; codec = dig_cdc->codec; - for (i = 0; i < (NUM_DECIMATORS - 1); i++) { + for (i = 0; i < NUM_DECIMATORS; i++) { if (dig_cdc->dec_active[i]) decimator = i + 1; - if (decimator && decimator < NUM_DECIMATORS) { + if (decimator && decimator <= NUM_DECIMATORS) { /* unmute decimators corresponding to Tx DAI's*/ tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG + 32 * (decimator - 1); - snd_soc_update_bits(codec, tx_vol_ctl_reg, + if (decimator == DEC_SVA) + tx_vol_ctl_reg = + MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG; + + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00); } decimator = 0; From a411b9ceed4f0dc652049f14ae4320ab6f4a4531 Mon Sep 17 00:00:00 2001 From: Praveen Kurapati Date: Thu, 17 Jan 2019 15:36:31 +0530 Subject: [PATCH 18/75] msm: ipa: Fix to validate the buffer size Adding code changes to validate buffer size. While calling ipa_read verifying the kernel buffer size in range or not. Change-Id: Idc608c2cf0587a00f19ece38a4eb646f7fde68e3 Signed-off-by: Praveen Kurapati --- drivers/platform/msm/ipa/ipa_v2/ipa_intf.c | 19 ++++++++++++++++--- drivers/platform/msm/ipa/ipa_v3/ipa_intf.c | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c b/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c index da56a2ed1b8d..23ebc771d0c7 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -735,6 +735,12 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count, IPADBG("msg=%pK\n", msg); locked = 0; mutex_unlock(&ipa_ctx->msg_lock); + if (count < sizeof(struct ipa_msg_meta)) { + kfree(msg); + msg = NULL; + ret = -EFAULT; + break; + } if (copy_to_user(buf, &msg->meta, sizeof(struct ipa_msg_meta))) { kfree(msg); @@ -745,8 +751,15 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count, buf += sizeof(struct ipa_msg_meta); count -= sizeof(struct ipa_msg_meta); if (msg->buff) { - if (copy_to_user(buf, msg->buff, - msg->meta.msg_len)) { + if (count >= msg->meta.msg_len) { + if (copy_to_user(buf, msg->buff, + msg->meta.msg_len)) { + kfree(msg); + msg = NULL; + ret = -EFAULT; + break; + } + } else { kfree(msg); msg = NULL; ret = -EFAULT; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_intf.c b/drivers/platform/msm/ipa/ipa_v3/ipa_intf.c index 456cf6c9fd60..933e9d907a4c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_intf.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_intf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -742,6 +742,12 @@ ssize_t ipa3_read(struct file *filp, char __user *buf, size_t count, if (msg) { locked = 0; mutex_unlock(&ipa3_ctx->msg_lock); + if (count < sizeof(struct ipa_msg_meta)) { + kfree(msg); + msg = NULL; + ret = -EFAULT; + break; + } if (copy_to_user(buf, &msg->meta, sizeof(struct ipa_msg_meta))) { ret = -EFAULT; @@ -752,8 +758,15 @@ ssize_t ipa3_read(struct file *filp, char __user *buf, size_t count, buf += sizeof(struct ipa_msg_meta); count -= sizeof(struct ipa_msg_meta); if (msg->buff) { - if (copy_to_user(buf, msg->buff, - msg->meta.msg_len)) { + if (count >= msg->meta.msg_len) { + if (copy_to_user(buf, msg->buff, + msg->meta.msg_len)) { + ret = -EFAULT; + kfree(msg); + msg = NULL; + break; + } + } else { ret = -EFAULT; kfree(msg); msg = NULL; From b0a3e87996280d8f4dcf3d8d9f74bc4d2676723b Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Mon, 5 Mar 2018 16:51:25 +0530 Subject: [PATCH 19/75] msm: kgsl: Correctly limit max number of contexts per process Read and increment context count atomic variable under a lock to avoid race condition between read and increment. This is necessary to make sure no process goes beyond the specified context limit. Change-Id: I483e2ac169beaff49e19b8ef1b46541f6eb740b0 Signed-off-by: Deepak Kumar --- drivers/gpu/msm/kgsl.c | 8 ++++++++ drivers/gpu/msm/kgsl_device.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 0c8c3b90deab..95a32796a864 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -536,14 +536,21 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, int ret = 0, id; struct kgsl_process_private *proc_priv = dev_priv->process_priv; + /* + * Read and increment the context count under lock to make sure + * no process goes beyond the specified context limit. + */ + spin_lock(&proc_priv->ctxt_count_lock); if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) { KGSL_DRV_ERR(device, "Per process context limit reached for pid %u", dev_priv->process_priv->pid); + spin_unlock(&proc_priv->ctxt_count_lock); return -ENOSPC; } atomic_inc(&proc_priv->ctxt_count); + spin_unlock(&proc_priv->ctxt_count_lock); id = _kgsl_get_context_id(device); if (id == -ENOSPC) { @@ -929,6 +936,7 @@ static struct kgsl_process_private *kgsl_process_private_new( spin_lock_init(&private->mem_lock); spin_lock_init(&private->syncsource_lock); + spin_lock_init(&private->ctxt_count_lock); idr_init(&private->mem_idr); idr_init(&private->syncsource_idr); diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 6622e89181a9..7b39af4ba81e 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -423,6 +423,7 @@ struct kgsl_context { * @syncsource_lock: Spinlock to protect the syncsource idr * @fd_count: Counter for the number of FDs for this process * @ctxt_count: Count for the number of contexts for this process + * @ctxt_count_lock: Spinlock to protect ctxt_count */ struct kgsl_process_private { unsigned long priv; @@ -444,6 +445,7 @@ struct kgsl_process_private { spinlock_t syncsource_lock; int fd_count; atomic_t ctxt_count; + spinlock_t ctxt_count_lock; }; /** From f46f0d774d08630265af7bb8eb54e96ceb8a5ca6 Mon Sep 17 00:00:00 2001 From: Xiaoyu Ye Date: Sun, 3 Mar 2019 21:14:10 -0800 Subject: [PATCH 20/75] dsp: codecs: fix range check for audio buffer copying The range checking for audio buffer copying in function "audio_in_write" is using the incorrect buffer size. Change it to the actual allocated audio buffer size. Change-Id: Ib7aaa2163c0d99161369eb85d09dc2d23d8c787b Signed-off-by: Xiaoyu Ye --- drivers/misc/qcom/qdsp6v2/audio_utils.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index 15d82d126df7..af95daef6503 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2016, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -879,8 +879,7 @@ ssize_t audio_in_write(struct file *file, __func__, audio->ac->session); } } - xfer = (count > (audio->pcm_cfg.buffer_size)) ? - (audio->pcm_cfg.buffer_size) : count; + xfer = (count > size) ? size : count; if (copy_from_user(cpy_ptr, buf, xfer)) { rc = -EFAULT; From 168a91f810360b67753d9ee81d31666d40b0d8ff Mon Sep 17 00:00:00 2001 From: Hardik Arya Date: Mon, 16 Apr 2018 16:46:58 +0530 Subject: [PATCH 21/75] diag: Free usb buffer's entry after removing from list Currently, there is possibility of memory leak due to not freeing allocated memory for usb buffer's entry after removing it from list. The patch handle this by freeing the entry. Change-Id: Idb08ecad859749e6ab1b09184362de38de4a9836 Signed-off-by: Hardik Arya --- drivers/char/diag/diag_usb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/char/diag/diag_usb.c b/drivers/char/diag/diag_usb.c index 87d021f6a956..7e0576f70ac8 100644 --- a/drivers/char/diag/diag_usb.c +++ b/drivers/char/diag/diag_usb.c @@ -139,8 +139,11 @@ static void diag_usb_buf_tbl_remove(struct diag_usb_info *usb_info, * Remove reference from the table if it is the * only instance of the buffer */ - if (atomic_read(&entry->ref_count) == 0) + if (atomic_read(&entry->ref_count) == 0) { list_del(&entry->track); + kfree(entry); + entry = NULL; + } break; } } @@ -330,6 +333,7 @@ static void diag_usb_write_done(struct diag_usb_info *ch, buf = entry->buf; len = entry->len; kfree(entry); + entry = NULL; diag_ws_on_copy_complete(DIAG_WS_MUX); if (ch->ops && ch->ops->write_done) From 6f1987e5d8dafc065559e37db9555e2abb525d5f Mon Sep 17 00:00:00 2001 From: Hardik Arya Date: Thu, 29 Mar 2018 13:58:19 +0530 Subject: [PATCH 22/75] diag: Add protection while accessing usb_info's buffer table Currently there a possibility of NULL pointer dereference while accessing usb_info's buffer table due to missing proper protection. The patch adds protection for the same. Change-Id: I974a70a48e7ac47b42bc237aac4db1b9e47be6be Signed-off-by: Hardik Arya --- drivers/char/diag/diag_usb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/char/diag/diag_usb.c b/drivers/char/diag/diag_usb.c index 87d021f6a956..5ea98b531b83 100644 --- a/drivers/char/diag/diag_usb.c +++ b/drivers/char/diag/diag_usb.c @@ -308,23 +308,25 @@ static void diag_usb_write_done(struct diag_usb_info *ch, if (!ch || !req) return; + spin_lock_irqsave(&ch->write_lock, flags); ch->write_cnt++; entry = diag_usb_buf_tbl_get(ch, req->context); if (!entry) { pr_err_ratelimited("diag: In %s, unable to find entry %pK in the table\n", __func__, req->context); + spin_unlock_irqrestore(&ch->write_lock, flags); return; } if (atomic_read(&entry->ref_count) != 0) { DIAG_LOG(DIAG_DEBUG_MUX, "partial write_done ref %d\n", atomic_read(&entry->ref_count)); diag_ws_on_copy_complete(DIAG_WS_MUX); + spin_unlock_irqrestore(&ch->write_lock, flags); diagmem_free(driver, req, ch->mempool); return; } DIAG_LOG(DIAG_DEBUG_MUX, "full write_done, ctxt: %d\n", ctxt); - spin_lock_irqsave(&ch->write_lock, flags); list_del(&entry->track); ctxt = entry->ctxt; buf = entry->buf; From d7807eff3a0a3199e36d9c06a7385eadbb9993d6 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 13 Dec 2018 14:44:16 +0530 Subject: [PATCH 23/75] diag: dci: Validate dci client entries prior read Validate the dci entries and its task structure before accessing structure members to prevent copying dci data to invalid entries. Change-Id: I07c59ef0705bc52a8268b0dc984ebfa9d26d178e Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 6 +++--- drivers/char/diag/diagchar_core.c | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index b0b36d00415d..0858b8585e30 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2296,8 +2296,8 @@ struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int tgid) pid_struct = find_get_pid(entry->tgid); if (!pid_struct) { DIAG_LOG(DIAG_DEBUG_DCI, - "diag: valid pid doesn't exist for pid = %d\n", - entry->tgid); + "diag: Exited pid (%d) doesn't match dci client of pid (%d)\n", + tgid, entry->tgid); continue; } task_s = get_pid_task(pid_struct, PIDTYPE_PID); diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 9cee52fdf870..fd851ef3cc87 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -583,8 +583,8 @@ static int diag_remove_client_entry(struct file *file) static int diagchar_close(struct inode *inode, struct file *file) { int ret; - DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: process exit %s\n", - current->comm); + DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: %s process exit with pid = %d\n", + current->comm, current->tgid); ret = diag_remove_client_entry(file); mutex_lock(&driver->diag_maskclear_mutex); driver->mask_clear = 0; @@ -3124,6 +3124,8 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, int exit_stat = 0; int write_len = 0; struct diag_md_session_t *session_info = NULL; + struct pid *pid_struct = NULL; + struct task_struct *task_s = NULL; mutex_lock(&driver->diagchar_mutex); for (i = 0; i < driver->num_clients; i++) @@ -3331,8 +3333,19 @@ exit: list_for_each_safe(start, temp, &driver->dci_client_list) { entry = list_entry(start, struct diag_dci_client_tbl, track); - if (entry->client->tgid != current->tgid) + pid_struct = find_get_pid(entry->tgid); + if (!pid_struct) continue; + task_s = get_pid_task(pid_struct, PIDTYPE_PID); + if (!task_s) { + DIAG_LOG(DIAG_DEBUG_DCI, + "diag: valid task doesn't exist for pid = %d\n", + entry->tgid); + continue; + } + if (task_s == entry->client) + if (entry->client->tgid != current->tgid) + continue; if (!entry->in_service) continue; if (copy_to_user(buf + ret, &data_type, sizeof(int))) { From 14961ab5bbb5ba36ca4cff997d616b62fb8b4273 Mon Sep 17 00:00:00 2001 From: Sandeep Singh Date: Wed, 13 Feb 2019 16:17:30 +0530 Subject: [PATCH 24/75] icnss: Add support for graceful shutdown Add a QMI command to indicate graceful shutdown to the FW and updating the QMI file. Change-Id: I0360f6f5b49bc19ea4a7acbbd0e192e1596463d6 Signed-off-by: Sandeep Singh --- drivers/soc/qcom/icnss.c | 59 +- drivers/soc/qcom/wlan_firmware_service_v01.c | 2045 +++++++++++++++--- drivers/soc/qcom/wlan_firmware_service_v01.h | 689 ++++-- 3 files changed, 2336 insertions(+), 457 deletions(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 81c3befa0812..fae06806b7db 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1636,6 +1636,56 @@ out: return ret; } +static int wlfw_send_modem_shutdown_msg(void) +{ + int ret; + struct wlfw_shutdown_req_msg_v01 req; + struct wlfw_shutdown_resp_msg_v01 resp; + struct msg_desc req_desc, resp_desc; + + if (!penv || !penv->wlfw_clnt) + return -ENODEV; + + icnss_pr_dbg("Sending modem shutdown request, state: 0x%lx\n", + penv->state); + + memset(&req, 0, sizeof(req)); + memset(&resp, 0, sizeof(resp)); + + req.shutdown_valid = 1; + req.shutdown = 1; + + req_desc.max_msg_len = WLFW_SHUTDOWN_REQ_MSG_V01_MAX_MSG_LEN; + req_desc.msg_id = QMI_WLFW_SHUTDOWN_REQ_V01; + req_desc.ei_array = wlfw_shutdown_req_msg_v01_ei; + + resp_desc.max_msg_len = WLFW_SHUTDOWN_RESP_MSG_V01_MAX_MSG_LEN; + resp_desc.msg_id = QMI_WLFW_SHUTDOWN_RESP_V01; + resp_desc.ei_array = wlfw_shutdown_resp_msg_v01_ei; + + ret = qmi_send_req_wait(penv->wlfw_clnt, &req_desc, &req, sizeof(req), + &resp_desc, &resp, sizeof(resp), + WLFW_TIMEOUT_MS); + if (ret < 0) { + icnss_pr_err("Send modem shutdown req failed, ret: %d\n", ret); + goto out; + } + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + icnss_pr_err("QMI modem shutdown request rejected result:%d error:%d\n", + resp.resp.result, resp.resp.error); + ret = -resp.resp.result; + goto out; + } + + icnss_pr_dbg("modem shutdown request sent successfully, state: 0x%lx\n", + penv->state); + return 0; + +out: + return ret; +} + static int wlfw_athdiag_read_send_sync_msg(struct icnss_priv *priv, uint32_t offset, uint32_t mem_type, uint32_t data_len, uint8_t *data) @@ -2534,6 +2584,13 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, if (code != SUBSYS_BEFORE_SHUTDOWN) return NOTIFY_OK; + if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) { + ret = wlfw_send_modem_shutdown_msg(); + if (ret) + icnss_pr_dbg("Fail to send modem shutdown Indication %d\n", + ret); + } + if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) { set_bit(ICNSS_FW_DOWN, &priv->state); icnss_ignore_qmi_timeout(true); diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.c b/drivers/soc/qcom/wlan_firmware_service_v01.c index e3ebea31c019..846a4bac16ac 100644 --- a/drivers/soc/qcom/wlan_firmware_service_v01.c +++ b/drivers/soc/qcom/wlan_firmware_service_v01.c @@ -1,4 +1,4 @@ - /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + /* Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,7 +20,7 @@ static struct elem_info wlfw_ce_tgt_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, @@ -38,7 +38,7 @@ static struct elem_info wlfw_ce_tgt_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, @@ -47,7 +47,7 @@ static struct elem_info wlfw_ce_tgt_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, @@ -56,7 +56,7 @@ static struct elem_info wlfw_ce_tgt_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01, @@ -65,7 +65,7 @@ static struct elem_info wlfw_ce_tgt_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -73,7 +73,7 @@ static struct elem_info wlfw_ce_svc_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01, @@ -91,7 +91,7 @@ static struct elem_info wlfw_ce_svc_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01, @@ -100,7 +100,7 @@ static struct elem_info wlfw_ce_svc_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -108,7 +108,7 @@ static struct elem_info wlfw_shadow_reg_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, - .elem_size = sizeof(uint16_t), + .elem_size = sizeof(u16), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_shadow_reg_cfg_s_v01, @@ -117,7 +117,7 @@ static struct elem_info wlfw_shadow_reg_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, - .elem_size = sizeof(uint16_t), + .elem_size = sizeof(u16), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_shadow_reg_cfg_s_v01, @@ -126,7 +126,7 @@ static struct elem_info wlfw_shadow_reg_cfg_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -134,7 +134,7 @@ static struct elem_info wlfw_shadow_reg_v2_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_shadow_reg_v2_cfg_s_v01, @@ -143,7 +143,59 @@ static struct elem_info wlfw_shadow_reg_v2_cfg_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct elem_info wlfw_rri_over_ddr_cfg_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_rri_over_ddr_cfg_s_v01, + base_addr_low), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_rri_over_ddr_cfg_s_v01, + base_addr_high), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct elem_info wlfw_msi_cfg_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(u16), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_msi_cfg_s_v01, + ce_id), + }, + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(u16), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_msi_cfg_s_v01, + msi_vector), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -151,7 +203,7 @@ static struct elem_info wlfw_memory_region_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, - .elem_size = sizeof(uint64_t), + .elem_size = sizeof(u64), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_memory_region_info_s_v01, @@ -160,7 +212,7 @@ static struct elem_info wlfw_memory_region_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_memory_region_info_s_v01, @@ -169,7 +221,7 @@ static struct elem_info wlfw_memory_region_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_memory_region_info_s_v01, @@ -178,7 +230,131 @@ static struct elem_info wlfw_memory_region_info_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct elem_info wlfw_mem_cfg_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_cfg_s_v01, + offset), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_cfg_s_v01, + size), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_cfg_s_v01, + secure_flag), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct elem_info wlfw_mem_seg_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_seg_s_v01, + size), + }, + { + .data_type = QMI_SIGNED_4_BYTE_ENUM, + .elem_len = 1, + .elem_size = sizeof(enum wlfw_mem_type_enum_v01), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_seg_s_v01, + type), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_seg_s_v01, + mem_cfg_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_MEM_CFG_V01, + .elem_size = sizeof(struct wlfw_mem_cfg_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_seg_s_v01, + mem_cfg), + .ei_array = wlfw_mem_cfg_s_v01_ei, + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static struct elem_info wlfw_mem_seg_resp_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_seg_resp_s_v01, + addr), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_seg_resp_s_v01, + size), + }, + { + .data_type = QMI_SIGNED_4_BYTE_ENUM, + .elem_len = 1, + .elem_size = sizeof(enum wlfw_mem_type_enum_v01), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_seg_resp_s_v01, + type), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct wlfw_mem_seg_resp_s_v01, + restore), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -186,7 +362,7 @@ static struct elem_info wlfw_rf_chip_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_rf_chip_info_s_v01, @@ -195,7 +371,7 @@ static struct elem_info wlfw_rf_chip_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_rf_chip_info_s_v01, @@ -204,7 +380,7 @@ static struct elem_info wlfw_rf_chip_info_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -212,7 +388,7 @@ static struct elem_info wlfw_rf_board_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_rf_board_info_s_v01, @@ -221,7 +397,7 @@ static struct elem_info wlfw_rf_board_info_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -229,7 +405,7 @@ static struct elem_info wlfw_soc_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_soc_info_s_v01, @@ -238,7 +414,7 @@ static struct elem_info wlfw_soc_info_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -246,7 +422,7 @@ static struct elem_info wlfw_fw_version_info_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0, .offset = offsetof(struct wlfw_fw_version_info_s_v01, @@ -264,7 +440,7 @@ static struct elem_info wlfw_fw_version_info_s_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -272,7 +448,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -281,7 +457,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -290,7 +466,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -299,7 +475,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -308,7 +484,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -317,7 +493,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -326,7 +502,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -335,7 +511,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -344,7 +520,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -353,7 +529,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -362,7 +538,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x15, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -371,7 +547,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x15, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -380,7 +556,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x16, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -389,7 +565,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x16, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -398,7 +574,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x17, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -407,7 +583,7 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x17, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -416,25 +592,25 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x18, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, - cold_boot_cal_done_enable_valid), + fw_init_done_enable_valid), }, { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x18, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, - cold_boot_cal_done_enable), + fw_init_done_enable), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x19, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, @@ -443,16 +619,106 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x19, .offset = offsetof(struct wlfw_ind_register_req_msg_v01, rejuvenate_enable), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1A, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + xo_cal_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1A, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + xo_cal_enable), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1B, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + cal_done_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1B, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + cal_done_enable), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1C, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + qdss_trace_req_mem_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1C, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + qdss_trace_req_mem_enable), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1D, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + qdss_trace_save_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1D, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + qdss_trace_save_enable), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1E, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + qdss_trace_free_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1E, + .offset = offsetof(struct wlfw_ind_register_req_msg_v01, + qdss_trace_free_enable), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -463,34 +729,35 @@ struct elem_info wlfw_ind_register_resp_msg_v01_ei[] = { .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof(struct wlfw_ind_register_resp_msg_v01, - resp), + .offset = + offsetof(struct wlfw_ind_register_resp_msg_v01, + resp), .ei_array = get_qmi_response_type_v01_ei(), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_ind_register_resp_msg_v01, - fw_status_valid), + .offset = + offsetof(struct wlfw_ind_register_resp_msg_v01, + fw_status_valid), }, { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, - .elem_size = sizeof(uint64_t), + .elem_size = sizeof(u64), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_ind_register_resp_msg_v01, - fw_status), + .offset = + offsetof(struct wlfw_ind_register_resp_msg_v01, + fw_status), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -498,7 +765,7 @@ struct elem_info wlfw_fw_ready_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -506,7 +773,7 @@ struct elem_info wlfw_msa_ready_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -514,67 +781,67 @@ struct elem_info wlfw_pin_connect_result_ind_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_pin_connect_result_ind_msg_v01, - pwr_pin_result_valid), + .offset = + offsetof(struct wlfw_pin_connect_result_ind_msg_v01, + pwr_pin_result_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_pin_connect_result_ind_msg_v01, - pwr_pin_result), + .offset = + offsetof(struct wlfw_pin_connect_result_ind_msg_v01, + pwr_pin_result), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, - .offset = offsetof( - struct wlfw_pin_connect_result_ind_msg_v01, - phy_io_pin_result_valid), + .offset = + offsetof(struct wlfw_pin_connect_result_ind_msg_v01, + phy_io_pin_result_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x11, - .offset = offsetof( - struct wlfw_pin_connect_result_ind_msg_v01, - phy_io_pin_result), + .offset = + offsetof(struct wlfw_pin_connect_result_ind_msg_v01, + phy_io_pin_result), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, - .offset = offsetof( - struct wlfw_pin_connect_result_ind_msg_v01, - rf_pin_result_valid), + .offset = + offsetof(struct wlfw_pin_connect_result_ind_msg_v01, + rf_pin_result_valid), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x12, - .offset = offsetof( - struct wlfw_pin_connect_result_ind_msg_v01, - rf_pin_result), + .offset = + offsetof(struct wlfw_pin_connect_result_ind_msg_v01, + rf_pin_result), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -591,7 +858,7 @@ struct elem_info wlfw_wlan_mode_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_wlan_mode_req_msg_v01, @@ -600,7 +867,7 @@ struct elem_info wlfw_wlan_mode_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_wlan_mode_req_msg_v01, @@ -609,7 +876,7 @@ struct elem_info wlfw_wlan_mode_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -627,7 +894,7 @@ struct elem_info wlfw_wlan_mode_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -635,7 +902,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -653,7 +920,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -662,7 +929,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -681,7 +948,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -690,7 +957,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -709,7 +976,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -718,7 +985,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -737,7 +1004,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -746,7 +1013,7 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, @@ -762,10 +1029,57 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = { shadow_reg_v2), .ei_array = wlfw_shadow_reg_v2_cfg_s_v01_ei, }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, + rri_over_ddr_cfg_valid), + }, + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct wlfw_rri_over_ddr_cfg_s_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, + rri_over_ddr_cfg), + .ei_array = wlfw_rri_over_ddr_cfg_s_v01_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, + msi_cfg_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, + msi_cfg_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_CE_V01, + .elem_size = sizeof(struct wlfw_msi_cfg_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01, + msi_cfg), + .ei_array = wlfw_msi_cfg_s_v01_ei, + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -783,7 +1097,7 @@ struct elem_info wlfw_wlan_cfg_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -791,7 +1105,7 @@ struct elem_info wlfw_cap_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -809,7 +1123,7 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_cap_resp_msg_v01, @@ -828,7 +1142,7 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_cap_resp_msg_v01, @@ -847,7 +1161,7 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_cap_resp_msg_v01, @@ -866,7 +1180,7 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_cap_resp_msg_v01, @@ -885,7 +1199,7 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_cap_resp_msg_v01, @@ -900,10 +1214,46 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = { .offset = offsetof(struct wlfw_cap_resp_msg_v01, fw_build_id), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cap_resp_msg_v01, + num_macs_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cap_resp_msg_v01, + num_macs), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_cap_resp_msg_v01, + voltage_mv_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_cap_resp_msg_v01, + voltage_mv), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -911,7 +1261,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -920,7 +1270,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -938,7 +1288,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -947,7 +1297,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -956,7 +1306,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -965,7 +1315,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -974,7 +1324,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -983,7 +1333,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint16_t), + .elem_size = sizeof(u16), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -992,7 +1342,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = VAR_LEN_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -1001,7 +1351,7 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, @@ -1010,16 +1360,34 @@ struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, end), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, + bdf_type_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_bdf_download_req_msg_v01, + bdf_type), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1030,14 +1398,15 @@ struct elem_info wlfw_bdf_download_resp_msg_v01_ei[] = { .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof(struct wlfw_bdf_download_resp_msg_v01, - resp), + .offset = + offsetof(struct wlfw_bdf_download_resp_msg_v01, + resp), .ei_array = get_qmi_response_type_v01_ei(), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1045,7 +1414,7 @@ struct elem_info wlfw_cal_report_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_cal_report_req_msg_v01, @@ -1060,10 +1429,28 @@ struct elem_info wlfw_cal_report_req_msg_v01_ei[] = { .offset = offsetof(struct wlfw_cal_report_req_msg_v01, meta_data), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_cal_report_req_msg_v01, + xo_cal_data_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_cal_report_req_msg_v01, + xo_cal_data), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1081,7 +1468,7 @@ struct elem_info wlfw_cal_report_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1092,13 +1479,54 @@ struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[] = { .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), .is_array = NO_ARRAY, .tlv_type = 0x01, - .offset = offsetof(struct wlfw_initiate_cal_download_ind_msg_v01, - cal_id), + .offset = + offsetof(struct wlfw_initiate_cal_download_ind_msg_v01, + cal_id), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_initiate_cal_download_ind_msg_v01, + total_size_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_initiate_cal_download_ind_msg_v01, + total_size), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_initiate_cal_download_ind_msg_v01, + cal_data_location_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_initiate_cal_download_ind_msg_v01, + cal_data_location), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1106,7 +1534,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1115,7 +1543,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1133,7 +1561,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1142,7 +1570,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1151,7 +1579,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1160,7 +1588,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1169,7 +1597,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1178,7 +1606,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint16_t), + .elem_size = sizeof(u16), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1187,7 +1615,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = VAR_LEN_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1196,7 +1624,7 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, @@ -1205,16 +1633,34 @@ struct elem_info wlfw_cal_download_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_cal_download_req_msg_v01, end), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cal_download_req_msg_v01, + cal_data_location_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cal_download_req_msg_v01, + cal_data_location), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1225,14 +1671,15 @@ struct elem_info wlfw_cal_download_resp_msg_v01_ei[] = { .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof(struct wlfw_cal_download_resp_msg_v01, - resp), + .offset = + offsetof(struct wlfw_cal_download_resp_msg_v01, + resp), .ei_array = get_qmi_response_type_v01_ei(), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1243,22 +1690,44 @@ struct elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[] = { .elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01), .is_array = NO_ARRAY, .tlv_type = 0x01, - .offset = offsetof(struct wlfw_initiate_cal_update_ind_msg_v01, - cal_id), + .offset = + offsetof(struct wlfw_initiate_cal_update_ind_msg_v01, + cal_id), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof(struct wlfw_initiate_cal_update_ind_msg_v01, - total_size), + .offset = + offsetof(struct wlfw_initiate_cal_update_ind_msg_v01, + total_size), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_initiate_cal_update_ind_msg_v01, + cal_data_location_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_initiate_cal_update_ind_msg_v01, + cal_data_location), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1275,7 +1744,7 @@ struct elem_info wlfw_cal_update_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x02, .offset = offsetof(struct wlfw_cal_update_req_msg_v01, @@ -1284,7 +1753,7 @@ struct elem_info wlfw_cal_update_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1302,7 +1771,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1320,7 +1789,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1329,7 +1798,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1338,7 +1807,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1347,7 +1816,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1356,7 +1825,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1365,7 +1834,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint16_t), + .elem_size = sizeof(u16), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1374,7 +1843,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = VAR_LEN_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1383,7 +1852,7 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, @@ -1392,16 +1861,34 @@ struct elem_info wlfw_cal_update_resp_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x14, .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, end), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, + cal_data_location_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_cal_update_resp_msg_v01, + cal_data_location), + }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1409,7 +1896,7 @@ struct elem_info wlfw_msa_info_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, - .elem_size = sizeof(uint64_t), + .elem_size = sizeof(u64), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_msa_info_req_msg_v01, @@ -1418,7 +1905,7 @@ struct elem_info wlfw_msa_info_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x02, .offset = offsetof(struct wlfw_msa_info_req_msg_v01, @@ -1427,7 +1914,7 @@ struct elem_info wlfw_msa_info_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1445,7 +1932,7 @@ struct elem_info wlfw_msa_info_resp_msg_v01_ei[] = { { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x03, .offset = offsetof(struct wlfw_msa_info_resp_msg_v01, @@ -1464,7 +1951,7 @@ struct elem_info wlfw_msa_info_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1472,7 +1959,7 @@ struct elem_info wlfw_msa_ready_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1490,7 +1977,7 @@ struct elem_info wlfw_msa_ready_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1498,7 +1985,7 @@ struct elem_info wlfw_ini_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_ini_req_msg_v01, @@ -1507,7 +1994,7 @@ struct elem_info wlfw_ini_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_ini_req_msg_v01, @@ -1516,7 +2003,7 @@ struct elem_info wlfw_ini_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1534,7 +2021,7 @@ struct elem_info wlfw_ini_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1542,7 +2029,7 @@ struct elem_info wlfw_athdiag_read_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_athdiag_read_req_msg_v01, @@ -1551,7 +2038,7 @@ struct elem_info wlfw_athdiag_read_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x02, .offset = offsetof(struct wlfw_athdiag_read_req_msg_v01, @@ -1560,7 +2047,7 @@ struct elem_info wlfw_athdiag_read_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x03, .offset = offsetof(struct wlfw_athdiag_read_req_msg_v01, @@ -1569,7 +2056,7 @@ struct elem_info wlfw_athdiag_read_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1580,45 +2067,45 @@ struct elem_info wlfw_athdiag_read_resp_msg_v01_ei[] = { .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof( - struct wlfw_athdiag_read_resp_msg_v01, - resp), + .offset = + offsetof(struct wlfw_athdiag_read_resp_msg_v01, + resp), .ei_array = get_qmi_response_type_v01_ei(), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_athdiag_read_resp_msg_v01, - data_valid), + .offset = + offsetof(struct wlfw_athdiag_read_resp_msg_v01, + data_valid), }, { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint16_t), + .elem_size = sizeof(u16), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_athdiag_read_resp_msg_v01, - data_len), + .offset = + offsetof(struct wlfw_athdiag_read_resp_msg_v01, + data_len), }, { .data_type = QMI_UNSIGNED_1_BYTE, - .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, - .elem_size = sizeof(uint8_t), + .elem_len = QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01, + .elem_size = sizeof(u8), .is_array = VAR_LEN_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_athdiag_read_resp_msg_v01, - data), + .offset = + offsetof(struct wlfw_athdiag_read_resp_msg_v01, + data), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1626,47 +2113,47 @@ struct elem_info wlfw_athdiag_write_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x01, - .offset = offsetof( - struct wlfw_athdiag_write_req_msg_v01, - offset), + .offset = + offsetof(struct wlfw_athdiag_write_req_msg_v01, + offset), }, { .data_type = QMI_UNSIGNED_4_BYTE, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u32), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof( - struct wlfw_athdiag_write_req_msg_v01, - mem_type), + .offset = + offsetof(struct wlfw_athdiag_write_req_msg_v01, + mem_type), }, { .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint16_t), + .elem_size = sizeof(u16), .is_array = NO_ARRAY, .tlv_type = 0x03, - .offset = offsetof( - struct wlfw_athdiag_write_req_msg_v01, - data_len), + .offset = + offsetof(struct wlfw_athdiag_write_req_msg_v01, + data_len), }, { .data_type = QMI_UNSIGNED_1_BYTE, - .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, - .elem_size = sizeof(uint8_t), + .elem_len = QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01, + .elem_size = sizeof(u8), .is_array = VAR_LEN_ARRAY, .tlv_type = 0x03, - .offset = offsetof( - struct wlfw_athdiag_write_req_msg_v01, - data), + .offset = + offsetof(struct wlfw_athdiag_write_req_msg_v01, + data), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1677,15 +2164,15 @@ struct elem_info wlfw_athdiag_write_resp_msg_v01_ei[] = { .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof( - struct wlfw_athdiag_write_resp_msg_v01, - resp), - .ei_array = get_qmi_response_type_v01_ei(), + .offset = + offsetof(struct wlfw_athdiag_write_resp_msg_v01, + resp), + .ei_array = qmi_response_type_v01_ei, }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1693,7 +2180,7 @@ struct elem_info wlfw_vbatt_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, - .elem_size = sizeof(uint64_t), + .elem_size = sizeof(u64), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_vbatt_req_msg_v01, @@ -1702,7 +2189,7 @@ struct elem_info wlfw_vbatt_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1720,7 +2207,7 @@ struct elem_info wlfw_vbatt_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1728,7 +2215,7 @@ struct elem_info wlfw_mac_addr_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_mac_addr_req_msg_v01, @@ -1737,7 +2224,7 @@ struct elem_info wlfw_mac_addr_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = QMI_WLFW_MAC_ADDR_SIZE_V01, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = STATIC_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_mac_addr_req_msg_v01, @@ -1746,7 +2233,7 @@ struct elem_info wlfw_mac_addr_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1764,7 +2251,7 @@ struct elem_info wlfw_mac_addr_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1772,25 +2259,268 @@ struct elem_info wlfw_host_cap_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_host_cap_req_msg_v01, - daemon_support_valid), + num_clients_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + num_clients), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + wake_msi_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + wake_msi), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x12, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + gpios_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x12, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + gpios_len), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = QMI_WLFW_MAX_NUM_GPIO_V01, + .elem_size = sizeof(u32), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x12, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + gpios), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x13, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + nm_modem_valid), }, { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, - .tlv_type = 0x10, + .tlv_type = 0x13, .offset = offsetof(struct wlfw_host_cap_req_msg_v01, - daemon_support), + nm_modem), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + bdf_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + bdf_support), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + bdf_cache_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x15, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + bdf_cache_support), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + m3_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + m3_support), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x17, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + m3_cache_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x17, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + m3_cache_support), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x18, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + cal_filesys_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x18, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + cal_filesys_support), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x19, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + cal_cache_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x19, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + cal_cache_support), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1A, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + cal_done_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1A, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + cal_done), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1B, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + mem_bucket_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x1B, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + mem_bucket), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1C, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + mem_cfg_mode_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1C, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + mem_cfg_mode), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x1D, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + cal_duration_valid), + }, + { + .data_type = QMI_UNSIGNED_2_BYTE, + .elem_len = 1, + .elem_size = sizeof(u16), + .is_array = NO_ARRAY, + .tlv_type = 0x1D, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + cal_duration), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1808,50 +2538,61 @@ struct elem_info wlfw_host_cap_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info wlfw_request_mem_ind_msg_v01_ei[] = { { - .data_type = QMI_UNSIGNED_4_BYTE, + .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint32_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_request_mem_ind_msg_v01, - size), + mem_seg_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01, + .elem_size = sizeof(struct wlfw_mem_seg_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct wlfw_request_mem_ind_msg_v01, + mem_seg), + .ei_array = wlfw_mem_seg_s_v01_ei, }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; struct elem_info wlfw_respond_mem_req_msg_v01_ei[] = { { - .data_type = QMI_UNSIGNED_8_BYTE, + .data_type = QMI_DATA_LEN, .elem_len = 1, - .elem_size = sizeof(uint64_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x01, .offset = offsetof(struct wlfw_respond_mem_req_msg_v01, - addr), + mem_seg_len), }, { - .data_type = QMI_UNSIGNED_4_BYTE, - .elem_len = 1, - .elem_size = sizeof(uint32_t), - .is_array = NO_ARRAY, - .tlv_type = 0x02, + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01, + .elem_size = sizeof(struct wlfw_mem_seg_resp_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x01, .offset = offsetof(struct wlfw_respond_mem_req_msg_v01, - size), + mem_seg), + .ei_array = wlfw_mem_seg_resp_s_v01_ei, }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1869,7 +2610,7 @@ struct elem_info wlfw_respond_mem_resp_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1877,15 +2618,15 @@ struct elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; -struct elem_info wlfw_cold_boot_cal_done_ind_msg_v01_ei[] = { +struct elem_info wlfw_fw_init_done_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1893,7 +2634,7 @@ struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, @@ -1902,7 +2643,7 @@ struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, @@ -1911,7 +2652,7 @@ struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, @@ -1920,7 +2661,7 @@ struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, @@ -1929,7 +2670,7 @@ struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, @@ -1938,7 +2679,7 @@ struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_2_BYTE, .elem_len = 1, - .elem_size = sizeof(uint16_t), + .elem_size = sizeof(u16), .is_array = NO_ARRAY, .tlv_type = 0x12, .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, @@ -1947,7 +2688,7 @@ struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x13, .offset = offsetof(struct wlfw_rejuvenate_ind_msg_v01, @@ -1965,7 +2706,7 @@ struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1973,7 +2714,7 @@ struct elem_info wlfw_rejuvenate_ack_req_msg_v01_ei[] = { { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -1984,15 +2725,15 @@ struct elem_info wlfw_rejuvenate_ack_resp_msg_v01_ei[] = { .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof( - struct wlfw_rejuvenate_ack_resp_msg_v01, - resp), + .offset = + offsetof(struct wlfw_rejuvenate_ack_resp_msg_v01, + resp), .ei_array = get_qmi_response_type_v01_ei(), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -2000,27 +2741,27 @@ struct elem_info wlfw_dynamic_feature_mask_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof(struct - wlfw_dynamic_feature_mask_req_msg_v01, - mask_valid), + .offset = + offsetof(struct wlfw_dynamic_feature_mask_req_msg_v01, + mask_valid), }, { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, - .elem_size = sizeof(uint64_t), + .elem_size = sizeof(u64), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_dynamic_feature_mask_req_msg_v01, - mask), + .offset = + offsetof(struct wlfw_dynamic_feature_mask_req_msg_v01, + mask), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; @@ -2031,55 +2772,771 @@ struct elem_info wlfw_dynamic_feature_mask_resp_msg_v01_ei[] = { .elem_size = sizeof(struct qmi_response_type_v01), .is_array = NO_ARRAY, .tlv_type = 0x02, - .offset = offsetof( - struct wlfw_dynamic_feature_mask_resp_msg_v01, - resp), + .offset = + offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, + resp), .ei_array = get_qmi_response_type_v01_ei(), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_dynamic_feature_mask_resp_msg_v01, - prev_mask_valid), + .offset = + offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, + prev_mask_valid), }, { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, - .elem_size = sizeof(uint64_t), + .elem_size = sizeof(u64), .is_array = NO_ARRAY, .tlv_type = 0x10, - .offset = offsetof( - struct wlfw_dynamic_feature_mask_resp_msg_v01, - prev_mask), + .offset = + offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, + prev_mask), }, { .data_type = QMI_OPT_FLAG, .elem_len = 1, - .elem_size = sizeof(uint8_t), + .elem_size = sizeof(u8), .is_array = NO_ARRAY, .tlv_type = 0x11, - .offset = offsetof( - struct wlfw_dynamic_feature_mask_resp_msg_v01, - curr_mask_valid), + .offset = + offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, + curr_mask_valid), }, { .data_type = QMI_UNSIGNED_8_BYTE, .elem_len = 1, - .elem_size = sizeof(uint64_t), + .elem_size = sizeof(u64), .is_array = NO_ARRAY, .tlv_type = 0x11, - .offset = offsetof( - struct wlfw_dynamic_feature_mask_resp_msg_v01, - curr_mask), + .offset = + offsetof(struct wlfw_dynamic_feature_mask_resp_msg_v01, + curr_mask), }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, - .is_array = QMI_COMMON_TLV_TYPE, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_m3_info_req_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct wlfw_m3_info_req_msg_v01, + addr), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wlfw_m3_info_req_msg_v01, + size), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_m3_info_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wlfw_m3_info_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_xo_cal_ind_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct wlfw_xo_cal_ind_msg_v01, + xo_cal_data), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_cal_done_ind_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_req_mem_ind_msg_v01_ei[] = { + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = + offsetof(struct wlfw_qdss_trace_req_mem_ind_msg_v01, + mem_seg_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01, + .elem_size = sizeof(struct wlfw_mem_seg_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x01, + .offset = + offsetof(struct wlfw_qdss_trace_req_mem_ind_msg_v01, + mem_seg), + .ei_array = wlfw_mem_seg_s_v01_ei, + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_mem_info_req_msg_v01_ei[] = { + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = + offsetof(struct wlfw_qdss_trace_mem_info_req_msg_v01, + mem_seg_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01, + .elem_size = sizeof(struct wlfw_mem_seg_resp_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x01, + .offset = + offsetof(struct wlfw_qdss_trace_mem_info_req_msg_v01, + mem_seg), + .ei_array = wlfw_mem_seg_resp_s_v01_ei, + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_mem_info_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = + offsetof(struct wlfw_qdss_trace_mem_info_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_save_ind_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = + offsetof(struct wlfw_qdss_trace_save_ind_msg_v01, + source), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = + offsetof(struct wlfw_qdss_trace_save_ind_msg_v01, + total_size), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_save_ind_msg_v01, + mem_seg_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_save_ind_msg_v01, + mem_seg_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01, + .elem_size = sizeof(struct wlfw_mem_seg_resp_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_save_ind_msg_v01, + mem_seg), + .ei_array = wlfw_mem_seg_resp_s_v01_ei, + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_qdss_trace_save_ind_msg_v01, + file_name_valid), + }, + { + .data_type = QMI_STRING, + .elem_len = QMI_WLFW_MAX_STR_LEN_V01 + 1, + .elem_size = sizeof(char), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_qdss_trace_save_ind_msg_v01, + file_name), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_data_req_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = + offsetof(struct wlfw_qdss_trace_data_req_msg_v01, + seg_id), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_data_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + total_size_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + total_size), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + seg_id_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + seg_id), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x12, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + data_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u16), + .is_array = NO_ARRAY, + .tlv_type = 0x12, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + data_len), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, + .elem_size = sizeof(u8), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x12, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + data), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x13, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + end_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x13, + .offset = + offsetof(struct wlfw_qdss_trace_data_resp_msg_v01, + end), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_config_download_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + total_size_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + total_size), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + seg_id_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + seg_id), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x12, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + data_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u16), + .is_array = NO_ARRAY, + .tlv_type = 0x12, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + data_len), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = QMI_WLFW_MAX_DATA_SIZE_V01, + .elem_size = sizeof(u8), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x12, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + data), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x13, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + end_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x13, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_req_msg_v01, + end), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_config_download_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = + offsetof(struct wlfw_qdss_trace_config_download_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_mode_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_mode_req_msg_v01, + mode_valid), + }, + { + .data_type = QMI_SIGNED_4_BYTE_ENUM, + .elem_len = 1, + .elem_size = sizeof(enum wlfw_qdss_trace_mode_enum_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_mode_req_msg_v01, + mode), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_qdss_trace_mode_req_msg_v01, + option_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .is_array = NO_ARRAY, + .tlv_type = 0x11, + .offset = + offsetof(struct wlfw_qdss_trace_mode_req_msg_v01, + option), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_mode_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = + offsetof(struct wlfw_qdss_trace_mode_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_qdss_trace_free_ind_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_free_ind_msg_v01, + mem_seg_valid), + }, + { + .data_type = QMI_DATA_LEN, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_free_ind_msg_v01, + mem_seg_len), + }, + { + .data_type = QMI_STRUCT, + .elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01, + .elem_size = sizeof(struct wlfw_mem_seg_resp_s_v01), + .is_array = VAR_LEN_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_qdss_trace_free_ind_msg_v01, + mem_seg), + .ei_array = wlfw_mem_seg_resp_s_v01_ei, + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_shutdown_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_shutdown_req_msg_v01, + shutdown_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_shutdown_req_msg_v01, + shutdown), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_shutdown_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = + offsetof(struct wlfw_shutdown_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_antenna_switch_req_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_antenna_switch_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = + offsetof(struct wlfw_antenna_switch_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_antenna_switch_resp_msg_v01, + antenna_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_antenna_switch_resp_msg_v01, + antenna), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_antenna_grant_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_antenna_grant_req_msg_v01, + grant_valid), + }, + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = + offsetof(struct wlfw_antenna_grant_req_msg_v01, + grant), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_antenna_grant_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = + offsetof(struct wlfw_antenna_grant_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, }, }; diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.h b/drivers/soc/qcom/wlan_firmware_service_v01.h index 751e92338a0f..121c491d2b30 100644 --- a/drivers/soc/qcom/wlan_firmware_service_v01.h +++ b/drivers/soc/qcom/wlan_firmware_service_v01.h @@ -1,4 +1,4 @@ - /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + /* Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -18,15 +18,26 @@ #define QMI_WLFW_BDF_DOWNLOAD_REQ_V01 0x0025 #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 +#define QMI_WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_V01 0x0044 #define QMI_WLFW_INITIATE_CAL_UPDATE_IND_V01 0x002A +#define QMI_WLFW_CAL_DONE_IND_V01 0x003E #define QMI_WLFW_HOST_CAP_REQ_V01 0x0034 #define QMI_WLFW_DYNAMIC_FEATURE_MASK_RESP_V01 0x003B +#define QMI_WLFW_M3_INFO_REQ_V01 0x003C #define QMI_WLFW_CAP_REQ_V01 0x0024 +#define QMI_WLFW_FW_INIT_DONE_IND_V01 0x0038 +#define QMI_WLFW_ANTENNA_GRANT_RESP_V01 0x0048 #define QMI_WLFW_CAL_REPORT_REQ_V01 0x0026 +#define QMI_WLFW_M3_INFO_RESP_V01 0x003C #define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029 #define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027 +#define QMI_WLFW_XO_CAL_IND_V01 0x003D #define QMI_WLFW_INI_RESP_V01 0x002F #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 +#define QMI_WLFW_QDSS_TRACE_MEM_INFO_REQ_V01 0x0040 +#define QMI_WLFW_ANTENNA_SWITCH_REQ_V01 0x0047 +#define QMI_WLFW_QDSS_TRACE_REQ_MEM_IND_V01 0x003F +#define QMI_WLFW_SHUTDOWN_RESP_V01 0x0043 #define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 #define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028 #define QMI_WLFW_HOST_CAP_RESP_V01 0x0034 @@ -35,42 +46,56 @@ #define QMI_WLFW_WLAN_MODE_REQ_V01 0x0022 #define QMI_WLFW_IND_REGISTER_REQ_V01 0x0020 #define QMI_WLFW_WLAN_CFG_RESP_V01 0x0023 -#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x0038 +#define QMI_WLFW_QDSS_TRACE_MODE_REQ_V01 0x0045 #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 +#define QMI_WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_RESP_V01 0x0044 #define QMI_WLFW_REJUVENATE_IND_V01 0x0039 #define QMI_WLFW_DYNAMIC_FEATURE_MASK_REQ_V01 0x003B #define QMI_WLFW_ATHDIAG_WRITE_REQ_V01 0x0031 #define QMI_WLFW_WLAN_MODE_RESP_V01 0x0022 #define QMI_WLFW_RESPOND_MEM_REQ_V01 0x0036 +#define QMI_WLFW_QDSS_TRACE_MODE_RESP_V01 0x0045 #define QMI_WLFW_PIN_CONNECT_RESULT_IND_V01 0x002C #define QMI_WLFW_FW_READY_IND_V01 0x0021 +#define QMI_WLFW_QDSS_TRACE_SAVE_IND_V01 0x0041 +#define QMI_WLFW_QDSS_TRACE_MEM_INFO_RESP_V01 0x0040 +#define QMI_WLFW_ANTENNA_GRANT_REQ_V01 0x0048 #define QMI_WLFW_MSA_READY_RESP_V01 0x002E +#define QMI_WLFW_QDSS_TRACE_DATA_REQ_V01 0x0042 #define QMI_WLFW_CAL_UPDATE_REQ_V01 0x0029 #define QMI_WLFW_INI_REQ_V01 0x002F #define QMI_WLFW_BDF_DOWNLOAD_RESP_V01 0x0025 #define QMI_WLFW_REJUVENATE_ACK_RESP_V01 0x003A #define QMI_WLFW_MSA_INFO_RESP_V01 0x002D #define QMI_WLFW_MSA_READY_REQ_V01 0x002E +#define QMI_WLFW_QDSS_TRACE_DATA_RESP_V01 0x0042 #define QMI_WLFW_CAP_RESP_V01 0x0024 #define QMI_WLFW_REJUVENATE_ACK_REQ_V01 0x003A #define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030 +#define QMI_WLFW_SHUTDOWN_REQ_V01 0x0043 #define QMI_WLFW_VBATT_REQ_V01 0x0032 +#define QMI_WLFW_ANTENNA_SWITCH_RESP_V01 0x0047 #define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033 #define QMI_WLFW_RESPOND_MEM_RESP_V01 0x0036 #define QMI_WLFW_VBATT_RESP_V01 0x0032 #define QMI_WLFW_MSA_INFO_REQ_V01 0x002D +#define QMI_WLFW_QDSS_TRACE_FREE_IND_V01 0x0046 #define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027 #define QMI_WLFW_ATHDIAG_READ_REQ_V01 0x0030 #define QMI_WLFW_WLAN_CFG_REQ_V01 0x0023 #define QMI_WLFW_IND_REGISTER_RESP_V01 0x0020 #define QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01 2 +#define QMI_WLFW_MAX_NUM_MEM_SEG_V01 32 #define QMI_WLFW_MAX_NUM_CAL_V01 5 #define QMI_WLFW_MAX_DATA_SIZE_V01 6144 #define QMI_WLFW_FUNCTION_NAME_LEN_V01 128 #define QMI_WLFW_MAX_NUM_CE_V01 12 #define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32 +#define QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01 6144 +#define QMI_WLFW_MAX_NUM_GPIO_V01 32 #define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128 +#define QMI_WLFW_MAX_NUM_MEM_CFG_V01 2 #define QMI_WLFW_MAX_STR_LEN_V01 16 #define QMI_WLFW_MAX_NUM_SHADOW_REG_V01 24 #define QMI_WLFW_MAC_ADDR_SIZE_V01 6 @@ -109,463 +134,803 @@ enum wlfw_pipedir_enum_v01 { WLFW_PIPEDIR_ENUM_MAX_VAL_V01 = INT_MAX, }; -#define QMI_WLFW_CE_ATTR_FLAGS_V01 ((uint32_t)0x00) -#define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((uint32_t)0x01) -#define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((uint32_t)0x02) -#define QMI_WLFW_CE_ATTR_SWIZZLE_DESCRIPTORS_V01 ((uint32_t)0x04) -#define QMI_WLFW_CE_ATTR_DISABLE_INTR_V01 ((uint32_t)0x08) -#define QMI_WLFW_CE_ATTR_ENABLE_POLL_V01 ((uint32_t)0x10) +enum wlfw_mem_type_enum_v01 { + WLFW_MEM_TYPE_ENUM_MIN_VAL_V01 = INT_MIN, + QMI_WLFW_MEM_TYPE_MSA_V01 = 0, + QMI_WLFW_MEM_TYPE_DDR_V01 = 1, + QMI_WLFW_MEM_BDF_V01 = 2, + QMI_WLFW_MEM_M3_V01 = 3, + QMI_WLFW_MEM_CAL_V01 = 4, + QMI_WLFW_MEM_DPD_V01 = 5, + QMI_WLFW_MEM_QDSS_V01 = 6, + WLFW_MEM_TYPE_ENUM_MAX_VAL_V01 = INT_MAX, +}; -#define QMI_WLFW_ALREADY_REGISTERED_V01 ((uint64_t)0x01ULL) -#define QMI_WLFW_FW_READY_V01 ((uint64_t)0x02ULL) -#define QMI_WLFW_MSA_READY_V01 ((uint64_t)0x04ULL) -#define QMI_WLFW_FW_MEM_READY_V01 ((uint64_t)0x08ULL) +enum wlfw_qdss_trace_mode_enum_v01 { + WLFW_QDSS_TRACE_MODE_ENUM_MIN_VAL_V01 = INT_MIN, + QMI_WLFW_QDSS_TRACE_OFF_V01 = 0, + QMI_WLFW_QDSS_TRACE_ON_V01 = 1, + WLFW_QDSS_TRACE_MODE_ENUM_MAX_VAL_V01 = INT_MAX, +}; -#define QMI_WLFW_FW_REJUVENATE_V01 ((uint64_t)0x01ULL) +#define QMI_WLFW_CE_ATTR_FLAGS_V01 ((u32)0x00) +#define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((u32)0x01) +#define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((u32)0x02) +#define QMI_WLFW_CE_ATTR_SWIZZLE_DESCRIPTORS_V01 ((u32)0x04) +#define QMI_WLFW_CE_ATTR_DISABLE_INTR_V01 ((u32)0x08) +#define QMI_WLFW_CE_ATTR_ENABLE_POLL_V01 ((u32)0x10) + +#define QMI_WLFW_ALREADY_REGISTERED_V01 ((u64)0x01ULL) +#define QMI_WLFW_FW_READY_V01 ((u64)0x02ULL) +#define QMI_WLFW_MSA_READY_V01 ((u64)0x04ULL) +#define QMI_WLFW_FW_MEM_READY_V01 ((u64)0x08ULL) +#define QMI_WLFW_FW_INIT_DONE_V01 ((u64)0x10ULL) + +#define QMI_WLFW_FW_REJUVENATE_V01 ((u64)0x01ULL) struct wlfw_ce_tgt_pipe_cfg_s_v01 { - uint32_t pipe_num; + u32 pipe_num; enum wlfw_pipedir_enum_v01 pipe_dir; - uint32_t nentries; - uint32_t nbytes_max; - uint32_t flags; + u32 nentries; + u32 nbytes_max; + u32 flags; }; struct wlfw_ce_svc_pipe_cfg_s_v01 { - uint32_t service_id; + u32 service_id; enum wlfw_pipedir_enum_v01 pipe_dir; - uint32_t pipe_num; + u32 pipe_num; }; struct wlfw_shadow_reg_cfg_s_v01 { - uint16_t id; - uint16_t offset; + u16 id; + u16 offset; }; struct wlfw_shadow_reg_v2_cfg_s_v01 { - uint32_t addr; + u32 addr; +}; + +struct wlfw_rri_over_ddr_cfg_s_v01 { + u32 base_addr_low; + u32 base_addr_high; +}; + +struct wlfw_msi_cfg_s_v01 { + u16 ce_id; + u16 msi_vector; }; struct wlfw_memory_region_info_s_v01 { - uint64_t region_addr; - uint32_t size; - uint8_t secure_flag; + u64 region_addr; + u32 size; + u8 secure_flag; +}; + +struct wlfw_mem_cfg_s_v01 { + u64 offset; + u32 size; + u8 secure_flag; +}; + +struct wlfw_mem_seg_s_v01 { + u32 size; + enum wlfw_mem_type_enum_v01 type; + u32 mem_cfg_len; + struct wlfw_mem_cfg_s_v01 mem_cfg[QMI_WLFW_MAX_NUM_MEM_CFG_V01]; +}; + +struct wlfw_mem_seg_resp_s_v01 { + u64 addr; + u32 size; + enum wlfw_mem_type_enum_v01 type; + u8 restore; }; struct wlfw_rf_chip_info_s_v01 { - uint32_t chip_id; - uint32_t chip_family; + u32 chip_id; + u32 chip_family; }; struct wlfw_rf_board_info_s_v01 { - uint32_t board_id; + u32 board_id; }; struct wlfw_soc_info_s_v01 { - uint32_t soc_id; + u32 soc_id; }; struct wlfw_fw_version_info_s_v01 { - uint32_t fw_version; + u32 fw_version; char fw_build_timestamp[QMI_WLFW_MAX_TIMESTAMP_LEN_V01 + 1]; }; struct wlfw_ind_register_req_msg_v01 { - uint8_t fw_ready_enable_valid; - uint8_t fw_ready_enable; - uint8_t initiate_cal_download_enable_valid; - uint8_t initiate_cal_download_enable; - uint8_t initiate_cal_update_enable_valid; - uint8_t initiate_cal_update_enable; - uint8_t msa_ready_enable_valid; - uint8_t msa_ready_enable; - uint8_t pin_connect_result_enable_valid; - uint8_t pin_connect_result_enable; - uint8_t client_id_valid; - uint32_t client_id; - uint8_t request_mem_enable_valid; - uint8_t request_mem_enable; - uint8_t fw_mem_ready_enable_valid; - uint8_t fw_mem_ready_enable; - uint8_t cold_boot_cal_done_enable_valid; - uint8_t cold_boot_cal_done_enable; - uint8_t rejuvenate_enable_valid; - uint32_t rejuvenate_enable; + u8 fw_ready_enable_valid; + u8 fw_ready_enable; + u8 initiate_cal_download_enable_valid; + u8 initiate_cal_download_enable; + u8 initiate_cal_update_enable_valid; + u8 initiate_cal_update_enable; + u8 msa_ready_enable_valid; + u8 msa_ready_enable; + u8 pin_connect_result_enable_valid; + u8 pin_connect_result_enable; + u8 client_id_valid; + u32 client_id; + u8 request_mem_enable_valid; + u8 request_mem_enable; + u8 fw_mem_ready_enable_valid; + u8 fw_mem_ready_enable; + u8 fw_init_done_enable_valid; + u8 fw_init_done_enable; + u8 rejuvenate_enable_valid; + u32 rejuvenate_enable; + u8 xo_cal_enable_valid; + u8 xo_cal_enable; + u8 cal_done_enable_valid; + u8 cal_done_enable; + u8 qdss_trace_req_mem_enable_valid; + u8 qdss_trace_req_mem_enable; + u8 qdss_trace_save_enable_valid; + u8 qdss_trace_save_enable; + u8 qdss_trace_free_enable_valid; + u8 qdss_trace_free_enable; }; -#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 46 + +#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 66 extern struct elem_info wlfw_ind_register_req_msg_v01_ei[]; struct wlfw_ind_register_resp_msg_v01 { struct qmi_response_type_v01 resp; - uint8_t fw_status_valid; - uint64_t fw_status; + u8 fw_status_valid; + u64 fw_status; }; + #define WLFW_IND_REGISTER_RESP_MSG_V01_MAX_MSG_LEN 18 extern struct elem_info wlfw_ind_register_resp_msg_v01_ei[]; struct wlfw_fw_ready_ind_msg_v01 { char placeholder; }; + #define WLFW_FW_READY_IND_MSG_V01_MAX_MSG_LEN 0 extern struct elem_info wlfw_fw_ready_ind_msg_v01_ei[]; struct wlfw_msa_ready_ind_msg_v01 { char placeholder; }; + #define WLFW_MSA_READY_IND_MSG_V01_MAX_MSG_LEN 0 extern struct elem_info wlfw_msa_ready_ind_msg_v01_ei[]; struct wlfw_pin_connect_result_ind_msg_v01 { - uint8_t pwr_pin_result_valid; - uint32_t pwr_pin_result; - uint8_t phy_io_pin_result_valid; - uint32_t phy_io_pin_result; - uint8_t rf_pin_result_valid; - uint32_t rf_pin_result; + u8 pwr_pin_result_valid; + u32 pwr_pin_result; + u8 phy_io_pin_result_valid; + u32 phy_io_pin_result; + u8 rf_pin_result_valid; + u32 rf_pin_result; }; + #define WLFW_PIN_CONNECT_RESULT_IND_MSG_V01_MAX_MSG_LEN 21 extern struct elem_info wlfw_pin_connect_result_ind_msg_v01_ei[]; struct wlfw_wlan_mode_req_msg_v01 { enum wlfw_driver_mode_enum_v01 mode; - uint8_t hw_debug_valid; - uint8_t hw_debug; + u8 hw_debug_valid; + u8 hw_debug; }; + #define WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN 11 extern struct elem_info wlfw_wlan_mode_req_msg_v01_ei[]; struct wlfw_wlan_mode_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_WLAN_MODE_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_wlan_mode_resp_msg_v01_ei[]; struct wlfw_wlan_cfg_req_msg_v01 { - uint8_t host_version_valid; + u8 host_version_valid; char host_version[QMI_WLFW_MAX_STR_LEN_V01 + 1]; - uint8_t tgt_cfg_valid; - uint32_t tgt_cfg_len; + u8 tgt_cfg_valid; + u32 tgt_cfg_len; struct wlfw_ce_tgt_pipe_cfg_s_v01 tgt_cfg[QMI_WLFW_MAX_NUM_CE_V01]; - uint8_t svc_cfg_valid; - uint32_t svc_cfg_len; + u8 svc_cfg_valid; + u32 svc_cfg_len; struct wlfw_ce_svc_pipe_cfg_s_v01 svc_cfg[QMI_WLFW_MAX_NUM_SVC_V01]; - uint8_t shadow_reg_valid; - uint32_t shadow_reg_len; + u8 shadow_reg_valid; + u32 shadow_reg_len; struct wlfw_shadow_reg_cfg_s_v01 shadow_reg[QMI_WLFW_MAX_NUM_SHADOW_REG_V01]; - uint8_t shadow_reg_v2_valid; - uint32_t shadow_reg_v2_len; + u8 shadow_reg_v2_valid; + u32 shadow_reg_v2_len; struct wlfw_shadow_reg_v2_cfg_s_v01 - shadow_reg_v2[QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01]; + shadow_reg_v2[QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01]; + u8 rri_over_ddr_cfg_valid; + struct wlfw_rri_over_ddr_cfg_s_v01 rri_over_ddr_cfg; + u8 msi_cfg_valid; + u32 msi_cfg_len; + struct wlfw_msi_cfg_s_v01 msi_cfg[QMI_WLFW_MAX_NUM_CE_V01]; }; -#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 803 + +#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 866 extern struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[]; struct wlfw_wlan_cfg_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_WLAN_CFG_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_wlan_cfg_resp_msg_v01_ei[]; struct wlfw_cap_req_msg_v01 { char placeholder; }; + #define WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN 0 extern struct elem_info wlfw_cap_req_msg_v01_ei[]; struct wlfw_cap_resp_msg_v01 { struct qmi_response_type_v01 resp; - uint8_t chip_info_valid; + u8 chip_info_valid; struct wlfw_rf_chip_info_s_v01 chip_info; - uint8_t board_info_valid; + u8 board_info_valid; struct wlfw_rf_board_info_s_v01 board_info; - uint8_t soc_info_valid; + u8 soc_info_valid; struct wlfw_soc_info_s_v01 soc_info; - uint8_t fw_version_info_valid; + u8 fw_version_info_valid; struct wlfw_fw_version_info_s_v01 fw_version_info; - uint8_t fw_build_id_valid; + u8 fw_build_id_valid; char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1]; + u8 num_macs_valid; + u8 num_macs; + u8 voltage_mv_valid; + u32 voltage_mv; }; -#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 203 + +#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 214 extern struct elem_info wlfw_cap_resp_msg_v01_ei[]; struct wlfw_bdf_download_req_msg_v01 { - uint8_t valid; - uint8_t file_id_valid; + u8 valid; + u8 file_id_valid; enum wlfw_cal_temp_id_enum_v01 file_id; - uint8_t total_size_valid; - uint32_t total_size; - uint8_t seg_id_valid; - uint32_t seg_id; - uint8_t data_valid; - uint32_t data_len; - uint8_t data[QMI_WLFW_MAX_DATA_SIZE_V01]; - uint8_t end_valid; - uint8_t end; + u8 total_size_valid; + u32 total_size; + u8 seg_id_valid; + u32 seg_id; + u8 data_valid; + u32 data_len; + u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; + u8 end_valid; + u8 end; + u8 bdf_type_valid; + u8 bdf_type; }; -#define WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6178 + +#define WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6182 extern struct elem_info wlfw_bdf_download_req_msg_v01_ei[]; struct wlfw_bdf_download_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_BDF_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_bdf_download_resp_msg_v01_ei[]; struct wlfw_cal_report_req_msg_v01 { - uint32_t meta_data_len; + u32 meta_data_len; enum wlfw_cal_temp_id_enum_v01 meta_data[QMI_WLFW_MAX_NUM_CAL_V01]; + u8 xo_cal_data_valid; + u8 xo_cal_data; }; -#define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 24 + +#define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 28 extern struct elem_info wlfw_cal_report_req_msg_v01_ei[]; struct wlfw_cal_report_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_CAL_REPORT_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_cal_report_resp_msg_v01_ei[]; struct wlfw_initiate_cal_download_ind_msg_v01 { enum wlfw_cal_temp_id_enum_v01 cal_id; + u8 total_size_valid; + u32 total_size; + u8 cal_data_location_valid; + u32 cal_data_location; }; -#define WLFW_INITIATE_CAL_DOWNLOAD_IND_MSG_V01_MAX_MSG_LEN 7 + +#define WLFW_INITIATE_CAL_DOWNLOAD_IND_MSG_V01_MAX_MSG_LEN 21 extern struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[]; struct wlfw_cal_download_req_msg_v01 { - uint8_t valid; - uint8_t file_id_valid; + u8 valid; + u8 file_id_valid; enum wlfw_cal_temp_id_enum_v01 file_id; - uint8_t total_size_valid; - uint32_t total_size; - uint8_t seg_id_valid; - uint32_t seg_id; - uint8_t data_valid; - uint32_t data_len; - uint8_t data[QMI_WLFW_MAX_DATA_SIZE_V01]; - uint8_t end_valid; - uint8_t end; + u8 total_size_valid; + u32 total_size; + u8 seg_id_valid; + u32 seg_id; + u8 data_valid; + u32 data_len; + u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; + u8 end_valid; + u8 end; + u8 cal_data_location_valid; + u32 cal_data_location; }; -#define WLFW_CAL_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6178 + +#define WLFW_CAL_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6185 extern struct elem_info wlfw_cal_download_req_msg_v01_ei[]; struct wlfw_cal_download_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_CAL_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_cal_download_resp_msg_v01_ei[]; struct wlfw_initiate_cal_update_ind_msg_v01 { enum wlfw_cal_temp_id_enum_v01 cal_id; - uint32_t total_size; + u32 total_size; + u8 cal_data_location_valid; + u32 cal_data_location; }; -#define WLFW_INITIATE_CAL_UPDATE_IND_MSG_V01_MAX_MSG_LEN 14 + +#define WLFW_INITIATE_CAL_UPDATE_IND_MSG_V01_MAX_MSG_LEN 21 extern struct elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[]; struct wlfw_cal_update_req_msg_v01 { enum wlfw_cal_temp_id_enum_v01 cal_id; - uint32_t seg_id; + u32 seg_id; }; + #define WLFW_CAL_UPDATE_REQ_MSG_V01_MAX_MSG_LEN 14 extern struct elem_info wlfw_cal_update_req_msg_v01_ei[]; struct wlfw_cal_update_resp_msg_v01 { struct qmi_response_type_v01 resp; - uint8_t file_id_valid; + u8 file_id_valid; enum wlfw_cal_temp_id_enum_v01 file_id; - uint8_t total_size_valid; - uint32_t total_size; - uint8_t seg_id_valid; - uint32_t seg_id; - uint8_t data_valid; - uint32_t data_len; - uint8_t data[QMI_WLFW_MAX_DATA_SIZE_V01]; - uint8_t end_valid; - uint8_t end; + u8 total_size_valid; + u32 total_size; + u8 seg_id_valid; + u32 seg_id; + u8 data_valid; + u32 data_len; + u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; + u8 end_valid; + u8 end; + u8 cal_data_location_valid; + u32 cal_data_location; }; -#define WLFW_CAL_UPDATE_RESP_MSG_V01_MAX_MSG_LEN 6181 + +#define WLFW_CAL_UPDATE_RESP_MSG_V01_MAX_MSG_LEN 6188 extern struct elem_info wlfw_cal_update_resp_msg_v01_ei[]; struct wlfw_msa_info_req_msg_v01 { - uint64_t msa_addr; - uint32_t size; + u64 msa_addr; + u32 size; }; + #define WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN 18 extern struct elem_info wlfw_msa_info_req_msg_v01_ei[]; struct wlfw_msa_info_resp_msg_v01 { struct qmi_response_type_v01 resp; - uint32_t mem_region_info_len; + u32 mem_region_info_len; struct wlfw_memory_region_info_s_v01 - mem_region_info[QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01]; + mem_region_info[QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01]; }; + #define WLFW_MSA_INFO_RESP_MSG_V01_MAX_MSG_LEN 37 extern struct elem_info wlfw_msa_info_resp_msg_v01_ei[]; struct wlfw_msa_ready_req_msg_v01 { char placeholder; }; + #define WLFW_MSA_READY_REQ_MSG_V01_MAX_MSG_LEN 0 extern struct elem_info wlfw_msa_ready_req_msg_v01_ei[]; struct wlfw_msa_ready_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_MSA_READY_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_msa_ready_resp_msg_v01_ei[]; struct wlfw_ini_req_msg_v01 { - uint8_t enablefwlog_valid; - uint8_t enablefwlog; + u8 enablefwlog_valid; + u8 enablefwlog; }; + #define WLFW_INI_REQ_MSG_V01_MAX_MSG_LEN 4 extern struct elem_info wlfw_ini_req_msg_v01_ei[]; struct wlfw_ini_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_INI_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_ini_resp_msg_v01_ei[]; struct wlfw_athdiag_read_req_msg_v01 { - uint32_t offset; - uint32_t mem_type; - uint32_t data_len; + u32 offset; + u32 mem_type; + u32 data_len; }; + #define WLFW_ATHDIAG_READ_REQ_MSG_V01_MAX_MSG_LEN 21 extern struct elem_info wlfw_athdiag_read_req_msg_v01_ei[]; struct wlfw_athdiag_read_resp_msg_v01 { struct qmi_response_type_v01 resp; - uint8_t data_valid; - uint32_t data_len; - uint8_t data[QMI_WLFW_MAX_DATA_SIZE_V01]; + u8 data_valid; + u32 data_len; + u8 data[QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01]; }; + #define WLFW_ATHDIAG_READ_RESP_MSG_V01_MAX_MSG_LEN 6156 extern struct elem_info wlfw_athdiag_read_resp_msg_v01_ei[]; struct wlfw_athdiag_write_req_msg_v01 { - uint32_t offset; - uint32_t mem_type; - uint32_t data_len; - uint8_t data[QMI_WLFW_MAX_DATA_SIZE_V01]; + u32 offset; + u32 mem_type; + u32 data_len; + u8 data[QMI_WLFW_MAX_ATHDIAG_DATA_SIZE_V01]; }; + #define WLFW_ATHDIAG_WRITE_REQ_MSG_V01_MAX_MSG_LEN 6163 extern struct elem_info wlfw_athdiag_write_req_msg_v01_ei[]; struct wlfw_athdiag_write_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_ATHDIAG_WRITE_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_athdiag_write_resp_msg_v01_ei[]; struct wlfw_vbatt_req_msg_v01 { - uint64_t voltage_uv; + u64 voltage_uv; }; + #define WLFW_VBATT_REQ_MSG_V01_MAX_MSG_LEN 11 extern struct elem_info wlfw_vbatt_req_msg_v01_ei[]; struct wlfw_vbatt_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_VBATT_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_vbatt_resp_msg_v01_ei[]; struct wlfw_mac_addr_req_msg_v01 { - uint8_t mac_addr_valid; - uint8_t mac_addr[QMI_WLFW_MAC_ADDR_SIZE_V01]; + u8 mac_addr_valid; + u8 mac_addr[QMI_WLFW_MAC_ADDR_SIZE_V01]; }; + #define WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN 9 extern struct elem_info wlfw_mac_addr_req_msg_v01_ei[]; struct wlfw_mac_addr_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_mac_addr_resp_msg_v01_ei[]; struct wlfw_host_cap_req_msg_v01 { - uint8_t daemon_support_valid; - uint8_t daemon_support; + u8 num_clients_valid; + u32 num_clients; + u8 wake_msi_valid; + u32 wake_msi; + u8 gpios_valid; + u32 gpios_len; + u32 gpios[QMI_WLFW_MAX_NUM_GPIO_V01]; + u8 nm_modem_valid; + u8 nm_modem; + u8 bdf_support_valid; + u8 bdf_support; + u8 bdf_cache_support_valid; + u8 bdf_cache_support; + u8 m3_support_valid; + u8 m3_support; + u8 m3_cache_support_valid; + u8 m3_cache_support; + u8 cal_filesys_support_valid; + u8 cal_filesys_support; + u8 cal_cache_support_valid; + u8 cal_cache_support; + u8 cal_done_valid; + u8 cal_done; + u8 mem_bucket_valid; + u32 mem_bucket; + u8 mem_cfg_mode_valid; + u8 mem_cfg_mode; + u8 cal_duration_valid; + u16 cal_duration; }; -#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 4 + +#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 194 extern struct elem_info wlfw_host_cap_req_msg_v01_ei[]; struct wlfw_host_cap_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_HOST_CAP_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_host_cap_resp_msg_v01_ei[]; struct wlfw_request_mem_ind_msg_v01 { - uint32_t size; + u32 mem_seg_len; + struct wlfw_mem_seg_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; }; -#define WLFW_REQUEST_MEM_IND_MSG_V01_MAX_MSG_LEN 7 + +#define WLFW_REQUEST_MEM_IND_MSG_V01_MAX_MSG_LEN 1124 extern struct elem_info wlfw_request_mem_ind_msg_v01_ei[]; struct wlfw_respond_mem_req_msg_v01 { - uint64_t addr; - uint32_t size; + u32 mem_seg_len; + struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; }; -#define WLFW_RESPOND_MEM_REQ_MSG_V01_MAX_MSG_LEN 18 + +#define WLFW_RESPOND_MEM_REQ_MSG_V01_MAX_MSG_LEN 548 extern struct elem_info wlfw_respond_mem_req_msg_v01_ei[]; struct wlfw_respond_mem_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_RESPOND_MEM_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_respond_mem_resp_msg_v01_ei[]; struct wlfw_fw_mem_ready_ind_msg_v01 { char placeholder; }; + #define WLFW_FW_MEM_READY_IND_MSG_V01_MAX_MSG_LEN 0 extern struct elem_info wlfw_fw_mem_ready_ind_msg_v01_ei[]; -struct wlfw_cold_boot_cal_done_ind_msg_v01 { +struct wlfw_fw_init_done_ind_msg_v01 { char placeholder; }; -#define WLFW_COLD_BOOT_CAL_DONE_IND_MSG_V01_MAX_MSG_LEN 0 -extern struct elem_info wlfw_cold_boot_cal_done_ind_msg_v01_ei[]; + +#define WLFW_FW_INIT_DONE_IND_MSG_V01_MAX_MSG_LEN 0 +extern struct elem_info wlfw_fw_init_done_ind_msg_v01_ei[]; struct wlfw_rejuvenate_ind_msg_v01 { - uint8_t cause_for_rejuvenation_valid; - uint8_t cause_for_rejuvenation; - uint8_t requesting_sub_system_valid; - uint8_t requesting_sub_system; - uint8_t line_number_valid; - uint16_t line_number; - uint8_t function_name_valid; + u8 cause_for_rejuvenation_valid; + u8 cause_for_rejuvenation; + u8 requesting_sub_system_valid; + u8 requesting_sub_system; + u8 line_number_valid; + u16 line_number; + u8 function_name_valid; char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1]; }; + #define WLFW_REJUVENATE_IND_MSG_V01_MAX_MSG_LEN 144 extern struct elem_info wlfw_rejuvenate_ind_msg_v01_ei[]; struct wlfw_rejuvenate_ack_req_msg_v01 { char placeholder; }; + #define WLFW_REJUVENATE_ACK_REQ_MSG_V01_MAX_MSG_LEN 0 extern struct elem_info wlfw_rejuvenate_ack_req_msg_v01_ei[]; struct wlfw_rejuvenate_ack_resp_msg_v01 { struct qmi_response_type_v01 resp; }; + #define WLFW_REJUVENATE_ACK_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_rejuvenate_ack_resp_msg_v01_ei[]; struct wlfw_dynamic_feature_mask_req_msg_v01 { - uint8_t mask_valid; - uint64_t mask; + u8 mask_valid; + u64 mask; }; + #define WLFW_DYNAMIC_FEATURE_MASK_REQ_MSG_V01_MAX_MSG_LEN 11 extern struct elem_info wlfw_dynamic_feature_mask_req_msg_v01_ei[]; struct wlfw_dynamic_feature_mask_resp_msg_v01 { struct qmi_response_type_v01 resp; - uint8_t prev_mask_valid; - uint64_t prev_mask; - uint8_t curr_mask_valid; - uint64_t curr_mask; + u8 prev_mask_valid; + u64 prev_mask; + u8 curr_mask_valid; + u64 curr_mask; }; + #define WLFW_DYNAMIC_FEATURE_MASK_RESP_MSG_V01_MAX_MSG_LEN 29 extern struct elem_info wlfw_dynamic_feature_mask_resp_msg_v01_ei[]; +struct wlfw_m3_info_req_msg_v01 { + u64 addr; + u32 size; +}; + +#define WLFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN 18 +extern struct elem_info wlfw_m3_info_req_msg_v01_ei[]; + +struct wlfw_m3_info_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define WLFW_M3_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_m3_info_resp_msg_v01_ei[]; + +struct wlfw_xo_cal_ind_msg_v01 { + u8 xo_cal_data; +}; + +#define WLFW_XO_CAL_IND_MSG_V01_MAX_MSG_LEN 4 +extern struct elem_info wlfw_xo_cal_ind_msg_v01_ei[]; + +struct wlfw_cal_done_ind_msg_v01 { + char placeholder; +}; + +#define WLFW_CAL_DONE_IND_MSG_V01_MAX_MSG_LEN 0 +extern struct elem_info wlfw_cal_done_ind_msg_v01_ei[]; + +struct wlfw_qdss_trace_req_mem_ind_msg_v01 { + u32 mem_seg_len; + struct wlfw_mem_seg_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; +}; + +#define WLFW_QDSS_TRACE_REQ_MEM_IND_MSG_V01_MAX_MSG_LEN 1124 +extern struct elem_info wlfw_qdss_trace_req_mem_ind_msg_v01_ei[]; + +struct wlfw_qdss_trace_mem_info_req_msg_v01 { + u32 mem_seg_len; + struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; +}; + +#define WLFW_QDSS_TRACE_MEM_INFO_REQ_MSG_V01_MAX_MSG_LEN 548 +extern struct elem_info wlfw_qdss_trace_mem_info_req_msg_v01_ei[]; + +struct wlfw_qdss_trace_mem_info_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define WLFW_QDSS_TRACE_MEM_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_qdss_trace_mem_info_resp_msg_v01_ei[]; + +struct wlfw_qdss_trace_save_ind_msg_v01 { + u32 source; + u32 total_size; + u8 mem_seg_valid; + u32 mem_seg_len; + struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; + u8 file_name_valid; + char file_name[QMI_WLFW_MAX_STR_LEN_V01 + 1]; +}; + +#define WLFW_QDSS_TRACE_SAVE_IND_MSG_V01_MAX_MSG_LEN 581 +extern struct elem_info wlfw_qdss_trace_save_ind_msg_v01_ei[]; + +struct wlfw_qdss_trace_data_req_msg_v01 { + u32 seg_id; +}; + +#define WLFW_QDSS_TRACE_DATA_REQ_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_qdss_trace_data_req_msg_v01_ei[]; + +struct wlfw_qdss_trace_data_resp_msg_v01 { + struct qmi_response_type_v01 resp; + u8 total_size_valid; + u32 total_size; + u8 seg_id_valid; + u32 seg_id; + u8 data_valid; + u32 data_len; + u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; + u8 end_valid; + u8 end; +}; + +#define WLFW_QDSS_TRACE_DATA_RESP_MSG_V01_MAX_MSG_LEN 6174 +extern struct elem_info wlfw_qdss_trace_data_resp_msg_v01_ei[]; + +struct wlfw_qdss_trace_config_download_req_msg_v01 { + u8 total_size_valid; + u32 total_size; + u8 seg_id_valid; + u32 seg_id; + u8 data_valid; + u32 data_len; + u8 data[QMI_WLFW_MAX_DATA_SIZE_V01]; + u8 end_valid; + u8 end; +}; + +#define WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6167 +extern struct elem_info wlfw_qdss_trace_config_download_req_msg_v01_ei[]; + +struct wlfw_qdss_trace_config_download_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_qdss_trace_config_download_resp_msg_v01_ei[]; + +struct wlfw_qdss_trace_mode_req_msg_v01 { + u8 mode_valid; + enum wlfw_qdss_trace_mode_enum_v01 mode; + u8 option_valid; + u64 option; +}; + +#define WLFW_QDSS_TRACE_MODE_REQ_MSG_V01_MAX_MSG_LEN 18 +extern struct elem_info wlfw_qdss_trace_mode_req_msg_v01_ei[]; + +struct wlfw_qdss_trace_mode_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define WLFW_QDSS_TRACE_MODE_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_qdss_trace_mode_resp_msg_v01_ei[]; + +struct wlfw_qdss_trace_free_ind_msg_v01 { + u8 mem_seg_valid; + u32 mem_seg_len; + struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01]; +}; + +#define WLFW_QDSS_TRACE_FREE_IND_MSG_V01_MAX_MSG_LEN 548 +extern struct elem_info wlfw_qdss_trace_free_ind_msg_v01_ei[]; + +struct wlfw_shutdown_req_msg_v01 { + u8 shutdown_valid; + u8 shutdown; +}; + +#define WLFW_SHUTDOWN_REQ_MSG_V01_MAX_MSG_LEN 4 +extern struct elem_info wlfw_shutdown_req_msg_v01_ei[]; + +struct wlfw_shutdown_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define WLFW_SHUTDOWN_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_shutdown_resp_msg_v01_ei[]; + +struct wlfw_antenna_switch_req_msg_v01 { + char placeholder; +}; + +#define WLFW_ANTENNA_SWITCH_REQ_MSG_V01_MAX_MSG_LEN 0 +extern struct elem_info wlfw_antenna_switch_req_msg_v01_ei[]; + +struct wlfw_antenna_switch_resp_msg_v01 { + struct qmi_response_type_v01 resp; + u8 antenna_valid; + u64 antenna; +}; + +#define WLFW_ANTENNA_SWITCH_RESP_MSG_V01_MAX_MSG_LEN 18 +extern struct elem_info wlfw_antenna_switch_resp_msg_v01_ei[]; + +struct wlfw_antenna_grant_req_msg_v01 { + u8 grant_valid; + u64 grant; +}; + +#define WLFW_ANTENNA_GRANT_REQ_MSG_V01_MAX_MSG_LEN 11 +extern struct elem_info wlfw_antenna_grant_req_msg_v01_ei[]; + +struct wlfw_antenna_grant_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#define WLFW_ANTENNA_GRANT_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_antenna_grant_resp_msg_v01_ei[]; + #endif From 8bc8a30bdbebdb81bba3fbf5fe91b60534863d7e Mon Sep 17 00:00:00 2001 From: Shadab Naseem Date: Wed, 20 Feb 2019 12:57:27 +0530 Subject: [PATCH 25/75] scripts: gcc-wrapper: Route the GCC errors to stderr The GCC wrapper writes any error message from GCC to stdout along with the messages from the wrapper itself. This is okay for most case, but when GCC is used with -print-xxx flags, the stdout output is supposed to be taken as input to some other build command, so putting error messages in there is pretty bad. Fix this by writing error messages to stderr. Change-Id: I4656033f11ba5212fdcc884cc588f8b9d2c23419 Signed-off-by: Shadab Naseem --- scripts/gcc-wrapper.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/gcc-wrapper.py b/scripts/gcc-wrapper.py index 8a0e0af1c39a..76fb91c57264 100755 --- a/scripts/gcc-wrapper.py +++ b/scripts/gcc-wrapper.py @@ -55,7 +55,7 @@ def interpret_warning(line): line = line.rstrip('\n') m = warning_re.match(line) if m and m.group(2) not in allowed_warnings: - print "error, forbidden warning:", m.group(2) + print >> sys.stderr, "error, forbidden warning:", m.group(2) # If there is a warning, remove any object if it exists. if ofile: @@ -80,17 +80,17 @@ def run_gcc(): try: proc = subprocess.Popen(args, stderr=subprocess.PIPE) for line in proc.stderr: - print line, + print >> sys.stderr, line, interpret_warning(line) result = proc.wait() except OSError as e: result = e.errno if result == errno.ENOENT: - print args[0] + ':',e.strerror - print 'Is your PATH set correctly?' + print >> sys.stderr, args[0] + ':',e.strerror + print >> sys.stderr, 'Is your PATH set correctly?' else: - print ' '.join(args), str(e) + print >> sys.stderr, ' '.join(args), str(e) return result From 7289a6a51e070fd0d8b86ff2e0db77c252740361 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 12 Feb 2019 17:01:22 +0800 Subject: [PATCH 26/75] dsp: validate token before usage as array index Token from DSP might be invalid for array index. Validate the token before being used as array index. Change-Id: I9f47e1328d75d9f9acf7e85ddb452019b6eced0a Signed-off-by: Xiaojun Sang --- sound/soc/msm/qdsp6v2/q6afe.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 0524ca21feba..20c933b80c66 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -482,6 +482,15 @@ static int32_t afe_lpass_resources_callback(struct apr_client_data *data) return 0; } +static bool afe_token_is_valid(uint32_t token) +{ + if (token >= AFE_MAX_PORTS) { + pr_err("%s: token %d is invalid.\n", __func__, token); + return false; + } + return true; +} + static int32_t afe_callback(struct apr_client_data *data, void *priv) { if (!data) { @@ -574,7 +583,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) ret = afe_lpass_resources_callback(data); atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; if (!ret) { return ret; } @@ -610,7 +622,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) case AFE_SVC_CMD_SET_PARAM_V2: case AFE_CMD_REQUEST_LPASS_RESOURCES: atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; break; case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER: break; @@ -622,7 +637,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) break; case AFE_CMD_ADD_TOPOLOGIES: atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n", __func__, payload[1]); break; @@ -678,7 +696,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) else this_afe.mmap_handle = payload[0]; atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; } else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) { port_id = (uint16_t)(0x0000FFFF & payload[0]); } From 0fe53af86212bd9fab635c526efff001e0584102 Mon Sep 17 00:00:00 2001 From: Sandeep Singh Date: Fri, 8 Feb 2019 15:29:11 +0530 Subject: [PATCH 27/75] icnss: Defer modem graceful shutdown until probe complete In case WLAN driver probe is in progress and modem graceful shutdown occurs and if modem shutdown request is sent just before the mode on request sent to firmware, firmware may end up in illegal memory access. To address this issue, modem notifier needs to be blocked needs for probe to complete or max 5 seconds timeout. CRs-Fixed: 2381846 Change-Id: I9e13a11c56059cb29e161c34df11de484f87ac5e Signed-off-by: Sandeep Singh --- drivers/soc/qcom/icnss.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index fae06806b7db..f1eeb66ed80a 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -75,6 +75,8 @@ module_param(qmi_timeout, ulong, 0600); #define ICNSS_MAX_PROBE_CNT 2 +#define PROBE_TIMEOUT 5000 + #define icnss_ipc_log_string(_x...) do { \ if (icnss_ipc_log_context) \ ipc_log_string(icnss_ipc_log_context, _x); \ @@ -299,6 +301,7 @@ enum icnss_driver_state { ICNSS_FW_DOWN, ICNSS_DRIVER_UNLOADING, ICNSS_REJUVENATE, + ICNSS_DRIVER_LOADING, }; struct ce_irq_list { @@ -491,6 +494,7 @@ static struct icnss_priv { u8 requesting_sub_system; u16 line_number; char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1]; + struct completion driver_probed; } *penv; #ifdef CONFIG_ICNSS_DEBUG @@ -2203,6 +2207,8 @@ static int icnss_call_driver_probe(struct icnss_priv *priv) icnss_hw_power_on(priv); + set_bit(ICNSS_DRIVER_LOADING, &priv->state); + reinit_completion(&penv->driver_probed); while (probe_cnt < ICNSS_MAX_PROBE_CNT) { ret = priv->ops->probe(&priv->pdev->dev); probe_cnt++; @@ -2212,9 +2218,13 @@ static int icnss_call_driver_probe(struct icnss_priv *priv) if (ret < 0) { icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", ret, priv->state, probe_cnt); + complete(&penv->driver_probed); + clear_bit(ICNSS_DRIVER_LOADING, &penv->state); goto out; } + complete(&penv->driver_probed); + clear_bit(ICNSS_DRIVER_LOADING, &penv->state); set_bit(ICNSS_DRIVER_PROBED, &priv->state); return 0; @@ -2350,6 +2360,8 @@ static int icnss_driver_event_register_driver(void *data) if (ret) goto out; + set_bit(ICNSS_DRIVER_LOADING, &penv->state); + reinit_completion(&penv->driver_probed); while (probe_cnt < ICNSS_MAX_PROBE_CNT) { ret = penv->ops->probe(&penv->pdev->dev); probe_cnt++; @@ -2359,9 +2371,13 @@ static int icnss_driver_event_register_driver(void *data) if (ret) { icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", ret, penv->state, probe_cnt); + clear_bit(ICNSS_DRIVER_LOADING, &penv->state); + complete(&penv->driver_probed); goto power_off; } + complete(&penv->driver_probed); + clear_bit(ICNSS_DRIVER_LOADING, &penv->state); set_bit(ICNSS_DRIVER_PROBED, &penv->state); return 0; @@ -2584,6 +2600,13 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, if (code != SUBSYS_BEFORE_SHUTDOWN) return NOTIFY_OK; + if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && + test_bit(ICNSS_DRIVER_LOADING, &priv->state)) { + if (!wait_for_completion_timeout(&priv->driver_probed, + PROBE_TIMEOUT)) + icnss_pr_err("wlan driver probe timeout\n"); + } + if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) { ret = wlfw_send_modem_shutdown_msg(); if (ret) @@ -3980,6 +4003,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) continue; case ICNSS_DRIVER_UNLOADING: seq_puts(s, "DRIVER UNLOADING"); + continue; + case ICNSS_DRIVER_LOADING: + seq_puts(s, "WLAN DRIVER LOADING"); } seq_printf(s, "UNKNOWN-%d", i); @@ -4651,6 +4677,8 @@ static int icnss_probe(struct platform_device *pdev) penv = priv; + init_completion(&priv->driver_probed); + icnss_pr_info("Platform driver probed successfully\n"); return 0; @@ -4673,6 +4701,8 @@ static int icnss_remove(struct platform_device *pdev) icnss_debugfs_destroy(penv); + complete_all(&penv->driver_probed); + icnss_modem_ssr_unregister_notifier(penv); destroy_ramdump_device(penv->msa0_dump_dev); From ab8f63420ca818ca92a85bf13db3711d2c936d26 Mon Sep 17 00:00:00 2001 From: Sandeep Singh Date: Fri, 8 Feb 2019 15:46:53 +0530 Subject: [PATCH 28/75] icnss: Add Api to Block/Unblock modem shutdown Add API to Block/Unblock modem graceful shutdown. Change-Id: I69b061fc7d25762b2c36d9590802addfc170f91f Signed-off-by: Sandeep Singh --- drivers/soc/qcom/icnss.c | 49 ++++++++++++++++++++++++---------------- include/soc/qcom/icnss.h | 9 ++------ 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index f1eeb66ed80a..454a897c19ab 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -301,7 +301,7 @@ enum icnss_driver_state { ICNSS_FW_DOWN, ICNSS_DRIVER_UNLOADING, ICNSS_REJUVENATE, - ICNSS_DRIVER_LOADING, + ICNSS_BLOCK_SHUTDOWN, }; struct ce_irq_list { @@ -494,7 +494,7 @@ static struct icnss_priv { u8 requesting_sub_system; u16 line_number; char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1]; - struct completion driver_probed; + struct completion unblock_shutdown; } *penv; #ifdef CONFIG_ICNSS_DEBUG @@ -1182,6 +1182,21 @@ bool icnss_is_fw_ready(void) } EXPORT_SYMBOL(icnss_is_fw_ready); +void icnss_block_shutdown(bool status) +{ + if (!penv) + return; + + if (status) { + set_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state); + reinit_completion(&penv->unblock_shutdown); + } else { + clear_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state); + complete(&penv->unblock_shutdown); + } +} +EXPORT_SYMBOL(icnss_block_shutdown); + bool icnss_is_fw_down(void) { if (!penv) @@ -2207,8 +2222,7 @@ static int icnss_call_driver_probe(struct icnss_priv *priv) icnss_hw_power_on(priv); - set_bit(ICNSS_DRIVER_LOADING, &priv->state); - reinit_completion(&penv->driver_probed); + icnss_block_shutdown(true); while (probe_cnt < ICNSS_MAX_PROBE_CNT) { ret = priv->ops->probe(&priv->pdev->dev); probe_cnt++; @@ -2218,13 +2232,11 @@ static int icnss_call_driver_probe(struct icnss_priv *priv) if (ret < 0) { icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", ret, priv->state, probe_cnt); - complete(&penv->driver_probed); - clear_bit(ICNSS_DRIVER_LOADING, &penv->state); + icnss_block_shutdown(false); goto out; } - complete(&penv->driver_probed); - clear_bit(ICNSS_DRIVER_LOADING, &penv->state); + icnss_block_shutdown(false); set_bit(ICNSS_DRIVER_PROBED, &priv->state); return 0; @@ -2360,8 +2372,7 @@ static int icnss_driver_event_register_driver(void *data) if (ret) goto out; - set_bit(ICNSS_DRIVER_LOADING, &penv->state); - reinit_completion(&penv->driver_probed); + icnss_block_shutdown(true); while (probe_cnt < ICNSS_MAX_PROBE_CNT) { ret = penv->ops->probe(&penv->pdev->dev); probe_cnt++; @@ -2371,13 +2382,11 @@ static int icnss_driver_event_register_driver(void *data) if (ret) { icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", ret, penv->state, probe_cnt); - clear_bit(ICNSS_DRIVER_LOADING, &penv->state); - complete(&penv->driver_probed); + icnss_block_shutdown(false); goto power_off; } - complete(&penv->driver_probed); - clear_bit(ICNSS_DRIVER_LOADING, &penv->state); + icnss_block_shutdown(false); set_bit(ICNSS_DRIVER_PROBED, &penv->state); return 0; @@ -2601,8 +2610,8 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, return NOTIFY_OK; if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && - test_bit(ICNSS_DRIVER_LOADING, &priv->state)) { - if (!wait_for_completion_timeout(&priv->driver_probed, + test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) { + if (!wait_for_completion_timeout(&priv->unblock_shutdown, PROBE_TIMEOUT)) icnss_pr_err("wlan driver probe timeout\n"); } @@ -4004,8 +4013,8 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) case ICNSS_DRIVER_UNLOADING: seq_puts(s, "DRIVER UNLOADING"); continue; - case ICNSS_DRIVER_LOADING: - seq_puts(s, "WLAN DRIVER LOADING"); + case ICNSS_BLOCK_SHUTDOWN: + seq_puts(s, "BLOCK SHUTDOWN"); } seq_printf(s, "UNKNOWN-%d", i); @@ -4677,7 +4686,7 @@ static int icnss_probe(struct platform_device *pdev) penv = priv; - init_completion(&priv->driver_probed); + init_completion(&priv->unblock_shutdown); icnss_pr_info("Platform driver probed successfully\n"); @@ -4701,7 +4710,7 @@ static int icnss_remove(struct platform_device *pdev) icnss_debugfs_destroy(penv); - complete_all(&penv->driver_probed); + complete_all(&penv->unblock_shutdown); icnss_modem_ssr_unregister_notifier(penv); diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h index 85ec8beb3157..010f29db8d48 100644 --- a/include/soc/qcom/icnss.h +++ b/include/soc/qcom/icnss.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -157,10 +157,5 @@ extern bool icnss_is_rejuvenate(void); extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len); extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num); extern int icnss_trigger_recovery(struct device *dev); -extern void cnss_set_cc_source(enum cnss_cc_src cc_source); -extern enum cnss_cc_src cnss_get_cc_source(void); -extern int icnss_get_driver_load_cnt(void); -extern void icnss_increment_driver_load_cnt(void); -extern void icnss_set_cc_source(enum cnss_cc_src cc_source); -extern enum cnss_cc_src icnss_get_cc_source(void); +extern void icnss_block_shutdown(bool status); #endif /* _ICNSS_WLAN_H_ */ From b55c37ac6febb70739af96dadd4168a9295f6956 Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Wed, 2 Jan 2019 20:55:34 +0530 Subject: [PATCH 29/75] msm: ice: check for crypto engine availability There can be many ice instances present in dtsi file but not all of them will be initialized by storage driver. Check if crypto instance is initialized before setting it up for data encryption/decryption usage. Change-Id: I7c9227007474052513b277dec5963a973781c524 Signed-off-by: Neeraj Soni --- drivers/crypto/msm/ice.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/msm/ice.c b/drivers/crypto/msm/ice.c index 68b6a26f00b8..64ddedeb2cca 100644 --- a/drivers/crypto/msm/ice.c +++ b/drivers/crypto/msm/ice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1729,7 +1729,7 @@ int qcom_ice_setup_ice_hw(const char *storage_type, int enable) if (ice_dev == ERR_PTR(-EPROBE_DEFER)) return -EPROBE_DEFER; - if (!ice_dev) + if (!ice_dev || (ice_dev->is_ice_enabled == false)) return ret; if (enable) From ed93ca6232dfd3182bbc99abdb254ac159af9301 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 28 Feb 2019 14:55:05 -0800 Subject: [PATCH 30/75] msm: asm: validate ADSP data before access Validate buffer index obtained from ADSP token before using it. CRs-Fixed: 2372302 Change-Id: I5c3b1634bd08b516844638dd67f726a882edfc17 Signed-off-by: Vignesh Kulothungan --- sound/soc/msm/qdsp6v2/q6asm.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index de2cc07a4ab0..8ec3af00028d 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1948,6 +1948,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) data->dest_port); if ((data->opcode != ASM_DATA_EVENT_RENDERED_EOS) && (data->opcode != ASM_DATA_EVENT_EOS) && + (data->opcode != ASM_SESSION_EVENTX_OVERFLOW) && (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { if (payload == NULL) { pr_err("%s: payload is null\n", __func__); @@ -2130,6 +2131,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } spin_lock_irqsave(&port->dsp_lock, dsp_flags); buf_index = asm_token._token.buf_index; + if (buf_index < 0 || + buf_index >= port->max_buf_cnt) { + pr_err("%s: Invalid buffer index %u\n", + __func__, buf_index); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return -EINVAL; + } if (lower_32_bits(port->buf[buf_index].phys) != payload[0] || msm_audio_populate_upper_32_bits( @@ -2220,6 +2232,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } spin_lock_irqsave(&port->dsp_lock, dsp_flags); buf_index = asm_token._token.buf_index; + if (buf_index < 0 || buf_index >= port->max_buf_cnt) { + pr_err("%s: Invalid buffer index %u\n", + __func__, buf_index); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return -EINVAL; + } port->buf[buf_index].used = 0; if (lower_32_bits(port->buf[buf_index].phys) != payload[READDONE_IDX_BUFADD_LSW] || From 920b58ced94bfba727cc09a786449f37280b8e03 Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 5 Mar 2019 16:00:21 +0530 Subject: [PATCH 31/75] dsp: q6voice: Check size of shared memory buffer before access Check buffer size in qdsp_cvs_callback before access in ul_pkt. Change-Id: Ic19994b46086709231656ec747d2df988b7a512f Signed-off-by: Vatsal Bucha --- sound/soc/msm/qdsp6v2/q6voice.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c index 69189140c936..3193dd0de140 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -6782,6 +6782,11 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) cvs_voc_pkt = v->shmem_info.sh_buf.buf[1].data; if (cvs_voc_pkt != NULL && common.mvs_info.ul_cb != NULL) { + if (v->shmem_info.sh_buf.buf[1].size < + ((3 * sizeof(uint32_t)) + cvs_voc_pkt[2])) { + pr_err("%s: invalid voc pkt size\n", __func__); + return -EINVAL; + } /* cvs_voc_pkt[0] contains tx timestamp */ common.mvs_info.ul_cb((uint8_t *)&cvs_voc_pkt[3], cvs_voc_pkt[2], From 950b66256c03a0c40f4304be1626a3a693597347 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 12 Feb 2019 17:18:18 +0800 Subject: [PATCH 32/75] asoc: check payload length against structure size Payload length must exceed structure size. Otherwise, it may lead to out-of-boundary memory access. Change-Id: I090de5116ab04a4ca2b9c485e17617fe9e861ad5 Signed-off-by: Xiaojun Sang --- sound/soc/msm/qdsp6v2/msm-qti-pp-config.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c index 29a5fd18081a..6f4653a07dad 100644 --- a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c +++ b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1020,6 +1020,13 @@ int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, } event_data = (struct msm_adsp_event_data *)payload; + if (event_data->payload_len < sizeof(struct msm_adsp_event_data)) { + pr_err("%s: event_data size of %x is less than expected.\n", + __func__, event_data->payload_len); + ret = -EINVAL; + goto done; + } + kctl->info(kctl, &kctl_info); if (event_data->payload_len > From ea2ee83c9247d94f466e532906bb16ae37e4657b Mon Sep 17 00:00:00 2001 From: Raghavendra Rao Ananta Date: Fri, 19 Oct 2018 10:06:28 -0700 Subject: [PATCH 33/75] perf: Cancel the mux hrtimer during CPU hotplug to avoid migration The current design of hrtimers migrates the pinned timers to a different CPU upon its hotplug. However, perf-core needs to maintain the mux-hrtimers on a per CPU basis. That is, each hrtimer carries the context for that particular CPU and would lose this context if it gets migrated to a different CPU. As a result, cancel the hrtimer for the CPU that's about to go down and restart it (if required) when the perf-events are being created. Change-Id: I7a1d0456208855e3a99a7d49e59c6dae811d146e Signed-off-by: Raghavendra Rao Ananta [mojha@codeaurora.org: Resolved merge conflict and added missing `cpuctx` variable to avoid build failure] Signed-off-by: Mukesh Ojha --- include/linux/perf_event.h | 2 +- kernel/events/core.c | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index f501b8c0de4e..efce166a9f17 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -231,7 +231,7 @@ struct pmu { int capabilities; int * __percpu pmu_disable_count; - struct perf_cpu_context * __percpu pmu_cpu_context; + struct perf_cpu_context __percpu *pmu_cpu_context; atomic_t exclusive_cnt; /* < 0: cpu; > 0: tsk */ int task_ctx_nr; int hrtimer_interval_ms; diff --git a/kernel/events/core.c b/kernel/events/core.c index a8f984b4fcff..3e6e5eb3e4d2 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -9654,13 +9654,26 @@ static void __perf_event_stop_swclock(void *__info) static void perf_event_exit_cpu_context(int cpu) { + struct perf_cpu_context *cpuctx; struct perf_event_context *ctx; + unsigned long flags; struct pmu *pmu; int idx; idx = srcu_read_lock(&pmus_srcu); list_for_each_entry_rcu(pmu, &pmus, entry) { - ctx = &per_cpu_ptr(pmu->pmu_cpu_context, cpu)->ctx; + cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); + ctx = &cpuctx->ctx; + + /* Cancel the mux hrtimer to avoid CPU migration */ + if (pmu->task_ctx_nr != perf_sw_context) { + raw_spin_lock_irqsave(&cpuctx->hrtimer_lock, flags); + hrtimer_cancel(&cpuctx->hrtimer); + cpuctx->hrtimer_active = 0; + raw_spin_unlock_irqrestore(&cpuctx->hrtimer_lock, + flags); + } + mutex_lock(&ctx->mutex); /* * If keeping events across hotplugging is supported, do not From f0cc7ca31096f58a28ab15dce1f522023857f5ee Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 12 Feb 2019 13:28:15 +0530 Subject: [PATCH 34/75] qdsp6v2: q6usm: Check size of payload before access Check size of payload array before access in q6usm_callback. Change-Id: Id0c85209a053f9dfdb53133aeb6b2510ecf18eb8 Signed-off-by: Vatsal Bucha --- drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c | 21 +++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c index 334e705ca8f1..085f68b22638 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -567,6 +567,11 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == APR_BASIC_RSP_RESULT) { + if (data->payload_size < (2 * sizeof(uint32_t))) { + pr_err("%s: payload has invalid size[%d]\n", __func__, + data->payload_size); + return -EINVAL; + } /* status field check */ if (payload[1]) { pr_err("%s: wrong response[%d] on cmd [%d]\n", @@ -630,6 +635,14 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv) opcode = Q6USM_EVENT_READ_DONE; spin_lock_irqsave(&port->dsp_lock, dsp_flags); + if (data->payload_size < + (sizeof(uint32_t)*(READDONE_IDX_STATUS + 1))) { + pr_err("%s: Invalid payload size for READDONE[%d]\n", + __func__, data->payload_size); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + return -EINVAL; + } if (payload[READDONE_IDX_STATUS]) { pr_err("%s: wrong READDONE[%d]; token[%d]\n", __func__, @@ -675,6 +688,12 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv) struct us_port_data *port = &usc->port[IN]; opcode = Q6USM_EVENT_WRITE_DONE; + if (data->payload_size < + (sizeof(uint32_t)*(WRITEDONE_IDX_STATUS + 1))) { + pr_err("%s: Invalid payload size for WRITEDONE[%d]\n", + __func__, data->payload_size); + return -EINVAL; + } if (payload[WRITEDONE_IDX_STATUS]) { pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n", __func__, From 9d3ba87f26263728d62e95c0435db642c0b081df Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Thu, 28 Feb 2019 18:03:17 +0530 Subject: [PATCH 35/75] drivers: soc: qcom: Added check to avoid opening multiple instance Opening of multiple instance of voice_svc user space from app will lead to pointer deference of private data within apr callback. As multi-instance not supported added check to deny open() from user space if previous instance hasn't been closed. Change-Id: Ia5ef16c69a517760fc9d45530a8a41a333fa2a21 Signed-off-by: Ajit Pandey --- drivers/soc/qcom/qdsp6v2/voice_svc.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c index f01ab2499a75..0a49a322c9da 100644 --- a/drivers/soc/qcom/qdsp6v2/voice_svc.c +++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -68,8 +68,9 @@ static void *dummy_q6_mvm; static void *dummy_q6_cvs; dev_t device_num; +static struct mutex session_lock; static spinlock_t voicesvc_lock; -static bool is_released; +static bool is_released = 1; static int voice_svc_dummy_reg(void); static int voice_svc_dummy_dereg(void); @@ -645,14 +646,23 @@ static int voice_svc_dummy_dereg(void) static int voice_svc_open(struct inode *inode, struct file *file) { struct voice_svc_prvt *prtd = NULL; + int ret = 0; pr_debug("%s\n", __func__); + mutex_lock(&session_lock); + if (is_released == 0) { + pr_err("%s: Access denied to device\n", __func__); + ret = -EBUSY; + goto done; + } + prtd = kmalloc(sizeof(struct voice_svc_prvt), GFP_KERNEL); if (prtd == NULL) { pr_err("%s: kmalloc failed\n", __func__); - return -ENOMEM; + ret = -ENOMEM; + goto done; } memset(prtd, 0, sizeof(struct voice_svc_prvt)); @@ -676,7 +686,9 @@ static int voice_svc_open(struct inode *inode, struct file *file) voice_svc_dummy_reg(); reg_dummy_sess = 1; } - return 0; +done: + mutex_unlock(&session_lock); + return ret; } static int voice_svc_release(struct inode *inode, struct file *file) @@ -810,6 +822,7 @@ static int voice_svc_probe(struct platform_device *pdev) } pr_debug("%s: Device created\n", __func__); spin_lock_init(&voicesvc_lock); + mutex_init(&session_lock); goto done; add_err: @@ -832,6 +845,7 @@ static int voice_svc_remove(struct platform_device *pdev) kfree(voice_svc_dev->cdev); device_destroy(voice_svc_class, device_num); class_destroy(voice_svc_class); + mutex_destroy(&session_lock); unregister_chrdev_region(0, MINOR_NUMBER); return 0; From 279b0b023c43f4728a2790ab21cdff29520fd7dd Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Tue, 12 Feb 2019 13:07:27 +0530 Subject: [PATCH 36/75] qdsp6v2: q6usm: Check size of payload before access Check size of payload before access in q6usm_mmapcallback. Change-Id: Iff0672532c2ea40e7129237a92d8365d6b554cf2 Signed-off-by: Vatsal Bucha --- drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c index 085f68b22638..30a81ba39001 100644 --- a/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c +++ b/drivers/misc/qcom/qdsp6v2/ultrasound/q6usm.c @@ -507,6 +507,12 @@ static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv) uint32_t token; uint32_t *payload = data->payload; + if (data->payload_size < (2 * sizeof(uint32_t))) { + pr_err("%s: payload has invalid size[%d]\n", __func__, + data->payload_size); + return -EINVAL; + } + pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n", __func__, payload[0], payload[1], data->opcode); pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n", From a1b80321aed4f21460564ab19c40b46069dcecfd Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Fri, 10 Aug 2018 13:30:07 +0530 Subject: [PATCH 37/75] msm: kgsl: Limit log frequency in case of context count maxed out kgsl_context_init() prints error message continuously if a process tries to create more number of contexts that KGSL supports. This hogs CPU and might lead to watchdog timeout. Reduce this log frequency by using KGSL_DRV_ERR_RATELIMIT(). Change-Id: I7e3a5d3db41ab0c60d1b6b620cbcdef96d5c21a9 Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/kgsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 95a32796a864..cd2466fd110f 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -542,7 +542,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, */ spin_lock(&proc_priv->ctxt_count_lock); if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) { - KGSL_DRV_ERR(device, + KGSL_DRV_ERR_RATELIMIT(device, "Per process context limit reached for pid %u", dev_priv->process_priv->pid); spin_unlock(&proc_priv->ctxt_count_lock); From e8909e3e1a27d7b1f15882ccfbe543e90e28a26c Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 12 Feb 2019 17:42:38 +0800 Subject: [PATCH 38/75] dsp: asm: validate payload size before access Payload size is not checked before payload access. Check size to avoid out-of-boundary memory access. Change-Id: Iaa39ee4ea5489bb5579e7b7d5dfada12d88c5809 Signed-off-by: Xiaojun Sang --- sound/soc/msm/qdsp6v2/q6asm.c | 250 ++++++++++++++++++++++++---------- 1 file changed, 176 insertions(+), 74 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index de2cc07a4ab0..9a0fcfad99da 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1722,14 +1722,14 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) return 0; } - if (data->payload_size > sizeof(int)) { + if (data->payload_size >= 2 * sizeof(uint32_t)) { pr_debug("%s:ptr0[0x%x]ptr1[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n", __func__, payload[0], payload[1], data->opcode, data->token, data->payload_size, data->src_port, data->dest_port, asm_token._token.session_id, dir); pr_debug("%s:Payload = [0x%x] status[0x%x]\n", __func__, payload[0], payload[1]); - } else if (data->payload_size == sizeof(int)) { + } else if (data->payload_size == sizeof(uint32_t)) { pr_debug("%s:ptr0[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n", __func__, payload[0], data->opcode, data->token, data->payload_size, data->src_port, @@ -1743,7 +1743,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) case ASM_CMD_SHARED_MEM_MAP_REGIONS: case ASM_CMD_SHARED_MEM_UNMAP_REGIONS: case ASM_CMD_ADD_TOPOLOGIES: - if (payload[1] != 0) { + if (data->payload_size >= 2 * sizeof(uint32_t) + && payload[1] != 0) { pr_err("%s: cmd = 0x%x returned error = 0x%x sid:%d\n", __func__, payload[0], payload[1], asm_token._token.session_id); @@ -1761,8 +1762,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) wake_up(&ac->mem_wait); - dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n", + if (data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n", __func__, payload[0], payload[1]); + else + dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); break; default: pr_debug("%s: command[0x%x] not expecting rsp\n", @@ -1791,8 +1796,13 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) break; } case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:{ - pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n", + __func__, payload[0], payload[1]); + else + pr_debug("%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); + spin_lock_irqsave(&port->dsp_lock, dsp_flags); if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) wake_up(&ac->mem_wait); @@ -1801,8 +1811,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) break; } default: - pr_debug("%s: command[0x%x]success [0x%x]\n", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: command[0x%x]success [0x%x]\n", + __func__, payload[0], payload[1]); + else + pr_debug("%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); } if (ac->cb) ac->cb(data->opcode, data->token, @@ -1955,8 +1969,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) &(session[session_id].session_lock), flags); return -EINVAL; } - dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", - __func__, payload[0], payload[1], data->opcode); + if (data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", + __func__, payload[0], payload[1], data->opcode); + else + dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); } if (data->opcode == APR_BASIC_RSP_RESULT) { switch (payload[0]) { @@ -2001,32 +2019,40 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE: case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS: case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED: - pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n", - __func__, ac->session, - data->opcode, data->token, - payload[0], payload[1], - data->src_port, data->dest_port); - if (payload[1] != 0) { + if (data->payload_size >= + 2 * sizeof(uint32_t) && + payload[1] != 0) { + pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + payload[0], payload[1], + data->src_port, data->dest_port); pr_err("%s: cmd = 0x%x returned error = 0x%x\n", - __func__, payload[0], payload[1]); + __func__, + payload[0], + payload[1]); if (wakeup_flag) { - if ((is_adsp_reg_event(payload[0]) >= - 0) || - (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V2) || - (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V3)) - atomic_set(&ac->cmd_state_pp, - payload[1]); + if ((is_adsp_reg_event(payload[0]) >= 0) + || (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V2) + || (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V3)) + atomic_set( + &ac->cmd_state_pp, + payload[1]); else - atomic_set(&ac->cmd_state, - payload[1]); + atomic_set( + &ac->cmd_state, + payload[1]); wake_up(&ac->cmd_wait); } spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } if ((is_adsp_reg_event(payload[0]) >= 0) || (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) || @@ -2048,11 +2074,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (uint32_t *)data->payload, ac->priv); break; case ASM_CMD_ADD_TOPOLOGIES: - pr_debug("%s:Payload = [0x%x]stat[0x%x]\n", - __func__, payload[0], payload[1]); - if (payload[1] != 0) { + if (data->payload_size >= + 2 * sizeof(uint32_t) && + payload[1] != 0) { + pr_debug("%s:Payload = [0x%x]stat[0x%x]\n", + __func__, payload[0], payload[1]); pr_err("%s: cmd = 0x%x returned error = 0x%x\n", - __func__, payload[0], payload[1]); + __func__, payload[0], payload[1]); if (wakeup_flag) { atomic_set(&ac->mem_state, payload[1]); wake_up(&ac->mem_wait); @@ -2071,8 +2099,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (uint32_t *)data->payload, ac->priv); break; case ASM_DATA_EVENT_WATERMARK: { - pr_debug("%s: Watermark opcode[0x%x] status[0x%x]", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: Watermark opcode[0x%x] status[0x%x]", + __func__, payload[0], payload[1]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); break; } case ASM_STREAM_CMD_GET_PP_PARAMS_V2: @@ -2084,11 +2116,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) /* error or malformed APR packet. Otherwise */ /* response will be returned as */ /* ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 */ - if (payload[1] != 0) { - pr_err("%s: ASM get param error = %d, resuming\n", - __func__, payload[1]); - rtac_make_asm_callback(ac->session, payload, + if (data->payload_size >= 2 * sizeof(uint32_t)) { + if (payload[1] != 0) { + pr_err("%s: ASM get param error = %d, resuming\n", + __func__, payload[1]); + rtac_make_asm_callback(ac->session, + payload, data->payload_size); + } + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } break; case ASM_STREAM_CMD_REGISTER_PP_EVENTS: @@ -2096,11 +2134,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, ac->session, data->opcode, data->token, data->src_port, data->dest_port); - if (payload[1] != 0) - pr_err("%s: ASM get param error = %d, resuming\n", - __func__, payload[1]); - atomic_set(&ac->cmd_state_pp, payload[1]); - wake_up(&ac->cmd_wait); + if (data->payload_size >= 2 * sizeof(uint32_t)) { + if (payload[1] != 0) + pr_err("%s: ASM get param error = %d, resuming\n", + __func__, payload[1]); + atomic_set(&ac->cmd_state_pp, payload[1]); + wake_up(&ac->cmd_wait); + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); + } break; default: pr_debug("%s: command[0x%x] not expecting rsp\n", @@ -2116,9 +2159,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) switch (data->opcode) { case ASM_DATA_EVENT_WRITE_DONE_V2:{ struct audio_port_data *port = &ac->port[IN]; - dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]", - __func__, payload[0], payload[1], - data->token); + if (data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]", + __func__, payload[0], payload[1], + data->token); + else + dev_err(ac->dev, "%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); if (ac->io_mode & SYNC_IO_MODE) { if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", @@ -2130,10 +2177,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } spin_lock_irqsave(&port->dsp_lock, dsp_flags); buf_index = asm_token._token.buf_index; - if (lower_32_bits(port->buf[buf_index].phys) != - payload[0] || - msm_audio_populate_upper_32_bits( - port->buf[buf_index].phys) != payload[1]) { + if (data->payload_size >= 2 * sizeof(uint32_t) && + (lower_32_bits(port->buf[buf_index].phys) != + payload[0] || + msm_audio_populate_upper_32_bits( + port->buf[buf_index].phys) != + payload[1])) { pr_debug("%s: Expected addr %pK\n", __func__, &port->buf[buf_index].phys); pr_err("%s: rxedl[0x%x] rxedu [0x%x]\n", @@ -2168,14 +2217,32 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } else if (generic_get_data) { generic_get_data->valid = 1; if (generic_get_data->is_inband) { - pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n", - __func__, payload[1], payload[2], payload[3]); - generic_get_data->size_in_ints = payload[3]>>2; - for (i = 0; i < payload[3]>>2; i++) { - generic_get_data->ints[i] = - payload[4+i]; - pr_debug("%s: ASM callback val %i = %i\n", - __func__, i, payload[4+i]); + if (data->payload_size >= 4 * sizeof(uint32_t)) + pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n", + __func__, + payload[1], + payload[2], + payload[3]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, + data->payload_size); + + if (data->payload_size >= + (4 + (payload[3]>>2)) + * sizeof(uint32_t)) { + generic_get_data->size_in_ints = + payload[3]>>2; + for (i = 0; i < payload[3]>>2; i++) { + generic_get_data->ints[i] = + payload[4+i]; + pr_debug("%s: ASM callback val %i = %i\n", + __func__, i, + payload[4+i]); + } + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } pr_debug("%s: callback size in ints = %i\n", __func__, @@ -2262,11 +2329,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) data->src_port, data->dest_port); break; case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3: - dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", - __func__, - payload[0], payload[1], payload[2]); - ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | - payload[1]); + if (data->payload_size >= 3 * sizeof(uint32_t)) { + dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", + __func__, + payload[0], payload[1], payload[2]); + ac->time_stamp = + (uint64_t)(((uint64_t)payload[2] << 32) | + payload[1]); + } else { + dev_err(ac->dev, "%s: payload size of %x is less than expected.n", + __func__, data->payload_size); + } if (atomic_cmpxchg(&ac->time_flag, 1, 0)) wake_up(&ac->time_wait); break; @@ -2276,10 +2349,14 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, ac->session, data->opcode, data->token, data->src_port, data->dest_port); - pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n", - __func__, - payload[0], payload[1], payload[2], - payload[3]); + if (data->payload_size >= 4 * sizeof(uint32_t)) + pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n", + __func__, + payload[0], payload[1], payload[2], + payload[3]); + else + pr_debug("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); break; case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2: q6asm_process_mtmx_get_param_rsp(ac, (void *) payload); @@ -2287,8 +2364,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) case ASM_STREAM_PP_EVENT: case ASM_STREAM_CMD_ENCDEC_EVENTS: case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE: - pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", + __func__, payload[0], payload[1]); + else + pr_debug("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); i = is_adsp_raise_event(data->opcode); if (i < 0) { spin_unlock_irqrestore( @@ -2300,6 +2381,14 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) * package is composed of event type + size + actual payload */ payload_size = data->payload_size; + if (payload_size > UINT_MAX - + sizeof(struct msm_adsp_event_data)) { + pr_err("%s: payload size = %d exceeds limit.\n", + __func__, payload_size); + spin_unlock(&(session[session_id].session_lock)); + return -EINVAL; + } + pp_event_package = kzalloc(payload_size + sizeof(struct msm_adsp_event_data), GFP_ATOMIC); @@ -2320,16 +2409,29 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) &(session[session_id].session_lock), flags); return 0; case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2: - pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", - __func__, ac->session, payload[0], payload[2], - payload[1]); + if (data->payload_size >= 3 * sizeof(uint32_t)) + pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", + __func__, ac->session, + payload[0], + payload[2], + payload[1]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); wake_up(&ac->cmd_wait); break; case ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2: - pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n", - __func__, ac->session, payload[0], payload[2], + if (data->payload_size >= 3 * sizeof(uint32_t)) + pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n", + __func__, ac->session, + payload[0], payload[2], payload[1]); - if (payload[0] == 0) { + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); + if (payload[0] == 0 && + data->payload_size >= + 2 * sizeof(uint32_t)) { atomic_set(&ac->cmd_state, 0); /* ignore msw, as a delay that large shouldn't happen */ ac->path_delay = payload[1]; From 07c5f7c8c94c76ba5b712bebe24bc9e1e2aeb7c8 Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Wed, 2 Jan 2019 20:55:34 +0530 Subject: [PATCH 39/75] msm: ice: check for crypto engine availability There can be many ice instances present in dtsi file but not all of them will be initialized by storage driver. Check if crypto instance is initialized before setting it up for data encryption/decryption usage. Change-Id: I7c9227007474052513b277dec5963a973781c524 Signed-off-by: Neeraj Soni --- drivers/crypto/msm/ice.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/msm/ice.c b/drivers/crypto/msm/ice.c index 68b6a26f00b8..64ddedeb2cca 100644 --- a/drivers/crypto/msm/ice.c +++ b/drivers/crypto/msm/ice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1729,7 +1729,7 @@ int qcom_ice_setup_ice_hw(const char *storage_type, int enable) if (ice_dev == ERR_PTR(-EPROBE_DEFER)) return -EPROBE_DEFER; - if (!ice_dev) + if (!ice_dev || (ice_dev->is_ice_enabled == false)) return ret; if (enable) From 48272dd0ff56497f18eedbd3760fbe983c78f43c Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 12 Feb 2019 17:01:22 +0800 Subject: [PATCH 40/75] dsp: validate token before usage as array index Token from DSP might be invalid for array index. Validate the token before being used as array index. Change-Id: I9f47e1328d75d9f9acf7e85ddb452019b6eced0a Signed-off-by: Xiaojun Sang --- sound/soc/msm/qdsp6v2/q6afe.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 0524ca21feba..b87e7f886fa6 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -482,6 +482,15 @@ static int32_t afe_lpass_resources_callback(struct apr_client_data *data) return 0; } +static bool afe_token_is_valid(uint32_t token) +{ + if (token >= AFE_MAX_PORTS) { + pr_err("%s: token %d is invalid.\n", __func__, token); + return false; + } + return true; +} + static int32_t afe_callback(struct apr_client_data *data, void *priv) { if (!data) { @@ -610,7 +619,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) case AFE_SVC_CMD_SET_PARAM_V2: case AFE_CMD_REQUEST_LPASS_RESOURCES: atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; break; case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER: break; @@ -622,7 +634,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) break; case AFE_CMD_ADD_TOPOLOGIES: atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n", __func__, payload[1]); break; @@ -678,7 +693,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) else this_afe.mmap_handle = payload[0]; atomic_set(&this_afe.state, 0); - wake_up(&this_afe.wait[data->token]); + if (afe_token_is_valid(data->token)) + wake_up(&this_afe.wait[data->token]); + else + return -EINVAL; } else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) { port_id = (uint16_t)(0x0000FFFF & payload[0]); } From 877ffd6d9dbddbb75d0f9b7cf0b47a38cf6886a4 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 28 Feb 2019 14:55:05 -0800 Subject: [PATCH 41/75] msm: asm: validate ADSP data before access Validate buffer index obtained from ADSP token before using it. CRs-Fixed: 2372302 Change-Id: I5c3b1634bd08b516844638dd67f726a882edfc17 Signed-off-by: Vignesh Kulothungan --- sound/soc/msm/qdsp6v2/q6asm.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 9a0fcfad99da..fd74f157d6f8 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1962,6 +1962,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) data->dest_port); if ((data->opcode != ASM_DATA_EVENT_RENDERED_EOS) && (data->opcode != ASM_DATA_EVENT_EOS) && + (data->opcode != ASM_SESSION_EVENTX_OVERFLOW) && (data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) { if (payload == NULL) { pr_err("%s: payload is null\n", __func__); @@ -2177,6 +2178,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } spin_lock_irqsave(&port->dsp_lock, dsp_flags); buf_index = asm_token._token.buf_index; + if (buf_index < 0 || + buf_index >= port->max_buf_cnt) { + pr_debug("%s: Invalid buffer index %u\n", + __func__, buf_index); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return -EINVAL; + } if (data->payload_size >= 2 * sizeof(uint32_t) && (lower_32_bits(port->buf[buf_index].phys) != payload[0] || @@ -2287,6 +2299,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } spin_lock_irqsave(&port->dsp_lock, dsp_flags); buf_index = asm_token._token.buf_index; + if (buf_index < 0 || buf_index >= port->max_buf_cnt) { + pr_debug("%s: Invalid buffer index %u\n", + __func__, buf_index); + spin_unlock_irqrestore(&port->dsp_lock, + dsp_flags); + spin_unlock_irqrestore( + &(session[session_id].session_lock), + flags); + return -EINVAL; + } port->buf[buf_index].used = 0; if (lower_32_bits(port->buf[buf_index].phys) != payload[READDONE_IDX_BUFADD_LSW] || From 4fedfe5c4d9fc63e8c701e865850ab81259fa9a9 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Singh Date: Tue, 5 Mar 2019 17:16:54 +0530 Subject: [PATCH 42/75] soc: qcom: qmi_encdec: Restrict string length in decode The QMI TLV value for strings in a lot of qmi element info structures account for null terminated strings with MAX_LEN + 1. If a string is actually MAX_LEN + 1 length, this will cause an out of bounds access when the NULL character is appended in decoding. CR-Fixed: 2359244 Change-Id: I4d789bc6017ff58458f77fe875ca4e175a4f1357 Signed-off-by: Chris Lew Signed-off-by: Deepak Kumar Singh --- lib/qmi_encdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/qmi_encdec.c b/lib/qmi_encdec.c index 72b506bececc..9d5c446830ed 100644 --- a/lib/qmi_encdec.c +++ b/lib/qmi_encdec.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2015, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -710,8 +710,8 @@ static int qmi_decode_string_elem(struct elem_info *ei_array, void *buf_dst, decoded_bytes += rc; } - if (string_len > temp_ei->elem_len) { - pr_err("%s: String len %d > Max Len %d\n", + if (string_len >= temp_ei->elem_len) { + pr_err("%s: String len %d >= Max Len %d\n", __func__, string_len, temp_ei->elem_len); return -ETOOSMALL; } else if (string_len > tlv_len) { From 1b75396524935592d749e3a34cd46f0044e4c7b3 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Tue, 12 Feb 2019 17:42:38 +0800 Subject: [PATCH 43/75] dsp: asm: validate payload size before access Payload size is not checked before payload access. Check it to avoid out-of-boundary memory access. Change-Id: Iaa39ee4ea5489bb5579e7b7d5dfada12d88c5809 Signed-off-by: Xiaojun Sang --- sound/soc/msm/qdsp6v2/q6asm.c | 250 ++++++++++++++++++++++++---------- 1 file changed, 176 insertions(+), 74 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 8ec3af00028d..79f1bc3be655 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1722,14 +1722,14 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) return 0; } - if (data->payload_size > sizeof(int)) { + if (data->payload_size >= 2 * sizeof(uint32_t)) { pr_debug("%s:ptr0[0x%x]ptr1[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n", __func__, payload[0], payload[1], data->opcode, data->token, data->payload_size, data->src_port, data->dest_port, asm_token._token.session_id, dir); pr_debug("%s:Payload = [0x%x] status[0x%x]\n", __func__, payload[0], payload[1]); - } else if (data->payload_size == sizeof(int)) { + } else if (data->payload_size == sizeof(uint32_t)) { pr_debug("%s:ptr0[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n", __func__, payload[0], data->opcode, data->token, data->payload_size, data->src_port, @@ -1743,7 +1743,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) case ASM_CMD_SHARED_MEM_MAP_REGIONS: case ASM_CMD_SHARED_MEM_UNMAP_REGIONS: case ASM_CMD_ADD_TOPOLOGIES: - if (payload[1] != 0) { + if (data->payload_size >= 2 * sizeof(uint32_t) + && payload[1] != 0) { pr_err("%s: cmd = 0x%x returned error = 0x%x sid:%d\n", __func__, payload[0], payload[1], asm_token._token.session_id); @@ -1761,8 +1762,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) wake_up(&ac->mem_wait); - dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n", + if (data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n", __func__, payload[0], payload[1]); + else + dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); break; default: pr_debug("%s: command[0x%x] not expecting rsp\n", @@ -1791,8 +1796,13 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) break; } case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:{ - pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n", + __func__, payload[0], payload[1]); + else + pr_debug("%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); + spin_lock_irqsave(&port->dsp_lock, dsp_flags); if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1) wake_up(&ac->mem_wait); @@ -1801,8 +1811,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv) break; } default: - pr_debug("%s: command[0x%x]success [0x%x]\n", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: command[0x%x]success [0x%x]\n", + __func__, payload[0], payload[1]); + else + pr_debug("%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); } if (ac->cb) ac->cb(data->opcode, data->token, @@ -1956,8 +1970,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) &(session[session_id].session_lock), flags); return -EINVAL; } - dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", - __func__, payload[0], payload[1], data->opcode); + if (data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n", + __func__, payload[0], payload[1], data->opcode); + else + dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n", + __func__, data->payload_size); } if (data->opcode == APR_BASIC_RSP_RESULT) { switch (payload[0]) { @@ -2002,32 +2020,40 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE: case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS: case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED: - pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n", - __func__, ac->session, - data->opcode, data->token, - payload[0], payload[1], - data->src_port, data->dest_port); - if (payload[1] != 0) { + if (data->payload_size >= + 2 * sizeof(uint32_t) && + payload[1] != 0) { + pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n", + __func__, ac->session, + data->opcode, data->token, + payload[0], payload[1], + data->src_port, data->dest_port); pr_err("%s: cmd = 0x%x returned error = 0x%x\n", - __func__, payload[0], payload[1]); + __func__, + payload[0], + payload[1]); if (wakeup_flag) { - if ((is_adsp_reg_event(payload[0]) >= - 0) || - (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V2) || - (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V3)) - atomic_set(&ac->cmd_state_pp, - payload[1]); + if ((is_adsp_reg_event(payload[0]) >= 0) + || (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V2) + || (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V3)) + atomic_set( + &ac->cmd_state_pp, + payload[1]); else - atomic_set(&ac->cmd_state, - payload[1]); + atomic_set( + &ac->cmd_state, + payload[1]); wake_up(&ac->cmd_wait); } spin_unlock_irqrestore( &(session[session_id].session_lock), flags); return 0; + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } if ((is_adsp_reg_event(payload[0]) >= 0) || (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) || @@ -2049,11 +2075,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (uint32_t *)data->payload, ac->priv); break; case ASM_CMD_ADD_TOPOLOGIES: - pr_debug("%s:Payload = [0x%x]stat[0x%x]\n", - __func__, payload[0], payload[1]); - if (payload[1] != 0) { + if (data->payload_size >= + 2 * sizeof(uint32_t) && + payload[1] != 0) { + pr_debug("%s:Payload = [0x%x]stat[0x%x]\n", + __func__, payload[0], payload[1]); pr_err("%s: cmd = 0x%x returned error = 0x%x\n", - __func__, payload[0], payload[1]); + __func__, payload[0], payload[1]); if (wakeup_flag) { atomic_set(&ac->mem_state, payload[1]); wake_up(&ac->mem_wait); @@ -2072,8 +2100,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) (uint32_t *)data->payload, ac->priv); break; case ASM_DATA_EVENT_WATERMARK: { - pr_debug("%s: Watermark opcode[0x%x] status[0x%x]", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: Watermark opcode[0x%x] status[0x%x]", + __func__, payload[0], payload[1]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); break; } case ASM_STREAM_CMD_GET_PP_PARAMS_V2: @@ -2085,11 +2117,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) /* error or malformed APR packet. Otherwise */ /* response will be returned as */ /* ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 */ - if (payload[1] != 0) { - pr_err("%s: ASM get param error = %d, resuming\n", - __func__, payload[1]); - rtac_make_asm_callback(ac->session, payload, + if (data->payload_size >= 2 * sizeof(uint32_t)) { + if (payload[1] != 0) { + pr_err("%s: ASM get param error = %d, resuming\n", + __func__, payload[1]); + rtac_make_asm_callback(ac->session, + payload, data->payload_size); + } + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } break; case ASM_STREAM_CMD_REGISTER_PP_EVENTS: @@ -2097,11 +2135,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, ac->session, data->opcode, data->token, data->src_port, data->dest_port); - if (payload[1] != 0) - pr_err("%s: ASM get param error = %d, resuming\n", - __func__, payload[1]); - atomic_set(&ac->cmd_state_pp, payload[1]); - wake_up(&ac->cmd_wait); + if (data->payload_size >= 2 * sizeof(uint32_t)) { + if (payload[1] != 0) + pr_err("%s: ASM get param error = %d, resuming\n", + __func__, payload[1]); + atomic_set(&ac->cmd_state_pp, payload[1]); + wake_up(&ac->cmd_wait); + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); + } break; default: pr_debug("%s: command[0x%x] not expecting rsp\n", @@ -2117,9 +2160,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) switch (data->opcode) { case ASM_DATA_EVENT_WRITE_DONE_V2:{ struct audio_port_data *port = &ac->port[IN]; - dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]", - __func__, payload[0], payload[1], - data->token); + if (data->payload_size >= 2 * sizeof(uint32_t)) + dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]", + __func__, payload[0], payload[1], + data->token); + else + dev_err(ac->dev, "%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); if (ac->io_mode & SYNC_IO_MODE) { if (port->buf == NULL) { pr_err("%s: Unexpected Write Done\n", @@ -2142,10 +2189,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) flags); return -EINVAL; } - if (lower_32_bits(port->buf[buf_index].phys) != - payload[0] || - msm_audio_populate_upper_32_bits( - port->buf[buf_index].phys) != payload[1]) { + if (data->payload_size >= 2 * sizeof(uint32_t) && + (lower_32_bits(port->buf[buf_index].phys) != + payload[0] || + msm_audio_populate_upper_32_bits( + port->buf[buf_index].phys) != + payload[1])) { pr_debug("%s: Expected addr %pK\n", __func__, &port->buf[buf_index].phys); pr_err("%s: rxedl[0x%x] rxedu [0x%x]\n", @@ -2180,14 +2229,32 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) } else if (generic_get_data) { generic_get_data->valid = 1; if (generic_get_data->is_inband) { - pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n", - __func__, payload[1], payload[2], payload[3]); - generic_get_data->size_in_ints = payload[3]>>2; - for (i = 0; i < payload[3]>>2; i++) { - generic_get_data->ints[i] = - payload[4+i]; - pr_debug("%s: ASM callback val %i = %i\n", - __func__, i, payload[4+i]); + if (data->payload_size >= 4 * sizeof(uint32_t)) + pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n", + __func__, + payload[1], + payload[2], + payload[3]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, + data->payload_size); + + if (data->payload_size >= + (4 + (payload[3]>>2)) + * sizeof(uint32_t)) { + generic_get_data->size_in_ints = + payload[3]>>2; + for (i = 0; i < payload[3]>>2; i++) { + generic_get_data->ints[i] = + payload[4+i]; + pr_debug("%s: ASM callback val %i = %i\n", + __func__, i, + payload[4+i]); + } + } else { + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); } pr_debug("%s: callback size in ints = %i\n", __func__, @@ -2284,11 +2351,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) data->src_port, data->dest_port); break; case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3: - dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", - __func__, - payload[0], payload[1], payload[2]); - ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | - payload[1]); + if (data->payload_size >= 3 * sizeof(uint32_t)) { + dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", + __func__, + payload[0], payload[1], payload[2]); + ac->time_stamp = + (uint64_t)(((uint64_t)payload[2] << 32) | + payload[1]); + } else { + dev_err(ac->dev, "%s: payload size of %x is less than expected.n", + __func__, data->payload_size); + } if (atomic_cmpxchg(&ac->time_flag, 1, 0)) wake_up(&ac->time_wait); break; @@ -2298,10 +2371,14 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) __func__, ac->session, data->opcode, data->token, data->src_port, data->dest_port); - pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n", - __func__, - payload[0], payload[1], payload[2], - payload[3]); + if (data->payload_size >= 4 * sizeof(uint32_t)) + pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n", + __func__, + payload[0], payload[1], payload[2], + payload[3]); + else + pr_debug("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); break; case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2: q6asm_process_mtmx_get_param_rsp(ac, (void *) payload); @@ -2309,8 +2386,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) case ASM_STREAM_PP_EVENT: case ASM_STREAM_CMD_ENCDEC_EVENTS: case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE: - pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", - __func__, payload[0], payload[1]); + if (data->payload_size >= 2 * sizeof(uint32_t)) + pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]", + __func__, payload[0], payload[1]); + else + pr_debug("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); i = is_adsp_raise_event(data->opcode); if (i < 0) { spin_unlock_irqrestore( @@ -2322,6 +2403,14 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) * package is composed of event type + size + actual payload */ payload_size = data->payload_size; + if (payload_size > UINT_MAX - + sizeof(struct msm_adsp_event_data)) { + pr_err("%s: payload size = %d exceeds limit.\n", + __func__, payload_size); + spin_unlock(&(session[session_id].session_lock)); + return -EINVAL; + } + pp_event_package = kzalloc(payload_size + sizeof(struct msm_adsp_event_data), GFP_ATOMIC); @@ -2342,16 +2431,29 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) &(session[session_id].session_lock), flags); return 0; case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2: - pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", - __func__, ac->session, payload[0], payload[2], - payload[1]); + if (data->payload_size >= 3 * sizeof(uint32_t)) + pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n", + __func__, ac->session, + payload[0], + payload[2], + payload[1]); + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); wake_up(&ac->cmd_wait); break; case ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2: - pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n", - __func__, ac->session, payload[0], payload[2], + if (data->payload_size >= 3 * sizeof(uint32_t)) + pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n", + __func__, ac->session, + payload[0], payload[2], payload[1]); - if (payload[0] == 0) { + else + pr_err("%s: payload size of %x is less than expected.\n", + __func__, data->payload_size); + if (payload[0] == 0 && + data->payload_size >= + 2 * sizeof(uint32_t)) { atomic_set(&ac->cmd_state, 0); /* ignore msw, as a delay that large shouldn't happen */ ac->path_delay = payload[1]; From bc0ac2b798ca553096862f205683a29d4f3b64d7 Mon Sep 17 00:00:00 2001 From: Dhoat Harpal Date: Thu, 18 Jan 2018 00:29:20 +0530 Subject: [PATCH 44/75] soc: qcom: glink: Initialize local state while fetching ctx Initialization of channel's local state is not done at the time of fetching context from list of channels. This leads to race condition if remote close happens during this time. Remote close will check if local state is not open then delete channel from list. This leads to use after free scenerio. Initialize local state at the time of fetching channel context from list of channels. CRs-Fixed: 2155992 Change-Id: If113daba129191bd67ef2460eb4e87c2d5614403 Signed-off-by: Dhoat Harpal --- drivers/soc/qcom/glink.c | 42 ++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index 813c97bb4a50..f9dbc4b29040 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -375,7 +375,7 @@ static void tx_func(struct kthread_work *work); static struct channel_ctx *ch_name_to_ch_ctx_create( struct glink_core_xprt_ctx *xprt_ctx, - const char *name); + const char *name, bool local); static void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t riid, void *cookie); @@ -1870,13 +1870,14 @@ static void glink_ch_ctx_release(struct rwref_lock *ch_st_lock) * it is not found and get reference of context. * @xprt_ctx: Transport to search for a matching channel. * @name: Name of the desired channel. + * @local: If called from local open or not * * Return: The channel corresponding to @name, NULL if a matching channel was * not found AND a new channel could not be created. */ static struct channel_ctx *ch_name_to_ch_ctx_create( struct glink_core_xprt_ctx *xprt_ctx, - const char *name) + const char *name, bool local) { struct channel_ctx *entry; struct channel_ctx *ctx; @@ -1920,10 +1921,23 @@ check_ctx: list_for_each_entry_safe(entry, temp, &xprt_ctx->channels, port_list_node) if (!strcmp(entry->name, name) && !entry->pending_delete) { + rwref_get(&entry->ch_state_lhb2); + /* port already exists */ + if (entry->local_open_state != GLINK_CHANNEL_CLOSED + && local) { + /* not ready to be re-opened */ + GLINK_INFO_CH_XPRT(entry, xprt_ctx, + "%s: Ch not ready. State: %u\n", + __func__, entry->local_open_state); + rwref_put(&entry->ch_state_lhb2); + entry = NULL; + } else if (local) { + entry->local_open_state = + GLINK_CHANNEL_OPENING; + } spin_unlock_irqrestore(&xprt_ctx->xprt_ctx_lock_lhb1, flags); kfree(ctx); - rwref_get(&entry->ch_state_lhb2); rwref_write_put(&xprt_ctx->xprt_state_lhb0); return entry; } @@ -1954,6 +1968,8 @@ check_ctx: ctx->transport_ptr = xprt_ctx; rwref_get(&ctx->ch_state_lhb2); + if (local) + ctx->local_open_state = GLINK_CHANNEL_OPENING; list_add_tail(&ctx->port_list_node, &xprt_ctx->channels); GLINK_INFO_PERF_CH_XPRT(ctx, xprt_ctx, @@ -2639,23 +2655,13 @@ void *glink_open(const struct glink_open_config *cfg) * look for an existing port structure which can occur in * reopen and remote-open-first cases */ - ctx = ch_name_to_ch_ctx_create(transport_ptr, cfg->name); + ctx = ch_name_to_ch_ctx_create(transport_ptr, cfg->name, true); if (ctx == NULL) { GLINK_ERR("%s:%s %s: Error - unable to allocate new channel\n", cfg->transport, cfg->edge, __func__); return ERR_PTR(-ENOMEM); } - /* port already exists */ - if (ctx->local_open_state != GLINK_CHANNEL_CLOSED) { - /* not ready to be re-opened */ - GLINK_INFO_CH_XPRT(ctx, transport_ptr, - "%s: Channel not ready to be re-opened. State: %u\n", - __func__, ctx->local_open_state); - rwref_put(&ctx->ch_state_lhb2); - return ERR_PTR(-EBUSY); - } - /* initialize port structure */ ctx->user_priv = cfg->priv; ctx->rx_intent_req_timeout_jiffies = @@ -2686,7 +2692,6 @@ void *glink_open(const struct glink_open_config *cfg) ctx->local_xprt_req = best_id; ctx->no_migrate = cfg->transport && !(cfg->options & GLINK_OPT_INITIAL_XPORT); - ctx->local_open_state = GLINK_CHANNEL_OPENING; GLINK_INFO_PERF_CH(ctx, "%s: local:GLINK_CHANNEL_CLOSED->GLINK_CHANNEL_OPENING\n", __func__); @@ -4943,7 +4948,7 @@ static void glink_core_rx_cmd_ch_remote_open(struct glink_transport_if *if_ptr, bool do_migrate; glink_core_migration_edge_lock(if_ptr->glink_core_priv); - ctx = ch_name_to_ch_ctx_create(if_ptr->glink_core_priv, name); + ctx = ch_name_to_ch_ctx_create(if_ptr->glink_core_priv, name, false); if (ctx == NULL) { GLINK_ERR_XPRT(if_ptr->glink_core_priv, "%s: invalid rcid %u received, name '%s'\n", @@ -5045,6 +5050,7 @@ static void glink_core_rx_cmd_ch_remote_close( struct channel_ctx *ctx; bool is_ch_fully_closed; struct glink_core_xprt_ctx *xprt_ptr = if_ptr->glink_core_priv; + unsigned long flags; ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid); if (!ctx) { @@ -5062,11 +5068,13 @@ static void glink_core_rx_cmd_ch_remote_close( rwref_put(&ctx->ch_state_lhb2); return; } + spin_lock_irqsave(&ctx->transport_ptr->xprt_ctx_lock_lhb1, flags); + ctx->pending_delete = true; + spin_unlock_irqrestore(&ctx->transport_ptr->xprt_ctx_lock_lhb1, flags); GLINK_INFO_CH(ctx, "%s: remote: OPENED->CLOSED\n", __func__); is_ch_fully_closed = glink_core_remote_close_common(ctx, false); - ctx->pending_delete = true; if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, rcid); if (is_ch_fully_closed) { From 189c079da22c4339b75dd257ca1053c46f037111 Mon Sep 17 00:00:00 2001 From: gaolez Date: Tue, 31 Jul 2018 14:04:45 +0800 Subject: [PATCH 45/75] msm: wlan: Update regulatory database Enable DFS flag for TT. Change-Id: I291dd2927ff0c92b243ee9c009b1549fb203165b CRs-Fixed: 2287335 Signed-off-by: Gaole Zhang --- net/wireless/db.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/wireless/db.txt b/net/wireless/db.txt index bc7a70a76685..ac25fc5e8078 100644 --- a/net/wireless/db.txt +++ b/net/wireless/db.txt @@ -1134,10 +1134,11 @@ country TR: DFS-ETSI (5490 - 5730 @ 160), (30), DFS (5735 - 5875 @ 80), (14) -country TT: +country TT: DFS-FCC (2402 - 2482 @ 40), (20) - (5170 - 5330 @ 160), (24) - (5490 - 5730 @ 160), (24) + (5170 - 5250 @ 80), (24) + (5250 - 5330 @ 80), (24), DFS + (5490 - 5730 @ 160), (24), DFS (5735 - 5835 @ 80), (30) # 60 gHz band channels 1-3, FCC (57240 - 63720 @ 2160), (40) From 1a649e08b2cda3e5a164d93bba7509cd03e0f882 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Sirasanagandla Date: Tue, 17 Oct 2017 18:00:55 +0800 Subject: [PATCH 46/75] msm: wlan: Update regulatory rules for JM As per regulatory master sheet, JM maps to FCC13 for 5GHz. For FCC13, there is no radar detect pattern. Therefore, Remove DFS flag for JM. CRs-Fixed: 2177739 Change-Id: I2dee046369ea4c3bd8feffbf97dbf40bea2137b6 Signed-off-by: Rajeev Kumar Sirasanagandla --- net/wireless/db.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/wireless/db.txt b/net/wireless/db.txt index bc7a70a76685..326a6f29c6bd 100644 --- a/net/wireless/db.txt +++ b/net/wireless/db.txt @@ -579,8 +579,8 @@ country IT: DFS-ETSI country JM: DFS-FCC (2402 - 2482 @ 40), (20) (5170 - 5250 @ 80), (24), AUTO-BW - (5250 - 5330 @ 80), (24), DFS, AUTO-BW - (5490 - 5730 @ 160), (24), DFS + (5250 - 5330 @ 80), (24), AUTO-BW + (5490 - 5730 @ 160), (24) (5735 - 5835 @ 80), (30) # 60 gHz band channels 1-3, FCC (57240 - 63720 @ 2160), (40) From 15c87d11b5af2203d79b639aba1b8952252a7480 Mon Sep 17 00:00:00 2001 From: kunleiz Date: Tue, 16 Apr 2019 17:46:37 +0800 Subject: [PATCH 47/75] lsm: check payload size validity before using it as array index Payload size validity is not checked before using it in array index. Check payload size to avoid out-of-boundary memory. Change-Id: Ic0b06bb331fc1753ff7543bb218ab12d6a4a3ca8 Signed-off-by: kunleiz --- include/sound/q6lsm.h | 4 +-- sound/soc/msm/qdsp6v2/msm-lsm-client.c | 45 +++++++++++++++++++++----- sound/soc/msm/qdsp6v2/q6lsm.c | 18 ++++++++--- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h index c046cd468b49..4600b0445955 100644 --- a/include/sound/q6lsm.h +++ b/include/sound/q6lsm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, 2019 Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -26,7 +26,7 @@ #define LSM_MAX_NUM_CHANNELS 8 typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, - uint32_t *payload, void *priv); + uint32_t *payload, uint16_t client_size, void *priv); struct lsm_sound_model { dma_addr_t phys; diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c index 5c4e145c2e31..9b0918cc579f 100644 --- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c +++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, 2019 Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -195,7 +195,8 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, } static void lsm_event_handler(uint32_t opcode, uint32_t token, - void *payload, void *priv) + void *payload, uint16_t client_size, + void *priv) { unsigned long flags; struct lsm_priv *prtd = priv; @@ -263,6 +264,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, } case LSM_SESSION_EVENT_DETECTION_STATUS: + if (client_size < 3 * sizeof(uint8_t)) { + dev_err(rtd->dev, + "%s: client_size has invalid size[%d]\n", + __func__, client_size); + return; + } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[2]; index = 4; @@ -272,6 +279,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, break; case LSM_SESSION_EVENT_DETECTION_STATUS_V2: + if (client_size < 2 * sizeof(uint8_t)) { + dev_err(rtd->dev, + "%s: client_size has invalid size[%d]\n", + __func__, client_size); + return; + } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[1]; index = 2; @@ -281,6 +294,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, break; case LSM_SESSION_EVENT_DETECTION_STATUS_V3: + if (client_size < 2 * (sizeof(uint32_t) + sizeof(uint8_t))) { + dev_err(rtd->dev, + "%s: client_size has invalid size[%d]\n", + __func__, client_size); + return; + } event_ts_lsw = ((uint32_t *)payload)[0]; event_ts_msw = ((uint32_t *)payload)[1]; status = (uint16_t)((uint8_t *)payload)[8]; @@ -318,12 +337,22 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, prtd->event_status->payload_size = payload_size; if (likely(prtd->event_status)) { - memcpy(prtd->event_status->payload, - &((uint8_t *)payload)[index], - payload_size); - prtd->event_avail = 1; - spin_unlock_irqrestore(&prtd->event_lock, flags); - wake_up(&prtd->event_wait); + if (client_size >= (payload_size + index)) { + memcpy(prtd->event_status->payload, + &((uint8_t *)payload)[index], + payload_size); + prtd->event_avail = 1; + spin_unlock_irqrestore(&prtd->event_lock, + flags); + wake_up(&prtd->event_wait); + } else { + spin_unlock_irqrestore(&prtd->event_lock, + flags); + dev_err(rtd->dev, + "%s: Failed to copy memory with invalid size = %d\n", + __func__, payload_size); + return; + } } else { spin_unlock_irqrestore(&prtd->event_lock, flags); dev_err(rtd->dev, diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c index a0fa233bb71e..d926623eaa19 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -127,7 +127,8 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (data->opcode == LSM_DATA_EVENT_READ_DONE) { struct lsm_cmd_read_done read_done; token = data->token; - if (data->payload_size > sizeof(read_done)) { + if (data->payload_size > sizeof(read_done) || + data->payload_size < 6 * sizeof(payload[0])) { pr_err("%s: read done error payload size %d expected size %zd\n", __func__, data->payload_size, sizeof(read_done)); @@ -145,6 +146,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (client->cb) client->cb(data->opcode, data->token, (void *)&read_done, + sizeof(read_done), client->priv); return 0; } else if (data->opcode == APR_BASIC_RSP_RESULT) { @@ -171,6 +173,11 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) __func__, token, client->session); return -EINVAL; } + if (data->payload_size < 2 * sizeof(payload[0])) { + pr_err("%s: payload has invalid size[%d]\n", + __func__, data->payload_size); + return -EINVAL; + } client->cmd_err_code = payload[1]; if (client->cmd_err_code) pr_err("%s: cmd 0x%x failed status %d\n", @@ -191,7 +198,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (client->cb) client->cb(data->opcode, data->token, data->payload, - client->priv); + data->payload_size, client->priv); return 0; } @@ -1365,6 +1372,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) pr_debug("%s: SSR event received 0x%x, event 0x%x,\n" "proc 0x%x SID 0x%x\n", __func__, data->opcode, data->reset_event, data->reset_proc, sid); + if (sid < LSM_MIN_SESSION_ID || sid > LSM_MAX_SESSION_ID) + pr_err("%s: Invalid session %d\n", __func__, sid); lsm_common.common_client[sid].lsm_cal_phy_addr = 0; cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, lsm_common.cal_data); @@ -1426,7 +1435,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) } if (client->cb) client->cb(data->opcode, data->token, - data->payload, client->priv); + data->payload, data->payload_size, + client->priv); return 0; } From 215ee16770c2d9dcb27e9efaee58ad089e87c73f Mon Sep 17 00:00:00 2001 From: Darshan Kumsi Srinivasa Date: Fri, 5 Oct 2018 17:14:32 +0530 Subject: [PATCH 48/75] msm: vidc: do not set video state to DEINIT very early If video state set to DEINIT before processing all frame done packets in the list may create video failures as explained below, the client communication to video hardware will fail because of DEINIT state and client will close the session upon failure which will happen in parallel to response thread processing the response packets in the list. It may happen that client already free'd the buffer references and response thread might access the same buffer reference and results in use-after-free memory fault. So In case of sys error from video hardware, set video state to DEINIT after processing all packets in the list to avoid use-after-free failure Change-Id: I688c3ec3feb2b5621d75c4da93ee9870aa0e6dfe Signed-off-by: Darshan Kumsi Srinivasa Signed-off-by: Sanjay Singh --- drivers/media/platform/msm/vidc/venus_hfi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 1ec06cb07523..ddc98da5dd27 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -1682,7 +1682,7 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, __strict_check(device); if (!__core_in_valid_state(device)) { - dprintk(VIDC_DBG, "%s - fw not in init state\n", __func__); + dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__); result = -EINVAL; goto err_q_null; } @@ -3408,8 +3408,6 @@ static void __process_sys_error(struct venus_hfi_device *device) { struct hfi_sfr_struct *vsfr = NULL; - __set_state(device, VENUS_STATE_DEINIT); - /* Once SYS_ERROR received from HW, it is safe to halt the AXI. * With SYS_ERROR, Venus FW may have crashed and HW might be * active and causing unnecessary transactions. Hence it is @@ -3656,6 +3654,10 @@ static int __response_handler(struct venus_hfi_device *device) "Too many packets in message queue to handle at once, deferring read\n"); break; } + + /* do not read packets after sys error packet */ + if (info->response_type == HAL_SYS_ERROR) + break; } if (requeue_pm_work && device->res->sw_power_collapsible) { From 2cae403c69cc3ab30fc5133c6ceff87786910d30 Mon Sep 17 00:00:00 2001 From: Darshan Kumsi Srinivasa Date: Fri, 5 Oct 2018 17:30:52 +0530 Subject: [PATCH 49/75] msm: vidc: ignore processing responses in invalid state No need to process response messages from video hardware after device went into invalid state. Processing responses may result in use-after-free memory fault because client might free all the resources after error. Change-Id: I3bfb26e5aa52aba33b7b62cda7820dcbc5fe033f Signed-off-by: Darshan Kumsi Srinivasa --- drivers/media/platform/msm/vidc/venus_hfi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 1ec06cb07523..99903c0e7944 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -3717,7 +3717,12 @@ err_no_work: for (i = 0; !IS_ERR_OR_NULL(device->response_pkt) && i < num_responses; ++i) { struct msm_vidc_cb_info *r = &device->response_pkt[i]; - + if (!__core_in_valid_state(device)) { + dprintk(VIDC_ERR, + "Ignore responses from %d to %d as device is in invalid state", + (i + 1), num_responses); + break; + } device->callback(r->response_type, &r->response); } From 94b04372771c255d7cbbf34225d323de85178d9e Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 16 Apr 2019 17:14:33 -0700 Subject: [PATCH 50/75] soc: qcom: secure_buffer: Process large SG tables in batches Currently, if processing an SG table consumes more memory than can fit in the pre-allocated buffer, then calls to hyp_assign_table() will fail as if there were not enough memory available to process the request. Instead, for every call to hyp assign, allocate enough memory to process the maximum batch size, and process large SG tables in pieces, using this memory. This avoids failures due to large SG tables. Also, since the memory for handling these requests is now allocated per hyp_assign_table() call, we can drop the pre-allocated buffer, as it is no longer in use. Change-Id: Ie9899a5e2c8de6127707609101f5fb557e3f0533 Signed-off-by: Isaac J. Manjarres --- drivers/soc/qcom/secure_buffer.c | 170 ++++++++++++------------------- 1 file changed, 65 insertions(+), 105 deletions(-) diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c index 59341ebf5e72..9d9c1245b9b9 100644 --- a/drivers/soc/qcom/secure_buffer.c +++ b/drivers/soc/qcom/secure_buffer.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google, Inc - * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -56,8 +56,8 @@ struct dest_vm_and_perm_info { u32 ctx_size; }; -static void *qcom_secure_mem; -#define QCOM_SECURE_MEM_SIZE (512*1024) +#define BATCH_MAX_SIZE SZ_2M +#define BATCH_MAX_SECTIONS 32 static int secure_buffer_change_chunk(u32 chunks, u32 nchunks, @@ -219,42 +219,67 @@ populate_dest_info(int *dest_vmids, int nelements, int *dest_perms, } /* Must hold secure_buffer_mutex while allocated buffer is in use */ -static struct mem_prot_info *get_info_list_from_table(struct sg_table *table, - size_t *size_in_bytes) +static unsigned int get_batches_from_sgl(struct mem_prot_info *sg_table_copy, + struct scatterlist *sgl, + struct scatterlist **next_sgl) { - int i; - struct scatterlist *sg; - struct mem_prot_info *info; - size_t size; + u64 batch_size = 0; + unsigned int i = 0; + struct scatterlist *curr_sgl = sgl; - size = table->nents * sizeof(*info); + /* Ensure no zero size batches */ + do { + sg_table_copy[i].addr = page_to_phys(sg_page(curr_sgl)); + sg_table_copy[i].size = curr_sgl->length; + batch_size += sg_table_copy[i].size; + curr_sgl = sg_next(curr_sgl); + i++; + } while (curr_sgl && i < BATCH_MAX_SECTIONS && + curr_sgl->length + batch_size < BATCH_MAX_SIZE); - if (size >= QCOM_SECURE_MEM_SIZE) { - pr_err("%s: Not enough memory allocated. Required size %zd\n", - __func__, size); - return NULL; - } - - if (!qcom_secure_mem) { - pr_err("%s is not functional as qcom_secure_mem is not allocated.\n", - __func__); - return NULL; - } - - /* "Allocate" it */ - info = qcom_secure_mem; - - for_each_sg(table->sgl, sg, table->nents, i) { - info[i].addr = page_to_phys(sg_page(sg)); - info[i].size = sg->length; - } - - *size_in_bytes = size; - return info; + *next_sgl = curr_sgl; + return i; } -#define BATCH_MAX_SIZE SZ_2M -#define BATCH_MAX_SECTIONS 32 +static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) +{ + unsigned int entries_size; + unsigned int batch_start = 0; + unsigned int batches_processed; + struct scatterlist *curr_sgl = table->sgl; + struct scatterlist *next_sgl; + int ret = 0; + struct mem_prot_info *sg_table_copy = kcalloc(BATCH_MAX_SECTIONS, + sizeof(*sg_table_copy), + GFP_KERNEL); + + if (!sg_table_copy) + return -ENOMEM; + + while (batch_start < table->nents) { + batches_processed = get_batches_from_sgl(sg_table_copy, + curr_sgl, &next_sgl); + curr_sgl = next_sgl; + entries_size = batches_processed * sizeof(*sg_table_copy); + dmac_flush_range(sg_table_copy, + (void *)sg_table_copy + entries_size); + desc->args[0] = virt_to_phys(sg_table_copy); + desc->args[1] = entries_size; + + ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, + MEM_PROT_ASSIGN_ID), desc); + if (ret) { + pr_info("%s: Failed to assign memory protection, ret = %d\n", + __func__, ret); + break; + } + + batch_start += batches_processed; + } + + kfree(sg_table_copy); + return ret; +} int hyp_assign_table(struct sg_table *table, u32 *source_vm_list, int source_nelems, @@ -267,11 +292,10 @@ int hyp_assign_table(struct sg_table *table, size_t source_vm_copy_size; struct dest_vm_and_perm_info *dest_vm_copy; size_t dest_vm_copy_size; - struct mem_prot_info *sg_table_copy; - size_t sg_table_copy_size; - int batch_start, batch_end; - u64 batch_size; + if (!table || !table->sgl || !source_vm_list || !source_nelems || + !dest_vmids || !dest_perms || !dest_nelems) + return -EINVAL; /* * We can only pass cache-aligned sizes to hypervisor, so we need @@ -289,19 +313,11 @@ int hyp_assign_table(struct sg_table *table, &dest_vm_copy_size); if (!dest_vm_copy) { ret = -ENOMEM; - goto out_free; + goto out_free_source; } mutex_lock(&secure_buffer_mutex); - sg_table_copy = get_info_list_from_table(table, &sg_table_copy_size); - if (!sg_table_copy) { - ret = -ENOMEM; - goto out_unlock; - } - - desc.args[0] = virt_to_phys(sg_table_copy); - desc.args[1] = sg_table_copy_size; desc.args[2] = virt_to_phys(source_vm_copy); desc.args[3] = source_vm_copy_size; desc.args[4] = virt_to_phys(dest_vm_copy); @@ -313,50 +329,14 @@ int hyp_assign_table(struct sg_table *table, dmac_flush_range(source_vm_copy, (void *)source_vm_copy + source_vm_copy_size); - dmac_flush_range(sg_table_copy, - (void *)sg_table_copy + sg_table_copy_size); dmac_flush_range(dest_vm_copy, (void *)dest_vm_copy + dest_vm_copy_size); - batch_start = 0; - while (batch_start < table->nents) { - /* Ensure no size zero batches */ - batch_size = sg_table_copy[batch_start].size; - batch_end = batch_start + 1; - while (1) { - u64 size; + ret = batched_hyp_assign(table, &desc); - if (batch_end >= table->nents) - break; - if (batch_end - batch_start >= BATCH_MAX_SECTIONS) - break; - - size = sg_table_copy[batch_end].size; - if (size + batch_size >= BATCH_MAX_SIZE) - break; - - batch_size += size; - batch_end++; - } - - desc.args[0] = virt_to_phys(&sg_table_copy[batch_start]); - desc.args[1] = (batch_end - batch_start) * - sizeof(sg_table_copy[0]); - - ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, - MEM_PROT_ASSIGN_ID), &desc); - if (ret) { - pr_info("%s: Failed to assign memory protection, ret = %d\n", - __func__, ret); - break; - } - batch_start = batch_end; - } - -out_unlock: mutex_unlock(&secure_buffer_mutex); kfree(dest_vm_copy); -out_free: +out_free_source: kfree(source_vm_copy); return ret; } @@ -436,23 +416,3 @@ bool msm_secure_v2_is_supported(void) */ return (ret == 0) && (version >= MAKE_CP_VERSION(1, 1, 0)); } - -static int __init alloc_secure_shared_memory(void) -{ - int ret = 0; - dma_addr_t dma_handle; - - qcom_secure_mem = kzalloc(QCOM_SECURE_MEM_SIZE, GFP_KERNEL); - if (!qcom_secure_mem) { - /* Fallback to CMA-DMA memory */ - qcom_secure_mem = dma_alloc_coherent(NULL, QCOM_SECURE_MEM_SIZE, - &dma_handle, GFP_KERNEL); - if (!qcom_secure_mem) { - pr_err("Couldn't allocate memory for secure use-cases. hyp_assign_table will not work\n"); - return -ENOMEM; - } - } - - return ret; -} -pure_initcall(alloc_secure_shared_memory); From c17751e14a8b302d9b202a65eed06b99c9be7312 Mon Sep 17 00:00:00 2001 From: Darshan Kumsi Srinivasa Date: Fri, 5 Oct 2018 17:14:32 +0530 Subject: [PATCH 51/75] msm: vidc: do not set video state to DEINIT very early If video state set to DEINIT before processing all frame done packets in the list may create video failures as explained below, the client communication to video hardware will fail because of DEINIT state and client will close the session upon failure which will happen in parallel to response thread processing the response packets in the list. It may happen that client already free'd the buffer references and response thread might access the same buffer reference and results in use-after-free memory fault. So In case of sys error from video hardware, set video state to DEINIT after processing all packets in the list to avoid use-after-free failure Change-Id: I688c3ec3feb2b5621d75c4da93ee9870aa0e6dfe Signed-off-by: Darshan Kumsi Srinivasa Signed-off-by: Sanjay Singh --- drivers/media/platform/msm/vidc/venus_hfi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 99903c0e7944..f6180b848c7f 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -1682,7 +1682,7 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device, __strict_check(device); if (!__core_in_valid_state(device)) { - dprintk(VIDC_DBG, "%s - fw not in init state\n", __func__); + dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__); result = -EINVAL; goto err_q_null; } @@ -3408,8 +3408,6 @@ static void __process_sys_error(struct venus_hfi_device *device) { struct hfi_sfr_struct *vsfr = NULL; - __set_state(device, VENUS_STATE_DEINIT); - /* Once SYS_ERROR received from HW, it is safe to halt the AXI. * With SYS_ERROR, Venus FW may have crashed and HW might be * active and causing unnecessary transactions. Hence it is @@ -3656,6 +3654,10 @@ static int __response_handler(struct venus_hfi_device *device) "Too many packets in message queue to handle at once, deferring read\n"); break; } + + /* do not read packets after sys error packet */ + if (info->response_type == HAL_SYS_ERROR) + break; } if (requeue_pm_work && device->res->sw_power_collapsible) { From 6845281c4c892da8117b6bce182274f18d48b096 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 28 Feb 2019 15:38:00 -0800 Subject: [PATCH 52/75] msm: adm: validate ADSP payload size before access Check the size of ADSP payload before accessing it. CRs-Fixed: 2380694 Change-Id: Icdc19a85b39a397ba6d7177f42ece4626b901832 Signed-off-by: Vignesh Kulothungan --- sound/soc/msm/qdsp6v2/q6adm.c | 68 ++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index c6f3b5ba96ba..14b962c894d1 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -1230,12 +1230,22 @@ static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, switch (opcode) { case ADM_CMDRSP_GET_PP_PARAMS_V5: struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v5); + if (payload_size < struct_size) { + pr_err("%s: payload size %d < expected size %d\n", + __func__, payload_size, struct_size); + break; + } v5_rsp = (struct adm_cmd_rsp_get_pp_params_v5 *) payload; data_size = v5_rsp->param_hdr.param_size; param_data = v5_rsp->param_data; break; case ADM_CMDRSP_GET_PP_PARAMS_V6: struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v6); + if (payload_size < struct_size) { + pr_err("%s: payload size %d < expected size %d\n", + __func__, payload_size, struct_size); + break; + } v6_rsp = (struct adm_cmd_rsp_get_pp_params_v6 *) payload; data_size = v6_rsp->param_hdr.param_size; param_data = v6_rsp->param_data; @@ -1399,7 +1409,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } adm_callback_debug_print(data); - if (data->payload_size) { + if (data->payload_size >= sizeof(uint32_t)) { copp_idx = (data->token) & 0XFF; port_idx = ((data->token) >> 16) & 0xFF; client_id = ((data->token) >> 8) & 0xFF; @@ -1421,6 +1431,16 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) if (data->opcode == APR_BASIC_RSP_RESULT) { pr_debug("%s: APR_BASIC_RSP_RESULT id 0x%x\n", __func__, payload[0]); + if (!((client_id != ADM_CLIENT_ID_SOURCE_TRACKING) && + ((payload[0] == ADM_CMD_SET_PP_PARAMS_V5) || + (payload[0] == ADM_CMD_SET_PP_PARAMS_V6)))) { + if (data->payload_size < + (2 * sizeof(uint32_t))) { + pr_err("%s: Invalid payload size %d\n", + __func__, data->payload_size); + return 0; + } + } if (payload[1] != 0) { pr_err("%s: cmd = 0x%x returned error = 0x%x\n", __func__, payload[0], payload[1]); @@ -1545,9 +1565,16 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) case ADM_CMDRSP_DEVICE_OPEN_V5: case ADM_CMDRSP_DEVICE_OPEN_V6: case ADM_CMDRSP_DEVICE_OPEN_V8: { - struct adm_cmd_rsp_device_open_v5 *open = - (struct adm_cmd_rsp_device_open_v5 *)data->payload; + struct adm_cmd_rsp_device_open_v5 *open = NULL; + if (data->payload_size < + sizeof(struct adm_cmd_rsp_device_open_v5)) { + pr_err("%s: Invalid payload size %d\n", + __func__, data->payload_size); + return 0; + } + open = + (struct adm_cmd_rsp_device_open_v5 *)data->payload; if (open->copp_id == INVALID_COPP_ID) { pr_err("%s: invalid coppid rxed %d\n", __func__, open->copp_id); @@ -1603,21 +1630,28 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2: pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n", __func__); - num_modules = payload[1]; - pr_debug("%s: Num modules %d\n", __func__, num_modules); - if (payload[0]) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n", - __func__, payload[0]); - } else if (num_modules > MAX_MODULES_IN_TOPO) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n", - __func__, num_modules); + if (data->payload_size >= (2 * sizeof(uint32_t))) { + num_modules = payload[1]; + pr_debug("%s: Num modules %d\n", __func__, + num_modules); + if (payload[0]) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n", + __func__, payload[0]); + } else if (num_modules > MAX_MODULES_IN_TOPO) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n", + __func__, num_modules); + } else { + ret = adm_process_get_topo_list_response + (data->opcode, copp_idx, + num_modules, payload, + data->payload_size); + if (ret) + pr_err("%s: Failed to process get topo modules list response, error %d\n", + __func__, ret); + } } else { - ret = adm_process_get_topo_list_response( - data->opcode, copp_idx, num_modules, - payload, data->payload_size); - if (ret) - pr_err("%s: Failed to process get topo modules list response, error %d\n", - __func__, ret); + pr_err("%s: Invalid payload size %d\n", + __func__, data->payload_size); } atomic_set(&this_adm.copp.stat[port_idx][copp_idx], payload[0]); From 4172e2077f9d3ab5b67260db91280a8ddd41d2e4 Mon Sep 17 00:00:00 2001 From: Dhoat Harpal Date: Thu, 18 Jan 2018 00:29:20 +0530 Subject: [PATCH 53/75] soc: qcom: glink: Initialize local state while fetching ctx Initialization of channel's local state is not done at the time of fetching context from list of channels. This leads to race condition if remote close happens during this time. Remote close will check if local state is not open then delete channel from list. This leads to use after free scenerio. Initialize local state at the time of fetching channel context from list of channels. CRs-Fixed: 2155992 Change-Id: If113daba129191bd67ef2460eb4e87c2d5614403 Signed-off-by: Dhoat Harpal --- drivers/soc/qcom/glink.c | 42 ++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index 813c97bb4a50..f9dbc4b29040 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -375,7 +375,7 @@ static void tx_func(struct kthread_work *work); static struct channel_ctx *ch_name_to_ch_ctx_create( struct glink_core_xprt_ctx *xprt_ctx, - const char *name); + const char *name, bool local); static void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size, uint32_t riid, void *cookie); @@ -1870,13 +1870,14 @@ static void glink_ch_ctx_release(struct rwref_lock *ch_st_lock) * it is not found and get reference of context. * @xprt_ctx: Transport to search for a matching channel. * @name: Name of the desired channel. + * @local: If called from local open or not * * Return: The channel corresponding to @name, NULL if a matching channel was * not found AND a new channel could not be created. */ static struct channel_ctx *ch_name_to_ch_ctx_create( struct glink_core_xprt_ctx *xprt_ctx, - const char *name) + const char *name, bool local) { struct channel_ctx *entry; struct channel_ctx *ctx; @@ -1920,10 +1921,23 @@ check_ctx: list_for_each_entry_safe(entry, temp, &xprt_ctx->channels, port_list_node) if (!strcmp(entry->name, name) && !entry->pending_delete) { + rwref_get(&entry->ch_state_lhb2); + /* port already exists */ + if (entry->local_open_state != GLINK_CHANNEL_CLOSED + && local) { + /* not ready to be re-opened */ + GLINK_INFO_CH_XPRT(entry, xprt_ctx, + "%s: Ch not ready. State: %u\n", + __func__, entry->local_open_state); + rwref_put(&entry->ch_state_lhb2); + entry = NULL; + } else if (local) { + entry->local_open_state = + GLINK_CHANNEL_OPENING; + } spin_unlock_irqrestore(&xprt_ctx->xprt_ctx_lock_lhb1, flags); kfree(ctx); - rwref_get(&entry->ch_state_lhb2); rwref_write_put(&xprt_ctx->xprt_state_lhb0); return entry; } @@ -1954,6 +1968,8 @@ check_ctx: ctx->transport_ptr = xprt_ctx; rwref_get(&ctx->ch_state_lhb2); + if (local) + ctx->local_open_state = GLINK_CHANNEL_OPENING; list_add_tail(&ctx->port_list_node, &xprt_ctx->channels); GLINK_INFO_PERF_CH_XPRT(ctx, xprt_ctx, @@ -2639,23 +2655,13 @@ void *glink_open(const struct glink_open_config *cfg) * look for an existing port structure which can occur in * reopen and remote-open-first cases */ - ctx = ch_name_to_ch_ctx_create(transport_ptr, cfg->name); + ctx = ch_name_to_ch_ctx_create(transport_ptr, cfg->name, true); if (ctx == NULL) { GLINK_ERR("%s:%s %s: Error - unable to allocate new channel\n", cfg->transport, cfg->edge, __func__); return ERR_PTR(-ENOMEM); } - /* port already exists */ - if (ctx->local_open_state != GLINK_CHANNEL_CLOSED) { - /* not ready to be re-opened */ - GLINK_INFO_CH_XPRT(ctx, transport_ptr, - "%s: Channel not ready to be re-opened. State: %u\n", - __func__, ctx->local_open_state); - rwref_put(&ctx->ch_state_lhb2); - return ERR_PTR(-EBUSY); - } - /* initialize port structure */ ctx->user_priv = cfg->priv; ctx->rx_intent_req_timeout_jiffies = @@ -2686,7 +2692,6 @@ void *glink_open(const struct glink_open_config *cfg) ctx->local_xprt_req = best_id; ctx->no_migrate = cfg->transport && !(cfg->options & GLINK_OPT_INITIAL_XPORT); - ctx->local_open_state = GLINK_CHANNEL_OPENING; GLINK_INFO_PERF_CH(ctx, "%s: local:GLINK_CHANNEL_CLOSED->GLINK_CHANNEL_OPENING\n", __func__); @@ -4943,7 +4948,7 @@ static void glink_core_rx_cmd_ch_remote_open(struct glink_transport_if *if_ptr, bool do_migrate; glink_core_migration_edge_lock(if_ptr->glink_core_priv); - ctx = ch_name_to_ch_ctx_create(if_ptr->glink_core_priv, name); + ctx = ch_name_to_ch_ctx_create(if_ptr->glink_core_priv, name, false); if (ctx == NULL) { GLINK_ERR_XPRT(if_ptr->glink_core_priv, "%s: invalid rcid %u received, name '%s'\n", @@ -5045,6 +5050,7 @@ static void glink_core_rx_cmd_ch_remote_close( struct channel_ctx *ctx; bool is_ch_fully_closed; struct glink_core_xprt_ctx *xprt_ptr = if_ptr->glink_core_priv; + unsigned long flags; ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid); if (!ctx) { @@ -5062,11 +5068,13 @@ static void glink_core_rx_cmd_ch_remote_close( rwref_put(&ctx->ch_state_lhb2); return; } + spin_lock_irqsave(&ctx->transport_ptr->xprt_ctx_lock_lhb1, flags); + ctx->pending_delete = true; + spin_unlock_irqrestore(&ctx->transport_ptr->xprt_ctx_lock_lhb1, flags); GLINK_INFO_CH(ctx, "%s: remote: OPENED->CLOSED\n", __func__); is_ch_fully_closed = glink_core_remote_close_common(ctx, false); - ctx->pending_delete = true; if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, rcid); if (is_ch_fully_closed) { From e6d0962b57019513b4770aaf96138fb433b66ceb Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 18 Apr 2019 16:49:49 +0530 Subject: [PATCH 54/75] diag: dci: Validate dci response length before parsing Prevent possible out of bound access due to missing length check while extracting dci packet response by adding proper checks. CRs-Fixed: 2434571 Change-Id: I7b6972bf6559bdca99333a75d989cd6d3431b801 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 0858b8585e30..9b2ee0368cfe 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -984,7 +984,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, int save_req_uid = 0; struct diag_dci_pkt_rsp_header_t pkt_rsp_header; - if (!buf) { + if (!buf || len <= 0) { pr_err("diag: Invalid pointer in %s\n", __func__); return; } @@ -998,6 +998,8 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, dci_cmd_code); return; } + if (len < (cmd_code_len + sizeof(int))) + return; temp += cmd_code_len; tag = *(int *)temp; temp += sizeof(int); @@ -1006,10 +1008,16 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, * The size of the response is (total length) - (length of the command * code, the tag (int) */ - rsp_len = len - (cmd_code_len + sizeof(int)); - if ((rsp_len == 0) || (rsp_len > (len - 5))) { - pr_err("diag: Invalid length in %s, len: %d, rsp_len: %d", - __func__, len, rsp_len); + if (len >= cmd_code_len + sizeof(int)) { + rsp_len = len - (cmd_code_len + sizeof(int)); + if ((rsp_len == 0) || (rsp_len > (len - 5))) { + pr_err("diag: Invalid length in %s, len: %d, rsp_len: %d\n", + __func__, len, rsp_len); + return; + } + } else { + pr_err("diag:%s: Invalid length(%d) for calculating rsp_len\n", + __func__, len); return; } From e2220d73ad253a8cb6df491bfbc57860cfcd92bd Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Wed, 1 May 2019 22:11:18 +0530 Subject: [PATCH 55/75] diag: Validate command length against size of command structure While processing a packet containing command request, buffer size need to be checked against size of the command structures that is being parsed to prevent possible out of bound access. CRs-Fixed: 2432633 Change-Id: I048bdbd0c096a6d03501bdd5b1d2d4bb50d45dd6 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diagfwd.c | 77 +++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index ff024c2200c0..8e9a6d7acafa 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -952,7 +952,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) struct diag_cmd_reg_t *reg_item = NULL; struct diag_md_session_t *info = NULL; - if (!buf) + if (!buf || len <= 0) return -EIO; /* Check if the command is a supported mask command */ @@ -963,18 +963,31 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) } temp = buf; - entry.cmd_code = (uint16_t)(*(uint8_t *)temp); - temp += sizeof(uint8_t); - entry.subsys_id = (uint16_t)(*(uint8_t *)temp); - temp += sizeof(uint8_t); - entry.cmd_code_hi = (uint16_t)(*(uint16_t *)temp); - entry.cmd_code_lo = (uint16_t)(*(uint16_t *)temp); - temp += sizeof(uint16_t); + if (len >= sizeof(uint8_t)) { + entry.cmd_code = (uint16_t)(*(uint8_t *)temp); + pr_debug("diag: received cmd_code %02x\n", entry.cmd_code); + } + if (len >= (2 * sizeof(uint8_t))) { + temp += sizeof(uint8_t); + entry.subsys_id = (uint16_t)(*(uint8_t *)temp); + pr_debug("diag: received subsys_id %02x\n", entry.subsys_id); + } + if (len == (3 * sizeof(uint8_t))) { + temp += sizeof(uint8_t); + entry.cmd_code_hi = (uint16_t)(*(uint8_t *)temp); + entry.cmd_code_lo = (uint16_t)(*(uint8_t *)temp); + pr_debug("diag: received cmd_code_hi %02x\n", + entry.cmd_code_hi); + } else if (len >= (2 * sizeof(uint8_t)) + sizeof(uint16_t)) { + temp += sizeof(uint8_t); + entry.cmd_code_hi = (uint16_t)(*(uint16_t *)temp); + entry.cmd_code_lo = (uint16_t)(*(uint16_t *)temp); + pr_debug("diag: received cmd_code_hi %02x\n", + entry.cmd_code_hi); + } - pr_debug("diag: In %s, received cmd %02x %02x %02x\n", - __func__, entry.cmd_code, entry.subsys_id, entry.cmd_code_hi); - - if (*buf == DIAG_CMD_LOG_ON_DMND && driver->log_on_demand_support && + if ((len >= sizeof(uint8_t)) && *buf == DIAG_CMD_LOG_ON_DMND && + driver->log_on_demand_support && driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask) { write_len = diag_cmd_log_on_demand(buf, len, driver->apps_rsp_buf, @@ -1014,14 +1027,16 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) #if defined(CONFIG_DIAG_OVER_USB) /* Check for the command/respond msg for the maximum packet length */ - if ((*buf == 0x4b) && (*(buf+1) == 0x12) && + if ((len >= (4 * sizeof(uint8_t))) && + (*buf == 0x4b) && (*(buf+1) == 0x12) && (*(uint16_t *)(buf+2) == 0x0055)) { for (i = 0; i < 4; i++) *(driver->apps_rsp_buf+i) = *(buf+i); *(uint32_t *)(driver->apps_rsp_buf+4) = DIAG_MAX_REQ_SIZE; diag_send_rsp(driver->apps_rsp_buf, 8, pid); return 0; - } else if ((*buf == 0x4b) && (*(buf+1) == 0x12) && + } else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) && + (*buf == 0x4b) && (*(buf+1) == 0x12) && (*(uint16_t *)(buf+2) == DIAG_DIAG_STM)) { len = diag_process_stm_cmd(buf, driver->apps_rsp_buf); if (len > 0) { @@ -1031,7 +1046,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) return len; } /* Check for time sync query command */ - else if ((*buf == DIAG_CMD_DIAG_SUBSYS) && + else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) && + (*buf == DIAG_CMD_DIAG_SUBSYS) && (*(buf+1) == DIAG_SS_DIAG) && (*(uint16_t *)(buf+2) == DIAG_GET_TIME_API)) { write_len = diag_process_time_sync_query_cmd(buf, len, @@ -1042,7 +1058,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) return 0; } /* Check for time sync switch command */ - else if ((*buf == DIAG_CMD_DIAG_SUBSYS) && + else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) && + (*buf == DIAG_CMD_DIAG_SUBSYS) && (*(buf+1) == DIAG_SS_DIAG) && (*(uint16_t *)(buf+2) == DIAG_SET_TIME_API)) { write_len = diag_process_time_sync_switch_cmd(buf, len, @@ -1053,7 +1070,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) return 0; } /* Check for download command */ - else if ((chk_apps_master()) && (*buf == 0x3A)) { + else if ((len >= sizeof(uint8_t)) && (chk_apps_master()) && + (*buf == 0x3A)) { /* send response back */ driver->apps_rsp_buf[0] = *buf; diag_send_rsp(driver->apps_rsp_buf, 1, pid); @@ -1066,8 +1084,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) return 0; } /* Check for polling for Apps only DIAG */ - else if ((*buf == 0x4b) && (*(buf+1) == 0x32) && - (*(buf+2) == 0x03)) { + else if ((len >= (3 * sizeof(uint8_t))) && + (*buf == 0x4b) && (*(buf+1) == 0x32) && (*(buf+2) == 0x03)) { /* If no one has registered for polling */ if (chk_polling_response()) { /* Respond to polling for Apps only DIAG */ @@ -1081,7 +1099,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) } } /* Return the Delayed Response Wrap Status */ - else if ((*buf == 0x4b) && (*(buf+1) == 0x32) && + else if ((len >= (4 * sizeof(uint8_t))) && + (*buf == 0x4b) && (*(buf+1) == 0x32) && (*(buf+2) == 0x04) && (*(buf+3) == 0x0)) { memcpy(driver->apps_rsp_buf, buf, 4); driver->apps_rsp_buf[4] = wrap_enabled; @@ -1089,7 +1108,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) return 0; } /* Wrap the Delayed Rsp ID */ - else if ((*buf == 0x4b) && (*(buf+1) == 0x32) && + else if ((len >= (4 * sizeof(uint8_t))) && + (*buf == 0x4b) && (*(buf+1) == 0x32) && (*(buf+2) == 0x05) && (*(buf+3) == 0x0)) { wrap_enabled = true; memcpy(driver->apps_rsp_buf, buf, 4); @@ -1098,10 +1118,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) return 0; } /* Mobile ID Rsp */ - else if ((*buf == DIAG_CMD_DIAG_SUBSYS) && - (*(buf+1) == DIAG_SS_PARAMS) && - (*(buf+2) == DIAG_EXT_MOBILE_ID) && (*(buf+3) == 0x0)) { - write_len = diag_cmd_get_mobile_id(buf, len, + else if ((len >= (4 * sizeof(uint8_t))) && + (*buf == DIAG_CMD_DIAG_SUBSYS) && + (*(buf+1) == DIAG_SS_PARAMS) && + (*(buf+2) == DIAG_EXT_MOBILE_ID) && (*(buf+3) == 0x0)) { + write_len = diag_cmd_get_mobile_id(buf, len, driver->apps_rsp_buf, DIAG_MAX_RSP_SIZE); if (write_len > 0) { @@ -1121,7 +1142,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) !(driver->diagfwd_cntl[PERIPHERAL_MODEM]->ch_open) && !(driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask)) { /* respond to 0x0 command */ - if (*buf == 0x00) { + if ((len >= sizeof(uint8_t)) && *buf == 0x00) { for (i = 0; i < 55; i++) driver->apps_rsp_buf[i] = 0; @@ -1129,7 +1150,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid) return 0; } /* respond to 0x7c command */ - else if (*buf == 0x7c) { + else if ((len >= sizeof(uint8_t)) && *buf == 0x7c) { driver->apps_rsp_buf[0] = 0x7c; for (i = 1; i < 8; i++) driver->apps_rsp_buf[i] = 0; From 60e2d8fafa1ef7f417670aa1ba5a2dc945c9cf46 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Mon, 29 Apr 2019 12:00:48 +0530 Subject: [PATCH 56/75] diag: Check buffer size against command structure size Validate the buffer size against the parsing command structure size before parsing to prevent possible out of bound error case. CRs-Fixed: 2437341 Change-Id: I31c9a556539fce403691294a76160ae4936e7065 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diagfwd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index ff024c2200c0..96ccd67c9216 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -684,7 +684,8 @@ int diag_process_time_sync_query_cmd(unsigned char *src_buf, int src_len, struct diag_cmd_time_sync_query_req_t *req = NULL; struct diag_cmd_time_sync_query_rsp_t rsp; - if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { + if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 || + src_len < sizeof(struct diag_cmd_time_sync_query_req_t)) { pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; @@ -711,7 +712,8 @@ int diag_process_time_sync_switch_cmd(unsigned char *src_buf, int src_len, int msg_size = sizeof(struct diag_ctrl_msg_time_sync); int err = 0, write_len = 0; - if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) { + if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 || + src_len < sizeof(struct diag_cmd_time_sync_switch_req_t)) { pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d", __func__, src_buf, src_len, dest_buf, dest_len); return -EINVAL; From 051345384790e28ab2101978954fcb9cc830bab0 Mon Sep 17 00:00:00 2001 From: Venkata Prahlad Valluru Date: Tue, 7 May 2019 19:46:22 +0530 Subject: [PATCH 57/75] ARM: msm: dts: add splash memory region for APQ8098 Add splash region to handle continuous splash over HDMI. Change-Id: I827111ce1656fcd4bc3bc61232c2f81af3bef5eb Signed-off-by: Venkata Prahlad Valluru --- arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts b/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts index 1fa49d8a060d..74edd4e9ac0f 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017,2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -38,6 +38,12 @@ qcom,display-type = "primary"; }; +&mdss_fb2 { + qcom,cont-splash-memory { + linux,contiguous-region = <&cont_splash_mem>; + }; +}; + &slim_aud { tasha_codec { wsa_spkr_sd1: msm_cdc_pinctrll { From 797de5526fef399ff7d6dd23fb3fcb0dfca92842 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Wed, 13 Mar 2019 18:12:26 +0530 Subject: [PATCH 58/75] msm: sps: Update debug message format specifier Restrict printing of kernel virtual addresses in SPS driver. In debug prints, handles to bam device structures may be printed as integers. As these handles are obtained by casting pointer to bam device structures to integer, they can reveal addresses of the structures to attackers. Cast the handles in debug prints to pointers, printed with with %pK, which hides these values if kptr_restrict is set (default on Android). Change-Id: Idd28c7d11a06113605f7428a4cfc2505c1ae0073 Signed-off-by: Jishnu Prakash --- drivers/platform/msm/sps/sps.c | 30 +++++++++++++++++------------- drivers/platform/msm/sps/sps_bam.c | 27 ++++++++++++++------------- drivers/platform/msm/sps/sps_dma.c | 12 +++++++----- drivers/platform/msm/sps/sps_mem.c | 10 +++++----- drivers/platform/msm/sps/sps_rm.c | 15 ++++++++------- 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c index 0f6b66719ef2..1fdad2c52cba 100644 --- a/drivers/platform/msm/sps/sps.c +++ b/drivers/platform/msm/sps/sps.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -677,7 +677,8 @@ int sps_get_bam_debug_info(unsigned long dev, u32 option, u32 para, /* Search for the target BAM device */ bam = sps_h2bam(dev); if (bam == NULL) { - pr_err("sps:Can't find any BAM with handle 0x%lx.", dev); + pr_err("sps:Can't find any BAM with handle 0x%pK.", + (void *)dev); mutex_unlock(&sps->lock); return SPS_ERROR; } @@ -1212,7 +1213,7 @@ struct sps_bam *sps_h2bam(unsigned long h) { struct sps_bam *bam; - SPS_DBG1(sps, "sps:%s: BAM handle:0x%lx.", __func__, h); + SPS_DBG1(sps, "sps:%s: BAM handle:0x%pK.", __func__, (void *)h); if (h == SPS_DEV_HANDLE_MEM || h == SPS_DEV_HANDLE_INVALID) return NULL; @@ -1222,7 +1223,7 @@ struct sps_bam *sps_h2bam(unsigned long h) return bam; } - SPS_ERR(sps, "sps:Can't find BAM device for handle 0x%lx.", h); + SPS_ERR(sps, "sps:Can't find BAM device for handle 0x%pK.", (void *)h); return NULL; } @@ -1327,16 +1328,17 @@ int sps_connect(struct sps_pipe *h, struct sps_connect *connect) bam = sps_h2bam(dev); if (bam == NULL) { - SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%lx", dev); + SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%pK", + (void *)dev); result = SPS_ERROR; goto exit_err; } mutex_lock(&bam->lock); - SPS_DBG2(bam, "sps:sps_connect: bam %pa src 0x%lx dest 0x%lx mode %s", + SPS_DBG2(bam, "sps:sps_connect: bam %pa src 0x%pK dest 0x%pK mode %s", BAM_ID(bam), - connect->source, - connect->destination, + (void *)connect->source, + (void *)connect->destination, connect->mode == SPS_MODE_SRC ? "SRC" : "DEST"); /* Allocate resources for the specified connection */ @@ -1400,10 +1402,10 @@ int sps_disconnect(struct sps_pipe *h) } SPS_DBG2(bam, - "sps:sps_disconnect: bam %pa src 0x%lx dest 0x%lx mode %s", + "sps:sps_disconnect: bam %pa src 0x%pK dest 0x%pK mode %s", BAM_ID(bam), - pipe->connect.source, - pipe->connect.destination, + (void *)pipe->connect.source, + (void *)pipe->connect.destination, pipe->connect.mode == SPS_MODE_SRC ? "SRC" : "DEST"); result = SPS_ERROR; @@ -1799,7 +1801,8 @@ int sps_device_reset(unsigned long dev) /* Search for the target BAM device */ bam = sps_h2bam(dev); if (bam == NULL) { - SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%lx", dev); + SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%pK", + (void *)dev); result = SPS_ERROR; goto exit_err; } @@ -1810,7 +1813,8 @@ int sps_device_reset(unsigned long dev) result = sps_bam_reset(bam); mutex_unlock(&bam->lock); if (result) { - SPS_ERR(sps, "sps:Fail to reset BAM device: 0x%lx", dev); + SPS_ERR(sps, "sps:Fail to reset BAM device: 0x%pK", + (void *)dev); goto exit_err; } diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c index 74b6894f889f..6266df43bd7d 100644 --- a/drivers/platform/msm/sps/sps_bam.c +++ b/drivers/platform/msm/sps/sps_bam.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2017, 2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -884,8 +884,8 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe, else iova = bam_pipe->connect.source_iova; SPS_DBG2(dev, - "sps:BAM %pa pipe %d uses IOVA 0x%lx.\n", - BAM_ID(dev), pipe_index, iova); + "sps:BAM %pa pipe %d uses IOVA 0x%pK.\n", + BAM_ID(dev), pipe_index, (void *)iova); hw_params.peer_phys_addr = (u32)iova; } else { hw_params.peer_phys_addr = peer_bam->props.phys_addr; @@ -907,9 +907,9 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe, hw_params.data_base = (phys_addr_t)bam_pipe->connect.data.iova; SPS_DBG2(dev, - "sps:BAM %pa pipe %d uses IOVA 0x%lx for data FIFO.\n", + "sps:BAM %pa pipe %d uses IOVA 0x%pK for data FIFO.\n", BAM_ID(dev), pipe_index, - bam_pipe->connect.data.iova); + (void *)(bam_pipe->connect.data.iova)); } else { hw_params.data_base = map->data.phys_base; } @@ -960,9 +960,9 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe, hw_params.desc_base = (phys_addr_t)bam_pipe->connect.desc.iova; SPS_DBG2(dev, - "sps:BAM %pa pipe %d uses IOVA 0x%lx for desc FIFO.\n", + "sps:BAM %pa pipe %d uses IOVA 0x%pK for desc FIFO.\n", BAM_ID(dev), pipe_index, - bam_pipe->connect.desc.iova); + (void *)(bam_pipe->connect.desc.iova)); } else { hw_params.desc_base = map->desc.phys_base; } @@ -1412,8 +1412,9 @@ int sps_bam_pipe_transfer_one(struct sps_bam *dev, u32 next_write; static int show_recom; - SPS_DBG(dev, "sps:BAM %pa pipe %d addr 0x%x size 0x%x flags 0x%x\n", - BAM_ID(dev), pipe_index, addr, size, flags); + SPS_DBG(dev, "sps:BAM %pa pipe %d addr 0x%pK size 0x%x flags 0x%x\n", + BAM_ID(dev), pipe_index, + (void *)(long)addr, size, flags); /* Is this a BAM-to-BAM or satellite connection? */ if ((pipe->state & (BAM_STATE_BAM2BAM | BAM_STATE_REMOTE))) { @@ -1937,8 +1938,8 @@ static void pipe_handler_eot(struct sps_bam *dev, struct sps_pipe *pipe) user = &pipe->sys.user_ptrs[offset / sizeof(struct sps_iovec)]; for (;;) { SPS_DBG(dev, - "sps:%s; pipe index:%d; iovec addr:0x%x; size:0x%x; flags:0x%x; enabled:0x%x; *user is %s NULL.\n", - __func__, pipe->pipe_index, cache->addr, + "sps:%s; pipe index:%d; iovec addr:0x%pK; size:0x%x; flags:0x%x; enabled:0x%x; *user is %s NULL.\n", + __func__, pipe->pipe_index, (void *)(long)cache->addr, cache->size, cache->flags, enabled, (*user == NULL) ? "" : "not"); @@ -2226,8 +2227,8 @@ int sps_bam_pipe_get_iovec(struct sps_bam *dev, u32 pipe_index, pipe->sys.acked_offset = 0; SPS_DBG(dev, - "sps:%s; pipe index:%d; iovec addr:0x%x; size:0x%x; flags:0x%x; acked_offset:0x%x.\n", - __func__, pipe->pipe_index, desc->addr, + "sps:%s; pipe index:%d; iovec addr:0x%pK; size:0x%x; flags:0x%x; acked_offset:0x%x.\n", + __func__, pipe->pipe_index, (void *)(long)desc->addr, desc->size, desc->flags, pipe->sys.acked_offset); return 0; diff --git a/drivers/platform/msm/sps/sps_dma.c b/drivers/platform/msm/sps/sps_dma.c index 545a21e85203..9385fa24202f 100644 --- a/drivers/platform/msm/sps/sps_dma.c +++ b/drivers/platform/msm/sps/sps_dma.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2011-2013, 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2013, 2015, 2019 The Linux Foundation. + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -380,7 +381,7 @@ int sps_dma_device_de_init(unsigned long h) dev = sps_dma_find_device(h); if (dev == NULL) { - SPS_ERR(sps, "sps:BAM-DMA: not registered: %lx", h); + SPS_ERR(sps, "sps:BAM-DMA: not registered: %pK", (void *)h); result = SPS_ERROR; goto exit_err; } @@ -546,8 +547,8 @@ int sps_alloc_dma_chan(const struct sps_alloc_dma_chan *alloc, dev = sps_dma_find_device(alloc->dev); if (dev == NULL) { - SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %lx", - alloc->dev); + SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %pK", + (void *)alloc->dev); goto exit_err; } @@ -620,7 +621,8 @@ int sps_free_dma_chan(struct sps_dma_chan *chan) dev = sps_dma_find_device(chan->dev); if (dev == NULL) { - SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %lx", chan->dev); + SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %pK", + (void *)chan->dev); result = SPS_ERROR; goto exit_err; } diff --git a/drivers/platform/msm/sps/sps_mem.c b/drivers/platform/msm/sps/sps_mem.c index db36e64f96d8..3aee9090e4ac 100644 --- a/drivers/platform/msm/sps/sps_mem.c +++ b/drivers/platform/msm/sps/sps_mem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2013, 2015, 2017, The Linux Foundation. +/* Copyright (c) 2011-2013, 2015, 2017, 2019, The Linux Foundation. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -75,8 +75,8 @@ phys_addr_t sps_mem_alloc_io(u32 bytes) return SPS_ADDR_INVALID; } - SPS_DBG3(sps, "sps:sps_mem_alloc_io.phys=%pa.virt=0x%lx.size=0x%x.", - &phys_addr, virt_addr, bytes); + SPS_DBG3(sps, "sps:sps_mem_alloc_io.phys=%pa.virt=0x%pK.size=0x%x.", + &phys_addr, (void *)virt_addr, bytes); return phys_addr; } @@ -92,8 +92,8 @@ void sps_mem_free_io(phys_addr_t phys_addr, u32 bytes) iomem_offset = phys_addr - iomem_phys; virt_addr = (uintptr_t) iomem_virt + iomem_offset; - SPS_DBG3(sps, "sps:sps_mem_free_io.phys=%pa.virt=0x%lx.size=0x%x.", - &phys_addr, virt_addr, bytes); + SPS_DBG3(sps, "sps:sps_mem_free_io.phys=%pa.virt=0x%pK.size=0x%x.", + &phys_addr, (void *)virt_addr, bytes); gen_pool_free(pool, virt_addr, bytes); total_free += bytes; diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c index db5db28d5f9e..176f8715e707 100644 --- a/drivers/platform/msm/sps/sps_rm.c +++ b/drivers/platform/msm/sps/sps_rm.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2015, 2017, 2019, The Linux Foundation. + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -380,8 +381,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe) map->src.bam = sps_h2bam(map->src.dev); if (map->src.bam == NULL) { if (map->src.dev != SPS_DEV_HANDLE_MEM) { - SPS_ERR(sps, "sps:Invalid BAM handle: %pa", - &map->src.dev); + SPS_ERR(sps, "sps:Invalid BAM handle: %pK", + (void *)(&map->src.dev)); goto exit_err; } map->src.pipe_index = SPS_BAM_PIPE_INVALID; @@ -389,8 +390,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe) map->dest.bam = sps_h2bam(map->dest.dev); if (map->dest.bam == NULL) { if (map->dest.dev != SPS_DEV_HANDLE_MEM) { - SPS_ERR(sps, "sps:Invalid BAM handle: %pa", - &map->dest.dev); + SPS_ERR(sps, "sps:Invalid BAM handle: %pK", + (void *)(&map->dest.dev)); goto exit_err; } map->dest.pipe_index = SPS_BAM_PIPE_INVALID; @@ -399,8 +400,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe) /* Check the BAM device for the pipe */ if ((dir == SPS_MODE_SRC && map->src.bam == NULL) || (dir != SPS_MODE_SRC && map->dest.bam == NULL)) { - SPS_ERR(sps, "sps:Invalid BAM endpt: dir %d src %pa dest %pa", - dir, &map->src.dev, &map->dest.dev); + SPS_ERR(sps, "sps:Invalid BAM endpt: dir %d src %pK dest %pK", + dir, (void *)(&map->src.dev), (void *)(&map->dest.dev)); goto exit_err; } From b03b261cfc1123002524b6c50d5b5e6ed754196f Mon Sep 17 00:00:00 2001 From: Venkata Prahlad Valluru Date: Tue, 7 May 2019 19:58:00 +0530 Subject: [PATCH 59/75] msm: mdss: hdmi: skip pan_display during handoff In case of HDMI as primary, skip pan_display until handoff completes. Change-Id: I5af8142292bcac0f085fffab1af99f635d3ff304 Signed-off-by: Venkata Prahlad Valluru --- drivers/video/fbdev/msm/mdss_fb.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 1b408e2838d6..2a184bb924ca 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -1,7 +1,7 @@ /* * Core MDSS framebuffer driver. * - * Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. * Copyright (C) 2007 Google Incorporated * * This software is licensed under the terms of the GNU General Public @@ -3507,16 +3507,19 @@ static int mdss_fb_pan_display(struct fb_var_screeninfo *var, { struct mdp_display_commit disp_commit; struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; + struct mdss_data_type *mdata = mfd_to_mdata(mfd); /* - * during mode switch through mode sysfs node, it will trigger a - * pan_display after switch. This assumes that fb has been adjusted, - * however when using overlays we may not have the right size at this - * point, so it needs to go through PREPARE first. Abort pan_display - * operations until that happens + * Abort pan_display operations in following cases: + * 1. during mode switch through mode sysfs node, it will trigger a + * pan_display after switch. This assumes that fb has been adjusted, + * however when using overlays we may not have the right size at this + * point, so it needs to go through PREPARE first. + * 2. When the splash handoff is pending. */ - if (mfd->switch_state != MDSS_MDP_NO_UPDATE_REQUESTED) { - pr_debug("fb%d: pan_display skipped during switch\n", + if ((mfd->switch_state != MDSS_MDP_NO_UPDATE_REQUESTED) || + mdata->handoff_pending) { + pr_debug("fb%d: pan_display skipped during switch or handoff\n", mfd->index); return 0; } From 2153161639b1bcdb5337fd6e16a331a5b0122c0e Mon Sep 17 00:00:00 2001 From: Sumalatha Malothu Date: Mon, 29 Apr 2019 18:05:53 +0530 Subject: [PATCH 60/75] msm: camera_v2: handle the error value returned during get clock currently only NULL pointer check is used to validate the return value from clk_get, this change to handle all the failures. This snapshot is taken from msm-4.9 Ported it from 4.9 to 4.4 Change-Id: Icd8b7e33d0f235a7c5dde2307972a594908e6a60 Signed-off-by: Sumalatha Malothu --- .../platform/msm/camera_v2/common/msm_camera_io_util.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c index 8a49c7cf9f4a..21438074bcc3 100644 --- a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c +++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2011-2014, 2017, The Linux Foundataion. All rights reserved. +/* Copyright (c) 2011-2014, 2017, 2019 The Linux Foundataion. + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -364,12 +365,13 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info, } } else { for (i = num_clk - 1; i >= 0; i--) { - if (clk_ptr[i] != NULL) { + if (!IS_ERR_OR_NULL(clk_ptr[i])) { CDBG("%s disable %s\n", __func__, clk_info[i].clk_name); clk_disable(clk_ptr[i]); clk_unprepare(clk_ptr[i]); clk_put(clk_ptr[i]); + clk_ptr[i] = NULL; } } } @@ -383,10 +385,11 @@ cam_clk_set_err: clk_put(clk_ptr[i]); cam_clk_get_err: for (i--; i >= 0; i--) { - if (clk_ptr[i] != NULL) { + if (!IS_ERR_OR_NULL(clk_ptr[i])) { clk_disable(clk_ptr[i]); clk_unprepare(clk_ptr[i]); clk_put(clk_ptr[i]); + clk_ptr[i] = NULL; } } return rc; From 1c16771a7b6fd7a56e6c7b3548f08e49778bb7c3 Mon Sep 17 00:00:00 2001 From: Naman Padhiar Date: Wed, 8 May 2019 16:34:37 +0530 Subject: [PATCH 61/75] icnss: Add check on msa region When icnss receive server arrive it send wlfw_msa_mem_info_send_sync_msg QMI request to firmware and in response expect range of addresses and size to be mapped. Add condition to check whether addresses in response falls under valid range otherwise it asserts. Change-Id: I9a8542cb6c3b3cefe112d1f08a76dd2eadf68d2f Signed-off-by: Naman Padhiar --- drivers/soc/qcom/icnss.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 454a897c19ab..2d736c7617cd 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -1240,6 +1240,7 @@ static int wlfw_msa_mem_info_send_sync_msg(void) struct wlfw_msa_info_req_msg_v01 req; struct wlfw_msa_info_resp_msg_v01 resp; struct msg_desc req_desc, resp_desc; + uint64_t max_mapped_addr; if (!penv || !penv->wlfw_clnt) return -ENODEV; @@ -1286,9 +1287,23 @@ static int wlfw_msa_mem_info_send_sync_msg(void) goto out; } + max_mapped_addr = penv->msa_pa + penv->msa_mem_size; penv->stats.msa_info_resp++; penv->nr_mem_region = resp.mem_region_info_len; for (i = 0; i < resp.mem_region_info_len; i++) { + + if (resp.mem_region_info[i].size > penv->msa_mem_size || + resp.mem_region_info[i].region_addr > max_mapped_addr || + resp.mem_region_info[i].region_addr < penv->msa_pa || + resp.mem_region_info[i].size + + resp.mem_region_info[i].region_addr > max_mapped_addr) { + icnss_pr_dbg("Received out of range Addr: 0x%llx Size: 0x%x\n", + resp.mem_region_info[i].region_addr, + resp.mem_region_info[i].size); + ret = -EINVAL; + goto fail_unwind; + } + penv->mem_region[i].reg_addr = resp.mem_region_info[i].region_addr; penv->mem_region[i].size = @@ -1303,6 +1318,8 @@ static int wlfw_msa_mem_info_send_sync_msg(void) return 0; +fail_unwind: + memset(&penv->mem_region[0], 0, sizeof(penv->mem_region[0]) * i); out: penv->stats.msa_info_err++; ICNSS_QMI_ASSERT(); From edc083e81200388e6237fc6db9033d01ef636747 Mon Sep 17 00:00:00 2001 From: Vijay kumar Tumati Date: Tue, 16 Apr 2019 15:37:42 +0530 Subject: [PATCH 62/75] msm: camera : Lock Implementation for avoid race condition Lock Implementation for avoid race condition leading to out-of-bound write in "msm_vb2_queue_setup CRs-Fixed: 2362627 Change-Id: I7f7420c7437b9ac2f215929a8614b0846e890c98 Signed-off-by: Vijay kumar Tumati Signed-off-by: Haibin Liu --- .../platform/msm/camera_v2/camera/camera.c | 35 +++++++++++++------ .../platform/msm/camera_v2/msm_vb2/msm_vb2.c | 20 +++++++---- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c index ccdd4622c120..1c721e95180a 100644 --- a/drivers/media/platform/msm/camera_v2/camera/camera.c +++ b/drivers/media/platform/msm/camera_v2/camera/camera.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -366,9 +366,12 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh, if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - if (WARN_ON(!sp->vb2_q.drv_priv)) - return -ENOMEM; - + mutex_lock(sp->vb2_q.lock); + if (WARN_ON(!sp->vb2_q.drv_priv)) { + rc = -ENOMEM; + mutex_unlock(sp->vb2_q.lock); + goto done; + } memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data, sizeof(struct msm_v4l2_format_data)); user_fmt = (struct msm_v4l2_format_data *)sp->vb2_q.drv_priv; @@ -377,27 +380,29 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh, user_fmt->num_planes); /*num_planes need to bound checked, otherwise for loop can execute forever */ - if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) - return -EINVAL; + if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) { + rc = -EINVAL; + mutex_unlock(sp->vb2_q.lock); + goto done; + } for (i = 0; i < user_fmt->num_planes; i++) pr_debug("%s: plane size[%d]\n", __func__, user_fmt->plane_sizes[i]); - + mutex_unlock(sp->vb2_q.lock); if (msm_is_daemon_present() != false) { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_S_FMT, -1, &event); rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); if (rc < 0) - return rc; - + goto done; rc = camera_check_event_status(&event); if (rc < 0) - return rc; + goto done; } sp->is_vb2_valid = 1; } - +done: return rc; } @@ -597,6 +602,12 @@ static int camera_v4l2_vb2_q_init(struct file *filep) pr_err("%s : memory not available\n", __func__); return -ENOMEM; } + q->lock = kzalloc(sizeof(struct mutex), GFP_KERNEL); + if (!q->lock) { + kzfree(q->drv_priv); + return -ENOMEM; + } + mutex_init(q->lock); q->mem_ops = msm_vb2_get_q_mem_ops(); q->ops = msm_vb2_get_q_ops(); @@ -616,6 +627,8 @@ static void camera_v4l2_vb2_q_release(struct file *filep) kzfree(sp->vb2_q.drv_priv); mutex_lock(&sp->lock); vb2_queue_release(&sp->vb2_q); + mutex_destroy(sp->vb2_q.lock); + kzfree(sp->vb2_q.lock); mutex_unlock(&sp->lock); } diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c index f2b048e37319..5943d57812f0 100644 --- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,15 +19,19 @@ static int msm_vb2_queue_setup(struct vb2_queue *q, unsigned int sizes[], void *alloc_ctxs[]) { int i; - struct msm_v4l2_format_data *data = q->drv_priv; + struct msm_v4l2_format_data *data = NULL; + int rc = -EINVAL; + + mutex_lock(q->lock); + data = q->drv_priv; if (!data) { pr_err("%s: drv_priv NULL\n", __func__); - return -EINVAL; + goto done; } if (data->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (WARN_ON(data->num_planes > VIDEO_MAX_PLANES)) - return -EINVAL; + goto done; *num_planes = data->num_planes; @@ -36,9 +40,13 @@ static int msm_vb2_queue_setup(struct vb2_queue *q, } else { pr_err("%s: Unsupported buf type :%d\n", __func__, data->type); - return -EINVAL; + goto done; } - return 0; + rc = 0; + +done: + mutex_unlock(q->lock); + return rc; } int msm_vb2_buf_init(struct vb2_buffer *vb) From 51f1f59a3f1e19a8106af9dc370d21a08fb072b8 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Tue, 30 Apr 2019 19:04:30 +0530 Subject: [PATCH 63/75] msm: kgsl: Fix race condition while making page as dirty set_page_dirty() is racy if the caller has no reference against page->mapping->host, and if the page is unlocked. This is because another CPU could truncate the page off the mapping and then free the mapping. Use set_page_dirty_lock() to avoid this race condition. Change-Id: I517fb9aee66560618c7676b311368f7a7498011f Signed-off-by: Rajesh Kemisetti Signed-off-by: Archana Sriram --- drivers/gpu/msm/kgsl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index cd2466fd110f..a0863f07fe36 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -328,7 +328,7 @@ kgsl_mem_entry_destroy(struct kref *kref) entry->memdesc.sgt->nents, i) { page = sg_page(sg); for (j = 0; j < (sg->length >> PAGE_SHIFT); j++) - set_page_dirty(nth_page(page, j)); + set_page_dirty_lock(nth_page(page, j)); } } From 26ac9f568e8a201f89bb6055c553cbbcd95ba1ef Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 12 Mar 2019 23:03:18 -0700 Subject: [PATCH 64/75] dsp: afe: check for payload size before payload access Check if payload data is big enough before accessing the data in it. Change-Id: I939f205a8cebf6ef4859f81fae5429bca013d540 Signed-off-by: Karthikeyan Mani --- sound/soc/msm/qdsp6v2/q6afe.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 20c933b80c66..6d38cb50a121 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -554,6 +554,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) { uint32_t *payload = data->payload; uint32_t param_id; + uint32_t param_id_pos = 0; if (!payload || (data->token >= AFE_MAX_PORTS)) { pr_err("%s: Error: size %d payload %pK token %d\n", @@ -562,17 +563,26 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } - param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? - payload[3] : - payload[2]; + if (rtac_make_afe_callback(data->payload, + data->payload_size)) + return 0; + + if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) + param_id_pos = 4; + else + param_id_pos = 3; + + if (data->payload_size >= param_id_pos * sizeof(uint32_t)) + param_id = payload[param_id_pos - 1]; + else { + pr_err("%s: Error: size %d is less than expected\n", + __func__, data->payload_size); + return -EINVAL; + } if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { av_dev_drift_afe_cb_handler(data->opcode, data->payload, data->payload_size); } else { - if (rtac_make_afe_callback(data->payload, - data->payload_size)) - return 0; - if (sp_make_afe_callback(data->opcode, data->payload, data->payload_size)) return -EINVAL; @@ -595,6 +605,11 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) uint16_t port_id = 0; payload = data->payload; if (data->opcode == APR_BASIC_RSP_RESULT) { + if (data->payload_size < (2 * sizeof(uint32_t))) { + pr_err("%s: Error: size %d is less than expected\n", + __func__, data->payload_size); + return -EINVAL; + } pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x token=%d\n", __func__, data->opcode, payload[0], payload[1], data->token); From 4d2f6ab9a889a4db5aa02168a17f25d2f44ccf02 Mon Sep 17 00:00:00 2001 From: Sharath Chandra Vurukala Date: Wed, 24 Apr 2019 11:35:26 +0530 Subject: [PATCH 65/75] net: sockev: avoid races between sockev and socket_close Use-after-free is seen when sending a sockev netlink message since socket is not held which can race with sk_free. KASAN: use-after-free in sockev_client_cb+0x41c/0x4b8 in net/core/sockev_nlmcast.c:104 Read of size 2 at addr ffffffc08420c550 Call trace: dump_backtrace+0x0/0x388 arch/arm64/kernel/time.c:55 show_stack+0x24/0x30 arch/arm64/kernel/traps.c:152 __dump_stack+0x24/0x2c lib/dump_stack.c:17 dump_stack+0x8c/0xd0 lib/dump_stack.c:53 print_address_description+0x74/0x234 mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report+0x240/0x264 mm/kasan/report.c:412 __asan_report_load2_noabort+0x2c/0x38 mm/kasan/report.c:431 sockev_client_cb+0x41c/0x4b8 net/core/sockev_nlmcast.c:104 notifier_call_chain+0x104/0x158 kernel/notifier.c:93 __blocking_notifier_call_chain+0x80/0xb0 kernel/notifier.c:317 blocking_notifier_call_chain+0x3c/0x4c kernel/notifier.c:328 sockev_notify+0x30/0x3c net/socket.c:181 SYSC_bind net/socket.c:1509 [inline] SyS_bind+0x1ec/0x30c net/socket.c:1489 el0_svc_naked+0x34/0x38 Freed by task 19460: save_stack mm/kasan/kasan.c:447 [inline] set_track mm/kasan/kasan.c:459 [inline] __kasan_slab_free+0x134/0x20c mm/kasan/kasan.c:520 kasan_slab_free+0x10/0x1c mm/kasan/kasan.c:527 slab_free_hook mm/slub.c:1401 [inline] slab_free_freelist_hook mm/slub.c:1422 [inline] slab_free mm/slub.c:2979 [inline] kmem_cache_free+0x114/0x664 mm/slub.c:3001 sk_prot_free net/core/sock.c:1504 [inline] __sk_destruct+0x324/0x3c0 net/core/sock.c:1585 __sk_free+0x180/0x200 net/core/sock.c:1601 sk_free+0x44/0x50 net/core/sock.c:1612 sock_put include/net/sock.h:1643 [inline] sk_common_release+0x198/0x20c net/core/sock.c:3014 raw_close+0x38/0x44 net/ipv4/raw.c:703 inet_release+0x128/0x15c net/ipv4/af_inet.c:446 __sock_release+0xb8/0x258 net/socket.c:614 sock_close+0x24/0x34 net/socket.c:1150 __fput+0x1f4/0x4e4 fs/file_table.c:345 ____fput+0x20/0x2c fs/file_table.c:380 task_work_run+0x9c/0x174 kernel/task_work.c:113 Change-Id: Idb4335889b6e4228f36d76ca5b6156cc5e5838da Signed-off-by: Sharath Chandra Vurukala --- net/core/sockev_nlmcast.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/core/sockev_nlmcast.c b/net/core/sockev_nlmcast.c index 1e92c5632b97..1e88dd8ee85d 100644 --- a/net/core/sockev_nlmcast.c +++ b/net/core/sockev_nlmcast.c @@ -73,11 +73,13 @@ static int sockev_client_cb(struct notifier_block *nb, sock = (struct socket *)data; if (!socknlmsgsk || !sock) - goto done; + goto sk_null; sk = sock->sk; if (!sk) - goto done; + goto sk_null; + + sock_hold(sk); if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6) goto done; @@ -108,6 +110,8 @@ static int sockev_client_cb(struct notifier_block *nb, smsg->skflags = sk->sk_flags; nlmsg_notify(socknlmsgsk, skb, 0, SKNLGRP_SOCKEV, 0, GFP_KERNEL); done: + sock_put(sk); +sk_null: return 0; } From 2cbfe924cf01c742edc184a016bede2e3c6eb0a7 Mon Sep 17 00:00:00 2001 From: Narender Ankam Date: Tue, 9 Apr 2019 18:56:37 +0530 Subject: [PATCH 66/75] msm: mdss: mdp: mixer allocation for pluggable primary display Try to allocate mixers LM0 and LM1 to an external pluggable display if it is configured as primary display. Change-Id: I81672132a6452535dcd7c2977e76f88a5f3aecf9 Signed-off-by: Narender Ankam --- drivers/video/fbdev/msm/mdss_mdp_ctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index ec56bcf6e64e..0b362895ceea 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -2577,6 +2577,7 @@ struct mdss_mdp_mixer *mdss_mdp_mixer_alloc( mixer_pool += ctl->mdata->ndspp; nmixers -= ctl->mdata->ndspp; } else if ((ctl->panel_data->panel_info.is_pluggable) && + !(ctl->panel_data->panel_info.is_prim_panel) && nmixers_active) { mixer_pool += ctl->mdata->ndspp; nmixers -= ctl->mdata->ndspp; From ee8a9362ca923da6d6ad6f12c030b61539afe510 Mon Sep 17 00:00:00 2001 From: Narender Ankam Date: Thu, 16 May 2019 18:10:54 +0530 Subject: [PATCH 67/75] msm: mdss: hdmi: reset sink_caps before parsing EDID Within EDID parser's data structure, sink_caps of previous EDID are being retained. Reset sink_caps before parsing new EDID. Change-Id: I7927161256ec87ab77b26a9d7bc5e0cd1df5583b Signed-off-by: Narender Ankam --- drivers/video/fbdev/msm/mdss_hdmi_edid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c index 0c04fd35c0d5..a82ebe36143d 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2017, 2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -200,6 +200,7 @@ static int hdmi_edid_reset_parser(struct hdmi_edid_ctrl *edid_ctrl) /* reset resolution related sink data */ memset(&edid_ctrl->sink_data, 0, sizeof(edid_ctrl->sink_data)); + memset(&edid_ctrl->sink_caps, 0, sizeof(edid_ctrl->sink_caps)); /* reset audio related data */ memset(edid_ctrl->audio_data_block, 0, From f455966ef0977e78f8005ce1ed82d66e21508f5d Mon Sep 17 00:00:00 2001 From: Vatsal Bucha Date: Fri, 22 Feb 2019 15:38:30 +0530 Subject: [PATCH 68/75] msm: qdsp6v2: Check size of payload before access Check size of payload array before access in qdsp_mvm_callback. Change-Id: I81d945f963cfb4a3cb26155700b82880d891ec5e Signed-off-by: Vatsal Bucha --- sound/soc/msm/qdsp6v2/q6voice.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c index 3193dd0de140..3b00f5b083c6 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -6398,7 +6398,7 @@ void voc_config_vocoder(uint32_t media_type, static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) { - uint32_t *ptr = NULL; + uint32_t *ptr = NULL, min_payload_size = 0; struct common_data *c = NULL; struct voice_data *v = NULL; int i = 0; @@ -6468,7 +6468,7 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) } if (data->opcode == APR_BASIC_RSP_RESULT) { - if (data->payload_size) { + if (data->payload_size >= sizeof(ptr[0]) * 2) { ptr = data->payload; pr_debug("%x %x\n", ptr[0], ptr[1]); @@ -6535,6 +6535,12 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) } else if (data->opcode == VSS_IMEMORY_RSP_MAP) { pr_debug("%s, Revd VSS_IMEMORY_RSP_MAP response\n", __func__); + if (data->payload_size < sizeof(ptr[0])) { + pr_err("%s: payload has invalid size[%d]\n", __func__, + data->payload_size); + return -EINVAL; + } + if (data->payload_size && data->token == VOIP_MEM_MAP_TOKEN) { ptr = data->payload; if (ptr[0]) { @@ -6602,10 +6608,15 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv) pr_debug("%s: Received VSS_IVERSION_RSP_GET\n", __func__); if (data->payload_size) { + min_payload_size = (data->payload_size > + CVD_VERSION_STRING_MAX_SIZE) + ? CVD_VERSION_STRING_MAX_SIZE : + data->payload_size; version_rsp = (struct vss_iversion_rsp_get_t *)data->payload; memcpy(common.cvd_version, version_rsp->version, - CVD_VERSION_STRING_MAX_SIZE); + min_payload_size); + common.cvd_version[min_payload_size - 1] = '\0'; pr_debug("%s: CVD Version = %s\n", __func__, common.cvd_version); From a919f50d967310eb7c150ba809c2c6434e0a7149 Mon Sep 17 00:00:00 2001 From: Karthikeyan Mani Date: Tue, 14 May 2019 14:10:55 -0700 Subject: [PATCH 69/75] dsp: afe: check for minimum size before payload access Check if payload data is atleast the minimum expected size before accessing the data in it. Change-Id: Ia1295ca5ad5d002122e416fae53588681da687ea Signed-off-by: Karthikeyan Mani --- sound/soc/msm/qdsp6v2/q6afe.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 6d38cb50a121..1b9a7f866f9f 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -332,6 +332,11 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, /* Set command specific details */ switch (opcode) { case AFE_PORT_CMDRSP_GET_PARAM_V2: + if (payload_size < (5 * sizeof(uint32_t))) { + pr_err("%s: Error: size %d is less than expected\n", + __func__, payload_size); + return -EINVAL; + } expected_size += sizeof(struct param_hdr_v1); param_hdr.module_id = payload[1]; param_hdr.instance_id = INSTANCE_ID_0; @@ -340,7 +345,17 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, data_start = &payload[4]; break; case AFE_PORT_CMDRSP_GET_PARAM_V3: + if (payload_size < (6 * sizeof(uint32_t))) { + pr_err("%s: Error: size %d is less than expected\n", + __func__, payload_size); + return -EINVAL; + } expected_size += sizeof(struct param_hdr_v3); + if (payload_size < expected_size) { + pr_err("%s: Error: size %d is less than expected\n", + __func__, payload_size); + return -EINVAL; + } memcpy(¶m_hdr, &payload[1], sizeof(struct param_hdr_v3)); data_start = &payload[5]; break; From dabba2bc7bea2366304ce48e25721c533552c53b Mon Sep 17 00:00:00 2001 From: E V Ravi Date: Mon, 6 May 2019 18:16:43 +0530 Subject: [PATCH 70/75] msm: ais : Lock Implementation for avoid race condition Lock Implementation for avoid race condition leading to out-of-bound write in "msm_vb2_queue_setup Change-Id: I386f1709bdf3328ae0c1db44980db8453849babf Signed-off-by: E V Ravi --- .../media/platform/msm/ais/camera/camera.c | 33 ++++++++++++++----- .../media/platform/msm/ais/msm_vb2/msm_vb2.c | 20 +++++++---- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/msm/ais/camera/camera.c b/drivers/media/platform/msm/ais/camera/camera.c index 353b74794bc8..dafd4be11bba 100644 --- a/drivers/media/platform/msm/ais/camera/camera.c +++ b/drivers/media/platform/msm/ais/camera/camera.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -370,8 +370,12 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh, if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - if (WARN_ON(!sp->vb2_q.drv_priv)) - return -ENOMEM; + mutex_lock(sp->vb2_q.lock); + if (WARN_ON(!sp->vb2_q.drv_priv)) { + rc = -ENOMEM; + mutex_unlock(sp->vb2_q.lock); + goto done; + } memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data, sizeof(struct msm_v4l2_format_data)); @@ -382,27 +386,30 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh, /* num_planes need to bound checked, otherwise for loop * can execute forever */ - if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) - return -EINVAL; + if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) { + rc = -EINVAL; + mutex_unlock(sp->vb2_q.lock); + goto done; + } for (i = 0; i < user_fmt->num_planes; i++) pr_debug("%s: plane size[%d]\n", __func__, user_fmt->plane_sizes[i]); - + mutex_unlock(sp->vb2_q.lock); if (msm_is_daemon_present() != false) { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_S_FMT, -1, &event); rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); if (rc < 0) - return rc; + goto done; rc = camera_check_event_status(&event); if (rc < 0) - return rc; + goto done; } sp->is_vb2_valid = 1; } - +done: return rc; } @@ -600,6 +607,12 @@ static int camera_v4l2_vb2_q_init(struct file *filep) pr_err("%s : memory not available\n", __func__); return -ENOMEM; } + q->lock = kzalloc(sizeof(struct mutex), GFP_KERNEL); + if (!q->lock) { + kzfree(q->drv_priv); + return -ENOMEM; + } + mutex_init(q->lock); q->mem_ops = msm_vb2_get_q_mem_ops(); q->ops = msm_vb2_get_q_ops(); @@ -619,6 +632,8 @@ static void camera_v4l2_vb2_q_release(struct file *filep) kzfree(sp->vb2_q.drv_priv); mutex_lock(&sp->lock); vb2_queue_release(&sp->vb2_q); + mutex_destroy(sp->vb2_q.lock); + kzfree(sp->vb2_q.lock); mutex_unlock(&sp->lock); } diff --git a/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c index 1cbc49c8485c..be3ea19d69d7 100644 --- a/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,15 +19,19 @@ static int msm_vb2_queue_setup(struct vb2_queue *q, unsigned int sizes[], void *alloc_ctxs[]) { int i; - struct msm_v4l2_format_data *data = q->drv_priv; + struct msm_v4l2_format_data *data = NULL; + int rc = -EINVAL; + + mutex_lock(q->lock); + data = q->drv_priv; if (!data) { pr_err("%s: drv_priv NULL\n", __func__); - return -EINVAL; + goto done; } if (data->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (WARN_ON(data->num_planes > VIDEO_MAX_PLANES)) - return -EINVAL; + goto done; *num_planes = data->num_planes; @@ -36,9 +40,13 @@ static int msm_vb2_queue_setup(struct vb2_queue *q, } else { pr_err("%s: Unsupported buf type :%d\n", __func__, data->type); - return -EINVAL; + goto done; } - return 0; + rc = 0; + +done: + mutex_unlock(q->lock); + return rc; } static int msm_vb2_buf_init(struct vb2_buffer *vb) From a935cbe4375cde0027646c6e838b98243be84e22 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Thu, 28 Feb 2019 15:38:00 -0800 Subject: [PATCH 71/75] msm: adm: validate ADSP payload size before access Check the size of ADSP payload before accessing it. CRs-Fixed: 2380694 Change-Id: Icdc19a85b39a397ba6d7177f42ece4626b901832 Signed-off-by: Vignesh Kulothungan --- sound/soc/msm/qdsp6v2/q6adm.c | 70 ++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index c6f3b5ba96ba..8569f5d2243a 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1230,12 +1230,22 @@ static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, switch (opcode) { case ADM_CMDRSP_GET_PP_PARAMS_V5: struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v5); + if (payload_size < struct_size) { + pr_err("%s: payload size %d < expected size %d\n", + __func__, payload_size, struct_size); + break; + } v5_rsp = (struct adm_cmd_rsp_get_pp_params_v5 *) payload; data_size = v5_rsp->param_hdr.param_size; param_data = v5_rsp->param_data; break; case ADM_CMDRSP_GET_PP_PARAMS_V6: struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v6); + if (payload_size < struct_size) { + pr_err("%s: payload size %d < expected size %d\n", + __func__, payload_size, struct_size); + break; + } v6_rsp = (struct adm_cmd_rsp_get_pp_params_v6 *) payload; data_size = v6_rsp->param_hdr.param_size; param_data = v6_rsp->param_data; @@ -1399,7 +1409,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } adm_callback_debug_print(data); - if (data->payload_size) { + if (data->payload_size >= sizeof(uint32_t)) { copp_idx = (data->token) & 0XFF; port_idx = ((data->token) >> 16) & 0xFF; client_id = ((data->token) >> 8) & 0xFF; @@ -1421,6 +1431,16 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) if (data->opcode == APR_BASIC_RSP_RESULT) { pr_debug("%s: APR_BASIC_RSP_RESULT id 0x%x\n", __func__, payload[0]); + if (!((client_id != ADM_CLIENT_ID_SOURCE_TRACKING) && + ((payload[0] == ADM_CMD_SET_PP_PARAMS_V5) || + (payload[0] == ADM_CMD_SET_PP_PARAMS_V6)))) { + if (data->payload_size < + (2 * sizeof(uint32_t))) { + pr_err("%s: Invalid payload size %d\n", + __func__, data->payload_size); + return 0; + } + } if (payload[1] != 0) { pr_err("%s: cmd = 0x%x returned error = 0x%x\n", __func__, payload[0], payload[1]); @@ -1545,9 +1565,16 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) case ADM_CMDRSP_DEVICE_OPEN_V5: case ADM_CMDRSP_DEVICE_OPEN_V6: case ADM_CMDRSP_DEVICE_OPEN_V8: { - struct adm_cmd_rsp_device_open_v5 *open = - (struct adm_cmd_rsp_device_open_v5 *)data->payload; + struct adm_cmd_rsp_device_open_v5 *open = NULL; + if (data->payload_size < + sizeof(struct adm_cmd_rsp_device_open_v5)) { + pr_err("%s: Invalid payload size %d\n", + __func__, data->payload_size); + return 0; + } + open = + (struct adm_cmd_rsp_device_open_v5 *)data->payload; if (open->copp_id == INVALID_COPP_ID) { pr_err("%s: invalid coppid rxed %d\n", __func__, open->copp_id); @@ -1603,21 +1630,28 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2: pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n", __func__); - num_modules = payload[1]; - pr_debug("%s: Num modules %d\n", __func__, num_modules); - if (payload[0]) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n", - __func__, payload[0]); - } else if (num_modules > MAX_MODULES_IN_TOPO) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n", - __func__, num_modules); + if (data->payload_size >= (2 * sizeof(uint32_t))) { + num_modules = payload[1]; + pr_debug("%s: Num modules %d\n", __func__, + num_modules); + if (payload[0]) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n", + __func__, payload[0]); + } else if (num_modules > MAX_MODULES_IN_TOPO) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n", + __func__, num_modules); + } else { + ret = adm_process_get_topo_list_response + (data->opcode, copp_idx, + num_modules, payload, + data->payload_size); + if (ret) + pr_err("%s: Failed to process get topo modules list response, error %d\n", + __func__, ret); + } } else { - ret = adm_process_get_topo_list_response( - data->opcode, copp_idx, num_modules, - payload, data->payload_size); - if (ret) - pr_err("%s: Failed to process get topo modules list response, error %d\n", - __func__, ret); + pr_err("%s: Invalid payload size %d\n", + __func__, data->payload_size); } atomic_set(&this_adm.copp.stat[port_idx][copp_idx], payload[0]); From 526404d09d6f68ffd3f11161566ca64728fb9214 Mon Sep 17 00:00:00 2001 From: Narender Ankam Date: Thu, 16 May 2019 19:30:37 +0530 Subject: [PATCH 72/75] msm: mdss: assign block_id for INTF_3 As part of destination scalar on HDMI, INTF3 will be configured as dual LM single display for higher video timings. Assign block_id for HDMI INTF. Change-Id: I09f5eb4136c4a8248f3dc9a36e2d94110419112d Signed-off-by: Narender Ankam --- drivers/video/fbdev/msm/mdss_debug.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/msm/mdss_debug.c b/drivers/video/fbdev/msm/mdss_debug.c index e9989fbdd2ba..9ccd290ba2a6 100644 --- a/drivers/video/fbdev/msm/mdss_debug.c +++ b/drivers/video/fbdev/msm/mdss_debug.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2009-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1450,6 +1450,9 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, case MDSS_MDP_INTF2: block_id = DISPLAY_MISR_DSI1; break; + case MDSS_MDP_INTF3: + block_id = DISPLAY_MISR_HDMI; + break; default: pr_err("Unmatch INTF for Dual LM single display configuration, INTF:%d\n", ctl->intf_num); From 96eca370719871e5e3f65a62bd9f0d37cb389432 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Wed, 24 Apr 2019 21:11:06 +0530 Subject: [PATCH 73/75] diag: Check command size against the minimum before parsing Add check for minimum length before typecasting to build mask structure to prevent out of bound access while processing get msg mask command. CRs-Fixed: 2431047 Change-Id: I5b8341f278b0b46359800e43c604c5671261c728 Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_masks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index bb28958412ed..438f33d8cadb 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -705,7 +705,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, mask_info = (!info) ? &msg_mask : info->msg_mask; if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 || - !mask_info) { + !mask_info || (src_len < sizeof(struct diag_build_mask_req_t))) { pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n", __func__, src_buf, src_len, dest_buf, dest_len, mask_info); From cac305db85109ac62ea21e1433d9c35db2cc299d Mon Sep 17 00:00:00 2001 From: Abhishek Choubey Date: Mon, 25 Feb 2019 15:52:46 +0530 Subject: [PATCH 74/75] msm: ipa: fix to validate input parameters Validate the input parameters to avoid any unexpected scenarios. Change-Id: If77ac66470baf937b160800174ea14f1a8cb6408 Signed-off-by: Pooja Kumari Signed-off-by: Abhishek Choubey --- .../platform/msm/ipa/ipa_v3/ipa_qmi_service.c | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index 6b90abf787b9..fe3edb5db9b2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -779,7 +779,7 @@ int ipa3_qmi_ul_filter_request_send( { struct ipa_configure_ul_firewall_rules_resp_msg_v01 resp; struct msg_desc req_desc, resp_desc; - int rc; + int rc, i; IPAWANDBG("IPACM pass %u rules to Q6\n", req->firewall_rules_list_len); @@ -799,6 +799,37 @@ int ipa3_qmi_ul_filter_request_send( } mutex_unlock(&ipa3_qmi_lock); + /* check if modem is up */ + if (!ipa3_qmi_indication_fin || + !ipa3_qmi_modem_init_fin || + !ipa_q6_clnt) { + IPAWANDBG("modem QMI service is not up yet\n"); + return -EINVAL; + } + + /* Passing 0 rules means that firewall is disabled */ + if (req->firewall_rules_list_len == 0) + IPAWANDBG("IPACM passed 0 rules to Q6\n"); + + if (req->firewall_rules_list_len >= QMI_IPA_MAX_UL_FIREWALL_RULES_V01) { + IPAWANERR( + "Number of rules passed by IPACM, %d, exceed limit %d\n", + req->firewall_rules_list_len, + QMI_IPA_MAX_UL_FIREWALL_RULES_V01); + return -EINVAL; + } + + /* Check for valid IP type */ + for (i = 0; i < req->firewall_rules_list_len; i++) { + if (req->firewall_rules_list[i].ip_type != + QMI_IPA_IP_TYPE_V4_V01 && + req->firewall_rules_list[i].ip_type != + QMI_IPA_IP_TYPE_V6_V01) + IPAWANERR("Invalid IP type %d\n", + req->firewall_rules_list[i].ip_type); + return -EINVAL; + } + req_desc.max_msg_len = QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_MAX_MSG_LEN_V01; req_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01; From 8d1f0491ed3edd4567de10961333b63142eaf56c Mon Sep 17 00:00:00 2001 From: E V Ravi Date: Thu, 16 May 2019 14:14:58 +0530 Subject: [PATCH 75/75] msm: ais: handle the error value returned during get clock currently only NULL pointer check is used to validate the return value from clk_get, this change to handle all the failures. This snapshot is taken from auto-kernel.lnx.4.4.c1 ported it from auto-kernel.lnx.4.4.c1 to 4.4 Change-Id: I275cb4717c675baf528e05c50058f2c6b0025011 Signed-off-by: E V Ravi --- .../media/platform/msm/ais/common/msm_camera_io_util.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/ais/common/msm_camera_io_util.c b/drivers/media/platform/msm/ais/common/msm_camera_io_util.c index c6c2e0d02b65..8cee210095eb 100644 --- a/drivers/media/platform/msm/ais/common/msm_camera_io_util.c +++ b/drivers/media/platform/msm/ais/common/msm_camera_io_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -357,12 +357,13 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info, } } else { for (i = num_clk - 1; i >= 0; i--) { - if (clk_ptr[i] != NULL) { + if (!IS_ERR_OR_NULL(clk_ptr[i])) { CDBG("%s disable %s\n", __func__, clk_info[i].clk_name); clk_disable(clk_ptr[i]); clk_unprepare(clk_ptr[i]); clk_put(clk_ptr[i]); + clk_ptr[i] = NULL; } } } @@ -378,10 +379,11 @@ cam_clk_set_err: clk_put(clk_ptr[i]); cam_clk_get_err: for (i--; i >= 0; i--) { - if (clk_ptr[i] != NULL) { + if (!IS_ERR_OR_NULL(clk_ptr[i])) { clk_disable(clk_ptr[i]); clk_unprepare(clk_ptr[i]); clk_put(clk_ptr[i]); + clk_ptr[i] = NULL; } } return rc;