--- /dev/null
+From 2d4584abfefb96ea91e6c92403e3f82995047708 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 05:41:46 -0700
+Subject: ARM: dts: am33xx: Fix MMCHS0 dma properties
+
+From: YuTong Chang <mtwget@gmail.com>
+
+[ Upstream commit 2eb502f496f7764027b7958d4e74356fed918059 ]
+
+According to technical manual(table 11-24), the DMA of MMCHS0 should be
+direct mapped.
+
+Fixes: b5e509066074 ("ARM: DTS: am33xx: Use the new DT bindings for the eDMA3")
+Signed-off-by: YuTong Chang <mtwget@gmail.com>
+Message-Id: <20220620124146.5330-1-mtwget@gmail.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/am33xx-l4.dtsi | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi
+index c9629cb5ccd1..9a750883b987 100644
+--- a/arch/arm/boot/dts/am33xx-l4.dtsi
++++ b/arch/arm/boot/dts/am33xx-l4.dtsi
+@@ -1500,8 +1500,7 @@
+ mmc1: mmc@0 {
+ compatible = "ti,am335-sdhci";
+ ti,needs-special-reset;
+- dmas = <&edma_xbar 24 0 0
+- &edma_xbar 25 0 0>;
++ dmas = <&edma 24 0>, <&edma 25 0>;
+ dma-names = "tx", "rx";
+ interrupts = <64>;
+ reg = <0x0 0x1000>;
+--
+2.35.1
+
--- /dev/null
+From 432027f08a5f33e9347ab022f7ee4f9e7c59c1c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Aug 2022 09:27:42 +0200
+Subject: ARM: dts: am5748: keep usb4_tm disabled
+
+From: Romain Naour <romain.naour@skf.com>
+
+[ Upstream commit 6a6d9ecff14a2a46c1deeffa3eb3825349639bdd ]
+
+Commit bcbb63b80284 ("ARM: dts: dra7: Separate AM57 dtsi files")
+disabled usb4_tm for am5748 devices since USB4 IP is not present
+in this SoC.
+
+The commit log explained the difference between AM5 and DRA7 families:
+
+AM5 and DRA7 SoC families have different set of modules in them so the
+SoC sepecific dtsi files need to be separated.
+
+e.g. Some of the major differences between AM576 and DRA76
+
+ DRA76x AM576x
+
+USB3 x
+USB4 x
+ATL x
+VCP x
+MLB x
+ISS x
+PRU-ICSS1 x
+PRU-ICSS2 x
+
+Then commit 176f26bcd41a ("ARM: dts: Add support for dra762 abz
+package") removed usb4_tm part from am5748.dtsi and introcuded new
+ti-sysc errors in dmesg:
+
+ti-sysc 48940000.target-module: clock get error for fck: -2
+ti-sysc: probe of 48940000.target-module failed with error -2
+
+Fixes: 176f26bcd41a ("ARM: dts: Add support for dra762 abz package")
+
+Signed-off-by: Romain Naour <romain.naour@skf.com>
+Signed-off-by: Romain Naour <romain.naour@smile.fr>
+Message-Id: <20220823072742.351368-1-romain.naour@smile.fr>
+Reviewed-by: Roger Quadros <rogerq@kernel.org>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/am5748.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am5748.dtsi b/arch/arm/boot/dts/am5748.dtsi
+index c260aa1a85bd..a1f029e9d1f3 100644
+--- a/arch/arm/boot/dts/am5748.dtsi
++++ b/arch/arm/boot/dts/am5748.dtsi
+@@ -25,6 +25,10 @@
+ status = "disabled";
+ };
+
++&usb4_tm {
++ status = "disabled";
++};
++
+ &atl_tm {
+ status = "disabled";
+ };
+--
+2.35.1
+
--- /dev/null
+From c197fc71ce25bdb169bcd0cfd8360b47bbb71138 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Sep 2022 11:36:03 +0200
+Subject: arm64: dts: qcom: sm8350: fix UFS PHY serdes size
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 40e9541959100e017533e18e44d07eed44f91dc5 ]
+
+The size of the UFS PHY serdes register region is 0x1c4 and the
+corresponding 'reg' property should specifically not include the
+adjacent regions that are defined in the child node (e.g. tx and rx).
+
+Fixes: 59c7cf814783 ("arm64: dts: qcom: sm8350: Add UFS nodes")
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20220916093603.24263-1-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index 9ffb7355850c..c0a3ea47302f 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -1109,7 +1109,7 @@
+
+ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sm8350-qmp-ufs-phy";
+- reg = <0 0x01d87000 0 0xe10>;
++ reg = <0 0x01d87000 0 0x1c4>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ #clock-cells = <1>;
+--
+2.35.1
+
--- /dev/null
+From 321621e5e48335e3c55cdb4aaf12eafbca7191b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 17:00:01 +0800
+Subject: ASoC: imx-card: Fix refcount issue with of_node_put
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit d56ba9a04d7548d4149c46ec86a0e3cc41a70f4a ]
+
+imx_card_parse_of will search all the node with loop,
+if there is defer probe happen in the middle of loop,
+the previous released codec node will be released
+twice, then cause refcount issue.
+
+Here assign NULL to pointer of released nodes to fix
+the issue.
+
+Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1663059601-29259-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-card.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
+index 593d69b96523..d59f5efbf7ed 100644
+--- a/sound/soc/fsl/imx-card.c
++++ b/sound/soc/fsl/imx-card.c
+@@ -698,6 +698,10 @@ static int imx_card_parse_of(struct imx_card_data *data)
+ of_node_put(cpu);
+ of_node_put(codec);
+ of_node_put(platform);
++
++ cpu = NULL;
++ codec = NULL;
++ platform = NULL;
+ }
+
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 3df2dd8ee672636b212e551f7f19ee8be07c7d45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Sep 2022 19:34:53 +0200
+Subject: ASoC: tas2770: Reinit regcache on reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Martin Povišer <povik+lin@cutebit.org>
+
+[ Upstream commit 0a0342ede303fc420f3a388e1ae82da3ae8ff6bd ]
+
+On probe of the ASoC component, the device is reset but the regcache is
+retained. This means the regcache gets out of sync if the codec is
+rebound to a sound card for a second time. Fix it by reinitializing the
+regcache to defaults after the device is reset.
+
+Fixes: b0bcbe615756 ("ASoC: tas2770: Fix calling reset in probe")
+Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
+Link: https://lore.kernel.org/r/20220919173453.84292-1-povik+lin@cutebit.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2770.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
+index b8cda6b14b49..a13b086a072b 100644
+--- a/sound/soc/codecs/tas2770.c
++++ b/sound/soc/codecs/tas2770.c
+@@ -495,6 +495,8 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = {
+ },
+ };
+
++static const struct regmap_config tas2770_i2c_regmap;
++
+ static int tas2770_codec_probe(struct snd_soc_component *component)
+ {
+ struct tas2770_priv *tas2770 =
+@@ -508,6 +510,7 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
+ }
+
+ tas2770_reset(tas2770);
++ regmap_reinit_cache(tas2770->regmap, &tas2770_i2c_regmap);
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 0c10932023b318bceafe782a36e9eb27ce80af2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Sep 2022 10:09:59 -0500
+Subject: clk: imx: imx6sx: remove the SET_RATE_PARENT flag for QSPI clocks
+
+From: Han Xu <han.xu@nxp.com>
+
+[ Upstream commit b1ff1bfe81e763420afd5f3f25f0b3cbfd97055c ]
+
+There is no dedicate parent clock for QSPI so SET_RATE_PARENT flag
+should not be used. For instance, the default parent clock for QSPI is
+pll2_bus, which is also the parent clock for quite a few modules, such
+as MMDC, once GPMI NAND set clock rate for EDO5 mode can cause system
+hang due to pll2_bus rate changed.
+
+Fixes: f1541e15e38e ("clk: imx6sx: Switch to clk_hw based API")
+Signed-off-by: Han Xu <han.xu@nxp.com>
+Link: https://lore.kernel.org/r/20220915150959.3646702-1-han.xu@nxp.com
+Tested-by: Fabio Estevam <festevam@denx.de>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx6sx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
+index fc1bd23d4583..598f3cf4eba4 100644
+--- a/drivers/clk/imx/clk-imx6sx.c
++++ b/drivers/clk/imx/clk-imx6sx.c
+@@ -280,13 +280,13 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
+ hws[IMX6SX_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ hws[IMX6SX_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ hws[IMX6SX_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+- hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT);
++ hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
+ hws[IMX6SX_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
+ hws[IMX6SX_CLK_VID_SEL] = imx_clk_hw_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels));
+ hws[IMX6SX_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ hws[IMX6SX_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
+ hws[IMX6SX_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
+- hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT);
++ hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels));
+ hws[IMX6SX_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ hws[IMX6SX_CLK_AUDIO_SEL] = imx_clk_hw_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ hws[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_hw_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels));
+--
+2.35.1
+
--- /dev/null
+From 6b8b65c704099e902e2773be65ca2f126a47373e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Sep 2022 09:15:03 -0700
+Subject: clk: iproc: Do not rely on node name for correct PLL setup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 1b24a132eba7a1c19475ba2510ec1c00af3ff914 ]
+
+After commit 31fd9b79dc58 ("ARM: dts: BCM5301X: update CRU block
+description") a warning from clk-iproc-pll.c was generated due to a
+duplicate PLL name as well as the console stopped working. Upon closer
+inspection it became clear that iproc_pll_clk_setup() used the Device
+Tree node unit name as an unique identifier as well as a parent name to
+parent all clocks under the PLL.
+
+BCM5301X was the first platform on which that got noticed because of the
+DT node unit name renaming but the same assumptions hold true for any
+user of the iproc_pll_clk_setup() function.
+
+The first 'clock-output-names' property is always guaranteed to be
+unique as well as providing the actual desired PLL clock name, so we
+utilize that to register the PLL and as a parent name of all children
+clock.
+
+Fixes: 5fe225c105fd ("clk: iproc: add initial common clock support")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20220905161504.1526-1-f.fainelli@gmail.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/bcm/clk-iproc-pll.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c
+index 33da30f99c79..d39c44b61c52 100644
+--- a/drivers/clk/bcm/clk-iproc-pll.c
++++ b/drivers/clk/bcm/clk-iproc-pll.c
+@@ -736,6 +736,7 @@ void iproc_pll_clk_setup(struct device_node *node,
+ const char *parent_name;
+ struct iproc_clk *iclk_array;
+ struct clk_hw_onecell_data *clk_data;
++ const char *clk_name;
+
+ if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl))
+ return;
+@@ -783,7 +784,12 @@ void iproc_pll_clk_setup(struct device_node *node,
+ iclk = &iclk_array[0];
+ iclk->pll = pll;
+
+- init.name = node->name;
++ ret = of_property_read_string_index(node, "clock-output-names",
++ 0, &clk_name);
++ if (WARN_ON(ret))
++ goto err_pll_register;
++
++ init.name = clk_name;
+ init.ops = &iproc_pll_ops;
+ init.flags = 0;
+ parent_name = of_clk_get_parent_name(node, 0);
+@@ -803,13 +809,11 @@ void iproc_pll_clk_setup(struct device_node *node,
+ goto err_pll_register;
+
+ clk_data->hws[0] = &iclk->hw;
++ parent_name = clk_name;
+
+ /* now initialize and register all leaf clocks */
+ for (i = 1; i < num_clks; i++) {
+- const char *clk_name;
+-
+ memset(&init, 0, sizeof(init));
+- parent_name = node->name;
+
+ ret = of_property_read_string_index(node, "clock-output-names",
+ i, &clk_name);
+--
+2.35.1
+
--- /dev/null
+From a9748e99abec43ed97185f75edc50499269df9b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 14:51:08 -0300
+Subject: cxgb4: fix missing unlock on ETHOFLD desc collect fail path
+
+From: Rafael Mendonca <rafaelmendsr@gmail.com>
+
+[ Upstream commit c635ebe8d911a93bd849a9419b01a58783de76f1 ]
+
+The label passed to the QDESC_GET for the ETHOFLD TXQ, RXQ, and FLQ, is the
+'out' one, which skips the 'out_unlock' label, and thus doesn't unlock the
+'uld_mutex' before returning. Additionally, since commit 5148e5950c67
+("cxgb4: add EOTID tracking and software context dump"), the access to
+these ETHOFLD hardware queues should be protected by the 'mqprio_mutex'
+instead.
+
+Fixes: 2d0cb84dd973 ("cxgb4: add ETHOFLD hardware queue support")
+Fixes: 5148e5950c67 ("cxgb4: add EOTID tracking and software context dump")
+Signed-off-by: Rafael Mendonca <rafaelmendsr@gmail.com>
+Reviewed-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
+Link: https://lore.kernel.org/r/20220922175109.764898-1-rafaelmendsr@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/chelsio/cxgb4/cudbg_lib.c | 28 +++++++++++++------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
+index a7f291c89702..557c591a6ce3 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
+@@ -14,6 +14,7 @@
+ #include "cudbg_entity.h"
+ #include "cudbg_lib.h"
+ #include "cudbg_zlib.h"
++#include "cxgb4_tc_mqprio.h"
+
+ static const u32 t6_tp_pio_array[][IREG_NUM_ELEM] = {
+ {0x7e40, 0x7e44, 0x020, 28}, /* t6_tp_pio_regs_20_to_3b */
+@@ -3458,7 +3459,7 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
+ for (i = 0; i < utxq->ntxq; i++)
+ QDESC_GET_TXQ(&utxq->uldtxq[i].q,
+ cudbg_uld_txq_to_qtype(j),
+- out_unlock);
++ out_unlock_uld);
+ }
+ }
+
+@@ -3475,7 +3476,7 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
+ for (i = 0; i < urxq->nrxq; i++)
+ QDESC_GET_RXQ(&urxq->uldrxq[i].rspq,
+ cudbg_uld_rxq_to_qtype(j),
+- out_unlock);
++ out_unlock_uld);
+ }
+
+ /* ULD FLQ */
+@@ -3487,7 +3488,7 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
+ for (i = 0; i < urxq->nrxq; i++)
+ QDESC_GET_FLQ(&urxq->uldrxq[i].fl,
+ cudbg_uld_flq_to_qtype(j),
+- out_unlock);
++ out_unlock_uld);
+ }
+
+ /* ULD CIQ */
+@@ -3500,29 +3501,34 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
+ for (i = 0; i < urxq->nciq; i++)
+ QDESC_GET_RXQ(&urxq->uldrxq[base + i].rspq,
+ cudbg_uld_ciq_to_qtype(j),
+- out_unlock);
++ out_unlock_uld);
+ }
+ }
++ mutex_unlock(&uld_mutex);
++
++ if (!padap->tc_mqprio)
++ goto out;
+
++ mutex_lock(&padap->tc_mqprio->mqprio_mutex);
+ /* ETHOFLD TXQ */
+ if (s->eohw_txq)
+ for (i = 0; i < s->eoqsets; i++)
+ QDESC_GET_TXQ(&s->eohw_txq[i].q,
+- CUDBG_QTYPE_ETHOFLD_TXQ, out);
++ CUDBG_QTYPE_ETHOFLD_TXQ, out_unlock_mqprio);
+
+ /* ETHOFLD RXQ and FLQ */
+ if (s->eohw_rxq) {
+ for (i = 0; i < s->eoqsets; i++)
+ QDESC_GET_RXQ(&s->eohw_rxq[i].rspq,
+- CUDBG_QTYPE_ETHOFLD_RXQ, out);
++ CUDBG_QTYPE_ETHOFLD_RXQ, out_unlock_mqprio);
+
+ for (i = 0; i < s->eoqsets; i++)
+ QDESC_GET_FLQ(&s->eohw_rxq[i].fl,
+- CUDBG_QTYPE_ETHOFLD_FLQ, out);
++ CUDBG_QTYPE_ETHOFLD_FLQ, out_unlock_mqprio);
+ }
+
+-out_unlock:
+- mutex_unlock(&uld_mutex);
++out_unlock_mqprio:
++ mutex_unlock(&padap->tc_mqprio->mqprio_mutex);
+
+ out:
+ qdesc_info->qdesc_entry_size = sizeof(*qdesc_entry);
+@@ -3559,6 +3565,10 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init,
+ #undef QDESC_GET
+
+ return rc;
++
++out_unlock_uld:
++ mutex_unlock(&uld_mutex);
++ goto out;
+ }
+
+ int cudbg_collect_flash(struct cudbg_init *pdbg_init,
+--
+2.35.1
+
--- /dev/null
+From a5a9fb5fa149036b2f1ef580c2427512b0856e9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Sep 2022 11:59:14 -0400
+Subject: don't use __kernel_write() on kmap_local_page()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit 06bbaa6dc53cb72040db952053432541acb9adc7 ]
+
+passing kmap_local_page() result to __kernel_write() is unsafe -
+random ->write_iter() might (and 9p one does) get unhappy when
+passed ITER_KVEC with pointer that came from kmap_local_page().
+
+Fix by providing a variant of __kernel_write() that takes an iov_iter
+from caller (__kernel_write() becomes a trivial wrapper) and adding
+dump_emit_page() that parallels dump_emit(), except that instead of
+__kernel_write() it uses __kernel_write_iter() with ITER_BVEC source.
+
+Fixes: 3159ed57792b "fs/coredump: use kmap_local_page()"
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/coredump.c | 38 +++++++++++++++++++++++++++++++++-----
+ fs/internal.h | 3 +++
+ fs/read_write.c | 22 ++++++++++++++--------
+ 3 files changed, 50 insertions(+), 13 deletions(-)
+
+diff --git a/fs/coredump.c b/fs/coredump.c
+index 26eb5a095832..43fdd82f82ab 100644
+--- a/fs/coredump.c
++++ b/fs/coredump.c
+@@ -902,6 +902,38 @@ static int __dump_skip(struct coredump_params *cprm, size_t nr)
+ }
+ }
+
++static int dump_emit_page(struct coredump_params *cprm, struct page *page)
++{
++ struct bio_vec bvec = {
++ .bv_page = page,
++ .bv_offset = 0,
++ .bv_len = PAGE_SIZE,
++ };
++ struct iov_iter iter;
++ struct file *file = cprm->file;
++ loff_t pos = file->f_pos;
++ ssize_t n;
++
++ if (cprm->to_skip) {
++ if (!__dump_skip(cprm, cprm->to_skip))
++ return 0;
++ cprm->to_skip = 0;
++ }
++ if (cprm->written + PAGE_SIZE > cprm->limit)
++ return 0;
++ if (dump_interrupted())
++ return 0;
++ iov_iter_bvec(&iter, WRITE, &bvec, 1, PAGE_SIZE);
++ n = __kernel_write_iter(cprm->file, &iter, &pos);
++ if (n != PAGE_SIZE)
++ return 0;
++ file->f_pos = pos;
++ cprm->written += PAGE_SIZE;
++ cprm->pos += PAGE_SIZE;
++
++ return 1;
++}
++
+ int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
+ {
+ if (cprm->to_skip) {
+@@ -933,7 +965,6 @@ int dump_user_range(struct coredump_params *cprm, unsigned long start,
+
+ for (addr = start; addr < start + len; addr += PAGE_SIZE) {
+ struct page *page;
+- int stop;
+
+ /*
+ * To avoid having to allocate page tables for virtual address
+@@ -944,10 +975,7 @@ int dump_user_range(struct coredump_params *cprm, unsigned long start,
+ */
+ page = get_dump_page(addr);
+ if (page) {
+- void *kaddr = kmap_local_page(page);
+-
+- stop = !dump_emit(cprm, kaddr, PAGE_SIZE);
+- kunmap_local(kaddr);
++ int stop = !dump_emit_page(cprm, page);
+ put_page(page);
+ if (stop)
+ return 0;
+diff --git a/fs/internal.h b/fs/internal.h
+index 4f1fe6d08866..69b64136ae4c 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -16,6 +16,7 @@ struct shrink_control;
+ struct fs_context;
+ struct user_namespace;
+ struct pipe_inode_info;
++struct iov_iter;
+
+ /*
+ * block/bdev.c
+@@ -219,3 +220,5 @@ struct xattr_ctx {
+ int setxattr_copy(const char __user *name, struct xattr_ctx *ctx);
+ int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+ struct xattr_ctx *ctx);
++
++ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos);
+diff --git a/fs/read_write.c b/fs/read_write.c
+index 8d3ec975514d..08299a8f3e05 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -512,14 +512,9 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t
+ }
+
+ /* caller is responsible for file_start_write/file_end_write */
+-ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
++ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos)
+ {
+- struct kvec iov = {
+- .iov_base = (void *)buf,
+- .iov_len = min_t(size_t, count, MAX_RW_COUNT),
+- };
+ struct kiocb kiocb;
+- struct iov_iter iter;
+ ssize_t ret;
+
+ if (WARN_ON_ONCE(!(file->f_mode & FMODE_WRITE)))
+@@ -535,8 +530,7 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t
+
+ init_sync_kiocb(&kiocb, file);
+ kiocb.ki_pos = pos ? *pos : 0;
+- iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len);
+- ret = file->f_op->write_iter(&kiocb, &iter);
++ ret = file->f_op->write_iter(&kiocb, from);
+ if (ret > 0) {
+ if (pos)
+ *pos = kiocb.ki_pos;
+@@ -546,6 +540,18 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t
+ inc_syscw(current);
+ return ret;
+ }
++
++/* caller is responsible for file_start_write/file_end_write */
++ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
++{
++ struct kvec iov = {
++ .iov_base = (void *)buf,
++ .iov_len = min_t(size_t, count, MAX_RW_COUNT),
++ };
++ struct iov_iter iter;
++ iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len);
++ return __kernel_write_iter(file, &iter, pos);
++}
+ /*
+ * This "EXPORT_SYMBOL_GPL()" is more of a "EXPORT_SYMBOL_DONTUSE()",
+ * but autofs is one of the few internal kernel users that actually
+--
+2.35.1
+
--- /dev/null
+From 96f8f0d53999bfcd26a050e87ca5571df29e6dda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 14:43:03 +0200
+Subject: drm/bridge: lt8912b: add vsync hsync
+
+From: Philippe Schenker <philippe.schenker@toradex.com>
+
+[ Upstream commit da73a94fa282f78d485bd0aab36c8ac15b6f792c ]
+
+Currently the bridge driver does not take care whether or not the display
+needs positive/negative vertical/horizontal syncs. Pass these two flags
+to the bridge from the EDID that was read out from the display.
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
+Acked-by: Adrien Grassein <adrien.grassein@gmail.com>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-2-dev@pschenker.ch
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index 1b0c7eaf6c84..0fae72d45040 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -266,7 +266,7 @@ static int lt8912_video_setup(struct lt8912 *lt)
+ u32 hactive, h_total, hpw, hfp, hbp;
+ u32 vactive, v_total, vpw, vfp, vbp;
+ u8 settle = 0x08;
+- int ret;
++ int ret, hsync_activehigh, vsync_activehigh;
+
+ if (!lt)
+ return -EINVAL;
+@@ -276,12 +276,14 @@ static int lt8912_video_setup(struct lt8912 *lt)
+ hpw = lt->mode.hsync_len;
+ hbp = lt->mode.hback_porch;
+ h_total = hactive + hfp + hpw + hbp;
++ hsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH;
+
+ vactive = lt->mode.vactive;
+ vfp = lt->mode.vfront_porch;
+ vpw = lt->mode.vsync_len;
+ vbp = lt->mode.vback_porch;
+ v_total = vactive + vfp + vpw + vbp;
++ vsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH;
+
+ if (vactive <= 600)
+ settle = 0x04;
+@@ -315,6 +317,11 @@ static int lt8912_video_setup(struct lt8912 *lt)
+ ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff);
+ ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8);
+
++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(0),
++ vsync_activehigh ? BIT(0) : 0);
++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1),
++ hsync_activehigh ? BIT(1) : 0);
++
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From c3bcdd9bc6b138079b260c2559a5217b22174ecb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 14:43:05 +0200
+Subject: drm/bridge: lt8912b: fix corrupted image output
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit 051ad2788d35ca07aec8402542e5d38429f2426a ]
+
+Correct I2C address for the register list in lt8912_write_lvds_config(),
+these registers are on the first I2C address (0x48), the current
+function is just writing garbage to the wrong registers and this creates
+multiple issues (artifacts and output completely corrupted) on some HDMI
+displays.
+
+Correct I2C address comes from Lontium documentation and it is the one
+used on other out-of-tree LT8912B drivers [1].
+
+[1] https://github.com/boundarydevices/linux/blob/boundary-imx_5.10.x_2.0.0/drivers/video/lt8912.c#L296
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
+Acked-by: Adrien Grassein <adrien.grassein@gmail.com>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-4-dev@pschenker.ch
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index 6e04d51b4636..82169b6bfca1 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -186,7 +186,7 @@ static int lt8912_write_lvds_config(struct lt8912 *lt)
+ {0x03, 0xff},
+ };
+
+- return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
++ return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
+ };
+
+ static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b)
+--
+2.35.1
+
--- /dev/null
+From daef5ce9c86c9b15a87d2d105201c4bf25453e72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 14:43:04 +0200
+Subject: drm/bridge: lt8912b: set hdmi or dvi mode
+
+From: Philippe Schenker <philippe.schenker@toradex.com>
+
+[ Upstream commit 6dd1de12e1243f2013e4fabf31e99e63b1a860d0 ]
+
+The Lontium LT8912 does have a setting for DVI or HDMI. This patch reads
+from EDID what the display needs and sets it accordingly.
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
+Acked-by: Adrien Grassein <adrien.grassein@gmail.com>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-3-dev@pschenker.ch
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index 0fae72d45040..6e04d51b4636 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -321,6 +321,8 @@ static int lt8912_video_setup(struct lt8912 *lt)
+ vsync_activehigh ? BIT(0) : 0);
+ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1),
+ hsync_activehigh ? BIT(1) : 0);
++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xb2, BIT(0),
++ lt->connector.display_info.is_hdmi ? BIT(0) : 0);
+
+ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From 20f372a6871e189c408feaf2d0965521cf651d29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Apr 2022 18:10:46 -0600
+Subject: fs: split off setxattr_copy and do_setxattr function from setxattr
+
+From: Stefan Roesch <shr@fb.com>
+
+[ Upstream commit 1a91794ce8481a293c5ef432feb440aee1455619 ]
+
+This splits of the setup part of the function setxattr in its own
+dedicated function called setxattr_copy. In addition it also exposes a new
+function called do_setxattr for making the setxattr call.
+
+This makes it possible to call these two functions from io_uring in the
+processing of an xattr request.
+
+Signed-off-by: Stefan Roesch <shr@fb.com>
+Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
+Link: https://lore.kernel.org/r/20220323154420.3301504-2-shr@fb.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 06bbaa6dc53c ("[coredump] don't use __kernel_write() on kmap_local_page()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/internal.h | 24 +++++++++++++++
+ fs/xattr.c | 84 ++++++++++++++++++++++++++++++++++++---------------
+ 2 files changed, 83 insertions(+), 25 deletions(-)
+
+diff --git a/fs/internal.h b/fs/internal.h
+index cdd83d4899bb..4f1fe6d08866 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -195,3 +195,27 @@ long splice_file_to_pipe(struct file *in,
+ struct pipe_inode_info *opipe,
+ loff_t *offset,
+ size_t len, unsigned int flags);
++
++/*
++ * fs/xattr.c:
++ */
++struct xattr_name {
++ char name[XATTR_NAME_MAX + 1];
++};
++
++struct xattr_ctx {
++ /* Value of attribute */
++ union {
++ const void __user *cvalue;
++ void __user *value;
++ };
++ void *kvalue;
++ size_t size;
++ /* Attribute name */
++ struct xattr_name *kname;
++ unsigned int flags;
++};
++
++int setxattr_copy(const char __user *name, struct xattr_ctx *ctx);
++int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
++ struct xattr_ctx *ctx);
+diff --git a/fs/xattr.c b/fs/xattr.c
+index 998045165916..7117cb253864 100644
+--- a/fs/xattr.c
++++ b/fs/xattr.c
+@@ -25,6 +25,8 @@
+
+ #include <linux/uaccess.h>
+
++#include "internal.h"
++
+ static const char *
+ strcmp_prefix(const char *a, const char *a_prefix)
+ {
+@@ -539,44 +541,76 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
+ /*
+ * Extended attribute SET operations
+ */
+-static long
+-setxattr(struct user_namespace *mnt_userns, struct dentry *d,
+- const char __user *name, const void __user *value, size_t size,
+- int flags)
++
++int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
+ {
+ int error;
+- void *kvalue = NULL;
+- char kname[XATTR_NAME_MAX + 1];
+
+- if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
++ if (ctx->flags & ~(XATTR_CREATE|XATTR_REPLACE))
+ return -EINVAL;
+
+- error = strncpy_from_user(kname, name, sizeof(kname));
+- if (error == 0 || error == sizeof(kname))
+- error = -ERANGE;
++ error = strncpy_from_user(ctx->kname->name, name,
++ sizeof(ctx->kname->name));
++ if (error == 0 || error == sizeof(ctx->kname->name))
++ return -ERANGE;
+ if (error < 0)
+ return error;
+
+- if (size) {
+- if (size > XATTR_SIZE_MAX)
++ error = 0;
++ if (ctx->size) {
++ if (ctx->size > XATTR_SIZE_MAX)
+ return -E2BIG;
+- kvalue = kvmalloc(size, GFP_KERNEL);
+- if (!kvalue)
+- return -ENOMEM;
+- if (copy_from_user(kvalue, value, size)) {
+- error = -EFAULT;
+- goto out;
++
++ ctx->kvalue = vmemdup_user(ctx->cvalue, ctx->size);
++ if (IS_ERR(ctx->kvalue)) {
++ error = PTR_ERR(ctx->kvalue);
++ ctx->kvalue = NULL;
+ }
+- if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
+- (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
+- posix_acl_fix_xattr_from_user(mnt_userns, d_inode(d),
+- kvalue, size);
+ }
+
+- error = vfs_setxattr(mnt_userns, d, kname, kvalue, size, flags);
+-out:
+- kvfree(kvalue);
++ return error;
++}
++
++static void setxattr_convert(struct user_namespace *mnt_userns,
++ struct dentry *d, struct xattr_ctx *ctx)
++{
++ if (ctx->size &&
++ ((strcmp(ctx->kname->name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
++ (strcmp(ctx->kname->name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)))
++ posix_acl_fix_xattr_from_user(mnt_userns, d_inode(d),
++ ctx->kvalue, ctx->size);
++}
++
++int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
++ struct xattr_ctx *ctx)
++{
++ setxattr_convert(mnt_userns, dentry, ctx);
++ return vfs_setxattr(mnt_userns, dentry, ctx->kname->name,
++ ctx->kvalue, ctx->size, ctx->flags);
++}
++
++static long
++setxattr(struct user_namespace *mnt_userns, struct dentry *d,
++ const char __user *name, const void __user *value, size_t size,
++ int flags)
++{
++ struct xattr_name kname;
++ struct xattr_ctx ctx = {
++ .cvalue = value,
++ .kvalue = NULL,
++ .size = size,
++ .kname = &kname,
++ .flags = flags,
++ };
++ int error;
++
++ error = setxattr_copy(name, &ctx);
++ if (error)
++ return error;
++
++ error = do_setxattr(mnt_userns, d, &ctx);
+
++ kvfree(ctx.kvalue);
+ return error;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 61093b34d7f3f549bfe077e5e338f217c9112214 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 20:33:25 +0200
+Subject: gpio: mvebu: Fix check for pwm support on non-A8K platforms
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 4335417da2b8d6d9b2d4411b5f9e248e5bb2d380 ]
+
+pwm support incompatible with Armada 80x0/70x0 API is not only in
+Armada 370, but also in Armada XP, 38x and 39x. So basically every non-A8K
+platform. Fix check for pwm support appropriately.
+
+Fixes: 85b7d8abfec7 ("gpio: mvebu: add pwm support for Armada 8K/7K")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mvebu.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
+index 1448dc874dfc..a245bfd5a617 100644
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -793,8 +793,12 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
+ u32 offset;
+ u32 set;
+
+- if (of_device_is_compatible(mvchip->chip.of_node,
+- "marvell,armada-370-gpio")) {
++ if (mvchip->soc_variant == MVEBU_GPIO_SOC_VARIANT_A8K) {
++ int ret = of_property_read_u32(dev->of_node,
++ "marvell,pwm-offset", &offset);
++ if (ret < 0)
++ return 0;
++ } else {
+ /*
+ * There are only two sets of PWM configuration registers for
+ * all the GPIO lines on those SoCs which this driver reserves
+@@ -804,13 +808,6 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
+ if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm"))
+ return 0;
+ offset = 0;
+- } else if (mvchip->soc_variant == MVEBU_GPIO_SOC_VARIANT_A8K) {
+- int ret = of_property_read_u32(dev->of_node,
+- "marvell,pwm-offset", &offset);
+- if (ret < 0)
+- return 0;
+- } else {
+- return 0;
+ }
+
+ if (IS_ERR(mvchip->clk))
+--
+2.35.1
+
--- /dev/null
+From 96bd3b6adb12c0aaf3ff9740d009ce05ee06ccf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Sep 2022 11:07:15 +0800
+Subject: Input: melfas_mip4 - fix return value check in mip4_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit a54dc27bd25f20ee3ea2009584b3166d25178243 ]
+
+devm_gpiod_get_optional() may return ERR_PTR(-EPROBE_DEFER),
+add a minus sign to fix it.
+
+Fixes: 6ccb1d8f78bd ("Input: add MELFAS MIP4 Touchscreen driver")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20220924030715.1653538-1-yangyingliang@huawei.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/melfas_mip4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c
+index 2745bf1aee38..83f4be05e27b 100644
+--- a/drivers/input/touchscreen/melfas_mip4.c
++++ b/drivers/input/touchscreen/melfas_mip4.c
+@@ -1453,7 +1453,7 @@ static int mip4_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ "ce", GPIOD_OUT_LOW);
+ if (IS_ERR(ts->gpio_ce)) {
+ error = PTR_ERR(ts->gpio_ce);
+- if (error != EPROBE_DEFER)
++ if (error != -EPROBE_DEFER)
+ dev_err(&client->dev,
+ "Failed to get gpio: %d\n", error);
+ return error;
+--
+2.35.1
+
--- /dev/null
+From dbf925bd27d56b04db6d95b9cc3da413cd06c766 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 16:18:54 -0700
+Subject: KVM: x86: Hide IA32_PLATFORM_DCA_CAP[31:0] from the guest
+
+From: Jim Mattson <jmattson@google.com>
+
+[ Upstream commit aae2e72229cdb21f90df2dbe4244c977e5d3265b ]
+
+The only thing reported by CPUID.9 is the value of
+IA32_PLATFORM_DCA_CAP[31:0] in EAX. This MSR doesn't even exist in the
+guest, since CPUID.1:ECX.DCA[bit 18] is clear in the guest.
+
+Clear CPUID.9 in KVM_GET_SUPPORTED_CPUID.
+
+Fixes: 24c82e576b78 ("KVM: Sanitize cpuid")
+Signed-off-by: Jim Mattson <jmattson@google.com>
+Message-Id: <20220922231854.249383-1-jmattson@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/cpuid.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index b17c9b00669e..d85a0808a446 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -718,8 +718,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ entry->edx = 0;
+ }
+ break;
+- case 9:
+- break;
+ case 0xa: { /* Architectural Performance Monitoring */
+ struct x86_pmu_capability cap;
+ union cpuid10_eax eax;
+--
+2.35.1
+
--- /dev/null
+From 30f24fe38185dea87cf66cb9c09fe2e451e048e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 02:36:40 +0000
+Subject: net/mlxbf_gige: Fix an IS_ERR() vs NULL bug in mlxbf_gige_mdio_probe
+
+From: Peng Wu <wupeng58@huawei.com>
+
+[ Upstream commit 4774db8dfc6a2e6649920ebb2fc8e2f062c2080d ]
+
+The devm_ioremap() function returns NULL on error, it doesn't return
+error pointers.
+
+Fixes: 3a1a274e933f ("mlxbf_gige: compute MDIO period based on i1clk")
+Signed-off-by: Peng Wu <wupeng58@huawei.com>
+Link: https://lore.kernel.org/r/20220923023640.116057-1-wupeng58@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
+index caa4380ada13..5819584345ab 100644
+--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
+@@ -244,8 +244,8 @@ int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv)
+ }
+
+ priv->clk_io = devm_ioremap(dev, res->start, resource_size(res));
+- if (IS_ERR(priv->clk_io))
+- return PTR_ERR(priv->clk_io);
++ if (!priv->clk_io)
++ return -ENOMEM;
+
+ mlxbf_gige_mdio_cfg(priv);
+
+--
+2.35.1
+
--- /dev/null
+From ed48621ed1b9781ed5f8d0c3e0bfc95fa8a1f80f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 06:09:52 +0200
+Subject: net: phy: Don't WARN for PHY_UP state in mdio_bus_phy_resume()
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit ea64cdfad124922c931633e39287c5a31a9b14a1 ]
+
+Commit 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume()
+state") introduced a WARN() on resume from system sleep if a PHY is not
+in PHY_HALTED state.
+
+Commit 6dbe852c379f ("net: phy: Don't WARN for PHY_READY state in
+mdio_bus_phy_resume()") added an exemption for PHY_READY state from
+the WARN().
+
+It turns out PHY_UP state needs to be exempted as well because the
+following may happen on suspend:
+
+ mdio_bus_phy_suspend()
+ phy_stop_machine()
+ phydev->state = PHY_UP # if (phydev->state >= PHY_UP)
+
+Fixes: 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state")
+Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/netdev/2b1a1588-505e-dff3-301d-bfc1fb14d685@samsung.com/
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Cc: Xiaolei Wang <xiaolei.wang@windriver.com>
+Link: https://lore.kernel.org/r/8128fdb51eeebc9efbf3776a4097363a1317aaf1.1663905575.git.lukas@wunner.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index b616f55ea222..c5b92ffaffb9 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -315,11 +315,13 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
+
+ phydev->suspended_by_mdio_bus = 0;
+
+- /* If we manged to get here with the PHY state machine in a state neither
+- * PHY_HALTED nor PHY_READY this is an indication that something went wrong
+- * and we should most likely be using MAC managed PM and we are not.
++ /* If we managed to get here with the PHY state machine in a state
++ * neither PHY_HALTED, PHY_READY nor PHY_UP, this is an indication
++ * that something went wrong and we should most likely be using
++ * MAC managed PM, but we are not.
+ */
+- WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY);
++ WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY &&
++ phydev->state != PHY_UP);
+
+ ret = phy_init_hw(phydev);
+ if (ret < 0)
+--
+2.35.1
+
--- /dev/null
+From 23d46b1d05593bc0626f3cc30347bfd3fb296b4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 10:00:46 +0800
+Subject: net: sched: act_ct: fix possible refcount leak in tcf_ct_init()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 6e23ec0ba92d426c77a73a9ccab16346e5e0ef49 ]
+
+nf_ct_put need to be called to put the refcount got by tcf_ct_fill_params
+to avoid possible refcount leak when tcf_ct_flow_table_get fails.
+
+Fixes: c34b961a2492 ("net/sched: act_ct: Create nf flow table per zone")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Link: https://lore.kernel.org/r/20220923020046.8021-1-hbh25y@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ct.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
+index f4fd584fba08..d85fdefe5730 100644
+--- a/net/sched/act_ct.c
++++ b/net/sched/act_ct.c
+@@ -1306,7 +1306,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla,
+
+ err = tcf_ct_flow_table_get(params);
+ if (err)
+- goto cleanup;
++ goto cleanup_params;
+
+ spin_lock_bh(&c->tcf_lock);
+ goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
+@@ -1321,6 +1321,9 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla,
+
+ return res;
+
++cleanup_params:
++ if (params->tmpl)
++ nf_ct_put(params->tmpl);
+ cleanup:
+ if (goto_ch)
+ tcf_chain_put_by_act(goto_ch);
+--
+2.35.1
+
--- /dev/null
+From f9d5f9e8c7cef582d267f12b0c7e97b5e36d20ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 13:04:48 +0800
+Subject: net: stmmac: power up/down serdes in stmmac_open/release
+
+From: Junxiao Chang <junxiao.chang@intel.com>
+
+[ Upstream commit 49725ffc15fc4e9fae68c55b691fd25168cbe5c1 ]
+
+This commit fixes DMA engine reset timeout issue in suspend/resume
+with ADLink I-Pi SMARC Plus board which dmesg shows:
+...
+[ 54.678271] PM: suspend exit
+[ 54.754066] intel-eth-pci 0000:00:1d.2 enp0s29f2: PHY [stmmac-3:01] driver [Maxlinear Ethernet GPY215B] (irq=POLL)
+[ 54.755808] intel-eth-pci 0000:00:1d.2 enp0s29f2: Register MEM_TYPE_PAGE_POOL RxQ-0
+...
+[ 54.780482] intel-eth-pci 0000:00:1d.2 enp0s29f2: Register MEM_TYPE_PAGE_POOL RxQ-7
+[ 55.784098] intel-eth-pci 0000:00:1d.2: Failed to reset the dma
+[ 55.784111] intel-eth-pci 0000:00:1d.2 enp0s29f2: stmmac_hw_setup: DMA engine initialization failed
+[ 55.784115] intel-eth-pci 0000:00:1d.2 enp0s29f2: stmmac_open: Hw setup failed
+...
+
+The issue is related with serdes which impacts clock. There is
+serdes in ADLink I-Pi SMARC board ethernet controller. Please refer to
+commit b9663b7ca6ff78 ("net: stmmac: Enable SERDES power up/down sequence")
+for detial. When issue is reproduced, DMA engine clock is not ready
+because serdes is not powered up.
+
+To reproduce DMA engine reset timeout issue with hardware which has
+serdes in GBE controller, install Ubuntu. In Ubuntu GUI, click
+"Power Off/Log Out" -> "Suspend" menu, it disables network interface,
+then goes to sleep mode. When it wakes up, it enables network
+interface again. Stmmac driver is called in this way:
+
+1. stmmac_release: Stop network interface. In this function, it
+ disables DMA engine and network interface;
+2. stmmac_suspend: It is called in kernel suspend flow. But because
+ network interface has been disabled(netif_running(ndev) is
+ false), it does nothing and returns directly;
+3. System goes into S3 or S0ix state. Some time later, system is
+ waken up by keyboard or mouse;
+4. stmmac_resume: It does nothing because network interface has
+ been disabled;
+5. stmmac_open: It is called to enable network interace again. DMA
+ engine is initialized in this API, but serdes is not power on so
+ there will be DMA engine reset timeout issue.
+
+Similarly, serdes powerdown should be added in stmmac_release.
+Network interface might be disabled by cmd "ifconfig eth0 down",
+DMA engine, phy and mac have been disabled in ndo_stop callback,
+serdes should be powered down as well. It doesn't make sense that
+serdes is on while other components have been turned off.
+
+If ethernet interface is in enabled state(netif_running(ndev) is true)
+before suspend/resume, the issue couldn't be reproduced because serdes
+could be powered up in stmmac_resume.
+
+Because serdes_powerup is added in stmmac_open, it doesn't need to be
+called in probe function.
+
+Fixes: b9663b7ca6ff78 ("net: stmmac: Enable SERDES power up/down sequence")
+Signed-off-by: Junxiao Chang <junxiao.chang@intel.com>
+Reviewed-by: Voon Weifeng <weifeng.voon@intel.com>
+Tested-by: Jimmy JS Chen <jimmyjs.chen@adlinktech.com>
+Tested-by: Looi, Hong Aun <hong.aun.looi@intel.com>
+Link: https://lore.kernel.org/r/20220923050448.1220250-1-junxiao.chang@intel.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 23 +++++++++++--------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 2569673559df..6f579f498993 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -3757,6 +3757,15 @@ static int stmmac_open(struct net_device *dev)
+ goto init_error;
+ }
+
++ if (priv->plat->serdes_powerup) {
++ ret = priv->plat->serdes_powerup(dev, priv->plat->bsp_priv);
++ if (ret < 0) {
++ netdev_err(priv->dev, "%s: Serdes powerup failed\n",
++ __func__);
++ goto init_error;
++ }
++ }
++
+ ret = stmmac_hw_setup(dev, true);
+ if (ret < 0) {
+ netdev_err(priv->dev, "%s: Hw setup failed\n", __func__);
+@@ -3846,6 +3855,10 @@ static int stmmac_release(struct net_device *dev)
+ /* Disable the MAC Rx/Tx */
+ stmmac_mac_set(priv, priv->ioaddr, false);
+
++ /* Powerdown Serdes if there is */
++ if (priv->plat->serdes_powerdown)
++ priv->plat->serdes_powerdown(dev, priv->plat->bsp_priv);
++
+ netif_carrier_off(dev);
+
+ stmmac_release_ptp(priv);
+@@ -7224,14 +7237,6 @@ int stmmac_dvr_probe(struct device *device,
+ goto error_netdev_register;
+ }
+
+- if (priv->plat->serdes_powerup) {
+- ret = priv->plat->serdes_powerup(ndev,
+- priv->plat->bsp_priv);
+-
+- if (ret < 0)
+- goto error_serdes_powerup;
+- }
+-
+ #ifdef CONFIG_DEBUG_FS
+ stmmac_init_fs(ndev);
+ #endif
+@@ -7246,8 +7251,6 @@ int stmmac_dvr_probe(struct device *device,
+
+ return ret;
+
+-error_serdes_powerup:
+- unregister_netdev(ndev);
+ error_netdev_register:
+ phylink_destroy(priv->phylink);
+ error_xpcs_setup:
+--
+2.35.1
+
--- /dev/null
+From e9df599681f606d3044190930b233b98a3e8ad23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 21:49:09 -0700
+Subject: nvme: Fix IOC_PR_CLEAR and IOC_PR_RELEASE ioctls for nvme devices
+
+From: Michael Kelley <mikelley@microsoft.com>
+
+[ Upstream commit c292a337d0e45a292c301e3cd51c35aa0ae91e95 ]
+
+The IOC_PR_CLEAR and IOC_PR_RELEASE ioctls are
+non-functional on NVMe devices because the nvme_pr_clear()
+and nvme_pr_release() functions set the IEKEY field incorrectly.
+The IEKEY field should be set only when the key is zero (i.e,
+not specified). The current code does it backwards.
+
+Furthermore, the NVMe spec describes the persistent
+reservation "clear" function as an option on the reservation
+release command. The current implementation of nvme_pr_clear()
+erroneously uses the reservation register command.
+
+Fix these errors. Note that NVMe version 1.3 and later specify
+that setting the IEKEY field will return an error of Invalid
+Field in Command. The fix will set IEKEY when the key is zero,
+which is appropriate as these ioctls consider a zero key to
+be "unspecified", and the intention of the spec change is
+to require a valid key.
+
+Tested on a version 1.4 PCI NVMe device in an Azure VM.
+
+Fixes: 1673f1f08c88 ("nvme: move block_device_operations and ns/ctrl freeing to common code")
+Fixes: 1d277a637a71 ("NVMe: Add persistent reservation ops")
+Signed-off-by: Michael Kelley <mikelley@microsoft.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index ed2740585c5d..76d8a72f52e2 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -2056,14 +2056,14 @@ static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new,
+
+ static int nvme_pr_clear(struct block_device *bdev, u64 key)
+ {
+- u32 cdw10 = 1 | (key ? 1 << 3 : 0);
++ u32 cdw10 = 1 | (key ? 0 : 1 << 3);
+
+- return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register);
++ return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
+ }
+
+ static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
+ {
+- u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 1 << 3 : 0);
++ u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 0 : 1 << 3);
+
+ return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release);
+ }
+--
+2.35.1
+
--- /dev/null
+From e927c72e5390396a7ce5aa5ed744d5ccbdef09c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Sep 2021 10:52:39 +0800
+Subject: perf list: Display hybrid PMU events with cpu type
+
+From: Jin Yao <yao.jin@linux.intel.com>
+
+[ Upstream commit 0e0ae8742207c3b477cf0357b8115cec7b19612c ]
+
+Add a new option '--cputype' to 'perf list' to display core-only PMU
+events or atom-only PMU events.
+
+Each hybrid PMU event has been assigned with a PMU name, this patch
+compares the PMU name before listing the result.
+
+For example:
+
+ perf list --cputype atom
+ ...
+ cache:
+ core_reject_l2q.any
+ [Counts the number of request that were not accepted into the L2Q because the L2Q is FULL. Unit: cpu_atom]
+ ...
+
+The "Unit: cpu_atom" is displayed in the brief description section
+to indicate this is an atom event.
+
+Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Jin Yao <yao.jin@intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: http://lore.kernel.org/lkml/20210903025239.22754-1-yao.jin@linux.intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/Documentation/perf-list.txt | 4 +++
+ tools/perf/builtin-list.c | 42 ++++++++++++++++++--------
+ tools/perf/util/metricgroup.c | 7 ++++-
+ tools/perf/util/metricgroup.h | 2 +-
+ tools/perf/util/parse-events.c | 8 +++--
+ tools/perf/util/parse-events.h | 3 +-
+ tools/perf/util/pmu.c | 29 +++++++++++++++---
+ tools/perf/util/pmu.h | 2 +-
+ 8 files changed, 73 insertions(+), 24 deletions(-)
+
+diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
+index 4c7db1da8fcc..4dc8d0af19df 100644
+--- a/tools/perf/Documentation/perf-list.txt
++++ b/tools/perf/Documentation/perf-list.txt
+@@ -39,6 +39,10 @@ any extra expressions computed by perf stat.
+ --deprecated::
+ Print deprecated events. By default the deprecated events are hidden.
+
++--cputype::
++Print events applying cpu with this type for hybrid platform
++(e.g. --cputype core or --cputype atom)
++
+ [[EVENT_MODIFIERS]]
+ EVENT MODIFIERS
+ ---------------
+diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
+index 10ab5e40a34f..468958154ed9 100644
+--- a/tools/perf/builtin-list.c
++++ b/tools/perf/builtin-list.c
+@@ -12,6 +12,7 @@
+
+ #include "util/parse-events.h"
+ #include "util/pmu.h"
++#include "util/pmu-hybrid.h"
+ #include "util/debug.h"
+ #include "util/metricgroup.h"
+ #include <subcmd/pager.h>
+@@ -20,13 +21,15 @@
+
+ static bool desc_flag = true;
+ static bool details_flag;
++static const char *hybrid_type;
+
+ int cmd_list(int argc, const char **argv)
+ {
+- int i;
++ int i, ret = 0;
+ bool raw_dump = false;
+ bool long_desc_flag = false;
+ bool deprecated = false;
++ char *pmu_name = NULL;
+ struct option list_options[] = {
+ OPT_BOOLEAN(0, "raw-dump", &raw_dump, "Dump raw events"),
+ OPT_BOOLEAN('d', "desc", &desc_flag,
+@@ -37,6 +40,9 @@ int cmd_list(int argc, const char **argv)
+ "Print information on the perf event names and expressions used internally by events."),
+ OPT_BOOLEAN(0, "deprecated", &deprecated,
+ "Print deprecated events."),
++ OPT_STRING(0, "cputype", &hybrid_type, "hybrid cpu type",
++ "Print events applying cpu with this type for hybrid platform "
++ "(e.g. core or atom)"),
+ OPT_INCR(0, "debug", &verbose,
+ "Enable debugging output"),
+ OPT_END()
+@@ -56,10 +62,16 @@ int cmd_list(int argc, const char **argv)
+ if (!raw_dump && pager_in_use())
+ printf("\nList of pre-defined events (to be used in -e):\n\n");
+
++ if (hybrid_type) {
++ pmu_name = perf_pmu__hybrid_type_to_pmu(hybrid_type);
++ if (!pmu_name)
++ pr_warning("WARNING: hybrid cputype is not supported!\n");
++ }
++
+ if (argc == 0) {
+ print_events(NULL, raw_dump, !desc_flag, long_desc_flag,
+- details_flag, deprecated);
+- return 0;
++ details_flag, deprecated, pmu_name);
++ goto out;
+ }
+
+ for (i = 0; i < argc; ++i) {
+@@ -82,25 +94,27 @@ int cmd_list(int argc, const char **argv)
+ else if (strcmp(argv[i], "pmu") == 0)
+ print_pmu_events(NULL, raw_dump, !desc_flag,
+ long_desc_flag, details_flag,
+- deprecated);
++ deprecated, pmu_name);
+ else if (strcmp(argv[i], "sdt") == 0)
+ print_sdt_events(NULL, NULL, raw_dump);
+ else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0)
+- metricgroup__print(true, false, NULL, raw_dump, details_flag);
++ metricgroup__print(true, false, NULL, raw_dump, details_flag, pmu_name);
+ else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0)
+- metricgroup__print(false, true, NULL, raw_dump, details_flag);
++ metricgroup__print(false, true, NULL, raw_dump, details_flag, pmu_name);
+ else if ((sep = strchr(argv[i], ':')) != NULL) {
+ int sep_idx;
+
+ sep_idx = sep - argv[i];
+ s = strdup(argv[i]);
+- if (s == NULL)
+- return -1;
++ if (s == NULL) {
++ ret = -1;
++ goto out;
++ }
+
+ s[sep_idx] = '\0';
+ print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
+ print_sdt_events(s, s + sep_idx + 1, raw_dump);
+- metricgroup__print(true, true, s, raw_dump, details_flag);
++ metricgroup__print(true, true, s, raw_dump, details_flag, pmu_name);
+ free(s);
+ } else {
+ if (asprintf(&s, "*%s*", argv[i]) < 0) {
+@@ -116,12 +130,16 @@ int cmd_list(int argc, const char **argv)
+ print_pmu_events(s, raw_dump, !desc_flag,
+ long_desc_flag,
+ details_flag,
+- deprecated);
++ deprecated,
++ pmu_name);
+ print_tracepoint_events(NULL, s, raw_dump);
+ print_sdt_events(NULL, s, raw_dump);
+- metricgroup__print(true, true, s, raw_dump, details_flag);
++ metricgroup__print(true, true, s, raw_dump, details_flag, pmu_name);
+ free(s);
+ }
+ }
+- return 0;
++
++out:
++ free(pmu_name);
++ return ret;
+ }
+diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
+index ec8195f1ab50..9d172ac66062 100644
+--- a/tools/perf/util/metricgroup.c
++++ b/tools/perf/util/metricgroup.c
+@@ -11,6 +11,7 @@
+ #include "evsel.h"
+ #include "strbuf.h"
+ #include "pmu.h"
++#include "pmu-hybrid.h"
+ #include "expr.h"
+ #include "rblist.h"
+ #include <string.h>
+@@ -616,7 +617,7 @@ static int metricgroup__print_sys_event_iter(struct pmu_event *pe, void *data)
+ }
+
+ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
+- bool raw, bool details)
++ bool raw, bool details, const char *pmu_name)
+ {
+ struct pmu_events_map *map = pmu_events_map__find();
+ struct pmu_event *pe;
+@@ -642,6 +643,10 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
+ break;
+ if (!pe->metric_expr)
+ continue;
++ if (pmu_name && perf_pmu__is_hybrid(pe->pmu) &&
++ strcmp(pmu_name, pe->pmu)) {
++ continue;
++ }
+ if (metricgroup__print_pmu_event(pe, metricgroups, filter,
+ raw, details, &groups,
+ metriclist) < 0)
+diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
+index cc4a92492a61..9deee6691f2e 100644
+--- a/tools/perf/util/metricgroup.h
++++ b/tools/perf/util/metricgroup.h
+@@ -53,7 +53,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist,
+ struct rblist *metric_events);
+
+ void metricgroup__print(bool metrics, bool groups, char *filter,
+- bool raw, bool details);
++ bool raw, bool details, const char *pmu_name);
+ bool metricgroup__has_metric(const char *metric);
+ int arch_get_runtimeparam(struct pmu_event *pe __maybe_unused);
+ void metricgroup__rblist_exit(struct rblist *metric_events);
+diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
+index e62514577b97..533c4b216ae2 100644
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -3034,7 +3034,8 @@ void print_symbol_events(const char *event_glob, unsigned type,
+ * Print the help text for the event symbols:
+ */
+ void print_events(const char *event_glob, bool name_only, bool quiet_flag,
+- bool long_desc, bool details_flag, bool deprecated)
++ bool long_desc, bool details_flag, bool deprecated,
++ const char *pmu_name)
+ {
+ print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
+ event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
+@@ -3046,7 +3047,7 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag,
+ print_hwcache_events(event_glob, name_only);
+
+ print_pmu_events(event_glob, name_only, quiet_flag, long_desc,
+- details_flag, deprecated);
++ details_flag, deprecated, pmu_name);
+
+ if (event_glob != NULL)
+ return;
+@@ -3072,7 +3073,8 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag,
+
+ print_sdt_events(NULL, NULL, name_only);
+
+- metricgroup__print(true, true, NULL, name_only, details_flag);
++ metricgroup__print(true, true, NULL, name_only, details_flag,
++ pmu_name);
+
+ print_libpfm_events(name_only, long_desc);
+ }
+diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
+index 9de27b7c9eec..46e9ec9588ec 100644
+--- a/tools/perf/util/parse-events.h
++++ b/tools/perf/util/parse-events.h
+@@ -221,7 +221,8 @@ void parse_events_evlist_error(struct parse_events_state *parse_state,
+ int idx, const char *str);
+
+ void print_events(const char *event_glob, bool name_only, bool quiet,
+- bool long_desc, bool details_flag, bool deprecated);
++ bool long_desc, bool details_flag, bool deprecated,
++ const char *pmu_name);
+
+ struct event_symbol {
+ const char *symbol;
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index c647b3633d1d..79ee52faaf9b 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -1608,6 +1608,7 @@ static int cmp_sevent(const void *a, const void *b)
+ {
+ const struct sevent *as = a;
+ const struct sevent *bs = b;
++ int ret;
+
+ /* Put extra events last */
+ if (!!as->desc != !!bs->desc)
+@@ -1623,7 +1624,13 @@ static int cmp_sevent(const void *a, const void *b)
+ if (as->is_cpu != bs->is_cpu)
+ return bs->is_cpu - as->is_cpu;
+
+- return strcmp(as->name, bs->name);
++ ret = strcmp(as->name, bs->name);
++ if (!ret) {
++ if (as->pmu && bs->pmu)
++ return strcmp(as->pmu, bs->pmu);
++ }
++
++ return ret;
+ }
+
+ static void wordwrap(char *s, int start, int max, int corr)
+@@ -1653,7 +1660,8 @@ bool is_pmu_core(const char *name)
+ }
+
+ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
+- bool long_desc, bool details_flag, bool deprecated)
++ bool long_desc, bool details_flag, bool deprecated,
++ const char *pmu_name)
+ {
+ struct perf_pmu *pmu;
+ struct perf_pmu_alias *alias;
+@@ -1679,10 +1687,16 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
+ pmu = NULL;
+ j = 0;
+ while ((pmu = perf_pmu__scan(pmu)) != NULL) {
++ if (pmu_name && perf_pmu__is_hybrid(pmu->name) &&
++ strcmp(pmu_name, pmu->name)) {
++ continue;
++ }
++
+ list_for_each_entry(alias, &pmu->aliases, list) {
+ char *name = alias->desc ? alias->name :
+ format_alias(buf, sizeof(buf), pmu, alias);
+- bool is_cpu = is_pmu_core(pmu->name);
++ bool is_cpu = is_pmu_core(pmu->name) ||
++ perf_pmu__is_hybrid(pmu->name);
+
+ if (alias->deprecated && !deprecated)
+ continue;
+@@ -1730,8 +1744,13 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
+ qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
+ for (j = 0; j < len; j++) {
+ /* Skip duplicates */
+- if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name))
+- continue;
++ if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name)) {
++ if (!aliases[j].pmu || !aliases[j - 1].pmu ||
++ !strcmp(aliases[j].pmu, aliases[j - 1].pmu)) {
++ continue;
++ }
++ }
++
+ if (name_only) {
+ printf("%s ", aliases[j].name);
+ continue;
+diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
+index dd0736de32c8..57f7b4847fe5 100644
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -111,7 +111,7 @@ struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
+ bool is_pmu_core(const char *name);
+ void print_pmu_events(const char *event_glob, bool name_only, bool quiet,
+ bool long_desc, bool details_flag,
+- bool deprecated);
++ bool deprecated, const char *pmu_name);
+ bool pmu_have_event(const char *pname, const char *name);
+
+ int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) __scanf(3, 4);
+--
+2.35.1
+
--- /dev/null
+From f752ec5fecaa469ef91d250df75bcd9ee72ab9f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Apr 2022 19:42:44 +0200
+Subject: perf list: Print all available tool events
+
+From: Florian Fischer <florian.fischer@muhq.space>
+
+[ Upstream commit 75eafc970bd9d36d906960a81376549f5dc99696 ]
+
+Introduce names for the new tool events 'user_time' and 'system_time'.
+
+ $ perf list
+ ...
+ duration_time [Tool event]
+ user_time [Tool event]
+ system_time [Tool event]
+ ...
+
+Committer testing:
+
+Before:
+
+ $ perf list | grep Tool
+ duration_time [Tool event]
+ $
+
+After:
+
+ $ perf list | grep Tool
+ duration_time [Tool event]
+ user_time [Tool event]
+ system_time [Tool event]
+ $
+
+Signed-off-by: Florian Fischer <florian.fischer@muhq.space>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
+Link: http://lore.kernel.org/lkml/20220420174244.1741958-2-florian.fischer@muhq.space
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evsel.c | 19 ++++++++++------
+ tools/perf/util/evsel.h | 1 +
+ tools/perf/util/parse-events.c | 40 +++++++++++++++++++++++++++++-----
+ 3 files changed, 47 insertions(+), 13 deletions(-)
+
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index 1e43fac90fc8..dbb27b61e0de 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -600,6 +600,17 @@ static int evsel__sw_name(struct evsel *evsel, char *bf, size_t size)
+ return r + evsel__add_modifiers(evsel, bf + r, size - r);
+ }
+
++const char *evsel__tool_names[PERF_TOOL_MAX] = {
++ "duration_time",
++ "user_time",
++ "system_time",
++};
++
++static int evsel__tool_name(enum perf_tool_event ev, char *bf, size_t size)
++{
++ return scnprintf(bf, size, "%s", evsel__tool_names[ev]);
++}
++
+ static int __evsel__bp_name(char *bf, size_t size, u64 addr, u64 type)
+ {
+ int r;
+@@ -726,12 +737,6 @@ static int evsel__raw_name(struct evsel *evsel, char *bf, size_t size)
+ return ret + evsel__add_modifiers(evsel, bf + ret, size - ret);
+ }
+
+-static int evsel__tool_name(char *bf, size_t size)
+-{
+- int ret = scnprintf(bf, size, "duration_time");
+- return ret;
+-}
+-
+ const char *evsel__name(struct evsel *evsel)
+ {
+ char bf[128];
+@@ -757,7 +762,7 @@ const char *evsel__name(struct evsel *evsel)
+
+ case PERF_TYPE_SOFTWARE:
+ if (evsel->tool_event)
+- evsel__tool_name(bf, sizeof(bf));
++ evsel__tool_name(evsel->tool_event, bf, sizeof(bf));
+ else
+ evsel__sw_name(evsel, bf, sizeof(bf));
+ break;
+diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
+index 45476a888942..cd3e38ed3dfa 100644
+--- a/tools/perf/util/evsel.h
++++ b/tools/perf/util/evsel.h
+@@ -257,6 +257,7 @@ extern const char *evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][EVSEL__MAX_ALI
+ extern const char *evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX][EVSEL__MAX_ALIASES];
+ extern const char *evsel__hw_names[PERF_COUNT_HW_MAX];
+ extern const char *evsel__sw_names[PERF_COUNT_SW_MAX];
++extern const char *evsel__tool_names[PERF_TOOL_MAX];
+ extern char *evsel__bpf_counter_events;
+ bool evsel__match_bpf_counter_events(const char *name);
+
+diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
+index 533c4b216ae2..e6b51810e85c 100644
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -156,6 +156,21 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
+ },
+ };
+
++struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = {
++ [PERF_TOOL_DURATION_TIME] = {
++ .symbol = "duration_time",
++ .alias = "",
++ },
++ [PERF_TOOL_USER_TIME] = {
++ .symbol = "user_time",
++ .alias = "",
++ },
++ [PERF_TOOL_SYSTEM_TIME] = {
++ .symbol = "system_time",
++ .alias = "",
++ },
++};
++
+ #define __PERF_EVENT_FIELD(config, name) \
+ ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
+
+@@ -2934,21 +2949,34 @@ int print_hwcache_events(const char *event_glob, bool name_only)
+ return evt_num;
+ }
+
+-static void print_tool_event(const char *name, const char *event_glob,
++static void print_tool_event(const struct event_symbol *syms, const char *event_glob,
+ bool name_only)
+ {
+- if (event_glob && !strglobmatch(name, event_glob))
++ if (syms->symbol == NULL)
++ return;
++
++ if (event_glob && !(strglobmatch(syms->symbol, event_glob) ||
++ (syms->alias && strglobmatch(syms->alias, event_glob))))
+ return;
++
+ if (name_only)
+- printf("%s ", name);
+- else
++ printf("%s ", syms->symbol);
++ else {
++ char name[MAX_NAME_LEN];
++ if (syms->alias && strlen(syms->alias))
++ snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
++ else
++ strlcpy(name, syms->symbol, MAX_NAME_LEN);
+ printf(" %-50s [%s]\n", name, "Tool event");
+-
++ }
+ }
+
+ void print_tool_events(const char *event_glob, bool name_only)
+ {
+- print_tool_event("duration_time", event_glob, name_only);
++ // Start at 1 because the first enum entry symbols no tool event
++ for (int i = 1; i < PERF_TOOL_MAX; ++i) {
++ print_tool_event(event_symbols_tool + i, event_glob, name_only);
++ }
+ if (pager_in_use())
+ printf("\n");
+ }
+--
+2.35.1
+
--- /dev/null
+From 5089ed4bb34997f7fc6d7536f2d1ea1bf59bcd88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Oct 2021 10:21:17 -0700
+Subject: perf metric: Add documentation and rename a variable.
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 68074811dfb9529bb7cade0e67d42c7f7bf209e6 ]
+
+Documentation to make current functionality clearer.
+
+Rename a variable called 'metric' to 'metric_name' as it can be
+ambiguous as to whether a string is the name of a metric or the
+expression.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Andi Kleen <ak@linux.intel.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Antonov <alexander.antonov@linux.intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andrew Kilroy <andrew.kilroy@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Changbin Du <changbin.du@intel.com>
+Cc: Denys Zagorui <dzagorui@cisco.com>
+Cc: Fabian Hemmer <copy@copy.sh>
+Cc: Felix Fietkau <nbd@nbd.name>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jacob Keller <jacob.e.keller@intel.com>
+Cc: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Cc: Jin Yao <yao.jin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Kees Kook <keescook@chromium.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Nicholas Fraser <nfraser@codeweavers.com>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Paul Clarke <pc@us.ibm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Riccardo Mancini <rickyman7@gmail.com>
+Cc: Sami Tolvanen <samitolvanen@google.com>
+Cc: ShihCheng Tu <mrtoastcheng@gmail.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Wan Jiabing <wanjiabing@vivo.com>
+Cc: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20211015172132.1162559-7-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/metricgroup.c | 59 ++++++++++++++++++++++++++++++++---
+ 1 file changed, 54 insertions(+), 5 deletions(-)
+
+diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
+index 29b747ac31c1..2dc2a0dcf846 100644
+--- a/tools/perf/util/metricgroup.c
++++ b/tools/perf/util/metricgroup.c
+@@ -772,13 +772,27 @@ int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused)
+
+ struct metricgroup_add_iter_data {
+ struct list_head *metric_list;
+- const char *metric;
++ const char *metric_name;
+ struct expr_ids *ids;
+ int *ret;
+ bool *has_match;
+ bool metric_no_group;
+ };
+
++/**
++ * __add_metric - Add a metric to metric_list.
++ * @metric_list: The list the metric is added to.
++ * @pe: The pmu_event containing the metric to be added.
++ * @metric_no_group: Should events written to events be grouped "{}" or
++ * global. Grouping is the default but due to multiplexing the
++ * user may override.
++ * @runtime: A special argument for the parser only known at runtime.
++ * @mp: The pointer to a location holding the first metric added to metric
++ * list. It is initialized here if this is the first metric.
++ * @parent: The last entry in a linked list of metrics being
++ * added/resolved. This is maintained to detect recursion.
++ * @ids: Storage for parent list.
++ */
+ static int __add_metric(struct list_head *metric_list,
+ struct pmu_event *pe,
+ bool metric_no_group,
+@@ -1068,7 +1082,7 @@ static int metricgroup__add_metric_sys_event_iter(struct pmu_event *pe,
+ struct metric *m = NULL;
+ int ret;
+
+- if (!match_pe_metric(pe, d->metric))
++ if (!match_pe_metric(pe, d->metric_name))
+ return 0;
+
+ ret = add_metric(d->metric_list, pe, d->metric_no_group, &m, NULL, d->ids);
+@@ -1087,7 +1101,22 @@ static int metricgroup__add_metric_sys_event_iter(struct pmu_event *pe,
+ return ret;
+ }
+
+-static int metricgroup__add_metric(const char *metric, bool metric_no_group,
++/**
++ * metricgroup__add_metric - Find and add a metric, or a metric group.
++ * @metric_name: The name of the metric or metric group. For example, "IPC"
++ * could be the name of a metric and "TopDownL1" the name of a
++ * metric group.
++ * @metric_no_group: Should events written to events be grouped "{}" or
++ * global. Grouping is the default but due to multiplexing the
++ * user may override.
++ * @events: an out argument string of events that need to be parsed and
++ * associated with the metric. For example, the metric "IPC" would
++ * create an events string like "{instructions,cycles}:W".
++ * @metric_list: The list that the metric or metric group are added to.
++ * @map: The map that is searched for metrics, most commonly the table for the
++ * architecture perf is running upon.
++ */
++static int metricgroup__add_metric(const char *metric_name, bool metric_no_group,
+ struct strbuf *events,
+ struct list_head *metric_list,
+ struct pmu_events_map *map)
+@@ -1099,7 +1128,11 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group,
+ int i, ret;
+ bool has_match = false;
+
+- map_for_each_metric(pe, i, map, metric) {
++ /*
++ * Iterate over all metrics seeing if metric matches either the name or
++ * group. When it does add the metric to the list.
++ */
++ map_for_each_metric(pe, i, map, metric_name) {
+ has_match = true;
+ m = NULL;
+
+@@ -1122,7 +1155,7 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group,
+ .fn = metricgroup__add_metric_sys_event_iter,
+ .data = (void *) &(struct metricgroup_add_iter_data) {
+ .metric_list = &list,
+- .metric = metric,
++ .metric_name = metric_name,
+ .metric_no_group = metric_no_group,
+ .ids = &ids,
+ .has_match = &has_match,
+@@ -1161,6 +1194,22 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group,
+ return ret;
+ }
+
++/**
++ * metricgroup__add_metric_list - Find and add metrics, or metric groups,
++ * specified in a list.
++ * @list: the list of metrics or metric groups. For example, "IPC,CPI,TopDownL1"
++ * would match the IPC and CPI metrics, and TopDownL1 would match all
++ * the metrics in the TopDownL1 group.
++ * @metric_no_group: Should events written to events be grouped "{}" or
++ * global. Grouping is the default but due to multiplexing the
++ * user may override.
++ * @events: an out argument string of events that need to be parsed and
++ * associated with the metric. For example, the metric "IPC" would
++ * create an events string like "{instructions,cycles}:W".
++ * @metric_list: The list that metrics are added to.
++ * @map: The map that is searched for metrics, most commonly the table for the
++ * architecture perf is running upon.
++ */
+ static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
+ struct strbuf *events,
+ struct list_head *metric_list,
+--
+2.35.1
+
--- /dev/null
+From aef9d246aa30dffd392308024c92bde60b7aa63a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Oct 2021 10:21:19 -0700
+Subject: perf metric: Only add a referenced metric once
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit a3de76903dd0786a8661e9e6eb9054a7519e10e7 ]
+
+If a metric references other metrics then the same other metrics may be
+referenced more than once, but the events and metric ref are only needed
+once.
+
+An example of this is in tests/parse-metric.c where DCache_L2_Hits
+references the metric DCache_L2_All_Hits twice, once directly and once
+through DCache_L2_All.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Andi Kleen <ak@linux.intel.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Antonov <alexander.antonov@linux.intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andrew Kilroy <andrew.kilroy@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Changbin Du <changbin.du@intel.com>
+Cc: Denys Zagorui <dzagorui@cisco.com>
+Cc: Fabian Hemmer <copy@copy.sh>
+Cc: Felix Fietkau <nbd@nbd.name>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jacob Keller <jacob.e.keller@intel.com>
+Cc: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Cc: Jin Yao <yao.jin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Kees Kook <keescook@chromium.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Nicholas Fraser <nfraser@codeweavers.com>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Paul Clarke <pc@us.ibm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Riccardo Mancini <rickyman7@gmail.com>
+Cc: Sami Tolvanen <samitolvanen@google.com>
+Cc: ShihCheng Tu <mrtoastcheng@gmail.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Wan Jiabing <wanjiabing@vivo.com>
+Cc: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20211015172132.1162559-9-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/metricgroup.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
+index 2dc2a0dcf846..ec8195f1ab50 100644
+--- a/tools/perf/util/metricgroup.c
++++ b/tools/perf/util/metricgroup.c
+@@ -836,12 +836,18 @@ static int __add_metric(struct list_head *metric_list,
+ *mp = m;
+ } else {
+ /*
+- * We got here for the referenced metric, via the
+- * recursive metricgroup__add_metric call, add
+- * it to the parent group.
++ * This metric was referenced in a metric higher in the
++ * tree. Check if the same metric is already resolved in the
++ * metric_refs list.
+ */
+ m = *mp;
+
++ list_for_each_entry(ref, &m->metric_refs, list) {
++ if (!strcmp(pe->metric_name, ref->metric_name))
++ return 0;
++ }
++
++ /*Add the new referenced metric to the pare the parent group. */
+ ref = malloc(sizeof(*ref));
+ if (!ref)
+ return -ENOMEM;
+--
+2.35.1
+
--- /dev/null
+From 670bef849880696397b2bdc3fc485f1746e40449 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Oct 2021 10:21:24 -0700
+Subject: perf parse-events: Add const to evsel name
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 8e8bbfb311a26a17834f1839e15e2c29ea5e58c6 ]
+
+The evsel name is strdup-ed before assignment and so can be const.
+
+A later change will add another similar string.
+
+Using const makes it clearer that these are not out arguments.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Andi Kleen <ak@linux.intel.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Antonov <alexander.antonov@linux.intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andrew Kilroy <andrew.kilroy@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Changbin Du <changbin.du@intel.com>
+Cc: Denys Zagorui <dzagorui@cisco.com>
+Cc: Fabian Hemmer <copy@copy.sh>
+Cc: Felix Fietkau <nbd@nbd.name>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jacob Keller <jacob.e.keller@intel.com>
+Cc: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Cc: Jin Yao <yao.jin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Kees Kook <keescook@chromium.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Nicholas Fraser <nfraser@codeweavers.com>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Paul Clarke <pc@us.ibm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Riccardo Mancini <rickyman7@gmail.com>
+Cc: Sami Tolvanen <samitolvanen@google.com>
+Cc: ShihCheng Tu <mrtoastcheng@gmail.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Wan Jiabing <wanjiabing@vivo.com>
+Cc: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20211015172132.1162559-14-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/parse-events-hybrid.c | 15 +++++++++------
+ tools/perf/util/parse-events-hybrid.h | 6 ++++--
+ tools/perf/util/parse-events.c | 15 ++++++++-------
+ tools/perf/util/parse-events.h | 7 ++++---
+ tools/perf/util/pmu.c | 2 +-
+ tools/perf/util/pmu.h | 2 +-
+ 6 files changed, 27 insertions(+), 20 deletions(-)
+
+diff --git a/tools/perf/util/parse-events-hybrid.c b/tools/perf/util/parse-events-hybrid.c
+index b234d95fb10a..7e44deee1343 100644
+--- a/tools/perf/util/parse-events-hybrid.c
++++ b/tools/perf/util/parse-events-hybrid.c
+@@ -38,7 +38,7 @@ static void config_hybrid_attr(struct perf_event_attr *attr,
+
+ static int create_event_hybrid(__u32 config_type, int *idx,
+ struct list_head *list,
+- struct perf_event_attr *attr, char *name,
++ struct perf_event_attr *attr, const char *name,
+ struct list_head *config_terms,
+ struct perf_pmu *pmu)
+ {
+@@ -70,7 +70,7 @@ static int pmu_cmp(struct parse_events_state *parse_state,
+
+ static int add_hw_hybrid(struct parse_events_state *parse_state,
+ struct list_head *list, struct perf_event_attr *attr,
+- char *name, struct list_head *config_terms)
++ const char *name, struct list_head *config_terms)
+ {
+ struct perf_pmu *pmu;
+ int ret;
+@@ -94,7 +94,8 @@ static int add_hw_hybrid(struct parse_events_state *parse_state,
+ }
+
+ static int create_raw_event_hybrid(int *idx, struct list_head *list,
+- struct perf_event_attr *attr, char *name,
++ struct perf_event_attr *attr,
++ const char *name,
+ struct list_head *config_terms,
+ struct perf_pmu *pmu)
+ {
+@@ -113,7 +114,7 @@ static int create_raw_event_hybrid(int *idx, struct list_head *list,
+
+ static int add_raw_hybrid(struct parse_events_state *parse_state,
+ struct list_head *list, struct perf_event_attr *attr,
+- char *name, struct list_head *config_terms)
++ const char *name, struct list_head *config_terms)
+ {
+ struct perf_pmu *pmu;
+ int ret;
+@@ -138,7 +139,8 @@ static int add_raw_hybrid(struct parse_events_state *parse_state,
+ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
+ struct list_head *list,
+ struct perf_event_attr *attr,
+- char *name, struct list_head *config_terms,
++ const char *name,
++ struct list_head *config_terms,
+ bool *hybrid)
+ {
+ *hybrid = false;
+@@ -159,7 +161,8 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
+ }
+
+ int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
+- struct perf_event_attr *attr, char *name,
++ struct perf_event_attr *attr,
++ const char *name,
+ struct list_head *config_terms,
+ bool *hybrid,
+ struct parse_events_state *parse_state)
+diff --git a/tools/perf/util/parse-events-hybrid.h b/tools/perf/util/parse-events-hybrid.h
+index f33bd67aa851..25a4a4f73f3a 100644
+--- a/tools/perf/util/parse-events-hybrid.h
++++ b/tools/perf/util/parse-events-hybrid.h
+@@ -11,11 +11,13 @@
+ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
+ struct list_head *list,
+ struct perf_event_attr *attr,
+- char *name, struct list_head *config_terms,
++ const char *name,
++ struct list_head *config_terms,
+ bool *hybrid);
+
+ int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
+- struct perf_event_attr *attr, char *name,
++ struct perf_event_attr *attr,
++ const char *name,
+ struct list_head *config_terms,
+ bool *hybrid,
+ struct parse_events_state *parse_state);
+diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
+index b93a36ffeb9e..aaeebf0752b7 100644
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -347,7 +347,7 @@ static int parse_events__is_name_term(struct parse_events_term *term)
+ return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME;
+ }
+
+-static char *get_config_name(struct list_head *head_terms)
++static const char *get_config_name(struct list_head *head_terms)
+ {
+ struct parse_events_term *term;
+
+@@ -365,7 +365,7 @@ static struct evsel *
+ __add_event(struct list_head *list, int *idx,
+ struct perf_event_attr *attr,
+ bool init_attr,
+- char *name, struct perf_pmu *pmu,
++ const char *name, struct perf_pmu *pmu,
+ struct list_head *config_terms, bool auto_merge_stats,
+ const char *cpu_list)
+ {
+@@ -404,14 +404,14 @@ __add_event(struct list_head *list, int *idx,
+ }
+
+ struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
+- char *name, struct perf_pmu *pmu)
++ const char *name, struct perf_pmu *pmu)
+ {
+ return __add_event(NULL, &idx, attr, false, name, pmu, NULL, false,
+ NULL);
+ }
+
+ static int add_event(struct list_head *list, int *idx,
+- struct perf_event_attr *attr, char *name,
++ struct perf_event_attr *attr, const char *name,
+ struct list_head *config_terms)
+ {
+ return __add_event(list, idx, attr, true, name, NULL, config_terms,
+@@ -474,7 +474,8 @@ int parse_events_add_cache(struct list_head *list, int *idx,
+ {
+ struct perf_event_attr attr;
+ LIST_HEAD(config_terms);
+- char name[MAX_NAME_LEN], *config_name;
++ char name[MAX_NAME_LEN];
++ const char *config_name;
+ int cache_type = -1, cache_op = -1, cache_result = -1;
+ char *op_result[2] = { op_result1, op_result2 };
+ int i, n, ret;
+@@ -2038,7 +2039,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
+ return 0;
+ }
+
+-int parse_events_name(struct list_head *list, char *name)
++int parse_events_name(struct list_head *list, const char *name)
+ {
+ struct evsel *evsel;
+
+@@ -3295,7 +3296,7 @@ char *parse_events_formats_error_string(char *additional_terms)
+
+ struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx,
+ struct perf_event_attr *attr,
+- char *name, struct perf_pmu *pmu,
++ const char *name, struct perf_pmu *pmu,
+ struct list_head *config_terms)
+ {
+ return __add_event(list, idx, attr, true, name, pmu,
+diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
+index bf6e41aa9b6a..6ef506c1b29e 100644
+--- a/tools/perf/util/parse-events.h
++++ b/tools/perf/util/parse-events.h
+@@ -162,7 +162,7 @@ void parse_events_terms__purge(struct list_head *terms);
+ void parse_events__clear_array(struct parse_events_array *a);
+ int parse_events__modifier_event(struct list_head *list, char *str, bool add);
+ int parse_events__modifier_group(struct list_head *list, char *event_mod);
+-int parse_events_name(struct list_head *list, char *name);
++int parse_events_name(struct list_head *list, const char *name);
+ int parse_events_add_tracepoint(struct list_head *list, int *idx,
+ const char *sys, const char *event,
+ struct parse_events_error *error,
+@@ -200,7 +200,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
+ bool use_alias);
+
+ struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
+- char *name, struct perf_pmu *pmu);
++ const char *name, struct perf_pmu *pmu);
+
+ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
+ char *str,
+@@ -267,7 +267,8 @@ int perf_pmu__test_parse_init(void);
+
+ struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx,
+ struct perf_event_attr *attr,
+- char *name, struct perf_pmu *pmu,
++ const char *name,
++ struct perf_pmu *pmu,
+ struct list_head *config_terms);
+
+ #endif /* __PERF_PARSE_EVENTS_H */
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index bdabd62170d2..c647b3633d1d 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -1906,7 +1906,7 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu)
+ }
+
+ void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
+- char *name)
++ const char *name)
+ {
+ struct perf_pmu_format *format;
+ __u64 masks = 0, bits;
+diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
+index 394898b07fd9..dd0736de32c8 100644
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -134,7 +134,7 @@ int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
+ int perf_pmu__caps_parse(struct perf_pmu *pmu);
+
+ void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
+- char *name);
++ const char *name);
+
+ bool perf_pmu__has_hybrid(void);
+ int perf_pmu__match(char *pattern, char *name, char *tok);
+--
+2.35.1
+
--- /dev/null
+From 082651a7812b0dba20aaea970ebd529b78f6202d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Oct 2021 10:21:25 -0700
+Subject: perf parse-events: Add new "metric-id" term
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 2b62b3a611715d3ca612e3225cf436277ed9648b ]
+
+Add a new "metric-id" term to events so that metric parsing can set an
+ID that can be reliably looked up.
+
+Metric parsing currently will turn a metric like "instructions/cycles"
+into a parse events string of "{instructions,cycles}:W".
+
+However, parse-events may change "instructions" into "instructions:u" if
+perf_event_paranoid=2.
+
+When this happens expr__resolve_id currently fails as stat-shadow adds
+the ID "instructions:u" to match with the counter value and the metric
+tries to look up the ID just "instructions".
+
+A later patch will use the new term.
+
+An example of the current problem:
+
+ $ echo -1 > /proc/sys/kernel/perf_event_paranoid
+ $ perf stat -M IPC /bin/true
+ Performance counter stats for '/bin/true':
+
+ 1,217,161 inst_retired.any # 0.97 IPC
+ 1,250,389 cpu_clk_unhalted.thread
+
+ 0.002064773 seconds time elapsed
+
+ 0.002378000 seconds user
+ 0.000000000 seconds sys
+
+ $ echo 2 > /proc/sys/kernel/perf_event_paranoid
+ $ perf stat -M IPC /bin/true
+ Performance counter stats for '/bin/true':
+
+ 150,298 inst_retired.any:u # nan IPC
+ 187,095 cpu_clk_unhalted.thread:u
+
+ 0.002042731 seconds time elapsed
+
+ 0.000000000 seconds user
+ 0.002377000 seconds sys
+
+Note: nan IPC is printed as an effect of "perf metric: Use NAN for
+missing event IDs." but earlier versions of perf just fail with a parse
+error and display no value.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Andi Kleen <ak@linux.intel.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Antonov <alexander.antonov@linux.intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andrew Kilroy <andrew.kilroy@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Changbin Du <changbin.du@intel.com>
+Cc: Denys Zagorui <dzagorui@cisco.com>
+Cc: Fabian Hemmer <copy@copy.sh>
+Cc: Felix Fietkau <nbd@nbd.name>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jacob Keller <jacob.e.keller@intel.com>
+Cc: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Cc: Jin Yao <yao.jin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Kees Kook <keescook@chromium.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Nicholas Fraser <nfraser@codeweavers.com>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Paul Clarke <pc@us.ibm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Riccardo Mancini <rickyman7@gmail.com>
+Cc: Sami Tolvanen <samitolvanen@google.com>
+Cc: ShihCheng Tu <mrtoastcheng@gmail.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Wan Jiabing <wanjiabing@vivo.com>
+Cc: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20211015172132.1162559-15-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evsel.c | 17 +++++
+ tools/perf/util/evsel.h | 2 +
+ tools/perf/util/parse-events-hybrid.c | 25 ++++---
+ tools/perf/util/parse-events-hybrid.h | 4 +-
+ tools/perf/util/parse-events.c | 95 ++++++++++++++++++---------
+ tools/perf/util/parse-events.h | 5 +-
+ tools/perf/util/parse-events.l | 1 +
+ tools/perf/util/pfm.c | 3 +-
+ 8 files changed, 107 insertions(+), 45 deletions(-)
+
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index c87f9974c0c1..1e43fac90fc8 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -410,6 +410,11 @@ struct evsel *evsel__clone(struct evsel *orig)
+ if (evsel->filter == NULL)
+ goto out_err;
+ }
++ if (orig->metric_id) {
++ evsel->metric_id = strdup(orig->metric_id);
++ if (evsel->metric_id == NULL)
++ goto out_err;
++ }
+ evsel->cgrp = cgroup__get(orig->cgrp);
+ evsel->tp_format = orig->tp_format;
+ evsel->handler = orig->handler;
+@@ -779,6 +784,17 @@ const char *evsel__name(struct evsel *evsel)
+ return "unknown";
+ }
+
++const char *evsel__metric_id(const struct evsel *evsel)
++{
++ if (evsel->metric_id)
++ return evsel->metric_id;
++
++ if (evsel->core.attr.type == PERF_TYPE_SOFTWARE && evsel->tool_event)
++ return "duration_time";
++
++ return "unknown";
++}
++
+ const char *evsel__group_name(struct evsel *evsel)
+ {
+ return evsel->group_name ?: "anon group";
+@@ -1432,6 +1448,7 @@ void evsel__exit(struct evsel *evsel)
+ zfree(&evsel->group_name);
+ zfree(&evsel->name);
+ zfree(&evsel->pmu_name);
++ zfree(&evsel->metric_id);
+ evsel__zero_per_pkg(evsel);
+ hashmap__free(evsel->per_pkg_mask);
+ evsel->per_pkg_mask = NULL;
+diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
+index 1f7edfa8568a..45476a888942 100644
+--- a/tools/perf/util/evsel.h
++++ b/tools/perf/util/evsel.h
+@@ -68,6 +68,7 @@ struct evsel {
+ double scale;
+ const char *unit;
+ struct cgroup *cgrp;
++ const char *metric_id;
+ enum perf_tool_event tool_event;
+ /* parse modifier helper */
+ int exclude_GH;
+@@ -261,6 +262,7 @@ bool evsel__match_bpf_counter_events(const char *name);
+
+ int __evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size);
+ const char *evsel__name(struct evsel *evsel);
++const char *evsel__metric_id(const struct evsel *evsel);
+
+ const char *evsel__group_name(struct evsel *evsel);
+ int evsel__group_desc(struct evsel *evsel, char *buf, size_t size);
+diff --git a/tools/perf/util/parse-events-hybrid.c b/tools/perf/util/parse-events-hybrid.c
+index 7e44deee1343..9fc86971027b 100644
+--- a/tools/perf/util/parse-events-hybrid.c
++++ b/tools/perf/util/parse-events-hybrid.c
+@@ -39,6 +39,7 @@ static void config_hybrid_attr(struct perf_event_attr *attr,
+ static int create_event_hybrid(__u32 config_type, int *idx,
+ struct list_head *list,
+ struct perf_event_attr *attr, const char *name,
++ const char *metric_id,
+ struct list_head *config_terms,
+ struct perf_pmu *pmu)
+ {
+@@ -47,7 +48,7 @@ static int create_event_hybrid(__u32 config_type, int *idx,
+ __u64 config = attr->config;
+
+ config_hybrid_attr(attr, config_type, pmu->type);
+- evsel = parse_events__add_event_hybrid(list, idx, attr, name,
++ evsel = parse_events__add_event_hybrid(list, idx, attr, name, metric_id,
+ pmu, config_terms);
+ if (evsel)
+ evsel->pmu_name = strdup(pmu->name);
+@@ -70,7 +71,8 @@ static int pmu_cmp(struct parse_events_state *parse_state,
+
+ static int add_hw_hybrid(struct parse_events_state *parse_state,
+ struct list_head *list, struct perf_event_attr *attr,
+- const char *name, struct list_head *config_terms)
++ const char *name, const char *metric_id,
++ struct list_head *config_terms)
+ {
+ struct perf_pmu *pmu;
+ int ret;
+@@ -84,7 +86,7 @@ static int add_hw_hybrid(struct parse_events_state *parse_state,
+ copy_config_terms(&terms, config_terms);
+ ret = create_event_hybrid(PERF_TYPE_HARDWARE,
+ &parse_state->idx, list, attr, name,
+- &terms, pmu);
++ metric_id, &terms, pmu);
+ free_config_terms(&terms);
+ if (ret)
+ return ret;
+@@ -96,13 +98,14 @@ static int add_hw_hybrid(struct parse_events_state *parse_state,
+ static int create_raw_event_hybrid(int *idx, struct list_head *list,
+ struct perf_event_attr *attr,
+ const char *name,
++ const char *metric_id,
+ struct list_head *config_terms,
+ struct perf_pmu *pmu)
+ {
+ struct evsel *evsel;
+
+ attr->type = pmu->type;
+- evsel = parse_events__add_event_hybrid(list, idx, attr, name,
++ evsel = parse_events__add_event_hybrid(list, idx, attr, name, metric_id,
+ pmu, config_terms);
+ if (evsel)
+ evsel->pmu_name = strdup(pmu->name);
+@@ -114,7 +117,8 @@ static int create_raw_event_hybrid(int *idx, struct list_head *list,
+
+ static int add_raw_hybrid(struct parse_events_state *parse_state,
+ struct list_head *list, struct perf_event_attr *attr,
+- const char *name, struct list_head *config_terms)
++ const char *name, const char *metric_id,
++ struct list_head *config_terms)
+ {
+ struct perf_pmu *pmu;
+ int ret;
+@@ -127,7 +131,7 @@ static int add_raw_hybrid(struct parse_events_state *parse_state,
+
+ copy_config_terms(&terms, config_terms);
+ ret = create_raw_event_hybrid(&parse_state->idx, list, attr,
+- name, &terms, pmu);
++ name, metric_id, &terms, pmu);
+ free_config_terms(&terms);
+ if (ret)
+ return ret;
+@@ -139,7 +143,7 @@ static int add_raw_hybrid(struct parse_events_state *parse_state,
+ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
+ struct list_head *list,
+ struct perf_event_attr *attr,
+- const char *name,
++ const char *name, const char *metric_id,
+ struct list_head *config_terms,
+ bool *hybrid)
+ {
+@@ -152,17 +156,18 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
+
+ *hybrid = true;
+ if (attr->type != PERF_TYPE_RAW) {
+- return add_hw_hybrid(parse_state, list, attr, name,
++ return add_hw_hybrid(parse_state, list, attr, name, metric_id,
+ config_terms);
+ }
+
+- return add_raw_hybrid(parse_state, list, attr, name,
++ return add_raw_hybrid(parse_state, list, attr, name, metric_id,
+ config_terms);
+ }
+
+ int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
+ struct perf_event_attr *attr,
+ const char *name,
++ const char *metric_id,
+ struct list_head *config_terms,
+ bool *hybrid,
+ struct parse_events_state *parse_state)
+@@ -183,7 +188,7 @@ int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
+
+ copy_config_terms(&terms, config_terms);
+ ret = create_event_hybrid(PERF_TYPE_HW_CACHE, idx, list,
+- attr, name, &terms, pmu);
++ attr, name, metric_id, &terms, pmu);
+ free_config_terms(&terms);
+ if (ret)
+ return ret;
+diff --git a/tools/perf/util/parse-events-hybrid.h b/tools/perf/util/parse-events-hybrid.h
+index 25a4a4f73f3a..cbc05fec02a2 100644
+--- a/tools/perf/util/parse-events-hybrid.h
++++ b/tools/perf/util/parse-events-hybrid.h
+@@ -11,13 +11,13 @@
+ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
+ struct list_head *list,
+ struct perf_event_attr *attr,
+- const char *name,
++ const char *name, const char *metric_id,
+ struct list_head *config_terms,
+ bool *hybrid);
+
+ int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
+ struct perf_event_attr *attr,
+- const char *name,
++ const char *name, const char *metric_id,
+ struct list_head *config_terms,
+ bool *hybrid,
+ struct parse_events_state *parse_state);
+diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
+index aaeebf0752b7..e62514577b97 100644
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -342,12 +342,7 @@ const char *event_type(int type)
+ return "unknown";
+ }
+
+-static int parse_events__is_name_term(struct parse_events_term *term)
+-{
+- return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME;
+-}
+-
+-static const char *get_config_name(struct list_head *head_terms)
++static char *get_config_str(struct list_head *head_terms, int type_term)
+ {
+ struct parse_events_term *term;
+
+@@ -355,17 +350,27 @@ static const char *get_config_name(struct list_head *head_terms)
+ return NULL;
+
+ list_for_each_entry(term, head_terms, list)
+- if (parse_events__is_name_term(term))
++ if (term->type_term == type_term)
+ return term->val.str;
+
+ return NULL;
+ }
+
++static char *get_config_metric_id(struct list_head *head_terms)
++{
++ return get_config_str(head_terms, PARSE_EVENTS__TERM_TYPE_METRIC_ID);
++}
++
++static char *get_config_name(struct list_head *head_terms)
++{
++ return get_config_str(head_terms, PARSE_EVENTS__TERM_TYPE_NAME);
++}
++
+ static struct evsel *
+ __add_event(struct list_head *list, int *idx,
+ struct perf_event_attr *attr,
+ bool init_attr,
+- const char *name, struct perf_pmu *pmu,
++ const char *name, const char *metric_id, struct perf_pmu *pmu,
+ struct list_head *config_terms, bool auto_merge_stats,
+ const char *cpu_list)
+ {
+@@ -394,6 +399,9 @@ __add_event(struct list_head *list, int *idx,
+ if (name)
+ evsel->name = strdup(name);
+
++ if (metric_id)
++ evsel->metric_id = strdup(metric_id);
++
+ if (config_terms)
+ list_splice_init(config_terms, &evsel->config_terms);
+
+@@ -404,18 +412,21 @@ __add_event(struct list_head *list, int *idx,
+ }
+
+ struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
+- const char *name, struct perf_pmu *pmu)
++ const char *name, const char *metric_id,
++ struct perf_pmu *pmu)
+ {
+- return __add_event(NULL, &idx, attr, false, name, pmu, NULL, false,
+- NULL);
++ return __add_event(/*list=*/NULL, &idx, attr, /*init_attr=*/false, name,
++ metric_id, pmu, /*config_terms=*/NULL,
++ /*auto_merge_stats=*/false, /*cpu_list=*/NULL);
+ }
+
+ static int add_event(struct list_head *list, int *idx,
+ struct perf_event_attr *attr, const char *name,
+- struct list_head *config_terms)
++ const char *metric_id, struct list_head *config_terms)
+ {
+- return __add_event(list, idx, attr, true, name, NULL, config_terms,
+- false, NULL) ? 0 : -ENOMEM;
++ return __add_event(list, idx, attr, /*init_attr*/true, name, metric_id,
++ /*pmu=*/NULL, config_terms,
++ /*auto_merge_stats=*/false, /*cpu_list=*/NULL) ? 0 : -ENOMEM;
+ }
+
+ static int add_event_tool(struct list_head *list, int *idx,
+@@ -427,8 +438,10 @@ static int add_event_tool(struct list_head *list, int *idx,
+ .config = PERF_COUNT_SW_DUMMY,
+ };
+
+- evsel = __add_event(list, idx, &attr, true, NULL, NULL, NULL, false,
+- "0");
++ evsel = __add_event(list, idx, &attr, /*init_attr=*/true, /*name=*/NULL,
++ /*metric_id=*/NULL, /*pmu=*/NULL,
++ /*config_terms=*/NULL, /*auto_merge_stats=*/false,
++ /*cpu_list=*/"0");
+ if (!evsel)
+ return -ENOMEM;
+ evsel->tool_event = tool_event;
+@@ -475,7 +488,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,
+ struct perf_event_attr attr;
+ LIST_HEAD(config_terms);
+ char name[MAX_NAME_LEN];
+- const char *config_name;
++ const char *config_name, *metric_id;
+ int cache_type = -1, cache_op = -1, cache_result = -1;
+ char *op_result[2] = { op_result1, op_result2 };
+ int i, n, ret;
+@@ -540,13 +553,17 @@ int parse_events_add_cache(struct list_head *list, int *idx,
+ return -ENOMEM;
+ }
+
++ metric_id = get_config_metric_id(head_config);
+ ret = parse_events__add_cache_hybrid(list, idx, &attr,
+- config_name ? : name, &config_terms,
++ config_name ? : name,
++ metric_id,
++ &config_terms,
+ &hybrid, parse_state);
+ if (hybrid)
+ goto out_free_terms;
+
+- ret = add_event(list, idx, &attr, config_name ? : name, &config_terms);
++ ret = add_event(list, idx, &attr, config_name ? : name, metric_id,
++ &config_terms);
+ out_free_terms:
+ free_config_terms(&config_terms);
+ return ret;
+@@ -1023,7 +1040,8 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
+ attr.type = PERF_TYPE_BREAKPOINT;
+ attr.sample_period = 1;
+
+- return add_event(list, idx, &attr, NULL, NULL);
++ return add_event(list, idx, &attr, /*name=*/NULL, /*mertic_id=*/NULL,
++ /*config_terms=*/NULL);
+ }
+
+ static int check_type_val(struct parse_events_term *term,
+@@ -1068,6 +1086,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
+ [PARSE_EVENTS__TERM_TYPE_PERCORE] = "percore",
+ [PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT] = "aux-output",
+ [PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE] = "aux-sample-size",
++ [PARSE_EVENTS__TERM_TYPE_METRIC_ID] = "metric-id",
+ };
+
+ static bool config_term_shrinked;
+@@ -1090,6 +1109,7 @@ config_term_avail(int term_type, struct parse_events_error *err)
+ case PARSE_EVENTS__TERM_TYPE_CONFIG1:
+ case PARSE_EVENTS__TERM_TYPE_CONFIG2:
+ case PARSE_EVENTS__TERM_TYPE_NAME:
++ case PARSE_EVENTS__TERM_TYPE_METRIC_ID:
+ case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
+ case PARSE_EVENTS__TERM_TYPE_PERCORE:
+ return true;
+@@ -1180,6 +1200,9 @@ do { \
+ case PARSE_EVENTS__TERM_TYPE_NAME:
+ CHECK_TYPE_VAL(STR);
+ break;
++ case PARSE_EVENTS__TERM_TYPE_METRIC_ID:
++ CHECK_TYPE_VAL(STR);
++ break;
+ case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
+ CHECK_TYPE_VAL(NUM);
+ break;
+@@ -1449,6 +1472,7 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
+ {
+ struct perf_event_attr attr;
+ LIST_HEAD(config_terms);
++ const char *name, *metric_id;
+ bool hybrid;
+ int ret;
+
+@@ -1465,14 +1489,16 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
+ return -ENOMEM;
+ }
+
++ name = get_config_name(head_config);
++ metric_id = get_config_metric_id(head_config);
+ ret = parse_events__add_numeric_hybrid(parse_state, list, &attr,
+- get_config_name(head_config),
++ name, metric_id,
+ &config_terms, &hybrid);
+ if (hybrid)
+ goto out_free_terms;
+
+- ret = add_event(list, &parse_state->idx, &attr,
+- get_config_name(head_config), &config_terms);
++ ret = add_event(list, &parse_state->idx, &attr, name, metric_id,
++ &config_terms);
+ out_free_terms:
+ free_config_terms(&config_terms);
+ return ret;
+@@ -1574,8 +1600,11 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
+
+ if (!head_config) {
+ attr.type = pmu->type;
+- evsel = __add_event(list, &parse_state->idx, &attr, true, NULL,
+- pmu, NULL, auto_merge_stats, NULL);
++ evsel = __add_event(list, &parse_state->idx, &attr,
++ /*init_attr=*/true, /*name=*/NULL,
++ /*metric_id=*/NULL, pmu,
++ /*config_terms=*/NULL, auto_merge_stats,
++ /*cpu_list=*/NULL);
+ if (evsel) {
+ evsel->pmu_name = name ? strdup(name) : NULL;
+ evsel->use_uncore_alias = use_uncore_alias;
+@@ -1628,9 +1657,10 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
+ return -EINVAL;
+ }
+
+- evsel = __add_event(list, &parse_state->idx, &attr, true,
+- get_config_name(head_config), pmu,
+- &config_terms, auto_merge_stats, NULL);
++ evsel = __add_event(list, &parse_state->idx, &attr, /*init_attr=*/true,
++ get_config_name(head_config),
++ get_config_metric_id(head_config), pmu,
++ &config_terms, auto_merge_stats, /*cpu_list=*/NULL);
+ if (!evsel)
+ return -ENOMEM;
+
+@@ -3296,9 +3326,12 @@ char *parse_events_formats_error_string(char *additional_terms)
+
+ struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx,
+ struct perf_event_attr *attr,
+- const char *name, struct perf_pmu *pmu,
++ const char *name,
++ const char *metric_id,
++ struct perf_pmu *pmu,
+ struct list_head *config_terms)
+ {
+- return __add_event(list, idx, attr, true, name, pmu,
+- config_terms, false, NULL);
++ return __add_event(list, idx, attr, /*init_attr=*/true, name, metric_id,
++ pmu, config_terms, /*auto_merge_stats=*/false,
++ /*cpu_list=*/NULL);
+ }
+diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
+index 6ef506c1b29e..9de27b7c9eec 100644
+--- a/tools/perf/util/parse-events.h
++++ b/tools/perf/util/parse-events.h
+@@ -87,6 +87,7 @@ enum {
+ PARSE_EVENTS__TERM_TYPE_PERCORE,
+ PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT,
+ PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE,
++ PARSE_EVENTS__TERM_TYPE_METRIC_ID,
+ __PARSE_EVENTS__TERM_TYPE_NR,
+ };
+
+@@ -200,7 +201,8 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
+ bool use_alias);
+
+ struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
+- const char *name, struct perf_pmu *pmu);
++ const char *name, const char *metric_id,
++ struct perf_pmu *pmu);
+
+ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
+ char *str,
+@@ -268,6 +270,7 @@ int perf_pmu__test_parse_init(void);
+ struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx,
+ struct perf_event_attr *attr,
+ const char *name,
++ const char *metric_id,
+ struct perf_pmu *pmu,
+ struct list_head *config_terms);
+
+diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
+index 923849024b15..b752eb2c620a 100644
+--- a/tools/perf/util/parse-events.l
++++ b/tools/perf/util/parse-events.l
+@@ -295,6 +295,7 @@ no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
+ percore { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_PERCORE); }
+ aux-output { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT); }
+ aux-sample-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE); }
++metric-id { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_METRIC_ID); }
+ r{num_raw_hex} { return raw(yyscanner); }
+ r0x{num_raw_hex} { return raw(yyscanner); }
+ , { return ','; }
+diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c
+index 756295dedccc..f0bcfcab1a93 100644
+--- a/tools/perf/util/pfm.c
++++ b/tools/perf/util/pfm.c
+@@ -87,7 +87,8 @@ int parse_libpfm_events_option(const struct option *opt, const char *str,
+
+ pmu = perf_pmu__find_by_type((unsigned int)attr.type);
+ evsel = parse_events__add_event(evlist->core.nr_entries,
+- &attr, q, pmu);
++ &attr, q, /*metric_id=*/NULL,
++ pmu);
+ if (evsel == NULL)
+ goto error;
+
+--
+2.35.1
+
--- /dev/null
+From c2cc7442de4aac9fadc5ea07cd3ebd72a4d0ee26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Oct 2021 10:21:31 -0700
+Subject: perf parse-events: Identify broken modifiers
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit eabd4523395e4a8f2b049165642801f2ab8ff893 ]
+
+Previously the broken modifier causes a usage message to printed but
+nothing else.
+
+After:
+
+ $ perf stat -e 'cycles:kk' -a sleep 2
+ event syntax error: 'cycles:kk'
+ \___ Bad modifier
+ Run 'perf list' for a list of valid events
+
+ Usage: perf stat [<options>] [<command>]
+
+ -e, --event <event> event selector. use 'perf list' to list available events
+
+ $ perf stat -e '{instructions,cycles}:kk' -a sleep 2
+ event syntax error: '..ns,cycles}:kk'
+ \___ Bad modifier
+ Run 'perf list' for a list of valid events
+
+ Usage: perf stat [<options>] [<command>]
+
+ -e, --event <event> event selector. use 'perf list' to list available events
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Andi Kleen <ak@linux.intel.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Antonov <alexander.antonov@linux.intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andrew Kilroy <andrew.kilroy@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Changbin Du <changbin.du@intel.com>
+Cc: Denys Zagorui <dzagorui@cisco.com>
+Cc: Fabian Hemmer <copy@copy.sh>
+Cc: Felix Fietkau <nbd@nbd.name>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jacob Keller <jacob.e.keller@intel.com>
+Cc: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Cc: Jin Yao <yao.jin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Joakim Zhang <qiangqing.zhang@nxp.com>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Kees Kook <keescook@chromium.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Nicholas Fraser <nfraser@codeweavers.com>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Paul Clarke <pc@us.ibm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Riccardo Mancini <rickyman7@gmail.com>
+Cc: Sami Tolvanen <samitolvanen@google.com>
+Cc: ShihCheng Tu <mrtoastcheng@gmail.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Wan Jiabing <wanjiabing@vivo.com>
+Cc: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20211015172132.1162559-21-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/parse-events.y | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
+index d94e48e1ff9b..467a426205a0 100644
+--- a/tools/perf/util/parse-events.y
++++ b/tools/perf/util/parse-events.y
+@@ -183,6 +183,11 @@ group_def ':' PE_MODIFIER_EVENT
+ err = parse_events__modifier_group(list, $3);
+ free($3);
+ if (err) {
++ struct parse_events_state *parse_state = _parse_state;
++ struct parse_events_error *error = parse_state->error;
++
++ parse_events__handle_error(error, @3.first_column,
++ strdup("Bad modifier"), NULL);
+ free_list_evsel(list);
+ YYABORT;
+ }
+@@ -240,6 +245,11 @@ event_name PE_MODIFIER_EVENT
+ err = parse_events__modifier_event(list, $2, false);
+ free($2);
+ if (err) {
++ struct parse_events_state *parse_state = _parse_state;
++ struct parse_events_error *error = parse_state->error;
++
++ parse_events__handle_error(error, @2.first_column,
++ strdup("Bad modifier"), NULL);
+ free_list_evsel(list);
+ YYABORT;
+ }
+--
+2.35.1
+
--- /dev/null
+From 5bfe448a3416e5cb7fe7c43623279e9d0c811407 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Oct 2021 14:48:42 +0100
+Subject: perf tools: Check vmlinux/kallsyms arguments in all tools
+
+From: James Clark <james.clark@arm.com>
+
+[ Upstream commit 7cc72553ac03ec20afe2dec91dce4624ccd379b8 ]
+
+Only perf report checked the validity of these arguments so apply the
+same check to all tools that read them for consistency.
+
+Signed-off-by: James Clark <james.clark@arm.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Denis Nikitin <denik@chromium.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20211018134844.2627174-3-james.clark@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-annotate.c | 4 ++++
+ tools/perf/builtin-c2c.c | 4 ++++
+ tools/perf/builtin-probe.c | 5 +++++
+ tools/perf/builtin-record.c | 4 ++++
+ tools/perf/builtin-sched.c | 4 ++++
+ tools/perf/builtin-script.c | 3 +++
+ tools/perf/builtin-top.c | 4 ++++
+ 7 files changed, 28 insertions(+)
+
+diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
+index 05eb098cb0e3..490bb9b8cf17 100644
+--- a/tools/perf/builtin-annotate.c
++++ b/tools/perf/builtin-annotate.c
+@@ -591,6 +591,10 @@ int cmd_annotate(int argc, const char **argv)
+ return ret;
+ }
+
++ ret = symbol__validate_sym_arguments();
++ if (ret)
++ return ret;
++
+ if (quiet)
+ perf_quiet_option();
+
+diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
+index e6f900c3accb..6d901ba6678f 100644
+--- a/tools/perf/builtin-c2c.c
++++ b/tools/perf/builtin-c2c.c
+@@ -2770,6 +2770,10 @@ static int perf_c2c__report(int argc, const char **argv)
+ if (c2c.stats_only)
+ c2c.use_stdio = true;
+
++ err = symbol__validate_sym_arguments();
++ if (err)
++ goto out;
++
+ if (!input_name || !strlen(input_name))
+ input_name = "perf.data";
+
+diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
+index e1dd51f2874b..c31627af75d4 100644
+--- a/tools/perf/builtin-probe.c
++++ b/tools/perf/builtin-probe.c
+@@ -21,6 +21,7 @@
+ #include "util/build-id.h"
+ #include "util/strlist.h"
+ #include "util/strfilter.h"
++#include "util/symbol.h"
+ #include "util/symbol_conf.h"
+ #include "util/debug.h"
+ #include <subcmd/parse-options.h>
+@@ -629,6 +630,10 @@ __cmd_probe(int argc, const char **argv)
+ params.command = 'a';
+ }
+
++ ret = symbol__validate_sym_arguments();
++ if (ret)
++ return ret;
++
+ if (params.quiet) {
+ if (verbose != 0) {
+ pr_err(" Error: -v and -q are exclusive.\n");
+diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
+index b3509d9d20cc..dcb3ed24fc4a 100644
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -2680,6 +2680,10 @@ int cmd_record(int argc, const char **argv)
+ if (quiet)
+ perf_quiet_option();
+
++ err = symbol__validate_sym_arguments();
++ if (err)
++ return err;
++
+ /* Make system wide (-a) the default target. */
+ if (!argc && target__none(&rec->opts.target))
+ rec->opts.target.system_wide = true;
+diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
+index 635a6b5a9ec9..4527f632ebe4 100644
+--- a/tools/perf/builtin-sched.c
++++ b/tools/perf/builtin-sched.c
+@@ -3538,6 +3538,7 @@ int cmd_sched(int argc, const char **argv)
+ .fork_event = replay_fork_event,
+ };
+ unsigned int i;
++ int ret;
+
+ for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++)
+ sched.curr_pid[i] = -1;
+@@ -3598,6 +3599,9 @@ int cmd_sched(int argc, const char **argv)
+ parse_options_usage(NULL, timehist_options, "n", true);
+ return -EINVAL;
+ }
++ ret = symbol__validate_sym_arguments();
++ if (ret)
++ return ret;
+
+ return perf_sched__timehist(&sched);
+ } else {
+diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
+index c6c40191933d..f346275c9d21 100644
+--- a/tools/perf/builtin-script.c
++++ b/tools/perf/builtin-script.c
+@@ -3839,6 +3839,9 @@ int cmd_script(int argc, const char **argv)
+ data.path = input_name;
+ data.force = symbol_conf.force;
+
++ if (symbol__validate_sym_arguments())
++ return -1;
++
+ if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
+ rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
+ if (!rec_script_path)
+diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
+index a3ae9176a83e..aa5190ecc72a 100644
+--- a/tools/perf/builtin-top.c
++++ b/tools/perf/builtin-top.c
+@@ -1618,6 +1618,10 @@ int cmd_top(int argc, const char **argv)
+ if (argc)
+ usage_with_options(top_usage, options);
+
++ status = symbol__validate_sym_arguments();
++ if (status)
++ goto out_delete_evlist;
++
+ if (annotate_check_args(&top.annotation_opts) < 0)
+ goto out_delete_evlist;
+
+--
+2.35.1
+
--- /dev/null
+From dfd877595c7a1781e02f81c5307883c321f5b8c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Mar 2022 17:20:32 +0800
+Subject: perf tools: Enhance the matching of sub-commands abbreviations
+
+From: Wei Li <liwei391@huawei.com>
+
+[ Upstream commit ae0f4eb34fc3014f7eba78fab90a0e98e441a4cd ]
+
+We support short command 'rec*' for 'record' and 'rep*' for 'report' in
+lots of sub-commands, but the matching is not quite strict currnetly.
+
+It may be puzzling sometime, like we mis-type a 'recport' to report but
+it will perform 'record' in fact without any message.
+
+To fix this, add a check to ensure that the short cmd is valid prefix
+of the real command.
+
+Committer testing:
+
+ [root@quaco ~]# perf c2c re sleep 1
+
+ Usage: perf c2c {record|report}
+
+ -v, --verbose be more verbose (show counter open errors, etc)
+
+ # perf c2c rec sleep 1
+ [ perf record: Woken up 1 times to write data ]
+ [ perf record: Captured and wrote 0.038 MB perf.data (16 samples) ]
+ # perf c2c recport sleep 1
+
+ Usage: perf c2c {record|report}
+
+ -v, --verbose be more verbose (show counter open errors, etc)
+
+ # perf c2c record sleep 1
+ [ perf record: Woken up 1 times to write data ]
+ [ perf record: Captured and wrote 0.038 MB perf.data (15 samples) ]
+ # perf c2c records sleep 1
+
+ Usage: perf c2c {record|report}
+
+ -v, --verbose be more verbose (show counter open errors, etc)
+
+ #
+
+Signed-off-by: Wei Li <liwei391@huawei.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Hanjun Guo <guohanjun@huawei.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Link: http://lore.kernel.org/lkml/20220325092032.2956161-1-liwei391@huawei.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-c2c.c | 5 +++--
+ tools/perf/builtin-kmem.c | 2 +-
+ tools/perf/builtin-kvm.c | 9 +++++----
+ tools/perf/builtin-lock.c | 5 +++--
+ tools/perf/builtin-mem.c | 5 +++--
+ tools/perf/builtin-sched.c | 4 ++--
+ tools/perf/builtin-script.c | 4 ++--
+ tools/perf/builtin-stat.c | 4 ++--
+ tools/perf/builtin-timechart.c | 3 ++-
+ 9 files changed, 23 insertions(+), 18 deletions(-)
+
+diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
+index 6d901ba6678f..ba798c64fed9 100644
+--- a/tools/perf/builtin-c2c.c
++++ b/tools/perf/builtin-c2c.c
+@@ -44,6 +44,7 @@
+ #include "../perf.h"
+ #include "pmu.h"
+ #include "pmu-hybrid.h"
++#include "string2.h"
+
+ struct c2c_hists {
+ struct hists hists;
+@@ -3026,9 +3027,9 @@ int cmd_c2c(int argc, const char **argv)
+ if (!argc)
+ usage_with_options(c2c_usage, c2c_options);
+
+- if (!strncmp(argv[0], "rec", 3)) {
++ if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
+ return perf_c2c__record(argc, argv);
+- } else if (!strncmp(argv[0], "rep", 3)) {
++ } else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
+ return perf_c2c__report(argc, argv);
+ } else {
+ usage_with_options(c2c_usage, c2c_options);
+diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
+index da03a341c63c..8595e6a92d39 100644
+--- a/tools/perf/builtin-kmem.c
++++ b/tools/perf/builtin-kmem.c
+@@ -1946,7 +1946,7 @@ int cmd_kmem(int argc, const char **argv)
+ kmem_page = 1;
+ }
+
+- if (!strncmp(argv[0], "rec", 3)) {
++ if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
+ symbol__init(NULL);
+ return __cmd_record(argc, argv);
+ }
+diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
+index aa1b127ffb5b..38735c405573 100644
+--- a/tools/perf/builtin-kvm.c
++++ b/tools/perf/builtin-kvm.c
+@@ -24,6 +24,7 @@
+ #include "util/ordered-events.h"
+ #include "util/kvm-stat.h"
+ #include "ui/ui.h"
++#include "util/string2.h"
+
+ #include <sys/prctl.h>
+ #ifdef HAVE_TIMERFD_SUPPORT
+@@ -1500,10 +1501,10 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
+ goto perf_stat;
+ }
+
+- if (!strncmp(argv[1], "rec", 3))
++ if (strlen(argv[1]) > 2 && strstarts("record", argv[1]))
+ return kvm_events_record(&kvm, argc - 1, argv + 1);
+
+- if (!strncmp(argv[1], "rep", 3))
++ if (strlen(argv[1]) > 2 && strstarts("report", argv[1]))
+ return kvm_events_report(&kvm, argc - 1 , argv + 1);
+
+ #ifdef HAVE_TIMERFD_SUPPORT
+@@ -1631,9 +1632,9 @@ int cmd_kvm(int argc, const char **argv)
+ }
+ }
+
+- if (!strncmp(argv[0], "rec", 3))
++ if (strlen(argv[0]) > 2 && strstarts("record", argv[0]))
+ return __cmd_record(file_name, argc, argv);
+- else if (!strncmp(argv[0], "rep", 3))
++ else if (strlen(argv[0]) > 2 && strstarts("report", argv[0]))
+ return __cmd_report(file_name, argc, argv);
+ else if (!strncmp(argv[0], "diff", 4))
+ return cmd_diff(argc, argv);
+diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
+index d70131b7b1b1..24d402e84022 100644
+--- a/tools/perf/builtin-lock.c
++++ b/tools/perf/builtin-lock.c
+@@ -18,6 +18,7 @@
+ #include "util/session.h"
+ #include "util/tool.h"
+ #include "util/data.h"
++#include "util/string2.h"
+
+ #include <sys/types.h>
+ #include <sys/prctl.h>
+@@ -997,9 +998,9 @@ int cmd_lock(int argc, const char **argv)
+ if (!argc)
+ usage_with_options(lock_usage, lock_options);
+
+- if (!strncmp(argv[0], "rec", 3)) {
++ if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
+ return __cmd_record(argc, argv);
+- } else if (!strncmp(argv[0], "report", 6)) {
++ } else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
+ trace_handler = &report_lock_ops;
+ if (argc) {
+ argc = parse_options(argc, argv,
+diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
+index fcf65a59bea2..9e435fd23503 100644
+--- a/tools/perf/builtin-mem.c
++++ b/tools/perf/builtin-mem.c
+@@ -20,6 +20,7 @@
+ #include "util/symbol.h"
+ #include "util/pmu.h"
+ #include "util/pmu-hybrid.h"
++#include "util/string2.h"
+ #include <linux/err.h>
+
+ #define MEM_OPERATION_LOAD 0x1
+@@ -496,9 +497,9 @@ int cmd_mem(int argc, const char **argv)
+ mem.input_name = "perf.data";
+ }
+
+- if (!strncmp(argv[0], "rec", 3))
++ if (strlen(argv[0]) > 2 && strstarts("record", argv[0]))
+ return __cmd_record(argc, argv, &mem);
+- else if (!strncmp(argv[0], "rep", 3))
++ else if (strlen(argv[0]) > 2 && strstarts("report", argv[0]))
+ return report_events(argc, argv, &mem);
+ else
+ usage_with_options(mem_usage, mem_options);
+diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
+index 4527f632ebe4..2cf806d66b1c 100644
+--- a/tools/perf/builtin-sched.c
++++ b/tools/perf/builtin-sched.c
+@@ -3554,7 +3554,7 @@ int cmd_sched(int argc, const char **argv)
+ if (!strcmp(argv[0], "script"))
+ return cmd_script(argc, argv);
+
+- if (!strncmp(argv[0], "rec", 3)) {
++ if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
+ return __cmd_record(argc, argv);
+ } else if (!strncmp(argv[0], "lat", 3)) {
+ sched.tp_handler = &lat_ops;
+@@ -3574,7 +3574,7 @@ int cmd_sched(int argc, const char **argv)
+ sched.tp_handler = &map_ops;
+ setup_sorting(&sched, latency_options, latency_usage);
+ return perf_sched__map(&sched);
+- } else if (!strncmp(argv[0], "rep", 3)) {
++ } else if (strlen(argv[0]) > 2 && strstarts("replay", argv[0])) {
+ sched.tp_handler = &replay_ops;
+ if (argc) {
+ argc = parse_options(argc, argv, replay_options, replay_usage, 0);
+diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
+index f346275c9d21..4baaf5652a42 100644
+--- a/tools/perf/builtin-script.c
++++ b/tools/perf/builtin-script.c
+@@ -3842,13 +3842,13 @@ int cmd_script(int argc, const char **argv)
+ if (symbol__validate_sym_arguments())
+ return -1;
+
+- if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
++ if (argc > 1 && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
+ rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
+ if (!rec_script_path)
+ return cmd_record(argc, argv);
+ }
+
+- if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
++ if (argc > 1 && strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
+ rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
+ if (!rep_script_path) {
+ fprintf(stderr,
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
+index abf88a1ad455..002eecc59536 100644
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -2255,11 +2255,11 @@ int cmd_stat(int argc, const char **argv)
+ } else
+ stat_config.csv_sep = DEFAULT_SEPARATOR;
+
+- if (argc && !strncmp(argv[0], "rec", 3)) {
++ if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
+ argc = __cmd_record(argc, argv);
+ if (argc < 0)
+ return -1;
+- } else if (argc && !strncmp(argv[0], "rep", 3))
++ } else if (argc && strlen(argv[0]) > 2 && strstarts("report", argv[0]))
+ return __cmd_report(argc, argv);
+
+ interval = stat_config.interval;
+diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
+index 43bf4d67edb0..afce731cec16 100644
+--- a/tools/perf/builtin-timechart.c
++++ b/tools/perf/builtin-timechart.c
+@@ -35,6 +35,7 @@
+ #include "util/tool.h"
+ #include "util/data.h"
+ #include "util/debug.h"
++#include "util/string2.h"
+ #include <linux/err.h>
+
+ #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE
+@@ -1983,7 +1984,7 @@ int cmd_timechart(int argc, const char **argv)
+ return -1;
+ }
+
+- if (argc && !strncmp(argv[0], "rec", 3)) {
++ if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
+ argc = parse_options(argc, argv, timechart_record_options,
+ timechart_record_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+--
+2.35.1
+
--- /dev/null
+From 3cccc99e1e0999cc8d576ad1cf5ee1d6050c8c83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Aug 2022 15:46:01 +0800
+Subject: reset: imx7: Fix the iMX8MP PCIe PHY PERST support
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+[ Upstream commit 051d9eb403887bb11852b7a4f744728a6a4b1b58 ]
+
+On i.MX7/iMX8MM/iMX8MQ, the initialized default value of PERST bit(BIT3)
+of SRC_PCIEPHY_RCR is 1b'1.
+But i.MX8MP has one inversed default value 1b'0 of PERST bit.
+
+And the PERST bit should be kept 1b'1 after power and clocks are stable.
+So fix the i.MX8MP PCIe PHY PERST support here.
+
+Fixes: e08672c03981 ("reset: imx7: Add support for i.MX8MP SoC")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Tested-by: Marek Vasut <marex@denx.de>
+Tested-by: Richard Leitner <richard.leitner@skidata.com>
+Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Link: https://lore.kernel.org/r/1661845564-11373-5-git-send-email-hongxing.zhu@nxp.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/reset/reset-imx7.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/reset/reset-imx7.c b/drivers/reset/reset-imx7.c
+index 185a333df66c..d2408725eb2c 100644
+--- a/drivers/reset/reset-imx7.c
++++ b/drivers/reset/reset-imx7.c
+@@ -329,6 +329,7 @@ static int imx8mp_reset_set(struct reset_controller_dev *rcdev,
+ break;
+
+ case IMX8MP_RESET_PCIE_CTRL_APPS_EN:
++ case IMX8MP_RESET_PCIEPHY_PERST:
+ value = assert ? 0 : bit;
+ break;
+ }
+--
+2.35.1
+
--- /dev/null
+From 8f41572ccc028f59b12383d60dcd13e07c3db1eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Aug 2022 18:08:04 -0700
+Subject: Revert "drm: bridge: analogix/dp: add panel prepare/unprepare in
+ suspend/resume time"
+
+From: Brian Norris <briannorris@chromium.org>
+
+[ Upstream commit cc62d98bd56d45de4531844ca23913a15136c05b ]
+
+This reverts commit 211f276ed3d96e964d2d1106a198c7f4a4b3f4c0.
+
+For quite some time, core DRM helpers already ensure that any relevant
+connectors/CRTCs/etc. are disabled, as well as their associated
+components (e.g., bridges) when suspending the system. Thus,
+analogix_dp_bridge_{enable,disable}() already get called, which in turn
+call drm_panel_{prepare,unprepare}(). This makes these drm_panel_*()
+calls redundant.
+
+Besides redundancy, there are a few problems with this handling:
+
+(1) drm_panel_{prepare,unprepare}() are *not* reference-counted APIs and
+are not in general designed to be handled by multiple callers --
+although some panel drivers have a coarse 'prepared' flag that mitigates
+some damage, at least. So at a minimum this is redundant and confusing,
+but in some cases, this could be actively harmful.
+
+(2) The error-handling is a bit non-standard. We ignored errors in
+suspend(), but handled errors in resume(). And recently, people noticed
+that the clk handling is unbalanced in error paths, and getting *that*
+right is not actually trivial, given the current way errors are mostly
+ignored.
+
+(3) In the particular way analogix_dp_{suspend,resume}() get used (e.g.,
+in rockchip_dp_*(), as a late/early callback), we don't necessarily have
+a proper PM relationship between the DP/bridge device and the panel
+device. So while the DP bridge gets resumed, the panel's parent device
+(e.g., platform_device) may still be suspended, and so any prepare()
+calls may fail.
+
+So remove the superfluous, possibly-harmful suspend()/resume() handling
+of panel state.
+
+Fixes: 211f276ed3d9 ("drm: bridge: analogix/dp: add panel prepare/unprepare in suspend/resume time")
+Link: https://lore.kernel.org/all/Yv2CPBD3Picg%2FgVe@google.com/
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220822180729.1.I8ac5abe3a4c1c6fd5c061686c6e883c22f69022c@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+index 873cf6882bd3..f0305f833b6c 100644
+--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+@@ -1860,12 +1860,6 @@ EXPORT_SYMBOL_GPL(analogix_dp_remove);
+ int analogix_dp_suspend(struct analogix_dp_device *dp)
+ {
+ clk_disable_unprepare(dp->clock);
+-
+- if (dp->plat_data->panel) {
+- if (drm_panel_unprepare(dp->plat_data->panel))
+- DRM_ERROR("failed to turnoff the panel\n");
+- }
+-
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(analogix_dp_suspend);
+@@ -1880,13 +1874,6 @@ int analogix_dp_resume(struct analogix_dp_device *dp)
+ return ret;
+ }
+
+- if (dp->plat_data->panel) {
+- if (drm_panel_prepare(dp->plat_data->panel)) {
+- DRM_ERROR("failed to setup the panel\n");
+- return -EBUSY;
+- }
+- }
+-
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(analogix_dp_resume);
+--
+2.35.1
+
--- /dev/null
+From 1fa207c55d1a704a5054bb3d57a5156b5c84d34b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 15:02:37 +0800
+Subject: selftests: Fix the if conditions of in test_extra_filter()
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit bc7a319844891746135dc1f34ab9df78d636a3ac ]
+
+The socket 2 bind the addr in use, bind should fail with EADDRINUSE. So
+if bind success or errno != EADDRINUSE, testcase should be failed.
+
+Fixes: 3ca8e4029969 ("soreuseport: BPF selection functional test")
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Link: https://lore.kernel.org/r/1663916557-10730-1-git-send-email-wangyufen@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/reuseport_bpf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/reuseport_bpf.c b/tools/testing/selftests/net/reuseport_bpf.c
+index b5277106df1f..b0cc082fbb84 100644
+--- a/tools/testing/selftests/net/reuseport_bpf.c
++++ b/tools/testing/selftests/net/reuseport_bpf.c
+@@ -330,7 +330,7 @@ static void test_extra_filter(const struct test_params p)
+ if (bind(fd1, addr, sockaddr_size()))
+ error(1, errno, "failed to bind recv socket 1");
+
+- if (!bind(fd2, addr, sockaddr_size()) && errno != EADDRINUSE)
++ if (!bind(fd2, addr, sockaddr_size()) || errno != EADDRINUSE)
+ error(1, errno, "bind socket 2 should fail with EADDRINUSE");
+
+ free(addr);
+--
+2.35.1
+
media-rkvdec-disable-h.264-error-detection.patch
media-v4l2-compat-ioctl32.c-zero-buffer-passed-to-v4l2_compat_get_array_args.patch
swiotlb-max-mapping-size-takes-min-align-mask-into-account.patch
+arm-dts-am33xx-fix-mmchs0-dma-properties.patch
+reset-imx7-fix-the-imx8mp-pcie-phy-perst-support.patch
+arm-dts-am5748-keep-usb4_tm-disabled.patch
+soc-sunxi-sram-actually-claim-sram-regions.patch
+soc-sunxi-sram-prevent-the-driver-from-being-unbound.patch
+soc-sunxi_sram-make-use-of-the-helper-function-devm_.patch
+soc-sunxi-sram-fix-probe-function-ordering-issues.patch
+soc-sunxi-sram-fix-debugfs-info-for-a64-sram-c.patch
+asoc-imx-card-fix-refcount-issue-with-of_node_put.patch
+arm64-dts-qcom-sm8350-fix-ufs-phy-serdes-size.patch
+asoc-tas2770-reinit-regcache-on-reset.patch
+drm-bridge-lt8912b-add-vsync-hsync.patch
+drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch
+drm-bridge-lt8912b-fix-corrupted-image-output.patch
+revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch
+input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch
+gpio-mvebu-fix-check-for-pwm-support-on-non-a8k-plat.patch
+usbnet-fix-memory-leak-in-usbnet_disconnect.patch
+net-sched-act_ct-fix-possible-refcount-leak-in-tcf_c.patch
+cxgb4-fix-missing-unlock-on-ethofld-desc-collect-fai.patch
+net-mlxbf_gige-fix-an-is_err-vs-null-bug-in-mlxbf_gi.patch
+nvme-fix-ioc_pr_clear-and-ioc_pr_release-ioctls-for-.patch
+wifi-mac80211-fix-regression-with-non-qos-drivers.patch
+net-stmmac-power-up-down-serdes-in-stmmac_open-relea.patch
+net-phy-don-t-warn-for-phy_up-state-in-mdio_bus_phy_.patch
+selftests-fix-the-if-conditions-of-in-test_extra_fil.patch
+vdpa-ifcvf-fix-the-calculation-of-queuepair.patch
+fs-split-off-setxattr_copy-and-do_setxattr-function-.patch
+don-t-use-__kernel_write-on-kmap_local_page.patch
+clk-imx-imx6sx-remove-the-set_rate_parent-flag-for-q.patch
+clk-iproc-do-not-rely-on-node-name-for-correct-pll-s.patch
+kvm-x86-hide-ia32_platform_dca_cap-31-0-from-the-gue.patch
+perf-metric-add-documentation-and-rename-a-variable.patch
+perf-metric-only-add-a-referenced-metric-once.patch
+perf-parse-events-add-const-to-evsel-name.patch
+perf-parse-events-add-new-metric-id-term.patch
+perf-parse-events-identify-broken-modifiers.patch
+perf-list-display-hybrid-pmu-events-with-cpu-type.patch
+perf-tools-check-vmlinux-kallsyms-arguments-in-all-t.patch
+perf-tools-enhance-the-matching-of-sub-commands-abbr.patch
+perf-list-print-all-available-tool-events.patch
--- /dev/null
+From a1aa4e1e0e89028303f53e1d4de6c7dc8c996b55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Aug 2022 23:12:40 -0500
+Subject: soc: sunxi: sram: Actually claim SRAM regions
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit fd362baad2e659ef0fb5652f023a606b248f1781 ]
+
+sunxi_sram_claim() checks the sram_desc->claimed flag before updating
+the register, with the intent that only one device can claim a region.
+However, this was ineffective because the flag was never set.
+
+Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs")
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20220815041248.53268-4-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sunxi/sunxi_sram.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
+index 42833e33a96c..20b5d38e6da8 100644
+--- a/drivers/soc/sunxi/sunxi_sram.c
++++ b/drivers/soc/sunxi/sunxi_sram.c
+@@ -254,6 +254,7 @@ int sunxi_sram_claim(struct device *dev)
+ writel(val | ((device << sram_data->offset) & mask),
+ base + sram_data->reg);
+
++ sram_desc->claimed = true;
+ spin_unlock(&sram_lock);
+
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 073d399f87e815190dedbfeca00110ffd526b427 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Aug 2022 23:12:43 -0500
+Subject: soc: sunxi: sram: Fix debugfs info for A64 SRAM C
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit e3c95edb1bd8b9c2cb0caa6ae382fc8080f6a0ed ]
+
+The labels were backward with respect to the register values. The SRAM
+is mapped to the CPU when the register value is 1.
+
+Fixes: 5e4fb6429761 ("drivers: soc: sunxi: add support for A64 and its SRAM C")
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20220815041248.53268-7-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sunxi/sunxi_sram.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
+index 52d07bed7664..09754cd1d57d 100644
+--- a/drivers/soc/sunxi/sunxi_sram.c
++++ b/drivers/soc/sunxi/sunxi_sram.c
+@@ -78,8 +78,8 @@ static struct sunxi_sram_desc sun4i_a10_sram_d = {
+
+ static struct sunxi_sram_desc sun50i_a64_sram_c = {
+ .data = SUNXI_SRAM_DATA("C", 0x4, 24, 1,
+- SUNXI_SRAM_MAP(0, 1, "cpu"),
+- SUNXI_SRAM_MAP(1, 0, "de2")),
++ SUNXI_SRAM_MAP(1, 0, "cpu"),
++ SUNXI_SRAM_MAP(0, 1, "de2")),
+ };
+
+ static const struct of_device_id sunxi_sram_dt_ids[] = {
+--
+2.35.1
+
--- /dev/null
+From b0d73ad306cfa6e997e906bc83921131ba45eb93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Aug 2022 23:12:42 -0500
+Subject: soc: sunxi: sram: Fix probe function ordering issues
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 49fad91a7b8941979c3e9a35f9894ac45bc5d3d6 ]
+
+Errors from debugfs are intended to be non-fatal, and should not prevent
+the driver from probing.
+
+Since debugfs file creation is treated as infallible, move it below the
+parts of the probe function that can fail. This prevents an error
+elsewhere in the probe function from causing the file to leak. Do the
+same for the call to of_platform_populate().
+
+Finally, checkpatch suggests an octal literal for the file permissions.
+
+Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs")
+Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on A64")
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20220815041248.53268-6-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sunxi/sunxi_sram.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
+index a858a37fcdd4..52d07bed7664 100644
+--- a/drivers/soc/sunxi/sunxi_sram.c
++++ b/drivers/soc/sunxi/sunxi_sram.c
+@@ -332,9 +332,9 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = {
+
+ static int __init sunxi_sram_probe(struct platform_device *pdev)
+ {
+- struct dentry *d;
+ struct regmap *emac_clock;
+ const struct sunxi_sramc_variant *variant;
++ struct device *dev = &pdev->dev;
+
+ sram_dev = &pdev->dev;
+
+@@ -346,13 +346,6 @@ static int __init sunxi_sram_probe(struct platform_device *pdev)
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+- of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+-
+- d = debugfs_create_file("sram", S_IRUGO, NULL, NULL,
+- &sunxi_sram_fops);
+- if (!d)
+- return -ENOMEM;
+-
+ if (variant->num_emac_clocks > 0) {
+ emac_clock = devm_regmap_init_mmio(&pdev->dev, base,
+ &sunxi_sram_emac_clock_regmap);
+@@ -361,6 +354,10 @@ static int __init sunxi_sram_probe(struct platform_device *pdev)
+ return PTR_ERR(emac_clock);
+ }
+
++ of_platform_populate(dev->of_node, NULL, NULL, dev);
++
++ debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops);
++
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 7a62761ada2cc1849a7d130b90abb41ef876b57a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Aug 2022 23:12:41 -0500
+Subject: soc: sunxi: sram: Prevent the driver from being unbound
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 90e10a1fcd9b24b4ba8c0d35136127473dcd829e ]
+
+This driver exports a regmap tied to the platform device (as opposed to
+a syscon, which exports a regmap tied to the OF node). Because of this,
+the driver can never be unbound, as that would destroy the regmap. Use
+builtin_platform_driver_probe() to enforce this limitation.
+
+Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on A64")
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20220815041248.53268-5-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sunxi/sunxi_sram.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
+index 20b5d38e6da8..852f0872f669 100644
+--- a/drivers/soc/sunxi/sunxi_sram.c
++++ b/drivers/soc/sunxi/sunxi_sram.c
+@@ -330,7 +330,7 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = {
+ .writeable_reg = sunxi_sram_regmap_accessible_reg,
+ };
+
+-static int sunxi_sram_probe(struct platform_device *pdev)
++static int __init sunxi_sram_probe(struct platform_device *pdev)
+ {
+ struct resource *res;
+ struct dentry *d;
+@@ -412,9 +412,8 @@ static struct platform_driver sunxi_sram_driver = {
+ .name = "sunxi-sram",
+ .of_match_table = sunxi_sram_dt_match,
+ },
+- .probe = sunxi_sram_probe,
+ };
+-module_platform_driver(sunxi_sram_driver);
++builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe);
+
+ MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+ MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver");
+--
+2.35.1
+
--- /dev/null
+From 277ccf95bc99dca9dcc1a384ae00a672ef9e9298 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Sep 2021 15:17:15 +0800
+Subject: soc: sunxi_sram: Make use of the helper function
+ devm_platform_ioremap_resource()
+
+From: Cai Huoqing <caihuoqing@baidu.com>
+
+[ Upstream commit 1f3753a5f042fea6539986f9caf2552877527d8a ]
+
+Use the devm_platform_ioremap_resource() helper instead of
+calling platform_get_resource() and devm_ioremap_resource()
+separately
+
+Signed-off-by: Cai Huoqing <caihuoqing@baidu.com>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://lore.kernel.org/r/20210908071716.772-1-caihuoqing@baidu.com
+Stable-dep-of: 49fad91a7b89 ("soc: sunxi: sram: Fix probe function ordering issues")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/sunxi/sunxi_sram.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
+index 852f0872f669..a858a37fcdd4 100644
+--- a/drivers/soc/sunxi/sunxi_sram.c
++++ b/drivers/soc/sunxi/sunxi_sram.c
+@@ -332,7 +332,6 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = {
+
+ static int __init sunxi_sram_probe(struct platform_device *pdev)
+ {
+- struct resource *res;
+ struct dentry *d;
+ struct regmap *emac_clock;
+ const struct sunxi_sramc_variant *variant;
+@@ -343,8 +342,7 @@ static int __init sunxi_sram_probe(struct platform_device *pdev)
+ if (!variant)
+ return -EINVAL;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- base = devm_ioremap_resource(&pdev->dev, res);
++ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+--
+2.35.1
+
--- /dev/null
+From 7c452a46cbf342102fccb73d6d6c6eefffc48048 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Sep 2022 21:25:51 -0700
+Subject: usbnet: Fix memory leak in usbnet_disconnect()
+
+From: Peilin Ye <peilin.ye@bytedance.com>
+
+[ Upstream commit a43206156263fbaf1f2b7f96257441f331e91bb7 ]
+
+Currently usbnet_disconnect() unanchors and frees all deferred URBs
+using usb_scuttle_anchored_urbs(), which does not free urb->context,
+causing a memory leak as reported by syzbot.
+
+Use a usb_get_from_anchor() while loop instead, similar to what we did
+in commit 19cfe912c37b ("Bluetooth: btusb: Fix memory leak in
+play_deferred"). Also free urb->sg.
+
+Reported-and-tested-by: syzbot+dcd3e13cf4472f2e0ba1@syzkaller.appspotmail.com
+Fixes: 69ee472f2706 ("usbnet & cdc-ether: Autosuspend for online devices")
+Fixes: 638c5115a794 ("USBNET: support DMA SG")
+Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
+Link: https://lore.kernel.org/r/20220923042551.2745-1-yepeilin.cs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/usbnet.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 5b7272fd25ee..e4fbb4d86606 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1599,6 +1599,7 @@ void usbnet_disconnect (struct usb_interface *intf)
+ struct usbnet *dev;
+ struct usb_device *xdev;
+ struct net_device *net;
++ struct urb *urb;
+
+ dev = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, NULL);
+@@ -1615,7 +1616,11 @@ void usbnet_disconnect (struct usb_interface *intf)
+ net = dev->net;
+ unregister_netdev (net);
+
+- usb_scuttle_anchored_urbs(&dev->deferred);
++ while ((urb = usb_get_from_anchor(&dev->deferred))) {
++ dev_kfree_skb(urb->context);
++ kfree(urb->sg);
++ usb_free_urb(urb);
++ }
+
+ if (dev->driver_info->unbind)
+ dev->driver_info->unbind(dev, intf);
+--
+2.35.1
+
--- /dev/null
+From aea5d801204ec65b94ff0854a7cc487b0c1afce2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Sep 2022 17:10:13 +0800
+Subject: vdpa/ifcvf: fix the calculation of queuepair
+
+From: Angus Chen <angus.chen@jaguarmicro.com>
+
+[ Upstream commit db5db1a00d0816207be3a0166fcb4f523eaf3b52 ]
+
+The q_pair_id to address a queue pair in the lm bar should be
+calculated by queue_id / 2 rather than queue_id / nr_vring.
+
+Fixes: 2ddae773c93b ("vDPA/ifcvf: detect and use the onboard number of queues directly")
+Signed-off-by: Angus Chen <angus.chen@jaguarmicro.com>
+Reviewed-by: Jason Wang <jasowang@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Zhu Lingshan <lingshan.zhu@intel.com>
+Message-Id: <20220923091013.191-1-angus.chen@jaguarmicro.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vdpa/ifcvf/ifcvf_base.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/vdpa/ifcvf/ifcvf_base.c b/drivers/vdpa/ifcvf/ifcvf_base.c
+index 7d41dfe48ade..5091ff9d6c93 100644
+--- a/drivers/vdpa/ifcvf/ifcvf_base.c
++++ b/drivers/vdpa/ifcvf/ifcvf_base.c
+@@ -327,7 +327,7 @@ u16 ifcvf_get_vq_state(struct ifcvf_hw *hw, u16 qid)
+ u32 q_pair_id;
+
+ ifcvf_lm = (struct ifcvf_lm_cfg __iomem *)hw->lm_cfg;
+- q_pair_id = qid / hw->nr_vring;
++ q_pair_id = qid / 2;
+ avail_idx_addr = &ifcvf_lm->vring_lm_cfg[q_pair_id].idx_addr[qid % 2];
+ last_avail_idx = ifc_ioread16(avail_idx_addr);
+
+@@ -341,7 +341,7 @@ int ifcvf_set_vq_state(struct ifcvf_hw *hw, u16 qid, u16 num)
+ u32 q_pair_id;
+
+ ifcvf_lm = (struct ifcvf_lm_cfg __iomem *)hw->lm_cfg;
+- q_pair_id = qid / hw->nr_vring;
++ q_pair_id = qid / 2;
+ avail_idx_addr = &ifcvf_lm->vring_lm_cfg[q_pair_id].idx_addr[qid % 2];
+ hw->vring[qid].last_avail_idx = num;
+ ifc_iowrite16(num, avail_idx_addr);
+--
+2.35.1
+
--- /dev/null
+From 2a2094a1af4584251937378668dea8fe71c5671e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Sep 2022 21:20:52 +0200
+Subject: wifi: mac80211: fix regression with non-QoS drivers
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit d873697ef2b7e1b6fdd8e9d449d9354bd5d29a4a ]
+
+Commit 10cb8e617560 ("mac80211: enable QoS support for nl80211 ctrl port")
+changed ieee80211_tx_control_port() to aways call
+__ieee80211_select_queue() without checking local->hw.queues.
+
+__ieee80211_select_queue() returns a queue-id between 0 and 3, which means
+that now ieee80211_tx_control_port() may end up setting the queue-mapping
+for a skb to a value higher then local->hw.queues if local->hw.queues
+is less then 4.
+
+Specifically this is a problem for ralink rt2500-pci cards where
+local->hw.queues is 2. There this causes rt2x00queue_get_tx_queue() to
+return NULL and the following error to be logged: "ieee80211 phy0:
+rt2x00mac_tx: Error - Attempt to send packet over invalid queue 2",
+after which association with the AP fails.
+
+Other callers of __ieee80211_select_queue() skip calling it when
+local->hw.queues < IEEE80211_NUM_ACS, add the same check to
+ieee80211_tx_control_port(). This fixes ralink rt2500-pci and
+similar cards when less then 4 tx-queues no longer working.
+
+Fixes: 10cb8e617560 ("mac80211: enable QoS support for nl80211 ctrl port")
+Cc: Markus Theil <markus.theil@tu-ilmenau.de>
+Suggested-by: Stanislaw Gruszka <stf_xl@wp.pl>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20220918192052.443529-1-hdegoede@redhat.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/tx.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index a499b07fee33..8f8dc2625d53 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -5719,6 +5719,9 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+ skb_reset_network_header(skb);
+ skb_reset_mac_header(skb);
+
++ if (local->hw.queues < IEEE80211_NUM_ACS)
++ goto start_xmit;
++
+ /* update QoS header to prioritize control port frames if possible,
+ * priorization also happens for control port frames send over
+ * AF_PACKET
+@@ -5734,6 +5737,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+
+ rcu_read_unlock();
+
++start_xmit:
+ /* mutex lock is only needed for incrementing the cookie counter */
+ mutex_lock(&local->mtx);
+
+--
+2.35.1
+