From: Greg Kroah-Hartman Date: Fri, 7 May 2021 12:52:23 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v5.4.118~109 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d9daad258709cfb6ea17d5b7df71931d1bdadb58;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: bus-mhi-core-clear-configuration-from-channel-context-during-reset.patch bus-mhi-core-fix-check-for-syserr-at-power_up.patch bus-mhi-core-sanity-check-values-from-remote-device-before-use.patch --- diff --git a/queue-5.10/bus-mhi-core-clear-configuration-from-channel-context-during-reset.patch b/queue-5.10/bus-mhi-core-clear-configuration-from-channel-context-during-reset.patch new file mode 100644 index 00000000000..333766f98f3 --- /dev/null +++ b/queue-5.10/bus-mhi-core-clear-configuration-from-channel-context-during-reset.patch @@ -0,0 +1,55 @@ +From 47705c08465931923e2f2b506986ca0bdf80380d Mon Sep 17 00:00:00 2001 +From: Bhaumik Bhatt +Date: Thu, 1 Apr 2021 14:16:15 -0700 +Subject: bus: mhi: core: Clear configuration from channel context during reset + +From: Bhaumik Bhatt + +commit 47705c08465931923e2f2b506986ca0bdf80380d upstream. + +When clearing up the channel context after client drivers are +done using channels, the configuration is currently not being +reset entirely. Ensure this is done to appropriately handle +issues where clients unaware of the context state end up calling +functions which expect a context. + +Signed-off-by: Bhaumik Bhatt +Reviewed-by: Hemant Kumar +Reviewed-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/1617311778-1254-7-git-send-email-bbhatt@codeaurora.org +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/core/init.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/bus/mhi/core/init.c ++++ b/drivers/bus/mhi/core/init.c +@@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con + struct mhi_ring *buf_ring; + struct mhi_ring *tre_ring; + struct mhi_chan_ctxt *chan_ctxt; ++ u32 tmp; + + buf_ring = &mhi_chan->buf_ring; + tre_ring = &mhi_chan->tre_ring; +@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con + vfree(buf_ring->base); + + buf_ring->base = tre_ring->base = NULL; ++ tre_ring->ctxt_wp = NULL; + chan_ctxt->rbase = 0; ++ chan_ctxt->rlen = 0; ++ chan_ctxt->rp = 0; ++ chan_ctxt->wp = 0; ++ ++ tmp = chan_ctxt->chcfg; ++ tmp &= ~CHAN_CTX_CHSTATE_MASK; ++ tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); ++ chan_ctxt->chcfg = tmp; ++ ++ /* Update to all cores */ ++ smp_wmb(); + } + + int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, diff --git a/queue-5.10/bus-mhi-core-fix-check-for-syserr-at-power_up.patch b/queue-5.10/bus-mhi-core-fix-check-for-syserr-at-power_up.patch new file mode 100644 index 00000000000..c0f7ec41be0 --- /dev/null +++ b/queue-5.10/bus-mhi-core-fix-check-for-syserr-at-power_up.patch @@ -0,0 +1,37 @@ +From 6403298c58d4858d93648f553abf0bcbd2dfaca2 Mon Sep 17 00:00:00 2001 +From: Jeffrey Hugo +Date: Fri, 12 Feb 2021 14:27:23 -0700 +Subject: bus: mhi: core: Fix check for syserr at power_up + +From: Jeffrey Hugo + +commit 6403298c58d4858d93648f553abf0bcbd2dfaca2 upstream. + +The check to see if we have reset the device after detecting syserr at +power_up is inverted. wait_for_event_timeout() returns 0 on failure, +and a positive value on success. The check is looking for non-zero +as a failure, which is likely to incorrectly cause a device init failure +if syserr was detected at power_up. Fix this. + +Fixes: e18d4e9fa79b ("bus: mhi: core: Handle syserr during power_up") +Signed-off-by: Jeffrey Hugo +Reviewed-by: Loic Poulain +Reviewed-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/1613165243-23359-1-git-send-email-jhugo@codeaurora.org +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/core/pm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/bus/mhi/core/pm.c ++++ b/drivers/bus/mhi/core/pm.c +@@ -992,7 +992,7 @@ int mhi_async_power_up(struct mhi_contro + &val) || + !val, + msecs_to_jiffies(mhi_cntrl->timeout_ms)); +- if (ret) { ++ if (!ret) { + ret = -EIO; + dev_info(dev, "Failed to reset MHI due to syserr state\n"); + goto error_bhi_offset; diff --git a/queue-5.10/bus-mhi-core-sanity-check-values-from-remote-device-before-use.patch b/queue-5.10/bus-mhi-core-sanity-check-values-from-remote-device-before-use.patch new file mode 100644 index 00000000000..aeeaa65bc4e --- /dev/null +++ b/queue-5.10/bus-mhi-core-sanity-check-values-from-remote-device-before-use.patch @@ -0,0 +1,209 @@ +From ec32332df7645e0ba463a08d483fe97665167071 Mon Sep 17 00:00:00 2001 +From: Jeffrey Hugo +Date: Wed, 10 Mar 2021 14:30:55 -0700 +Subject: bus: mhi: core: Sanity check values from remote device before use + +From: Jeffrey Hugo + +commit ec32332df7645e0ba463a08d483fe97665167071 upstream. + +When parsing the structures in the shared memory, there are values which +come from the remote device. For example, a transfer completion event +will have a pointer to the tre in the relevant channel's transfer ring. +As another example, event ring elements may specify a channel in which +the event occurred, however the specified channel value may not be valid +as no channel is defined at that index even though the index may be less +than the maximum allowed index. Such values should be considered to be +untrusted, and validated before use. If we blindly use such values, we +may access invalid data or crash if the values are corrupted. + +If validation fails, drop the relevant event. + +Signed-off-by: Jeffrey Hugo +Reviewed-by: Manivannan Sadhasivam +Reviewed-by: Hemant Kumar +Link: https://lore.kernel.org/r/1615411855-15053-1-git-send-email-jhugo@codeaurora.org +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/core/main.c | 81 ++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 74 insertions(+), 7 deletions(-) + +--- a/drivers/bus/mhi/core/main.c ++++ b/drivers/bus/mhi/core/main.c +@@ -220,6 +220,11 @@ static void mhi_del_ring_element(struct + smp_wmb(); + } + ++static bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr) ++{ ++ return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len; ++} ++ + int mhi_destroy_device(struct device *dev, void *data) + { + struct mhi_device *mhi_dev; +@@ -349,7 +354,16 @@ irqreturn_t mhi_irq_handler(int irq_numb + struct mhi_event_ctxt *er_ctxt = + &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; + struct mhi_ring *ev_ring = &mhi_event->ring; +- void *dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); ++ dma_addr_t ptr = er_ctxt->rp; ++ void *dev_rp; ++ ++ if (!is_valid_ring_ptr(ev_ring, ptr)) { ++ dev_err(&mhi_cntrl->mhi_dev->dev, ++ "Event ring rp points outside of the event ring\n"); ++ return IRQ_HANDLED; ++ } ++ ++ dev_rp = mhi_to_virtual(ev_ring, ptr); + + /* Only proceed if event ring has pending events */ + if (ev_ring->rp == dev_rp) +@@ -498,6 +512,11 @@ static int parse_xfer_event(struct mhi_c + struct mhi_buf_info *buf_info; + u16 xfer_len; + ++ if (!is_valid_ring_ptr(tre_ring, ptr)) { ++ dev_err(&mhi_cntrl->mhi_dev->dev, ++ "Event element points outside of the tre ring\n"); ++ break; ++ } + /* Get the TRB this event points to */ + ev_tre = mhi_to_virtual(tre_ring, ptr); + +@@ -657,6 +676,12 @@ static void mhi_process_cmd_completion(s + struct mhi_chan *mhi_chan; + u32 chan; + ++ if (!is_valid_ring_ptr(mhi_ring, ptr)) { ++ dev_err(&mhi_cntrl->mhi_dev->dev, ++ "Event element points outside of the cmd ring\n"); ++ return; ++ } ++ + cmd_pkt = mhi_to_virtual(mhi_ring, ptr); + + chan = MHI_TRE_GET_CMD_CHID(cmd_pkt); +@@ -681,6 +706,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + u32 chan; + int count = 0; ++ dma_addr_t ptr = er_ctxt->rp; + + /* + * This is a quick check to avoid unnecessary event processing +@@ -690,7 +716,13 @@ int mhi_process_ctrl_ev_ring(struct mhi_ + if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) + return -EIO; + +- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); ++ if (!is_valid_ring_ptr(ev_ring, ptr)) { ++ dev_err(&mhi_cntrl->mhi_dev->dev, ++ "Event ring rp points outside of the event ring\n"); ++ return -EIO; ++ } ++ ++ dev_rp = mhi_to_virtual(ev_ring, ptr); + local_rp = ev_ring->rp; + + while (dev_rp != local_rp) { +@@ -801,6 +833,8 @@ int mhi_process_ctrl_ev_ring(struct mhi_ + */ + if (chan < mhi_cntrl->max_chan) { + mhi_chan = &mhi_cntrl->mhi_chan[chan]; ++ if (!mhi_chan->configured) ++ break; + parse_xfer_event(mhi_cntrl, local_rp, mhi_chan); + event_quota--; + } +@@ -812,7 +846,15 @@ int mhi_process_ctrl_ev_ring(struct mhi_ + + mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); + local_rp = ev_ring->rp; +- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); ++ ++ ptr = er_ctxt->rp; ++ if (!is_valid_ring_ptr(ev_ring, ptr)) { ++ dev_err(&mhi_cntrl->mhi_dev->dev, ++ "Event ring rp points outside of the event ring\n"); ++ return -EIO; ++ } ++ ++ dev_rp = mhi_to_virtual(ev_ring, ptr); + count++; + } + +@@ -835,11 +877,18 @@ int mhi_process_data_event_ring(struct m + int count = 0; + u32 chan; + struct mhi_chan *mhi_chan; ++ dma_addr_t ptr = er_ctxt->rp; + + if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) + return -EIO; + +- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); ++ if (!is_valid_ring_ptr(ev_ring, ptr)) { ++ dev_err(&mhi_cntrl->mhi_dev->dev, ++ "Event ring rp points outside of the event ring\n"); ++ return -EIO; ++ } ++ ++ dev_rp = mhi_to_virtual(ev_ring, ptr); + local_rp = ev_ring->rp; + + while (dev_rp != local_rp && event_quota > 0) { +@@ -853,7 +902,8 @@ int mhi_process_data_event_ring(struct m + * Only process the event ring elements whose channel + * ID is within the maximum supported range. + */ +- if (chan < mhi_cntrl->max_chan) { ++ if (chan < mhi_cntrl->max_chan && ++ mhi_cntrl->mhi_chan[chan].configured) { + mhi_chan = &mhi_cntrl->mhi_chan[chan]; + + if (likely(type == MHI_PKT_TYPE_TX_EVENT)) { +@@ -867,7 +917,15 @@ int mhi_process_data_event_ring(struct m + + mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); + local_rp = ev_ring->rp; +- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); ++ ++ ptr = er_ctxt->rp; ++ if (!is_valid_ring_ptr(ev_ring, ptr)) { ++ dev_err(&mhi_cntrl->mhi_dev->dev, ++ "Event ring rp points outside of the event ring\n"); ++ return -EIO; ++ } ++ ++ dev_rp = mhi_to_virtual(ev_ring, ptr); + count++; + } + read_lock_bh(&mhi_cntrl->pm_lock); +@@ -1394,6 +1452,7 @@ static void mhi_mark_stale_events(struct + struct mhi_ring *ev_ring; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + unsigned long flags; ++ dma_addr_t ptr; + + dev_dbg(dev, "Marking all events for chan: %d as stale\n", chan); + +@@ -1401,7 +1460,15 @@ static void mhi_mark_stale_events(struct + + /* mark all stale events related to channel as STALE event */ + spin_lock_irqsave(&mhi_event->lock, flags); +- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); ++ ++ ptr = er_ctxt->rp; ++ if (!is_valid_ring_ptr(ev_ring, ptr)) { ++ dev_err(&mhi_cntrl->mhi_dev->dev, ++ "Event ring rp points outside of the event ring\n"); ++ dev_rp = ev_ring->rp; ++ } else { ++ dev_rp = mhi_to_virtual(ev_ring, ptr); ++ } + + local_rp = ev_ring->rp; + while (dev_rp != local_rp) { diff --git a/queue-5.10/series b/queue-5.10/series new file mode 100644 index 00000000000..90d6c62acbe --- /dev/null +++ b/queue-5.10/series @@ -0,0 +1,3 @@ +bus-mhi-core-fix-check-for-syserr-at-power_up.patch +bus-mhi-core-clear-configuration-from-channel-context-during-reset.patch +bus-mhi-core-sanity-check-values-from-remote-device-before-use.patch diff --git a/queue-5.11/series b/queue-5.11/series new file mode 100644 index 00000000000..7517ba9519e --- /dev/null +++ b/queue-5.11/series @@ -0,0 +1,5 @@ +bus-mhi-core-fix-check-for-syserr-at-power_up.patch +bus-mhi-core-clear-configuration-from-channel-context-during-reset.patch +bus-mhi-core-sanity-check-values-from-remote-device-before-use.patch +bus-mhi-core-add-missing-checks-for-mmio-register-entries.patch +bus-mhi-pci_generic-remove-wq_mem_reclaim-flag-from-state-workqueue.patch diff --git a/queue-5.12/series b/queue-5.12/series new file mode 100644 index 00000000000..88d1aee5b62 --- /dev/null +++ b/queue-5.12/series @@ -0,0 +1,7 @@ +bus-mhi-core-fix-check-for-syserr-at-power_up.patch +bus-mhi-core-clear-configuration-from-channel-context-during-reset.patch +bus-mhi-core-sanity-check-values-from-remote-device-before-use.patch +bus-mhi-core-add-missing-checks-for-mmio-register-entries.patch +bus-mhi-pci_generic-remove-wq_mem_reclaim-flag-from-state-workqueue.patch +bus-mhi-core-fix-mhi-runtime_pm-behavior.patch +bus-mhi-core-fix-invalid-error-returning-in-mhi_queue.patch diff --git a/queue-5.4/series b/queue-5.4/series new file mode 100644 index 00000000000..e69de29bb2d