--- /dev/null
+From e54a4424925a27ed94dff046db3ce5caf4b1e748 Mon Sep 17 00:00:00 2001
+From: Brian Norris <briannorris@chromium.org>
+Date: Mon, 28 Feb 2022 12:25:32 -0800
+Subject: drm/atomic: Force bridge self-refresh-exit on CRTC switch
+
+From: Brian Norris <briannorris@chromium.org>
+
+commit e54a4424925a27ed94dff046db3ce5caf4b1e748 upstream.
+
+It's possible to change which CRTC is in use for a given
+connector/encoder/bridge while we're in self-refresh without fully
+disabling the connector/encoder/bridge along the way. This can confuse
+the bridge encoder/bridge, because
+(a) it needs to track the SR state (trying to perform "active"
+ operations while the panel is still in SR can be Bad(TM)); and
+(b) it tracks the SR state via the CRTC state (and after the switch, the
+ previous SR state is lost).
+
+Thus, we need to either somehow carry the self-refresh state over to the
+new CRTC, or else force an encoder/bridge self-refresh transition during
+such a switch.
+
+I choose the latter, so we disable the encoder (and exit PSR) before
+attaching it to the new CRTC (where we can continue to assume a clean
+(non-self-refresh) state).
+
+This fixes PSR issues seen on Rockchip RK3399 systems with
+drivers/gpu/drm/bridge/analogix/analogix_dp_core.c.
+
+Change in v2:
+
+- Drop "->enable" condition; this could possibly be "->active" to
+ reflect the intended hardware state, but it also is a little
+ over-specific. We want to make a transition through "disabled" any
+ time we're exiting PSR at the same time as a CRTC switch.
+ (Thanks Liu Ying)
+
+Cc: Liu Ying <victor.liu@oss.nxp.com>
+Cc: <stable@vger.kernel.org>
+Fixes: 1452c25b0e60 ("drm: Add helpers to kick off self refresh mode in drivers")
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Reviewed-by: Sean Paul <seanpaul@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220228122522.v2.2.Ic15a2ef69c540aee8732703103e2cff51fb9c399@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/drm_atomic_helper.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/drm_atomic_helper.c
++++ b/drivers/gpu/drm/drm_atomic_helper.c
+@@ -996,9 +996,19 @@ crtc_needs_disable(struct drm_crtc_state
+ return drm_atomic_crtc_effectively_active(old_state);
+
+ /*
+- * We need to run through the crtc_funcs->disable() function if the CRTC
+- * is currently on, if it's transitioning to self refresh mode, or if
+- * it's in self refresh mode and needs to be fully disabled.
++ * We need to disable bridge(s) and CRTC if we're transitioning out of
++ * self-refresh and changing CRTCs at the same time, because the
++ * bridge tracks self-refresh status via CRTC state.
++ */
++ if (old_state->self_refresh_active &&
++ old_state->crtc != new_state->crtc)
++ return true;
++
++ /*
++ * We also need to run through the crtc_funcs->disable() function if
++ * the CRTC is currently on, if it's transitioning to self refresh
++ * mode, or if it's in self refresh mode and needs to be fully
++ * disabled.
+ */
+ return old_state->active ||
+ (old_state->self_refresh_active && !new_state->enable) ||
--- /dev/null
+From ca871659ec1606d33b1e76de8d4cf924cf627e34 Mon Sep 17 00:00:00 2001
+From: Brian Norris <briannorris@chromium.org>
+Date: Mon, 28 Feb 2022 12:25:31 -0800
+Subject: drm/bridge: analogix_dp: Support PSR-exit to disable transition
+
+From: Brian Norris <briannorris@chromium.org>
+
+commit ca871659ec1606d33b1e76de8d4cf924cf627e34 upstream.
+
+Most eDP panel functions only work correctly when the panel is not in
+self-refresh. In particular, analogix_dp_bridge_disable() tends to hit
+AUX channel errors if the panel is in self-refresh.
+
+Given the above, it appears that so far, this driver assumes that we are
+never in self-refresh when it comes time to fully disable the bridge.
+Prior to commit 846c7dfc1193 ("drm/atomic: Try to preserve the crtc
+enabled state in drm_atomic_remove_fb, v2."), this tended to be true,
+because we would automatically disable the pipe when framebuffers were
+removed, and so we'd typically disable the bridge shortly after the last
+display activity.
+
+However, that is not guaranteed: an idle (self-refresh) display pipe may
+be disabled, e.g., when switching CRTCs. We need to exit PSR first.
+
+Stable notes: this is definitely a bugfix, and the bug has likely
+existed in some form for quite a while. It may predate the "PSR helpers"
+refactor, but the code looked very different before that, and it's
+probably not worth rewriting the fix.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 6c836d965bad ("drm/rockchip: Use the helpers for PSR")
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Reviewed-by: Sean Paul <seanpaul@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220228122522.v2.1.I161904be17ba14526f78536ccd78b85818449b51@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 42 +++++++++++++++++++--
+ 1 file changed, 38 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+@@ -1269,6 +1269,25 @@ static int analogix_dp_bridge_attach(str
+ }
+
+ static
++struct drm_crtc *analogix_dp_get_old_crtc(struct analogix_dp_device *dp,
++ struct drm_atomic_state *state)
++{
++ struct drm_encoder *encoder = dp->encoder;
++ struct drm_connector *connector;
++ struct drm_connector_state *conn_state;
++
++ connector = drm_atomic_get_old_connector_for_encoder(state, encoder);
++ if (!connector)
++ return NULL;
++
++ conn_state = drm_atomic_get_old_connector_state(state, connector);
++ if (!conn_state)
++ return NULL;
++
++ return conn_state->crtc;
++}
++
++static
+ struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp,
+ struct drm_atomic_state *state)
+ {
+@@ -1448,14 +1467,16 @@ analogix_dp_bridge_atomic_disable(struct
+ {
+ struct drm_atomic_state *old_state = old_bridge_state->base.state;
+ struct analogix_dp_device *dp = bridge->driver_private;
+- struct drm_crtc *crtc;
++ struct drm_crtc *old_crtc, *new_crtc;
++ struct drm_crtc_state *old_crtc_state = NULL;
+ struct drm_crtc_state *new_crtc_state = NULL;
++ int ret;
+
+- crtc = analogix_dp_get_new_crtc(dp, old_state);
+- if (!crtc)
++ new_crtc = analogix_dp_get_new_crtc(dp, old_state);
++ if (!new_crtc)
+ goto out;
+
+- new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc);
++ new_crtc_state = drm_atomic_get_new_crtc_state(old_state, new_crtc);
+ if (!new_crtc_state)
+ goto out;
+
+@@ -1464,6 +1485,19 @@ analogix_dp_bridge_atomic_disable(struct
+ return;
+
+ out:
++ old_crtc = analogix_dp_get_old_crtc(dp, old_state);
++ if (old_crtc) {
++ old_crtc_state = drm_atomic_get_old_crtc_state(old_state,
++ old_crtc);
++
++ /* When moving from PSR to fully disabled, exit PSR first. */
++ if (old_crtc_state && old_crtc_state->self_refresh_active) {
++ ret = analogix_dp_disable_psr(dp);
++ if (ret)
++ DRM_ERROR("Failed to disable psr (%d)\n", ret);
++ }
++ }
++
+ analogix_dp_bridge_disable(bridge);
+ }
+
--- /dev/null
+From c42e65664390be7c1ef3838cd84956d3a2739d60 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Tue, 7 Jun 2022 12:11:33 -0700
+Subject: Input: bcm5974 - set missing URB_NO_TRANSFER_DMA_MAP urb flag
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit c42e65664390be7c1ef3838cd84956d3a2739d60 upstream.
+
+The bcm5974 driver does the allocation and dma mapping of the usb urb
+data buffer, but driver does not set the URB_NO_TRANSFER_DMA_MAP flag
+to let usb core know the buffer is already mapped.
+
+usb core tries to map the already mapped buffer, causing a warning:
+"xhci_hcd 0000:00:14.0: rejecting DMA map of vmalloc memory"
+
+Fix this by setting the URB_NO_TRANSFER_DMA_MAP, letting usb core
+know buffer is already mapped by bcm5974 driver
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Cc: stable@vger.kernel.org
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=215890
+Link: https://lore.kernel.org/r/20220606113636.588955-1-mathias.nyman@linux.intel.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/input/mouse/bcm5974.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/input/mouse/bcm5974.c
++++ b/drivers/input/mouse/bcm5974.c
+@@ -942,17 +942,22 @@ static int bcm5974_probe(struct usb_inte
+ if (!dev->tp_data)
+ goto err_free_bt_buffer;
+
+- if (dev->bt_urb)
++ if (dev->bt_urb) {
+ usb_fill_int_urb(dev->bt_urb, udev,
+ usb_rcvintpipe(udev, cfg->bt_ep),
+ dev->bt_data, dev->cfg.bt_datalen,
+ bcm5974_irq_button, dev, 1);
+
++ dev->bt_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++ }
++
+ usb_fill_int_urb(dev->tp_urb, udev,
+ usb_rcvintpipe(udev, cfg->tp_ep),
+ dev->tp_data, dev->cfg.tp_datalen,
+ bcm5974_irq_trackpad, dev, 1);
+
++ dev->tp_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++
+ /* create bcm5974 device */
+ usb_make_path(udev, dev->phys, sizeof(dev->phys));
+ strlcat(dev->phys, "/input0", sizeof(dev->phys));
--- /dev/null
+From foo@baz Mon Jun 13 10:02:03 AM CEST 2022
+From: Alex Elder <elder@linaro.org>
+Date: Wed, 8 Jun 2022 15:54:14 -0500
+Subject: interconnect: qcom: sc7180: Drop IP0 interconnects
+To: stable@vger.kernel.org
+Cc: Stephen Boyd <swboyd@chromium.org>, elder@linaro.org, dianders@chromium.org, bjorn.andersson@linaro.org, djakov@kernel.org, quic_mdtipton@quicinc.com, quic_tdas@quicinc.com
+Message-ID: <20220608205415.185248-2-elder@linaro.org>
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+commit 2f3724930eb4bba74f7d10bc3bef5bb22dd323df upstream.
+
+The IPA BCM resource ("IP0") on sc7180 was moved to the clk-rpmh driver
+in commit bcd63d222b60 ("clk: qcom: rpmh: Add IPA clock for SC7180") and
+modeled as a clk, but this interconnect driver still had it modeled as
+an interconnect. This was mostly OK because nobody used the interconnect
+definition, until the interconnect framework started dropping bandwidth
+requests on interconnects that aren't used via the sync_state callback
+in commit 7d3b0b0d8184 ("interconnect: qcom: Use icc_sync_state"). Once
+that patch was applied the IP0 resource was going to be controlled from
+two places, the clk framework and the interconnect framework.
+
+Even then, things were probably going to be OK, because commit
+b95b668eaaa2 ("interconnect: qcom: icc-rpmh: Add BCMs to commit list in
+pre_aggregate") was needed to actually drop bandwidth requests on unused
+interconnects, of which the IPA was one of the interconnect that wasn't
+getting dropped to zero. Combining the three commits together leads to
+bad behavior where the interconnect framework is disabling the IP0
+resource because it has no users while the clk framework thinks the IP0
+resource is on because the only user, the IPA driver, has turned it on
+via clk_prepare_enable(). Depending on when sync_state is called, we can
+get into a situation like below:
+
+ IPA driver probes
+ IPA driver gets notified modem started
+ runtime PM get()
+ IPA clk enabled -> IP0 resource is ON
+ sync_state runs
+ interconnect zeroes out the IP0 resource -> IP0 resource is off
+ IPA driver tries to access a register and blows up
+
+The crash is an unclocked access that manifest as an SError.
+
+ SError Interrupt on CPU0, code 0xbe000011 -- SError
+ CPU: 0 PID: 3595 Comm: mmdata_mgr Not tainted 5.17.1+ #166
+ Hardware name: Google Lazor (rev1 - 2) with LTE (DT)
+ pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : mutex_lock+0x4c/0x80
+ lr : mutex_lock+0x30/0x80
+ sp : ffffffc00da9b9c0
+ x29: ffffffc00da9b9c0 x28: 0000000000000000 x27: 0000000000000000
+ x26: ffffffc00da9bc90 x25: ffffff80c2024010 x24: ffffff80c2024000
+ x23: ffffff8083100000 x22: ffffff80831000d0 x21: ffffff80831000a8
+ x20: ffffff80831000a8 x19: ffffff8083100070 x18: 00000000ffff0a00
+ x17: 000000002f7254f1 x16: 0000000000000100 x15: 0000000000000000
+ x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
+ x11: 000000000001f0b8 x10: ffffffc00931f0b8 x9 : 0000000000000000
+ x8 : 0000000000000000 x7 : fefefefefeff2f60 x6 : 0000808080808080
+ x5 : 0000000000000000 x4 : 8080808080800000 x3 : ffffff80d2d4ee28
+ x2 : ffffff808c1d6e40 x1 : 0000000000000000 x0 : ffffff8083100070
+ Kernel panic - not syncing: Asynchronous SError Interrupt
+ CPU: 0 PID: 3595 Comm: mmdata_mgr Not tainted 5.17.1+ #166
+ Hardware name: Google Lazor (rev1 - 2) with LTE (DT)
+ Call trace:
+ dump_backtrace+0xf4/0x114
+ show_stack+0x24/0x30
+ dump_stack_lvl+0x64/0x7c
+ dump_stack+0x18/0x38
+ panic+0x150/0x38c
+ nmi_panic+0x88/0xa0
+ arm64_serror_panic+0x74/0x80
+ do_serror+0x0/0x80
+ do_serror+0x58/0x80
+ el1h_64_error_handler+0x34/0x4c
+ el1h_64_error+0x78/0x7c
+ mutex_lock+0x4c/0x80
+ __gsi_channel_start+0x50/0x17c
+ gsi_channel_start+0x54/0x90
+ ipa_endpoint_enable_one+0x34/0xc0
+ ipa_open+0x4c/0x120
+
+Remove all IP0 resource management from the interconnect driver so that
+clk-rpmh is the sole owner. This fixes the issue by preventing the
+interconnect driver from overwriting the IP0 resource data that the
+clk-rpmh driver wrote.
+
+Cc: Alex Elder <elder@linaro.org>
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: Taniya Das <quic_tdas@quicinc.com>
+Cc: Mike Tipton <quic_mdtipton@quicinc.com>
+Cc: <stable@vger.kernel.org> # 5.10.x
+Fixes: b95b668eaaa2 ("interconnect: qcom: icc-rpmh: Add BCMs to commit list in pre_aggregate")
+Fixes: bcd63d222b60 ("clk: qcom: rpmh: Add IPA clock for SC7180")
+Fixes: 7d3b0b0d8184 ("interconnect: qcom: Use icc_sync_state")
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Tested-by: Alex Elder <elder@linaro.org>
+Reviewed-by: Alex Elder <elder@linaro.org>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220412220033.1273607-2-swboyd@chromium.org
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Alex Elder <elder@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/interconnect/qcom/sc7180.c | 21 ---------------------
+ 1 file changed, 21 deletions(-)
+
+--- a/drivers/interconnect/qcom/sc7180.c
++++ b/drivers/interconnect/qcom/sc7180.c
+@@ -47,7 +47,6 @@ DEFINE_QNODE(qnm_mnoc_sf, SC7180_MASTER_
+ DEFINE_QNODE(qnm_snoc_gc, SC7180_MASTER_SNOC_GC_MEM_NOC, 1, 8, SC7180_SLAVE_LLCC);
+ DEFINE_QNODE(qnm_snoc_sf, SC7180_MASTER_SNOC_SF_MEM_NOC, 1, 16, SC7180_SLAVE_LLCC);
+ DEFINE_QNODE(qxm_gpu, SC7180_MASTER_GFX3D, 2, 32, SC7180_SLAVE_GEM_NOC_SNOC, SC7180_SLAVE_LLCC);
+-DEFINE_QNODE(ipa_core_master, SC7180_MASTER_IPA_CORE, 1, 8, SC7180_SLAVE_IPA_CORE);
+ DEFINE_QNODE(llcc_mc, SC7180_MASTER_LLCC, 2, 4, SC7180_SLAVE_EBI1);
+ DEFINE_QNODE(qhm_mnoc_cfg, SC7180_MASTER_CNOC_MNOC_CFG, 1, 4, SC7180_SLAVE_SERVICE_MNOC);
+ DEFINE_QNODE(qxm_camnoc_hf0, SC7180_MASTER_CAMNOC_HF0, 2, 32, SC7180_SLAVE_MNOC_HF_MEM_NOC);
+@@ -129,7 +128,6 @@ DEFINE_QNODE(qhs_mdsp_ms_mpu_cfg, SC7180
+ DEFINE_QNODE(qns_gem_noc_snoc, SC7180_SLAVE_GEM_NOC_SNOC, 1, 8, SC7180_MASTER_GEM_NOC_SNOC);
+ DEFINE_QNODE(qns_llcc, SC7180_SLAVE_LLCC, 1, 16, SC7180_MASTER_LLCC);
+ DEFINE_QNODE(srvc_gemnoc, SC7180_SLAVE_SERVICE_GEM_NOC, 1, 4);
+-DEFINE_QNODE(ipa_core_slave, SC7180_SLAVE_IPA_CORE, 1, 8);
+ DEFINE_QNODE(ebi, SC7180_SLAVE_EBI1, 2, 4);
+ DEFINE_QNODE(qns_mem_noc_hf, SC7180_SLAVE_MNOC_HF_MEM_NOC, 1, 32, SC7180_MASTER_MNOC_HF_MEM_NOC);
+ DEFINE_QNODE(qns_mem_noc_sf, SC7180_SLAVE_MNOC_SF_MEM_NOC, 1, 32, SC7180_MASTER_MNOC_SF_MEM_NOC);
+@@ -160,7 +158,6 @@ DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi);
+ DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc);
+ DEFINE_QBCM(bcm_mm0, "MM0", false, &qns_mem_noc_hf);
+ DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto);
+-DEFINE_QBCM(bcm_ip0, "IP0", false, &ipa_core_slave);
+ DEFINE_QBCM(bcm_cn0, "CN0", true, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_ahb2phy0, &qhs_aop, &qhs_aoss, &qhs_boot_rom, &qhs_camera_cfg, &qhs_camera_nrt_throttle_cfg, &qhs_camera_rt_throttle_cfg, &qhs_clk_ctl, &qhs_cpr_cx, &qhs_cpr_mx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_display_rt_throttle_cfg, &qhs_display_throttle_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_mss_cfg, &qhs_npu_cfg, &qhs_npu_dma_throttle_cfg, &qhs_npu_dsp_throttle_cfg, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qm_cfg, &qhs_qm_mpu_cfg, &qhs_qup0, &qhs_qup1, &qhs_security, &qhs_snoc_cfg, &qhs_tcsr, &qhs_tlmm_1, &qhs_tlmm_2, &qhs_tlmm_3, &qhs_ufs_mem_cfg, &qhs_usb3, &qhs_venus_cfg, &qhs_venus_throttle_cfg, &qhs_vsense_ctrl_cfg, &srvc_cnoc);
+ DEFINE_QBCM(bcm_mm1, "MM1", false, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qhm_mnoc_cfg, &qxm_mdp0, &qxm_rot, &qxm_venus0, &qxm_venus_arm9);
+ DEFINE_QBCM(bcm_sh2, "SH2", false, &acm_sys_tcu);
+@@ -372,22 +369,6 @@ static struct qcom_icc_desc sc7180_gem_n
+ .num_bcms = ARRAY_SIZE(gem_noc_bcms),
+ };
+
+-static struct qcom_icc_bcm *ipa_virt_bcms[] = {
+- &bcm_ip0,
+-};
+-
+-static struct qcom_icc_node *ipa_virt_nodes[] = {
+- [MASTER_IPA_CORE] = &ipa_core_master,
+- [SLAVE_IPA_CORE] = &ipa_core_slave,
+-};
+-
+-static struct qcom_icc_desc sc7180_ipa_virt = {
+- .nodes = ipa_virt_nodes,
+- .num_nodes = ARRAY_SIZE(ipa_virt_nodes),
+- .bcms = ipa_virt_bcms,
+- .num_bcms = ARRAY_SIZE(ipa_virt_bcms),
+-};
+-
+ static struct qcom_icc_bcm *mc_virt_bcms[] = {
+ &bcm_acv,
+ &bcm_mc0,
+@@ -611,8 +592,6 @@ static const struct of_device_id qnoc_of
+ .data = &sc7180_dc_noc},
+ { .compatible = "qcom,sc7180-gem-noc",
+ .data = &sc7180_gem_noc},
+- { .compatible = "qcom,sc7180-ipa-virt",
+- .data = &sc7180_ipa_virt},
+ { .compatible = "qcom,sc7180-mc-virt",
+ .data = &sc7180_mc_virt},
+ { .compatible = "qcom,sc7180-mmss-noc",
--- /dev/null
+From foo@baz Mon Jun 13 10:02:03 AM CEST 2022
+From: Alex Elder <elder@linaro.org>
+Date: Wed, 8 Jun 2022 15:54:15 -0500
+Subject: interconnect: Restore sync state by ignoring ipa-virt in provider count
+To: stable@vger.kernel.org
+Cc: Stephen Boyd <swboyd@chromium.org>, elder@linaro.org, dianders@chromium.org, bjorn.andersson@linaro.org, djakov@kernel.org, quic_mdtipton@quicinc.com, quic_tdas@quicinc.com
+Message-ID: <20220608205415.185248-3-elder@linaro.org>
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+commit 20ce30fb4750f2ffc130cdcb26232b1dd87cd0a5 upstream.
+
+Ignore compatible strings for the IPA virt drivers that were removed in
+commits 2fb251c26560 ("interconnect: qcom: sdx55: Drop IP0
+interconnects") and 2f3724930eb4 ("interconnect: qcom: sc7180: Drop IP0
+interconnects") so that the sync state logic can kick in again.
+Otherwise all the interconnects in the system will stay pegged at max
+speeds because 'providers_count' is always going to be one larger than
+the number of drivers that will ever probe on sc7180 or sdx55. This
+fixes suspend on sc7180 and sdx55 devices when you don't have a
+devicetree patch to remove the ipa-virt compatible node.
+
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: Doug Anderson <dianders@chromium.org>
+Cc: Alex Elder <elder@linaro.org>
+Cc: Taniya Das <quic_tdas@quicinc.com>
+Cc: Mike Tipton <quic_mdtipton@quicinc.com>
+Cc: <stable@vger.kernel.org> # 5.10.x
+Fixes: 2fb251c26560 ("interconnect: qcom: sdx55: Drop IP0 interconnects")
+Fixes: 2f3724930eb4 ("interconnect: qcom: sc7180: Drop IP0 interconnects")
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Alex Elder <elder@linaro.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20220427013226.341209-1-swboyd@chromium.org
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Alex Elder <elder@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/interconnect/core.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/interconnect/core.c
++++ b/drivers/interconnect/core.c
+@@ -1084,9 +1084,14 @@ static int of_count_icc_providers(struct
+ {
+ struct device_node *child;
+ int count = 0;
++ const struct of_device_id __maybe_unused ignore_list[] = {
++ { .compatible = "qcom,sc7180-ipa-virt" },
++ {}
++ };
+
+ for_each_available_child_of_node(np, child) {
+- if (of_property_read_bool(child, "#interconnect-cells"))
++ if (of_property_read_bool(child, "#interconnect-cells") &&
++ likely(!of_match_node(ignore_list, child)))
+ count++;
+ count += of_count_icc_providers(child);
+ }
--- /dev/null
+From 803e9895ea2b0fe80bc85980ae2d7a7e44037914 Mon Sep 17 00:00:00 2001
+From: Olivier Matz <olivier.matz@6wind.com>
+Date: Wed, 6 Apr 2022 11:52:51 +0200
+Subject: ixgbe: fix bcast packets Rx on VF after promisc removal
+
+From: Olivier Matz <olivier.matz@6wind.com>
+
+commit 803e9895ea2b0fe80bc85980ae2d7a7e44037914 upstream.
+
+After a VF requested to remove the promiscuous flag on an interface, the
+broadcast packets are not received anymore. This breaks some protocols
+like ARP.
+
+In ixgbe_update_vf_xcast_mode(), we should keep the IXGBE_VMOLR_BAM
+bit (Broadcast Accept) on promiscuous removal.
+
+This flag is already set by default in ixgbe_set_vmolr() on VF reset.
+
+Fixes: 8443c1a4b192 ("ixgbe, ixgbevf: Add new mbox API xcast mode")
+Cc: stable@vger.kernel.org
+Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+@@ -1157,9 +1157,9 @@ static int ixgbe_update_vf_xcast_mode(st
+
+ switch (xcast_mode) {
+ case IXGBEVF_XCAST_MODE_NONE:
+- disable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE |
++ disable = IXGBE_VMOLR_ROMPE |
+ IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
+- enable = 0;
++ enable = IXGBE_VMOLR_BAM;
+ break;
+ case IXGBEVF_XCAST_MODE_MULTI:
+ disable = IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
--- /dev/null
+From 7bb0fb7c63df95d6027dc50d6af3bc3bbbc25483 Mon Sep 17 00:00:00 2001
+From: Olivier Matz <olivier.matz@6wind.com>
+Date: Wed, 6 Apr 2022 11:52:52 +0200
+Subject: ixgbe: fix unexpected VLAN Rx in promisc mode on VF
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Olivier Matz <olivier.matz@6wind.com>
+
+commit 7bb0fb7c63df95d6027dc50d6af3bc3bbbc25483 upstream.
+
+When the promiscuous mode is enabled on a VF, the IXGBE_VMOLR_VPE
+bit (VLAN Promiscuous Enable) is set. This means that the VF will
+receive packets whose VLAN is not the same than the VLAN of the VF.
+
+For instance, in this situation:
+
+┌────────┐ ┌────────┐ ┌────────┐
+│ │ │ │ │ │
+│ │ │ │ │ │
+│ VF0├────┤VF1 VF2├────┤VF3 │
+│ │ │ │ │ │
+└────────┘ └────────┘ └────────┘
+ VM1 VM2 VM3
+
+vf 0: vlan 1000
+vf 1: vlan 1000
+vf 2: vlan 1001
+vf 3: vlan 1001
+
+If we tcpdump on VF3, we see all the packets, even those transmitted
+on vlan 1000.
+
+This behavior prevents to bridge VF1 and VF2 in VM2, because it will
+create a loop: packets transmitted on VF1 will be received by VF2 and
+vice-versa, and bridged again through the software bridge.
+
+This patch remove the activation of VLAN Promiscuous when a VF enables
+the promiscuous mode. However, the IXGBE_VMOLR_UPE bit (Unicast
+Promiscuous) is kept, so that a VF receives all packets that has the
+same VLAN, whatever the destination MAC address.
+
+Fixes: 8443c1a4b192 ("ixgbe, ixgbevf: Add new mbox API xcast mode")
+Cc: stable@vger.kernel.org
+Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+@@ -1181,9 +1181,9 @@ static int ixgbe_update_vf_xcast_mode(st
+ return -EPERM;
+ }
+
+- disable = 0;
++ disable = IXGBE_VMOLR_VPE;
+ enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE |
+- IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
++ IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE;
+ break;
+ default:
+ return -EOPNOTSUPP;
--- /dev/null
+From f2e19b36593caed4c977c2f55aeba7408aeb2132 Mon Sep 17 00:00:00 2001
+From: Martin Faltesek <mfaltesek@google.com>
+Date: Mon, 6 Jun 2022 21:57:29 -0500
+Subject: nfc: st21nfca: fix incorrect sizing calculations in EVT_TRANSACTION
+
+From: Martin Faltesek <mfaltesek@google.com>
+
+commit f2e19b36593caed4c977c2f55aeba7408aeb2132 upstream.
+
+The transaction buffer is allocated by using the size of the packet buf,
+and subtracting two which seem intended to remove the two tags which are
+not present in the target structure. This calculation leads to under
+counting memory because of differences between the packet contents and the
+target structure. The aid_len field is a u8 in the packet, but a u32 in
+the structure, resulting in at least 3 bytes always being under counted.
+Further, the aid data is a variable length field in the packet, but fixed
+in the structure, so if this field is less than the max, the difference is
+added to the under counting.
+
+The last validation check for transaction->params_len is also incorrect
+since it employs the same accounting error.
+
+To fix, perform validation checks progressively to safely reach the
+next field, to determine the size of both buffers and verify both tags.
+Once all validation checks pass, allocate the buffer and copy the data.
+This eliminates freeing memory on the error path, as those checks are
+moved ahead of memory allocation.
+
+Fixes: 26fc6c7f02cb ("NFC: st21nfca: Add HCI transaction event support")
+Fixes: 4fbcc1a4cb20 ("nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION")
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Faltesek <mfaltesek@google.com>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nfc/st21nfca/se.c | 62 +++++++++++++++++++++++-----------------------
+ 1 file changed, 31 insertions(+), 31 deletions(-)
+
+--- a/drivers/nfc/st21nfca/se.c
++++ b/drivers/nfc/st21nfca/se.c
+@@ -304,6 +304,8 @@ int st21nfca_connectivity_event_received
+ int r = 0;
+ struct device *dev = &hdev->ndev->dev;
+ struct nfc_evt_transaction *transaction;
++ u32 aid_len;
++ u8 params_len;
+
+ pr_debug("connectivity gate event: %x\n", event);
+
+@@ -312,50 +314,48 @@ int st21nfca_connectivity_event_received
+ r = nfc_se_connectivity(hdev->ndev, host);
+ break;
+ case ST21NFCA_EVT_TRANSACTION:
+- /*
+- * According to specification etsi 102 622
++ /* According to specification etsi 102 622
+ * 11.2.2.4 EVT_TRANSACTION Table 52
+ * Description Tag Length
+ * AID 81 5 to 16
+ * PARAMETERS 82 0 to 255
++ *
++ * The key differences are aid storage length is variably sized
++ * in the packet, but fixed in nfc_evt_transaction, and that the aid_len
++ * is u8 in the packet, but u32 in the structure, and the tags in
++ * the packet are not included in nfc_evt_transaction.
++ *
++ * size in bytes: 1 1 5-16 1 1 0-255
++ * offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4
++ * member name: aid_tag(M) aid_len aid params_tag(M) params_len params
++ * example: 0x81 5-16 X 0x82 0-255 X
+ */
+- if (skb->len < NFC_MIN_AID_LENGTH + 2 ||
+- skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
++ if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+ return -EPROTO;
+
+- transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL);
+- if (!transaction)
+- return -ENOMEM;
++ aid_len = skb->data[1];
++
++ if (skb->len < aid_len + 4 || aid_len > sizeof(transaction->aid))
++ return -EPROTO;
+
+- transaction->aid_len = skb->data[1];
++ params_len = skb->data[aid_len + 3];
+
+- /* Checking if the length of the AID is valid */
+- if (transaction->aid_len > sizeof(transaction->aid)) {
+- devm_kfree(dev, transaction);
+- return -EINVAL;
+- }
+-
+- memcpy(transaction->aid, &skb->data[2],
+- transaction->aid_len);
+-
+- /* Check next byte is PARAMETERS tag (82) */
+- if (skb->data[transaction->aid_len + 2] !=
+- NFC_EVT_TRANSACTION_PARAMS_TAG) {
+- devm_kfree(dev, transaction);
++ /* Verify PARAMETERS tag is (82), and final check that there is enough
++ * space in the packet to read everything.
++ */
++ if ((skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG) ||
++ (skb->len < aid_len + 4 + params_len))
+ return -EPROTO;
+- }
+
+- transaction->params_len = skb->data[transaction->aid_len + 3];
++ transaction = devm_kzalloc(dev, sizeof(*transaction) + params_len, GFP_KERNEL);
++ if (!transaction)
++ return -ENOMEM;
+
+- /* Total size is allocated (skb->len - 2) minus fixed array members */
+- if (transaction->params_len > ((skb->len - 2) -
+- sizeof(struct nfc_evt_transaction))) {
+- devm_kfree(dev, transaction);
+- return -EINVAL;
+- }
++ transaction->aid_len = aid_len;
++ transaction->params_len = params_len;
+
+- memcpy(transaction->params, skb->data +
+- transaction->aid_len + 4, transaction->params_len);
++ memcpy(transaction->aid, &skb->data[2], aid_len);
++ memcpy(transaction->params, &skb->data[aid_len + 4], params_len);
+
+ r = nfc_se_transaction(hdev->ndev, host, transaction);
+ break;
--- /dev/null
+From 77e5fe8f176a525523ae091d6fd0fbb8834c156d Mon Sep 17 00:00:00 2001
+From: Martin Faltesek <mfaltesek@google.com>
+Date: Mon, 6 Jun 2022 21:57:27 -0500
+Subject: nfc: st21nfca: fix incorrect validating logic in EVT_TRANSACTION
+
+From: Martin Faltesek <mfaltesek@google.com>
+
+commit 77e5fe8f176a525523ae091d6fd0fbb8834c156d upstream.
+
+The first validation check for EVT_TRANSACTION has two different checks
+tied together with logical AND. One is a check for minimum packet length,
+and the other is for a valid aid_tag. If either condition is true (fails),
+then an error should be triggered. The fix is to change && to ||.
+
+Fixes: 26fc6c7f02cb ("NFC: st21nfca: Add HCI transaction event support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Faltesek <mfaltesek@google.com>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nfc/st21nfca/se.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nfc/st21nfca/se.c
++++ b/drivers/nfc/st21nfca/se.c
+@@ -319,7 +319,7 @@ int st21nfca_connectivity_event_received
+ * AID 81 5 to 16
+ * PARAMETERS 82 0 to 255
+ */
+- if (skb->len < NFC_MIN_AID_LENGTH + 2 &&
++ if (skb->len < NFC_MIN_AID_LENGTH + 2 ||
+ skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+ return -EPROTO;
+
--- /dev/null
+From 996419e0594abb311fb958553809f24f38e7abbe Mon Sep 17 00:00:00 2001
+From: Martin Faltesek <mfaltesek@google.com>
+Date: Mon, 6 Jun 2022 21:57:28 -0500
+Subject: nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling
+
+From: Martin Faltesek <mfaltesek@google.com>
+
+commit 996419e0594abb311fb958553809f24f38e7abbe upstream.
+
+Error paths do not free previously allocated memory. Add devm_kfree() to
+those failure paths.
+
+Fixes: 26fc6c7f02cb ("NFC: st21nfca: Add HCI transaction event support")
+Fixes: 4fbcc1a4cb20 ("nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION")
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Faltesek <mfaltesek@google.com>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nfc/st21nfca/se.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/nfc/st21nfca/se.c
++++ b/drivers/nfc/st21nfca/se.c
+@@ -330,22 +330,29 @@ int st21nfca_connectivity_event_received
+ transaction->aid_len = skb->data[1];
+
+ /* Checking if the length of the AID is valid */
+- if (transaction->aid_len > sizeof(transaction->aid))
++ if (transaction->aid_len > sizeof(transaction->aid)) {
++ devm_kfree(dev, transaction);
+ return -EINVAL;
++ }
+
+ memcpy(transaction->aid, &skb->data[2],
+ transaction->aid_len);
+
+ /* Check next byte is PARAMETERS tag (82) */
+ if (skb->data[transaction->aid_len + 2] !=
+- NFC_EVT_TRANSACTION_PARAMS_TAG)
++ NFC_EVT_TRANSACTION_PARAMS_TAG) {
++ devm_kfree(dev, transaction);
+ return -EPROTO;
++ }
+
+ transaction->params_len = skb->data[transaction->aid_len + 3];
+
+ /* Total size is allocated (skb->len - 2) minus fixed array members */
+- if (transaction->params_len > ((skb->len - 2) - sizeof(struct nfc_evt_transaction)))
++ if (transaction->params_len > ((skb->len - 2) -
++ sizeof(struct nfc_evt_transaction))) {
++ devm_kfree(dev, transaction);
+ return -EINVAL;
++ }
+
+ memcpy(transaction->params, skb->data +
+ transaction->aid_len + 4, transaction->params_len);
--- /dev/null
+From 8e1278444446fc97778a5e5c99bca1ce0bbc5ec9 Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Tue, 7 Jun 2022 00:34:56 +1000
+Subject: powerpc/32: Fix overread/overwrite of thread_struct via ptrace
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 8e1278444446fc97778a5e5c99bca1ce0bbc5ec9 upstream.
+
+The ptrace PEEKUSR/POKEUSR (aka PEEKUSER/POKEUSER) API allows a process
+to read/write registers of another process.
+
+To get/set a register, the API takes an index into an imaginary address
+space called the "USER area", where the registers of the process are
+laid out in some fashion.
+
+The kernel then maps that index to a particular register in its own data
+structures and gets/sets the value.
+
+The API only allows a single machine-word to be read/written at a time.
+So 4 bytes on 32-bit kernels and 8 bytes on 64-bit kernels.
+
+The way floating point registers (FPRs) are addressed is somewhat
+complicated, because double precision float values are 64-bit even on
+32-bit CPUs. That means on 32-bit kernels each FPR occupies two
+word-sized locations in the USER area. On 64-bit kernels each FPR
+occupies one word-sized location in the USER area.
+
+Internally the kernel stores the FPRs in an array of u64s, or if VSX is
+enabled, an array of pairs of u64s where one half of each pair stores
+the FPR. Which half of the pair stores the FPR depends on the kernel's
+endianness.
+
+To handle the different layouts of the FPRs depending on VSX/no-VSX and
+big/little endian, the TS_FPR() macro was introduced.
+
+Unfortunately the TS_FPR() macro does not take into account the fact
+that the addressing of each FPR differs between 32-bit and 64-bit
+kernels. It just takes the index into the "USER area" passed from
+userspace and indexes into the fp_state.fpr array.
+
+On 32-bit there are 64 indexes that address FPRs, but only 32 entries in
+the fp_state.fpr array, meaning the user can read/write 256 bytes past
+the end of the array. Because the fp_state sits in the middle of the
+thread_struct there are various fields than can be overwritten,
+including some pointers. As such it may be exploitable.
+
+It has also been observed to cause systems to hang or otherwise
+misbehave when using gdbserver, and is probably the root cause of this
+report which could not be easily reproduced:
+ https://lore.kernel.org/linuxppc-dev/dc38afe9-6b78-f3f5-666b-986939e40fc6@keymile.com/
+
+Rather than trying to make the TS_FPR() macro even more complicated to
+fix the bug, or add more macros, instead add a special-case for 32-bit
+kernels. This is more obvious and hopefully avoids a similar bug
+happening again in future.
+
+Note that because 32-bit kernels never have VSX enabled the code doesn't
+need to consider TS_FPRWIDTH/OFFSET at all. Add a BUILD_BUG_ON() to
+ensure that 32-bit && VSX is never enabled.
+
+Fixes: 87fec0514f61 ("powerpc: PTRACE_PEEKUSR/PTRACE_POKEUSER of FPR registers in little endian builds")
+Cc: stable@vger.kernel.org # v3.13+
+Reported-by: Ariel Miculas <ariel.miculas@belden.com>
+Tested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220609133245.573565-1-mpe@ellerman.id.au
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/kernel/ptrace/ptrace.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+--- a/arch/powerpc/kernel/ptrace/ptrace.c
++++ b/arch/powerpc/kernel/ptrace/ptrace.c
+@@ -75,8 +75,13 @@ long arch_ptrace(struct task_struct *chi
+
+ flush_fp_to_thread(child);
+ if (fpidx < (PT_FPSCR - PT_FPR0))
+- memcpy(&tmp, &child->thread.TS_FPR(fpidx),
+- sizeof(long));
++ if (IS_ENABLED(CONFIG_PPC32)) {
++ // On 32-bit the index we are passed refers to 32-bit words
++ tmp = ((u32 *)child->thread.fp_state.fpr)[fpidx];
++ } else {
++ memcpy(&tmp, &child->thread.TS_FPR(fpidx),
++ sizeof(long));
++ }
+ else
+ tmp = child->thread.fp_state.fpscr;
+ }
+@@ -108,8 +113,13 @@ long arch_ptrace(struct task_struct *chi
+
+ flush_fp_to_thread(child);
+ if (fpidx < (PT_FPSCR - PT_FPR0))
+- memcpy(&child->thread.TS_FPR(fpidx), &data,
+- sizeof(long));
++ if (IS_ENABLED(CONFIG_PPC32)) {
++ // On 32-bit the index we are passed refers to 32-bit words
++ ((u32 *)child->thread.fp_state.fpr)[fpidx] = data;
++ } else {
++ memcpy(&child->thread.TS_FPR(fpidx), &data,
++ sizeof(long));
++ }
+ else
+ child->thread.fp_state.fpscr = data;
+ ret = 0;
+@@ -478,4 +488,7 @@ void __init pt_regs_check(void)
+ * real registers.
+ */
+ BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long));
++
++ // ptrace_get/put_fpr() rely on PPC32 and VSX being incompatible
++ BUILD_BUG_ON(IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_VSX));
+ }
--- /dev/null
+From d51f86cfd8e378d4907958db77da3074f6dce3ba Mon Sep 17 00:00:00 2001
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+Date: Tue, 21 Dec 2021 16:59:03 +1100
+Subject: powerpc/mm: Switch obsolete dssall to .long
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+commit d51f86cfd8e378d4907958db77da3074f6dce3ba upstream.
+
+The dssall ("Data Stream Stop All") instruction is obsolete altogether
+with other Data Cache Instructions since ISA 2.03 (year 2006).
+
+LLVM IAS does not support it but PPC970 seems to be using it.
+This switches dssall to .long as there is no much point in fixing LLVM.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20211221055904.555763-6-aik@ozlabs.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/ppc-opcode.h | 2 ++
+ arch/powerpc/kernel/idle.c | 2 +-
+ arch/powerpc/kernel/idle_6xx.S | 2 +-
+ arch/powerpc/kernel/l2cr_6xx.S | 6 +++---
+ arch/powerpc/kernel/swsusp_32.S | 2 +-
+ arch/powerpc/kernel/swsusp_asm64.S | 2 +-
+ arch/powerpc/mm/mmu_context.c | 2 +-
+ arch/powerpc/platforms/powermac/cache.S | 4 ++--
+ 8 files changed, 12 insertions(+), 10 deletions(-)
+
+--- a/arch/powerpc/include/asm/ppc-opcode.h
++++ b/arch/powerpc/include/asm/ppc-opcode.h
+@@ -212,6 +212,7 @@
+ #define PPC_INST_COPY 0x7c20060c
+ #define PPC_INST_DCBA 0x7c0005ec
+ #define PPC_INST_DCBA_MASK 0xfc0007fe
++#define PPC_INST_DSSALL 0x7e00066c
+ #define PPC_INST_ISEL 0x7c00001e
+ #define PPC_INST_ISEL_MASK 0xfc00003e
+ #define PPC_INST_LSWI 0x7c0004aa
+@@ -517,6 +518,7 @@
+ #define PPC_DCBZL(a, b) stringify_in_c(.long PPC_RAW_DCBZL(a, b))
+ #define PPC_DIVDE(t, a, b) stringify_in_c(.long PPC_RAW_DIVDE(t, a, b))
+ #define PPC_DIVDEU(t, a, b) stringify_in_c(.long PPC_RAW_DIVDEU(t, a, b))
++#define PPC_DSSALL stringify_in_c(.long PPC_INST_DSSALL)
+ #define PPC_LQARX(t, a, b, eh) stringify_in_c(.long PPC_RAW_LQARX(t, a, b, eh))
+ #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_RAW_LDARX(t, a, b, eh))
+ #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_RAW_LWARX(t, a, b, eh))
+--- a/arch/powerpc/kernel/idle.c
++++ b/arch/powerpc/kernel/idle.c
+@@ -82,7 +82,7 @@ void power4_idle(void)
+ return;
+
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+- asm volatile("DSSALL ; sync" ::: "memory");
++ asm volatile(PPC_DSSALL " ; sync" ::: "memory");
+
+ power4_idle_nap();
+
+--- a/arch/powerpc/kernel/idle_6xx.S
++++ b/arch/powerpc/kernel/idle_6xx.S
+@@ -129,7 +129,7 @@ BEGIN_FTR_SECTION
+ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
+ mtspr SPRN_HID0,r4
+ BEGIN_FTR_SECTION
+- DSSALL
++ PPC_DSSALL
+ sync
+ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ lwz r8,TI_LOCAL_FLAGS(r2) /* set napping bit */
+--- a/arch/powerpc/kernel/l2cr_6xx.S
++++ b/arch/powerpc/kernel/l2cr_6xx.S
+@@ -96,7 +96,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
+
+ /* Stop DST streams */
+ BEGIN_FTR_SECTION
+- DSSALL
++ PPC_DSSALL
+ sync
+ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+
+@@ -292,7 +292,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
+ isync
+
+ /* Stop DST streams */
+- DSSALL
++ PPC_DSSALL
+ sync
+
+ /* Get the current enable bit of the L3CR into r4 */
+@@ -401,7 +401,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
+ _GLOBAL(__flush_disable_L1)
+ /* Stop pending alitvec streams and memory accesses */
+ BEGIN_FTR_SECTION
+- DSSALL
++ PPC_DSSALL
+ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ sync
+
+--- a/arch/powerpc/kernel/swsusp_32.S
++++ b/arch/powerpc/kernel/swsusp_32.S
+@@ -181,7 +181,7 @@ _GLOBAL(swsusp_arch_resume)
+ #ifdef CONFIG_ALTIVEC
+ /* Stop pending alitvec streams and memory accesses */
+ BEGIN_FTR_SECTION
+- DSSALL
++ PPC_DSSALL
+ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ #endif
+ sync
+--- a/arch/powerpc/kernel/swsusp_asm64.S
++++ b/arch/powerpc/kernel/swsusp_asm64.S
+@@ -142,7 +142,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR
+ _GLOBAL(swsusp_arch_resume)
+ /* Stop pending alitvec streams and memory accesses */
+ BEGIN_FTR_SECTION
+- DSSALL
++ PPC_DSSALL
+ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ sync
+
+--- a/arch/powerpc/mm/mmu_context.c
++++ b/arch/powerpc/mm/mmu_context.c
+@@ -79,7 +79,7 @@ void switch_mm_irqs_off(struct mm_struct
+ * context
+ */
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+- asm volatile ("dssall");
++ asm volatile (PPC_DSSALL);
+
+ if (new_on_cpu)
+ radix_kvm_prefetch_workaround(next);
+--- a/arch/powerpc/platforms/powermac/cache.S
++++ b/arch/powerpc/platforms/powermac/cache.S
+@@ -48,7 +48,7 @@ flush_disable_75x:
+
+ /* Stop DST streams */
+ BEGIN_FTR_SECTION
+- DSSALL
++ PPC_DSSALL
+ sync
+ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+
+@@ -197,7 +197,7 @@ flush_disable_745x:
+ isync
+
+ /* Stop prefetch streams */
+- DSSALL
++ PPC_DSSALL
+ sync
+
+ /* Disable L2 prefetching */
ata-libata-transport-fix-dma-pio-xfer-_mode-sysfs-files.patch
mmc-block-fix-cqe-recovery-reset-success.patch
net-phy-dp83867-retrigger-sgmii-an-when-link-change.patch
+nfc-st21nfca-fix-incorrect-validating-logic-in-evt_transaction.patch
+nfc-st21nfca-fix-memory-leaks-in-evt_transaction-handling.patch
+nfc-st21nfca-fix-incorrect-sizing-calculations-in-evt_transaction.patch
+ixgbe-fix-bcast-packets-rx-on-vf-after-promisc-removal.patch
+ixgbe-fix-unexpected-vlan-rx-in-promisc-mode-on-vf.patch
+input-bcm5974-set-missing-urb_no_transfer_dma_map-urb-flag.patch
+drm-bridge-analogix_dp-support-psr-exit-to-disable-transition.patch
+drm-atomic-force-bridge-self-refresh-exit-on-crtc-switch.patch
+powerpc-32-fix-overread-overwrite-of-thread_struct-via-ptrace.patch
+powerpc-mm-switch-obsolete-dssall-to-.long.patch
+interconnect-qcom-sc7180-drop-ip0-interconnects.patch
+interconnect-restore-sync-state-by-ignoring-ipa-virt-in-provider-count.patch