From dc674586ed5336472c27edf2e1bb081bbed87b24 Mon Sep 17 00:00:00 2001 From: Lynus Vaz Date: Thu, 15 Jun 2023 14:12:21 -0700 Subject: [PATCH 1/5] msm: kgsl: Defer drawobj_sync_timeline_fence_work() to a workqueue drawobj_sync_timeline_fence_work() does a cleanup of fence and syncobj allocations. Doing this cleanup in irq context requires the irq_work struct to remain valid after the function executes. Avoid this constraint by deferring this work to the memory workqueue. Change-Id: Icf648a61686c1ef3fd84467a2376b11a9a4bb803 Signed-off-by: Lynus Vaz --- drivers/gpu/msm/kgsl_drawobj.c | 7 ++++--- drivers/gpu/msm/kgsl_drawobj.h | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c index af0054bcd95e..9e00d2c08234 100644 --- a/drivers/gpu/msm/kgsl_drawobj.c +++ b/drivers/gpu/msm/kgsl_drawobj.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ /* @@ -253,7 +254,7 @@ static void drawobj_sync_func(struct kgsl_device *device, kgsl_drawobj_put(&event->syncobj->base); } -static void drawobj_sync_timeline_fence_work(struct irq_work *work) +static void drawobj_sync_timeline_fence_work(struct work_struct *work) { struct kgsl_drawobj_sync_event *event = container_of(work, struct kgsl_drawobj_sync_event, work); @@ -301,7 +302,7 @@ static void drawobj_sync_timeline_fence_callback(struct dma_fence *f, * removing the fence */ if (drawobj_sync_expire(event->device, event)) - irq_work_queue(&event->work); + queue_work(kgsl_driver.mem_workqueue, &event->work); } static void syncobj_destroy(struct kgsl_drawobj *drawobj) @@ -498,7 +499,7 @@ static int drawobj_add_sync_timeline(struct kgsl_device *device, event->device = device; event->context = NULL; event->fence = fence; - init_irq_work(&event->work, drawobj_sync_timeline_fence_work); + INIT_WORK(&event->work, drawobj_sync_timeline_fence_work); INIT_LIST_HEAD(&event->cb.node); diff --git a/drivers/gpu/msm/kgsl_drawobj.h b/drivers/gpu/msm/kgsl_drawobj.h index 3719dc171e1d..a1e160a220fb 100644 --- a/drivers/gpu/msm/kgsl_drawobj.h +++ b/drivers/gpu/msm/kgsl_drawobj.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __KGSL_DRAWOBJ_H @@ -170,8 +171,8 @@ struct kgsl_drawobj_sync_event { struct dma_fence *fence; /** @cb: Callback struct for KGSL_CMD_SYNCPOINT_TYPE_TIMELINE */ struct dma_fence_cb cb; - /** @work : irq worker for KGSL_CMD_SYNCPOINT_TYPE_TIMELINE */ - struct irq_work work; + /** @work : work_struct for KGSL_CMD_SYNCPOINT_TYPE_TIMELINE */ + struct work_struct work; }; #define KGSL_DRAWOBJ_FLAGS \ From 98c03480eca635a0af8701cfbaf0d07e6a865347 Mon Sep 17 00:00:00 2001 From: Naveen S Nair Date: Wed, 2 Aug 2023 14:51:32 +0530 Subject: [PATCH 2/5] soc: qcom: add buffer overflow check on AON rx_buffer Add buffer overflow check while accessing data buffer received from AON. Change-Id: I0472a0ad1e6edc3fe8102850fddacd89ceea4959 Signed-off-by: Naveen S Nair --- drivers/soc/qcom/slate_events_bridge.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/soc/qcom/slate_events_bridge.c b/drivers/soc/qcom/slate_events_bridge.c index ebddd7c04b80..261be187ff50 100644 --- a/drivers/soc/qcom/slate_events_bridge.c +++ b/drivers/soc/qcom/slate_events_bridge.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -439,6 +440,10 @@ void seb_rx_msg(void *data, int len) dev->seb_resp_cmplt = true; wake_up(&dev->link_state_wait); if (dev->wait_for_resp) { + if (len > SEB_GLINK_INTENT_SIZE) { + pr_err("Invalid seb rx buffer length\n"); + return; + } memcpy(dev->rx_buf, data, len); } else { /* Handle the event received from Slate */ From dc03cfa27f784edbd497e28ef67762a28073bce9 Mon Sep 17 00:00:00 2001 From: Khaja Hussain Shaik Khaji Date: Wed, 2 Aug 2023 12:29:07 +0530 Subject: [PATCH 3/5] drivers: qcom: pil: Use update_marker for modem book kpi Use update_marker instead of place_marker to avoid OOM issue if boot kpi file keeps growing. Add update_marker() declaration in boot_stats header file. Change-Id: I9b842c10670b2adb918e246174fdac45fb53de40 Signed-off-by: Khaja Hussain Shaik Khaji --- drivers/soc/qcom/boot_stats.c | 9 ++++++++- drivers/soc/qcom/msm_subsystem_restart.c | 2 +- drivers/soc/qcom/peripheral-loader.c | 6 +++--- drivers/soc/qcom/subsys-pil-tz.c | 4 ++-- include/soc/qcom/boot_stats.h | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/soc/qcom/boot_stats.c b/drivers/soc/qcom/boot_stats.c index b94493faa7af..af4315625102 100644 --- a/drivers/soc/qcom/boot_stats.c +++ b/drivers/soc/qcom/boot_stats.c @@ -150,6 +150,13 @@ void place_marker(const char *name) } EXPORT_SYMBOL(place_marker); +void update_marker(const char *name) +{ + destroy_marker(name); + place_marker(name); +} +EXPORT_SYMBOL(update_marker); + void destroy_marker(const char *name) { _destroy_boot_marker((char *) name); @@ -217,7 +224,7 @@ static ssize_t bootkpi_writer(struct kobject *obj, struct kobj_attribute *attr, return rc; buf[rc] = '\0'; - place_marker(buf); + update_marker(buf); return rc; } diff --git a/drivers/soc/qcom/msm_subsystem_restart.c b/drivers/soc/qcom/msm_subsystem_restart.c index f115e25fa5cd..707a882b9cf6 100644 --- a/drivers/soc/qcom/msm_subsystem_restart.c +++ b/drivers/soc/qcom/msm_subsystem_restart.c @@ -654,7 +654,7 @@ static int subsystem_shutdown(struct subsys_device *dev, void *data) #ifdef CONFIG_QGKI_MSM_BOOT_TIME_MARKER if (!strcmp(dev->desc->name, "modem")) - place_marker("M - Modem Stop"); + update_marker("M - Modem Stop"); #endif return 0; diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c index 95125c88f2c1..b7f17cc80d22 100644 --- a/drivers/soc/qcom/peripheral-loader.c +++ b/drivers/soc/qcom/peripheral-loader.c @@ -474,7 +474,7 @@ int pil_do_ramdump(struct pil_desc *desc, __func__, desc->name, ret); #ifdef CONFIG_QGKI_MSM_BOOT_TIME_MARKER if (!strcmp(desc->name, "modem")) - place_marker("M - Modem Dump completed"); + update_marker("M - Modem Dump completed"); #endif if (desc->subsys_vmid > 0) ret = pil_assign_mem_to_subsys(desc, priv->region_start, @@ -873,7 +873,7 @@ static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt) #ifdef CONFIG_QGKI_MSM_BOOT_TIME_MARKER if (!strcmp(desc->name, "modem")) - place_marker("M - Modem Image Start Loading"); + update_marker("M - Modem Image Start Loading"); #endif pil_info(desc, "loading from %pa to %pa\n", &priv->region_start, @@ -1339,7 +1339,7 @@ int pil_boot(struct pil_desc *desc) #ifdef CONFIG_QGKI_MSM_BOOT_TIME_MARKER if (!strcmp(desc->name, "modem")) - place_marker("M - Modem out of reset"); + update_marker("M - Modem out of reset"); #endif pil_info(desc, "Brought out of reset\n"); diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c index 03e7b8fcccf8..ddd30f512b0d 100644 --- a/drivers/soc/qcom/subsys-pil-tz.c +++ b/drivers/soc/qcom/subsys-pil-tz.c @@ -873,7 +873,7 @@ static int subsys_ramdump(int enable, const struct subsys_desc *subsys) return 0; #ifdef CONFIG_QGKI_MSM_BOOT_TIME_MARKER if (!strcmp(subsys->name, "modem")) - place_marker("M - Modem Dump start"); + update_marker("M - Modem Dump start"); #endif return pil_do_ramdump(&d->desc, d->ramdump_dev, d->minidump_dev); @@ -921,7 +921,7 @@ static irqreturn_t subsys_err_fatal_intr_handler (int irq, void *drv_data) } #ifdef CONFIG_QGKI_MSM_BOOT_TIME_MARKER if (!strcmp(d->subsys_desc.name, "modem")) - place_marker("M - Modem crash"); + update_marker("M - Modem crash"); #endif subsys_set_crash_status(d->subsys, CRASH_STATUS_ERR_FATAL); log_failure_reason(d); diff --git a/include/soc/qcom/boot_stats.h b/include/soc/qcom/boot_stats.h index 4d34eace03d4..ba8b8e7de981 100644 --- a/include/soc/qcom/boot_stats.h +++ b/include/soc/qcom/boot_stats.h @@ -6,6 +6,7 @@ #ifdef CONFIG_QGKI_MSM_BOOT_TIME_MARKER void place_marker(const char *name); +void update_marker(const char *name); void destroy_marker(const char *name); unsigned long long msm_timer_get_sclk_ticks(void); static inline int boot_marker_enabled(void) { return 1; } @@ -13,6 +14,7 @@ static inline int boot_marker_enabled(void) { return 1; } static inline int init_bootkpi(void) { return 0; } static inline void exit_bootkpi(void) { }; static inline void place_marker(char *name) { }; +static inline void update_marker(char *name) { }; static inline void destroy_marker(const char *name) { }; static inline int boot_marker_enabled(void) { return 0; } static inline unsigned long long msm_timer_get_sclk_ticks(void) { return -EINVAL; } From f4a90045e0debd718232768bfe33e2842af99d32 Mon Sep 17 00:00:00 2001 From: Krishna chaitanya chundru Date: Wed, 5 Jul 2023 14:48:10 +0530 Subject: [PATCH 4/5] bus: mhi: misc: Add check for dev_rp if it is iommu range or not er_ctxt->rp pointer is updated by MDM which is untrusted to HLOS, it could be arbitrary value. If there is security issue on MDM, and updated pointer which is not align then driver will never come out of loop where checking against dev_rp != rp. So added check to make sure it is in the buffer range & aligned to 128bit. Change-Id: Ib484e07f2c75fcd657a4ccc648a3a20de3edeebc Signed-off-by: Krishna chaitanya chundru --- drivers/bus/mhi/core/mhi_internal.h | 6 ++++++ drivers/bus/mhi/core/mhi_main.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index c02eee9886c7..ea2f5bfda1b5 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -809,6 +809,12 @@ static inline void mhi_trigger_resume(struct mhi_controller *mhi_cntrl) pm_wakeup_hard_event(&mhi_cntrl->mhi_dev->dev); } +static inline bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr) +{ + return ((addr >= ring->iommu_base && + addr < ring->iommu_base + ring->len) && (addr % 16 == 0)); +} + /* queue transfer buffer */ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, void *buf, void *cb, size_t buf_len, enum MHI_FLAGS flags); diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 0ddbbeec7b8d..532bbd6151a4 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -1403,6 +1403,12 @@ int mhi_process_tsync_ev_ring(struct mhi_controller *mhi_cntrl, int ret = 0; spin_lock_bh(&mhi_event->lock); + if (!is_valid_ring_ptr(ev_ring, er_ctxt->rp)) { + MHI_ERR("Event ring rp points outside of the event ring or unalign rp %llx\n", + er_ctxt->rp); + spin_unlock_bh(&mhi_event->lock); + return 0; + } dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); if (ev_ring->rp == dev_rp) { spin_unlock_bh(&mhi_event->lock); @@ -1496,8 +1502,14 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl, int ret = 0; spin_lock_bh(&mhi_event->lock); - dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); + if (!is_valid_ring_ptr(ev_ring, er_ctxt->rp)) { + MHI_ERR("Event ring rp points outside of the event ring or unalign rp %llx\n", + er_ctxt->rp); + spin_unlock_bh(&mhi_event->lock); + return 0; + } + dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); if (ev_ring->rp == dev_rp) { spin_unlock_bh(&mhi_event->lock); goto exit_bw_scale_process; From eaecb5470660c1a2ca5c970d2945bd448eaf672e Mon Sep 17 00:00:00 2001 From: Subramanian Ananthanarayanan Date: Tue, 25 Jul 2023 03:32:15 -0700 Subject: [PATCH 5/5] PCI: Configure RC MPS to 128 for Realtek 8168 attach Change is to configure QC RC MPS 128 bytes as 8168 device only supports 128 bytes. Without this quirk, since RC is using pcie_bus_perf flag MPS is configured to 256 bytes, when EP MRRS is changed to 4096 bytes RC is responding with packets of 256 bytes causing functionality break. Since pcie_bus_perf is used for many products, this change provies a provision to configure RC to 128 bytes for realtek 8168 attach alone. Change-Id: I4a82293e4f71bf188d4f0f2be8fa194c5ab007c2 Signed-off-by: Subramanian Ananthanarayanan --- drivers/pci/quirks.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f8f37f09ab4d..974a6be26fbd 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2415,6 +2415,20 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_pcie_aer_ext_cap); +/* + * Quirk to limit QCOM RC MPS to 128 in case of Realtek 8168 + * attaches. + */ +static void quirk_realtek_rc_mpss_limit(struct pci_dev *pdev) +{ + struct pci_dev *root_port = pcie_find_root_port(pdev); + + if (root_port->vendor == PCI_VENDOR_ID_QCOM) + pcie_set_mps(root_port, 128); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, 0x8168, + quirk_realtek_rc_mpss_limit); + static void quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) { /*