--- /dev/null
+From b5256deb551959cc4946179122260abf2aaa0aec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 10:04:24 +0800
+Subject: 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv()
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 74a25e6e916cb57dab4267a96fbe8864ed21abdb ]
+
+When down_interruptible() or ib_post_send() failed in rdma_request(),
+receive dma buffer is not unmapped. Add unmap action to error path.
+Also if ib_post_recv() failed in post_recv(), dma buffer is not unmapped.
+Add unmap action to error path.
+
+Link: https://lkml.kernel.org/r/20230104020424.611926-1-shaozhengchao@huawei.com
+Fixes: fc79d4b104f0 ("9p: rdma: RDMA Transport Support for 9P")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/trans_rdma.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
+index e9a830c69058c..29a9292303ea3 100644
+--- a/net/9p/trans_rdma.c
++++ b/net/9p/trans_rdma.c
+@@ -386,6 +386,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c)
+ struct p9_trans_rdma *rdma = client->trans;
+ struct ib_recv_wr wr;
+ struct ib_sge sge;
++ int ret;
+
+ c->busa = ib_dma_map_single(rdma->cm_id->device,
+ c->rc.sdata, client->msize,
+@@ -403,7 +404,12 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c)
+ wr.wr_cqe = &c->cqe;
+ wr.sg_list = &sge;
+ wr.num_sge = 1;
+- return ib_post_recv(rdma->qp, &wr, NULL);
++
++ ret = ib_post_recv(rdma->qp, &wr, NULL);
++ if (ret)
++ ib_dma_unmap_single(rdma->cm_id->device, c->busa,
++ client->msize, DMA_FROM_DEVICE);
++ return ret;
+
+ error:
+ p9_debug(P9_DEBUG_ERROR, "EIO\n");
+@@ -500,7 +506,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
+
+ if (down_interruptible(&rdma->sq_sem)) {
+ err = -EINTR;
+- goto send_error;
++ goto dma_unmap;
+ }
+
+ /* Mark request as `sent' *before* we actually send it,
+@@ -510,11 +516,14 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
+ WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ err = ib_post_send(rdma->qp, &wr, NULL);
+ if (err)
+- goto send_error;
++ goto dma_unmap;
+
+ /* Success */
+ return 0;
+
++dma_unmap:
++ ib_dma_unmap_single(rdma->cm_id->device, c->busa,
++ c->req->tc.size, DMA_TO_DEVICE);
+ /* Handle errors that happened during or while preparing the send: */
+ send_error:
+ WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+--
+2.39.2
+
--- /dev/null
+From f52900eae1af459b703ca528d26c9ee532b1915f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 12:30:36 +0100
+Subject: 9p/xen: fix connection sequence
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit c15fe55d14b3b4ded5af2a3260877460a6ffb8ad ]
+
+Today the connection sequence of the Xen 9pfs frontend doesn't match
+the documented sequence. It can work reliably only for a PV 9pfs device
+having been added at boot time already, as the frontend is not waiting
+for the backend to have set its state to "XenbusStateInitWait" before
+reading the backend properties from Xenstore.
+
+Fix that by following the documented sequence [1] (the documentation
+has a bug, so the reference is for the patch fixing that).
+
+[1]: https://lore.kernel.org/xen-devel/20230130090937.31623-1-jgross@suse.com/T/#u
+
+Link: https://lkml.kernel.org/r/20230130113036.7087-3-jgross@suse.com
+Fixes: 868eb122739a ("xen/9pfs: introduce Xen 9pfs transport driver")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/trans_xen.c | 38 +++++++++++++++++++++++---------------
+ 1 file changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 80cc0289dd0d6..75c03a82baf38 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -371,12 +371,11 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
+ return ret;
+ }
+
+-static int xen_9pfs_front_probe(struct xenbus_device *dev,
+- const struct xenbus_device_id *id)
++static int xen_9pfs_front_init(struct xenbus_device *dev)
+ {
+ int ret, i;
+ struct xenbus_transaction xbt;
+- struct xen_9pfs_front_priv *priv = NULL;
++ struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev);
+ char *versions, *v;
+ unsigned int max_rings, max_ring_order, len = 0;
+
+@@ -404,11 +403,6 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
+ if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order))
+ p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2;
+
+- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- priv->dev = dev;
+ priv->num_rings = XEN_9PFS_NUM_RINGS;
+ priv->rings = kcalloc(priv->num_rings, sizeof(*priv->rings),
+ GFP_KERNEL);
+@@ -467,23 +461,35 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
+ goto error;
+ }
+
+- write_lock(&xen_9pfs_lock);
+- list_add_tail(&priv->list, &xen_9pfs_devs);
+- write_unlock(&xen_9pfs_lock);
+- dev_set_drvdata(&dev->dev, priv);
+- xenbus_switch_state(dev, XenbusStateInitialised);
+-
+ return 0;
+
+ error_xenbus:
+ xenbus_transaction_end(xbt, 1);
+ xenbus_dev_fatal(dev, ret, "writing xenstore");
+ error:
+- dev_set_drvdata(&dev->dev, NULL);
+ xen_9pfs_front_free(priv);
+ return ret;
+ }
+
++static int xen_9pfs_front_probe(struct xenbus_device *dev,
++ const struct xenbus_device_id *id)
++{
++ struct xen_9pfs_front_priv *priv = NULL;
++
++ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ priv->dev = dev;
++ dev_set_drvdata(&dev->dev, priv);
++
++ write_lock(&xen_9pfs_lock);
++ list_add_tail(&priv->list, &xen_9pfs_devs);
++ write_unlock(&xen_9pfs_lock);
++
++ return 0;
++}
++
+ static int xen_9pfs_front_resume(struct xenbus_device *dev)
+ {
+ dev_warn(&dev->dev, "suspend/resume unsupported\n");
+@@ -502,6 +508,8 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev,
+ break;
+
+ case XenbusStateInitWait:
++ if (!xen_9pfs_front_init(dev))
++ xenbus_switch_state(dev, XenbusStateInitialised);
+ break;
+
+ case XenbusStateConnected:
+--
+2.39.2
+
--- /dev/null
+From 2dc56d7e7d14d5d20385c7cd6ee213c55b72c360 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 12:30:35 +0100
+Subject: 9p/xen: fix version parsing
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit f1956f4ec15195ec60976d9b5625326285ab102e ]
+
+When connecting the Xen 9pfs frontend to the backend, the "versions"
+Xenstore entry written by the backend is parsed in a wrong way.
+
+The "versions" entry is defined to contain the versions supported by
+the backend separated by commas (e.g. "1,2"). Today only version "1"
+is defined. Unfortunately the frontend doesn't look for "1" being
+listed in the entry, but it is expecting the entry to have the value
+"1".
+
+This will result in failure as soon as the backend will support e.g.
+versions "1" and "2".
+
+Fix that by scanning the entry correctly.
+
+Link: https://lkml.kernel.org/r/20230130113036.7087-2-jgross@suse.com
+Fixes: 71ebd71921e4 ("xen/9pfs: connect to the backend")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/trans_xen.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index cf1b89ba522b4..80cc0289dd0d6 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -377,13 +377,19 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
+ int ret, i;
+ struct xenbus_transaction xbt;
+ struct xen_9pfs_front_priv *priv = NULL;
+- char *versions;
++ char *versions, *v;
+ unsigned int max_rings, max_ring_order, len = 0;
+
+ versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len);
+ if (IS_ERR(versions))
+ return PTR_ERR(versions);
+- if (strcmp(versions, "1")) {
++ for (v = versions; *v; v++) {
++ if (simple_strtoul(v, &v, 10) == 1) {
++ v = NULL;
++ break;
++ }
++ }
++ if (v) {
+ kfree(versions);
+ return -EINVAL;
+ }
+--
+2.39.2
+
--- /dev/null
+From cc2405c9141917c8e52759fafdb2c0feff0e4360 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Feb 2023 17:22:37 +0100
+Subject: ARM: dts: spear320-hmi: correct STMPE GPIO compatible
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 33a0c1b850c8c85f400531dab3a0b022cdb164b1 ]
+
+The compatible is st,stmpe-gpio.
+
+Fixes: e2eb69183ec4 ("ARM: SPEAr320: DT: Add SPEAr 320 HMI board support")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Link: https://lore.kernel.org/r/20230225162237.40242-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/spear320-hmi.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts
+index 34503ac9c51c2..721e5ee7b6803 100644
+--- a/arch/arm/boot/dts/spear320-hmi.dts
++++ b/arch/arm/boot/dts/spear320-hmi.dts
+@@ -241,7 +241,7 @@
+ irq-trigger = <0x1>;
+
+ stmpegpio: stmpe-gpio {
+- compatible = "stmpe,gpio";
++ compatible = "st,stmpe-gpio";
+ reg = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+--
+2.39.2
+
--- /dev/null
+From fb1624995fe82b8a73bd4cb2c1d09a27fae59bb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 11:45:51 +0100
+Subject: ASoC: adau7118: don't disable regulators on device unbind
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nuno Sá <nuno.sa@analog.com>
+
+[ Upstream commit b5bfa7277ee7d944421e0ef193586c6e34d7492c ]
+
+The regulators are supposed to be controlled through the
+set_bias_level() component callback. Moreover, the regulators are not
+enabled during probe and so, this would lead to a regulator unbalanced
+use count.
+
+Fixes: ca514c0f12b02 ("ASOC: Add ADAU7118 8 Channel PDM-to-I2S/TDM Converter driver")
+Signed-off-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20230224104551.1139981-1-nuno.sa@analog.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/adau7118.c | 19 +------------------
+ 1 file changed, 1 insertion(+), 18 deletions(-)
+
+diff --git a/sound/soc/codecs/adau7118.c b/sound/soc/codecs/adau7118.c
+index bbb0972498876..a663d37e57760 100644
+--- a/sound/soc/codecs/adau7118.c
++++ b/sound/soc/codecs/adau7118.c
+@@ -444,22 +444,6 @@ static const struct snd_soc_component_driver adau7118_component_driver = {
+ .endianness = 1,
+ };
+
+-static void adau7118_regulator_disable(void *data)
+-{
+- struct adau7118_data *st = data;
+- int ret;
+- /*
+- * If we fail to disable DVDD, don't bother in trying IOVDD. We
+- * actually don't want to be left in the situation where DVDD
+- * is enabled and IOVDD is disabled.
+- */
+- ret = regulator_disable(st->dvdd);
+- if (ret)
+- return;
+-
+- regulator_disable(st->iovdd);
+-}
+-
+ static int adau7118_regulator_setup(struct adau7118_data *st)
+ {
+ st->iovdd = devm_regulator_get(st->dev, "iovdd");
+@@ -481,8 +465,7 @@ static int adau7118_regulator_setup(struct adau7118_data *st)
+ regcache_cache_only(st->map, true);
+ }
+
+- return devm_add_action_or_reset(st->dev, adau7118_regulator_disable,
+- st);
++ return 0;
+ }
+
+ static int adau7118_parset_dt(const struct adau7118_data *st)
+--
+2.39.2
+
--- /dev/null
+From 4d563ad4254c450cb68bbaec3be26cf3d1aa8f17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 16:33:00 +0100
+Subject: ASoC: apple: mca: Fix final status read on SERDES 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 aaf5f0d76b6e1870e3674408de2b13a92a4d4059 ]
+
+From within the early trigger we are doing a reset of the SERDES unit,
+but the final status read is on a bad address. Add the missing SERDES
+unit offset in calculation of the address.
+
+Fixes: 3df5d0d97289 ("ASoC: apple: mca: Start new platform driver")
+Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
+Link: https://lore.kernel.org/r/20230224153302.45365-1-povik+lin@cutebit.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/apple/mca.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
+index 24381c42eb54c..9cceeb2599524 100644
+--- a/sound/soc/apple/mca.c
++++ b/sound/soc/apple/mca.c
+@@ -210,7 +210,7 @@ static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
+ SERDES_CONF_SOME_RST);
+ readl_relaxed(cl->base + serdes_conf);
+ mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
+- WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
++ WARN_ON(readl_relaxed(cl->base + serdes_unit + REG_SERDES_STATUS) &
+ SERDES_STATUS_RST);
+ break;
+ default:
+--
+2.39.2
+
--- /dev/null
+From a8bec31586050ba588428348b16e8297594ab6db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 16:33:01 +0100
+Subject: ASoC: apple: mca: Fix SERDES reset sequence
+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 d8b3e396088d787771f19fd3b7949e080dc31d6f ]
+
+Fix the reset sequence of reads and writes that we invoke from within
+the early trigger. It looks like there never was a SERDES_CONF_SOME_RST
+bit that should be involved in the reset sequence, and its presence in
+the driver code is a mistake from earlier.
+
+Instead, the reset sequence should go as follows: We should switch the
+the SERDES unit's SYNC_SEL mux to the value of 7 (so outside the range
+of 1...6 representing cluster's SYNCGEN units), then raise the RST bit
+in SERDES_STATUS and wait for it to clear.
+
+Properly resetting the SERDES unit fixes frame desynchronization hazard
+in case of long frames (longer than 4 used slots). The desynchronization
+manifests itself by rotating the PCM channels.
+
+Fixes: 3df5d0d97289 ("ASoC: apple: mca: Start new platform driver")
+Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
+Link: https://lore.kernel.org/r/20230224153302.45365-2-povik+lin@cutebit.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/apple/mca.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
+index 9cceeb2599524..aea08c7b2ee85 100644
+--- a/sound/soc/apple/mca.c
++++ b/sound/soc/apple/mca.c
+@@ -101,7 +101,6 @@
+ #define SERDES_CONF_UNK3 BIT(14)
+ #define SERDES_CONF_NO_DATA_FEEDBACK BIT(15)
+ #define SERDES_CONF_SYNC_SEL GENMASK(18, 16)
+-#define SERDES_CONF_SOME_RST BIT(19)
+ #define REG_TX_SERDES_BITSTART 0x08
+ #define REG_RX_SERDES_BITSTART 0x0c
+ #define REG_TX_SERDES_SLOTMASK 0x0c
+@@ -203,15 +202,24 @@ static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
++ FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
++ mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
++ FIELD_PREP(SERDES_CONF_SYNC_SEL, 7));
+ mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
+ SERDES_STATUS_EN | SERDES_STATUS_RST,
+ SERDES_STATUS_RST);
+- mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
+- SERDES_CONF_SOME_RST);
+- readl_relaxed(cl->base + serdes_conf);
+- mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
++ /*
++ * Experiments suggest that it takes at most ~1 us
++ * for the bit to clear, so wait 2 us for good measure.
++ */
++ udelay(2);
+ WARN_ON(readl_relaxed(cl->base + serdes_unit + REG_SERDES_STATUS) &
+ SERDES_STATUS_RST);
++ mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
++ FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
++ mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
++ FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1));
+ break;
+ default:
+ break;
+--
+2.39.2
+
--- /dev/null
+From aa19f15c39b1d4da4e30ee0d38dcc4ab1312c8a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 16:33:02 +0100
+Subject: ASoC: apple: mca: Improve handling of unavailable DMA channels
+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 fb1847cc460c127b12720119eae5f438ffc62e85 ]
+
+When we fail to obtain a DMA channel, don't return a blanket -EINVAL,
+instead return the original error code if there's one. This makes
+deferring work as it should. Also don't print an error message for
+-EPROBE_DEFER.
+
+Fixes: 4ec8179c212f ("ASoC: apple: mca: Postpone requesting of DMA channels")
+Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
+Link: https://lore.kernel.org/r/20230224153302.45365-3-povik+lin@cutebit.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/apple/mca.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
+index aea08c7b2ee85..64750db9b9639 100644
+--- a/sound/soc/apple/mca.c
++++ b/sound/soc/apple/mca.c
+@@ -950,10 +950,17 @@ static int mca_pcm_new(struct snd_soc_component *component,
+ chan = mca_request_dma_channel(cl, i);
+
+ if (IS_ERR_OR_NULL(chan)) {
++ mca_pcm_free(component, rtd->pcm);
++
++ if (chan && PTR_ERR(chan) == -EPROBE_DEFER)
++ return PTR_ERR(chan);
++
+ dev_err(component->dev, "unable to obtain DMA channel (stream %d cluster %d): %pe\n",
+ i, cl->no, chan);
+- mca_pcm_free(component, rtd->pcm);
+- return -EINVAL;
++
++ if (!chan)
++ return -EINVAL;
++ return PTR_ERR(chan);
+ }
+
+ cl->dma_chans[i] = chan;
+--
+2.39.2
+
--- /dev/null
+From c6986212feb81740e7df57a00f3b063ed768fe78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 19:02:00 +0800
+Subject: ASoC: mediatek: mt8195: add missing initialization
+
+From: Trevor Wu <trevor.wu@mediatek.com>
+
+[ Upstream commit b56ec2992a2e43bc3e60d6db86849d31640e791f ]
+
+In etdm dai driver, dai_etdm_parse_of() function is used to parse dts
+properties to get parameters. There are two for-loops which are
+sepearately for all etdm and etdm input only cases. In etdm in only
+loop, dai_id is not initialized, so it keeps the value intiliazed in
+another loop.
+
+In the patch, add the missing initialization to fix the unexpected
+parsing problem.
+
+Fixes: 1de9a54acafb ("ASoC: mediatek: mt8195: support etdm in platform driver")
+Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230301110200.26177-3-trevor.wu@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt8195/mt8195-dai-etdm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
+index c2e268054773d..f2c9a1fdbe0d0 100644
+--- a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
++++ b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
+@@ -2567,6 +2567,9 @@ static void mt8195_dai_etdm_parse_of(struct mtk_base_afe *afe)
+
+ /* etdm in only */
+ for (i = 0; i < 2; i++) {
++ dai_id = ETDM_TO_DAI_ID(i);
++ etdm_data = afe_priv->dai_priv[dai_id];
++
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-chn-disabled",
+ of_afe_etdms[i].name);
+--
+2.39.2
+
--- /dev/null
+From 46d939f743dc1e4c82a5fb07254633fc4aff9461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Feb 2023 09:58:26 +0100
+Subject: ASoC: zl38060 add gpiolib dependency
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 0de2cc3707b6b6e2ad40bd24ce09a5c1f65d01e1 ]
+
+Without gpiolib, this driver fails to link:
+
+arm-linux-gnueabi-ld: sound/soc/codecs/zl38060.o: in function `chip_gpio_get':
+zl38060.c:(.text+0x30): undefined reference to `gpiochip_get_data'
+arm-linux-gnueabi-ld: sound/soc/codecs/zl38060.o: in function `zl38_spi_probe':
+zl38060.c:(.text+0xa18): undefined reference to `devm_gpiochip_add_data_with_key'
+
+This appears to have been in the driver since the start, but is hard to
+hit in randconfig testing since gpiolib is almost always selected by something
+else.
+
+Fixes: 52e8a94baf90 ("ASoC: Add initial ZL38060 driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230227085850.2503725-1-arnd@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 7022e6286e6cb..3f16ad1c37585 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -2039,6 +2039,7 @@ config SND_SOC_WSA883X
+ config SND_SOC_ZL38060
+ tristate "Microsemi ZL38060 Connected Home Audio Processor"
+ depends on SPI_MASTER
++ depends on GPIOLIB
+ select REGMAP
+ help
+ Support for ZL38060 Connected Home Audio Processor from Microsemi,
+--
+2.39.2
+
--- /dev/null
+From df20efdb96f451d7f1d8e6680f9eb8c9addc2767 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 16:15:42 +0800
+Subject: auxdisplay: hd44780: Fix potential memory leak in hd44780_remove()
+
+From: Jianglei Nie <niejianglei2021@163.com>
+
+[ Upstream commit ddf75a86aba2cfb7ec4497e8692b60c8c8fe0ee7 ]
+
+hd44780_probe() allocates a memory chunk for hd with kzalloc() and
+makes "lcd->drvdata->hd44780" point to it. When we call hd44780_remove(),
+we should release all relevant memory and resource. But "lcd->drvdata
+->hd44780" is not released, which will lead to a memory leak.
+
+We should release the "lcd->drvdata->hd44780" in hd44780_remove() to fix
+the memory leak bug.
+
+Fixes: 718e05ed92ec ("auxdisplay: Introduce hd44780_common.[ch]")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Jianglei Nie <niejianglei2021@163.com>
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/auxdisplay/hd44780.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
+index 8b2a0eb3f32a4..d56a5d508ccd7 100644
+--- a/drivers/auxdisplay/hd44780.c
++++ b/drivers/auxdisplay/hd44780.c
+@@ -322,8 +322,10 @@ static int hd44780_probe(struct platform_device *pdev)
+ static int hd44780_remove(struct platform_device *pdev)
+ {
+ struct charlcd *lcd = platform_get_drvdata(pdev);
++ struct hd44780_common *hdc = lcd->drvdata;
+
+ charlcd_unregister(lcd);
++ kfree(hdc->hd44780);
+ kfree(lcd->drvdata);
+
+ kfree(lcd);
+--
+2.39.2
+
--- /dev/null
+From 6e955e649a76085dc25948f72e5703e417138fd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Feb 2023 08:27:49 +0900
+Subject: bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for
+ DCC support
+
+From: Souradeep Chowdhury <quic_schowdhu@quicinc.com>
+
+[ Upstream commit 6c40624930c58529185a257380442547580ed837 ]
+
+The Data Capture and Compare(DCC) is a debugging tool that uses the bootconfig
+for configuring the register values during boot-time. Increase the max nodes
+supported by bootconfig to cater to the requirements of the Data Capture and
+Compare Driver.
+
+Link: https://lore.kernel.org/all/1674536682-18404-1-git-send-email-quic_schowdhu@quicinc.com/
+
+Signed-off-by: Souradeep Chowdhury <quic_schowdhu@quicinc.com>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bootconfig.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
+index 1611f9db878e7..ca73940e26df8 100644
+--- a/include/linux/bootconfig.h
++++ b/include/linux/bootconfig.h
+@@ -59,7 +59,7 @@ struct xbc_node {
+ /* Maximum size of boot config is 32KB - 1 */
+ #define XBC_DATA_MAX (XBC_VALUE - 1)
+
+-#define XBC_NODE_MAX 1024
++#define XBC_NODE_MAX 8192
+ #define XBC_KEYLEN_MAX 256
+ #define XBC_DEPTH_MAX 16
+
+--
+2.39.2
+
--- /dev/null
+From 15963d3ea10f9d203b633402497cf3cd6a03c3f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Dec 2022 21:47:02 +0530
+Subject: bus: mhi: ep: Fix the debug message for MHI_PKT_TYPE_RESET_CHAN_CMD
+ cmd
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 8e697fcfdb9809634e268058ca743369c216b7ac ]
+
+The debug log incorrectly mentions that STOP command is received instead of
+RESET command. Fix that.
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Link: https://lore.kernel.org/r/20221228161704.255268-5-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/ep/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
+index 9c42886818418..357c61c12ce5b 100644
+--- a/drivers/bus/mhi/ep/main.c
++++ b/drivers/bus/mhi/ep/main.c
+@@ -219,7 +219,7 @@ static int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ring_ele
+ mutex_unlock(&mhi_chan->lock);
+ break;
+ case MHI_PKT_TYPE_RESET_CHAN_CMD:
+- dev_dbg(dev, "Received STOP command for channel (%u)\n", ch_id);
++ dev_dbg(dev, "Received RESET command for channel (%u)\n", ch_id);
+ if (!ch_ring->started) {
+ dev_err(dev, "Channel (%u) not opened\n", ch_id);
+ return -ENODEV;
+--
+2.39.2
+
--- /dev/null
+From 331953df57fdba05b5fffbeda75435e63610d383 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 10:51:33 +0000
+Subject: cacheinfo: Fix shared_cpu_map to handle shared caches at different
+ levels
+
+From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+
+[ Upstream commit 198102c9103fc78d8478495971947af77edb05c1 ]
+
+The cacheinfo sets up the shared_cpu_map by checking whether the caches
+with the same index are shared between CPUs. However, this will trigger
+slab-out-of-bounds access if the CPUs do not have the same cache hierarchy.
+Another problem is the mismatched shared_cpu_map when the shared cache does
+not have the same index between CPUs.
+
+CPU0 I D L3
+index 0 1 2 x
+ ^ ^ ^ ^
+index 0 1 2 3
+CPU1 I D L2 L3
+
+This patch checks each cache is shared with all caches on other CPUs.
+
+Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>
+Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+Link: https://lore.kernel.org/r/20230117105133.4445-2-yongxuan.wang@sifive.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/cacheinfo.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c
+index 4b5cd08c5a657..f30256a524be6 100644
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -251,7 +251,7 @@ static int cache_shared_cpu_map_setup(unsigned int cpu)
+ {
+ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+ struct cacheinfo *this_leaf, *sib_leaf;
+- unsigned int index;
++ unsigned int index, sib_index;
+ int ret = 0;
+
+ if (this_cpu_ci->cpu_map_populated)
+@@ -279,11 +279,13 @@ static int cache_shared_cpu_map_setup(unsigned int cpu)
+
+ if (i == cpu || !sib_cpu_ci->info_list)
+ continue;/* skip if itself or no cacheinfo */
+-
+- sib_leaf = per_cpu_cacheinfo_idx(i, index);
+- if (cache_leaves_are_shared(this_leaf, sib_leaf)) {
+- cpumask_set_cpu(cpu, &sib_leaf->shared_cpu_map);
+- cpumask_set_cpu(i, &this_leaf->shared_cpu_map);
++ for (sib_index = 0; sib_index < cache_leaves(i); sib_index++) {
++ sib_leaf = per_cpu_cacheinfo_idx(i, sib_index);
++ if (cache_leaves_are_shared(this_leaf, sib_leaf)) {
++ cpumask_set_cpu(cpu, &sib_leaf->shared_cpu_map);
++ cpumask_set_cpu(i, &this_leaf->shared_cpu_map);
++ break;
++ }
+ }
+ }
+ /* record the maximum cache line size */
+@@ -297,7 +299,7 @@ static int cache_shared_cpu_map_setup(unsigned int cpu)
+ static void cache_shared_cpu_map_remove(unsigned int cpu)
+ {
+ struct cacheinfo *this_leaf, *sib_leaf;
+- unsigned int sibling, index;
++ unsigned int sibling, index, sib_index;
+
+ for (index = 0; index < cache_leaves(cpu); index++) {
+ this_leaf = per_cpu_cacheinfo_idx(cpu, index);
+@@ -308,9 +310,14 @@ static void cache_shared_cpu_map_remove(unsigned int cpu)
+ if (sibling == cpu || !sib_cpu_ci->info_list)
+ continue;/* skip if itself or no cacheinfo */
+
+- sib_leaf = per_cpu_cacheinfo_idx(sibling, index);
+- cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map);
+- cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map);
++ for (sib_index = 0; sib_index < cache_leaves(sibling); sib_index++) {
++ sib_leaf = per_cpu_cacheinfo_idx(sibling, sib_index);
++ if (cache_leaves_are_shared(this_leaf, sib_leaf)) {
++ cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map);
++ cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map);
++ break;
++ }
++ }
+ }
+ if (of_have_populated_dt())
+ of_node_put(this_leaf->fw_token);
+--
+2.39.2
+
--- /dev/null
+From d6401cb8f6e03920b3da4b5e46e59b49d042c523 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Nov 2022 09:01:46 +0800
+Subject: driver: soc: xilinx: fix memory leak in
+ xlnx_add_cb_for_notify_event()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 1bea534991b9b35c41848a397666ada436456beb ]
+
+The kfree() should be called when memory fails to be allocated for
+cb_data in xlnx_add_cb_for_notify_event(), otherwise there will be
+a memory leak, so add kfree() to fix it.
+
+Fixes: 05e5ba40ea7a ("driver: soc: xilinx: Add support of multiple callbacks for same event in event management driver")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Link: https://lore.kernel.org/r/20221129010146.1026685-1-cuigaosheng1@huawei.com
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/xilinx/xlnx_event_manager.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c
+index 2de082765befa..c76381899ef49 100644
+--- a/drivers/soc/xilinx/xlnx_event_manager.c
++++ b/drivers/soc/xilinx/xlnx_event_manager.c
+@@ -116,8 +116,10 @@ static int xlnx_add_cb_for_notify_event(const u32 node_id, const u32 event, cons
+ INIT_LIST_HEAD(&eve_data->cb_list_head);
+
+ cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL);
+- if (!cb_data)
++ if (!cb_data) {
++ kfree(eve_data);
+ return -ENOMEM;
++ }
+ cb_data->eve_cb = cb_fun;
+ cb_data->agent_data = data;
+
+--
+2.39.2
+
--- /dev/null
+From eeff1c2953f1dd7651d3c023bd9b621d8cf9a2bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 15:16:20 +0100
+Subject: drivers: base: component: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 8deb87b1e810dd558371e88ffd44339fbef27870 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Link: https://lore.kernel.org/r/20230202141621.2296458-1-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/component.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/base/component.c b/drivers/base/component.c
+index 5eadeac6c5322..7dbf14a1d9157 100644
+--- a/drivers/base/component.c
++++ b/drivers/base/component.c
+@@ -125,7 +125,7 @@ static void component_debugfs_add(struct aggregate_device *m)
+
+ static void component_debugfs_del(struct aggregate_device *m)
+ {
+- debugfs_remove(debugfs_lookup(dev_name(m->parent), component_debugfs_dir));
++ debugfs_lookup_and_remove(dev_name(m->parent), component_debugfs_dir);
+ }
+
+ #else
+--
+2.39.2
+
--- /dev/null
+From afed666d4672419477f38c94c18471dbe1c08387 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 15:16:21 +0100
+Subject: drivers: base: dd: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 36c893d3a759ae7c91ee7d4871ebfc7504f08c40 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Link: https://lore.kernel.org/r/20230202141621.2296458-2-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/dd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index 9ae2b5c4fc496..c463173f1fb1a 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -372,7 +372,7 @@ late_initcall(deferred_probe_initcall);
+
+ static void __exit deferred_probe_exit(void)
+ {
+- debugfs_remove_recursive(debugfs_lookup("devices_deferred", NULL));
++ debugfs_lookup_and_remove("devices_deferred", NULL);
+ }
+ __exitcall(deferred_probe_exit);
+
+--
+2.39.2
+
--- /dev/null
+From ffea15173f9772828e646aea40439ef00c0e6636 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 20:45:33 -0800
+Subject: drm/i915: move a Kconfig symbol to unbreak the menu presentation
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 0b93efca3659f6d55ed31cff6722dca5f6e4d6e2 ]
+
+Inserting a Kconfig symbol that does not have a dependency (DRM_I915_GVT)
+into a list of other symbols that do have a dependency (on DRM_I915)
+breaks the driver menu presentation in 'make *config'.
+
+Relocate the DRM_I915_GVT symbol so that it does not cause this
+problem.
+
+Fixes: 8b750bf74418 ("drm/i915/gvt: move the gvt code into kvmgt.ko")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Zhi Wang <zhi.a.wang@intel.com>
+Cc: Jani Nikula <jani.nikula@linux.intel.com>
+Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
+Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
+Cc: intel-gfx@lists.freedesktop.org
+Cc: intel-gvt-dev@lists.freedesktop.org
+Cc: dri-devel@lists.freedesktop.org
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20230215044533.4847-1-rdunlap@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/Kconfig | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
+index 3efce05d7b57c..3a6e176d77aa5 100644
+--- a/drivers/gpu/drm/i915/Kconfig
++++ b/drivers/gpu/drm/i915/Kconfig
+@@ -107,9 +107,6 @@ config DRM_I915_USERPTR
+
+ If in doubt, say "Y".
+
+-config DRM_I915_GVT
+- bool
+-
+ config DRM_I915_GVT_KVMGT
+ tristate "Enable KVM host support Intel GVT-g graphics virtualization"
+ depends on DRM_I915
+@@ -160,3 +157,6 @@ menu "drm/i915 Unstable Evolution"
+ depends on DRM_I915
+ source "drivers/gpu/drm/i915/Kconfig.unstable"
+ endmenu
++
++config DRM_I915_GVT
++ bool
+--
+2.39.2
+
--- /dev/null
+From 50ec172d9b0a5415747a7b13da3ab3b55b5eb352 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Dec 2022 09:51:28 +0800
+Subject: ext4: don't show commit interval if it is zero
+
+From: Wang Jianjian <wangjianjian3@huawei.com>
+
+[ Upstream commit 934b0de1e9fdea93c4c7f2e18915c54fae67bdc6 ]
+
+If commit interval is 0, it means using default value.
+
+Fixes: 6e47a3cc68fc ("ext4: get rid of super block and sbi from handle_mount_ops()")
+Signed-off-by: Wang Jianjian <wangjianjian3@huawei.com>
+Link: https://lore.kernel.org/r/20221219015128.876717-1-wangjianjian3@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index aa4f65663fad8..22ddd89c868aa 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2146,7 +2146,7 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
+ return 0;
+ case Opt_commit:
+ if (result.uint_32 == 0)
+- ctx->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE;
++ result.uint_32 = JBD2_DEFAULT_MAX_COMMIT_AGE;
+ else if (result.uint_32 > INT_MAX / HZ) {
+ ext4_msg(NULL, KERN_ERR,
+ "Invalid commit interval %d, "
+--
+2.39.2
+
--- /dev/null
+From 7c42d081471325b77d5a1e50bc2ba161aab29961 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 Jan 2023 11:49:39 +0800
+Subject: ext4: fix incorrect options show of original mount_opt and extend
+ mount_opt2
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit e3645d72f8865ffe36f9dc811540d40aa3c848d3 ]
+
+Current _ext4_show_options() do not distinguish MOPT_2 flag, so it mixed
+extend sbi->s_mount_opt2 options with sbi->s_mount_opt, it could lead to
+show incorrect options, e.g. show fc_debug_force if we mount with
+errors=continue mode and miss it if we set.
+
+ $ mkfs.ext4 /dev/pmem0
+ $ mount -o errors=remount-ro /dev/pmem0 /mnt
+ $ cat /proc/fs/ext4/pmem0/options | grep fc_debug_force
+ #empty
+ $ mount -o remount,errors=continue /mnt
+ $ cat /proc/fs/ext4/pmem0/options | grep fc_debug_force
+ fc_debug_force
+ $ mount -o remount,errors=remount-ro,fc_debug_force /mnt
+ $ cat /proc/fs/ext4/pmem0/options | grep fc_debug_force
+ #empty
+
+Fixes: 995a3ed67fc8 ("ext4: add fast_commit feature and handling for extended mount options")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20230129034939.3702550-1-yi.zhang@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h | 1 +
+ fs/ext4/super.c | 28 +++++++++++++++++++++-------
+ 2 files changed, 22 insertions(+), 7 deletions(-)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 4e739902dc03a..a2bc440743ae4 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1529,6 +1529,7 @@ struct ext4_sb_info {
+ unsigned int s_mount_opt2;
+ unsigned long s_mount_flags;
+ unsigned int s_def_mount_opt;
++ unsigned int s_def_mount_opt2;
+ ext4_fsblk_t s_sb_block;
+ atomic64_t s_resv_clusters;
+ kuid_t s_resuid;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 22ddd89c868aa..8011600999586 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2894,7 +2894,7 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
+ {
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct ext4_super_block *es = sbi->s_es;
+- int def_errors, def_mount_opt = sbi->s_def_mount_opt;
++ int def_errors;
+ const struct mount_opts *m;
+ char sep = nodefs ? '\n' : ',';
+
+@@ -2906,15 +2906,28 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
+
+ for (m = ext4_mount_opts; m->token != Opt_err; m++) {
+ int want_set = m->flags & MOPT_SET;
++ int opt_2 = m->flags & MOPT_2;
++ unsigned int mount_opt, def_mount_opt;
++
+ if (((m->flags & (MOPT_SET|MOPT_CLEAR)) == 0) ||
+ m->flags & MOPT_SKIP)
+ continue;
+- if (!nodefs && !(m->mount_opt & (sbi->s_mount_opt ^ def_mount_opt)))
+- continue; /* skip if same as the default */
++
++ if (opt_2) {
++ mount_opt = sbi->s_mount_opt2;
++ def_mount_opt = sbi->s_def_mount_opt2;
++ } else {
++ mount_opt = sbi->s_mount_opt;
++ def_mount_opt = sbi->s_def_mount_opt;
++ }
++ /* skip if same as the default */
++ if (!nodefs && !(m->mount_opt & (mount_opt ^ def_mount_opt)))
++ continue;
++ /* select Opt_noFoo vs Opt_Foo */
+ if ((want_set &&
+- (sbi->s_mount_opt & m->mount_opt) != m->mount_opt) ||
+- (!want_set && (sbi->s_mount_opt & m->mount_opt)))
+- continue; /* select Opt_noFoo vs Opt_Foo */
++ (mount_opt & m->mount_opt) != m->mount_opt) ||
++ (!want_set && (mount_opt & m->mount_opt)))
++ continue;
+ SEQ_OPTS_PRINT("%s", token2str(m->token));
+ }
+
+@@ -2942,7 +2955,7 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
+ if (nodefs || sbi->s_stripe)
+ SEQ_OPTS_PRINT("stripe=%lu", sbi->s_stripe);
+ if (nodefs || EXT4_MOUNT_DATA_FLAGS &
+- (sbi->s_mount_opt ^ def_mount_opt)) {
++ (sbi->s_mount_opt ^ sbi->s_def_mount_opt)) {
+ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+ SEQ_OPTS_PUTS("data=journal");
+ else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
+@@ -5087,6 +5100,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
+ goto failed_mount;
+
+ sbi->s_def_mount_opt = sbi->s_mount_opt;
++ sbi->s_def_mount_opt2 = sbi->s_mount_opt2;
+
+ err = ext4_check_opt_consistency(fc, sb);
+ if (err < 0)
+--
+2.39.2
+
--- /dev/null
+From 7f31205d9b4d898691d46b02df9a5fa3841d609d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Dec 2022 21:02:12 -0800
+Subject: ext4: use ext4_fc_tl_mem in fast-commit replay path
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 11768cfd98136dd8399480c60b7a5d3d3c7b109b ]
+
+To avoid 'sparse' warnings about missing endianness conversions, don't
+store native endianness values into struct ext4_fc_tl. Instead, use a
+separate struct type, ext4_fc_tl_mem.
+
+Fixes: dcc5827484d6 ("ext4: factor out ext4_fc_get_tl()")
+Cc: Ye Bin <yebin10@huawei.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20221217050212.150665-1-ebiggers@kernel.org
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/fast_commit.c | 44 +++++++++++++++++++++++++------------------
+ 1 file changed, 26 insertions(+), 18 deletions(-)
+
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index 7ed71c652f67f..1110bfa0a5b73 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -1354,8 +1354,14 @@ struct dentry_info_args {
+ char *dname;
+ };
+
++/* Same as struct ext4_fc_tl, but uses native endianness fields */
++struct ext4_fc_tl_mem {
++ u16 fc_tag;
++ u16 fc_len;
++};
++
+ static inline void tl_to_darg(struct dentry_info_args *darg,
+- struct ext4_fc_tl *tl, u8 *val)
++ struct ext4_fc_tl_mem *tl, u8 *val)
+ {
+ struct ext4_fc_dentry_info fcd;
+
+@@ -1367,16 +1373,18 @@ static inline void tl_to_darg(struct dentry_info_args *darg,
+ darg->dname_len = tl->fc_len - sizeof(struct ext4_fc_dentry_info);
+ }
+
+-static inline void ext4_fc_get_tl(struct ext4_fc_tl *tl, u8 *val)
++static inline void ext4_fc_get_tl(struct ext4_fc_tl_mem *tl, u8 *val)
+ {
+- memcpy(tl, val, EXT4_FC_TAG_BASE_LEN);
+- tl->fc_len = le16_to_cpu(tl->fc_len);
+- tl->fc_tag = le16_to_cpu(tl->fc_tag);
++ struct ext4_fc_tl tl_disk;
++
++ memcpy(&tl_disk, val, EXT4_FC_TAG_BASE_LEN);
++ tl->fc_len = le16_to_cpu(tl_disk.fc_len);
++ tl->fc_tag = le16_to_cpu(tl_disk.fc_tag);
+ }
+
+ /* Unlink replay function */
+-static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl,
+- u8 *val)
++static int ext4_fc_replay_unlink(struct super_block *sb,
++ struct ext4_fc_tl_mem *tl, u8 *val)
+ {
+ struct inode *inode, *old_parent;
+ struct qstr entry;
+@@ -1473,8 +1481,8 @@ static int ext4_fc_replay_link_internal(struct super_block *sb,
+ }
+
+ /* Link replay function */
+-static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl,
+- u8 *val)
++static int ext4_fc_replay_link(struct super_block *sb,
++ struct ext4_fc_tl_mem *tl, u8 *val)
+ {
+ struct inode *inode;
+ struct dentry_info_args darg;
+@@ -1528,8 +1536,8 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino)
+ /*
+ * Inode replay function
+ */
+-static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+- u8 *val)
++static int ext4_fc_replay_inode(struct super_block *sb,
++ struct ext4_fc_tl_mem *tl, u8 *val)
+ {
+ struct ext4_fc_inode fc_inode;
+ struct ext4_inode *raw_inode;
+@@ -1631,8 +1639,8 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+ * inode for which we are trying to create a dentry here, should already have
+ * been replayed before we start here.
+ */
+-static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl,
+- u8 *val)
++static int ext4_fc_replay_create(struct super_block *sb,
++ struct ext4_fc_tl_mem *tl, u8 *val)
+ {
+ int ret = 0;
+ struct inode *inode = NULL;
+@@ -1730,7 +1738,7 @@ int ext4_fc_record_regions(struct super_block *sb, int ino,
+
+ /* Replay add range tag */
+ static int ext4_fc_replay_add_range(struct super_block *sb,
+- struct ext4_fc_tl *tl, u8 *val)
++ struct ext4_fc_tl_mem *tl, u8 *val)
+ {
+ struct ext4_fc_add_range fc_add_ex;
+ struct ext4_extent newex, *ex;
+@@ -1850,8 +1858,8 @@ static int ext4_fc_replay_add_range(struct super_block *sb,
+
+ /* Replay DEL_RANGE tag */
+ static int
+-ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
+- u8 *val)
++ext4_fc_replay_del_range(struct super_block *sb,
++ struct ext4_fc_tl_mem *tl, u8 *val)
+ {
+ struct inode *inode;
+ struct ext4_fc_del_range lrange;
+@@ -2047,7 +2055,7 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ struct ext4_fc_replay_state *state;
+ int ret = JBD2_FC_REPLAY_CONTINUE;
+ struct ext4_fc_add_range ext;
+- struct ext4_fc_tl tl;
++ struct ext4_fc_tl_mem tl;
+ struct ext4_fc_tail tail;
+ __u8 *start, *end, *cur, *val;
+ struct ext4_fc_head head;
+@@ -2166,7 +2174,7 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ {
+ struct super_block *sb = journal->j_private;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+- struct ext4_fc_tl tl;
++ struct ext4_fc_tl_mem tl;
+ __u8 *start, *end, *cur, *val;
+ int ret = JBD2_FC_REPLAY_CONTINUE;
+ struct ext4_fc_replay_state *state = &sbi->s_fc_replay_state;
+--
+2.39.2
+
--- /dev/null
+From a63e1ac3030fae3cea3b8ab1faa833a42250c5f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Jan 2023 17:46:01 +0800
+Subject: f2fs: allow set compression option of files without blocks
+
+From: Yangtao Li <frank.li@vivo.com>
+
+[ Upstream commit e6261beb0c629403dc58997294dd521bd23664af ]
+
+Files created by truncate have a size but no blocks, so
+they can be allowed to set compression option.
+
+Fixes: e1e8debec656 ("f2fs: add F2FS_IOC_SET_COMPRESS_OPTION ioctl")
+Signed-off-by: Yangtao Li <frank.li@vivo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 7bb0c05e943cf..88eecd7149cd5 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3937,7 +3937,7 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
+ goto out;
+ }
+
+- if (inode->i_size != 0) {
++ if (F2FS_HAS_BLOCKS(inode)) {
+ ret = -EFBIG;
+ goto out;
+ }
+--
+2.39.2
+
--- /dev/null
+From bb518c9b9ac2b9d02ff071f8ece9be4480bf6714 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 11:44:50 +0800
+Subject: f2fs: clear atomic_write_task in f2fs_abort_atomic_write()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 0e8d040bfa4c476d7d2a23119527c744c7de13cd ]
+
+Otherwise, last .atomic_write_task will be remained in structure
+f2fs_inode_info, resulting in aborting atomic_write accidentally
+in race case. Meanwhile, clear original_i_size as well.
+
+Fixes: 7a10f0177e11 ("f2fs: don't give partially written atomic data from process crash")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 60d79e427f988..63c6894099799 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -200,9 +200,12 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean)
+ clear_inode_flag(inode, FI_ATOMIC_FILE);
+ stat_dec_atomic_inode(inode);
+
++ F2FS_I(inode)->atomic_write_task = NULL;
++
+ if (clean) {
+ truncate_inode_pages_final(inode->i_mapping);
+ f2fs_i_size_write(inode, fi->original_i_size);
++ fi->original_i_size = 0;
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 0025fdd4e286364f973277d0388715dc39517bd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 12:24:15 -0700
+Subject: f2fs: correct i_size change for atomic writes
+
+From: Daeho Jeong <daehojeong@google.com>
+
+[ Upstream commit 4d8d45df2252980f800c1b2fde941a103a18a70e ]
+
+We need to make sure i_size doesn't change until atomic write commit is
+successful and restore it when commit is failed.
+
+Signed-off-by: Daeho Jeong <daehojeong@google.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 0e8d040bfa4c ("f2fs: clear atomic_write_task in f2fs_abort_atomic_write()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 8 ++++++++
+ fs/f2fs/file.c | 18 +++++++++++-------
+ fs/f2fs/inode.c | 5 ++++-
+ fs/f2fs/segment.c | 14 ++++++++++----
+ 4 files changed, 33 insertions(+), 12 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 8b9f0b3c77232..87664c309b3c8 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -764,6 +764,7 @@ enum {
+ FI_COMPRESS_RELEASED, /* compressed blocks were released */
+ FI_ALIGNED_WRITE, /* enable aligned write */
+ FI_COW_FILE, /* indicate COW file */
++ FI_ATOMIC_COMMITTED, /* indicate atomic commit completed except disk sync */
+ FI_MAX, /* max flag, never be used */
+ };
+
+@@ -822,6 +823,7 @@ struct f2fs_inode_info {
+ unsigned int i_cluster_size; /* cluster size */
+
+ unsigned int atomic_write_cnt;
++ loff_t original_i_size; /* original i_size before atomic write */
+ };
+
+ static inline void get_extent_info(struct extent_info *ext,
+@@ -3072,6 +3074,8 @@ static inline void f2fs_i_blocks_write(struct inode *inode,
+ set_inode_flag(inode, FI_AUTO_RECOVER);
+ }
+
++static inline bool f2fs_is_atomic_file(struct inode *inode);
++
+ static inline void f2fs_i_size_write(struct inode *inode, loff_t i_size)
+ {
+ bool clean = !is_inode_flag_set(inode, FI_DIRTY_INODE);
+@@ -3081,6 +3085,10 @@ static inline void f2fs_i_size_write(struct inode *inode, loff_t i_size)
+ return;
+
+ i_size_write(inode, i_size);
++
++ if (f2fs_is_atomic_file(inode))
++ return;
++
+ f2fs_mark_inode_dirty_sync(inode, true);
+ if (clean || recover)
+ set_inode_flag(inode, FI_AUTO_RECOVER);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index a03c61bd70165..7bb0c05e943cf 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -2041,6 +2041,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ struct f2fs_inode_info *fi = F2FS_I(inode);
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct inode *pinode;
++ loff_t isize;
+ int ret;
+
+ if (!inode_owner_or_capable(mnt_userns, inode))
+@@ -2099,7 +2100,12 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
+ goto out;
+ }
+- f2fs_i_size_write(fi->cow_inode, i_size_read(inode));
++
++ f2fs_write_inode(inode, NULL);
++
++ isize = i_size_read(inode);
++ fi->original_i_size = isize;
++ f2fs_i_size_write(fi->cow_inode, isize);
+
+ stat_inc_atomic_inode(inode);
+
+@@ -2137,16 +2143,14 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
+
+ if (f2fs_is_atomic_file(inode)) {
+ ret = f2fs_commit_atomic_write(inode);
+- if (ret)
+- goto unlock_out;
+-
+- ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
+ if (!ret)
+- f2fs_abort_atomic_write(inode, false);
++ ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
++
++ f2fs_abort_atomic_write(inode, ret);
+ } else {
+ ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false);
+ }
+-unlock_out:
++
+ inode_unlock(inode);
+ mnt_drop_write_file(filp);
+ return ret;
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index 5d6fd824f74f2..e8413b080e0a7 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -621,9 +621,12 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
+ ri->i_uid = cpu_to_le32(i_uid_read(inode));
+ ri->i_gid = cpu_to_le32(i_gid_read(inode));
+ ri->i_links = cpu_to_le32(inode->i_nlink);
+- ri->i_size = cpu_to_le64(i_size_read(inode));
+ ri->i_blocks = cpu_to_le64(SECTOR_TO_BLOCK(inode->i_blocks) + 1);
+
++ if (!f2fs_is_atomic_file(inode) ||
++ is_inode_flag_set(inode, FI_ATOMIC_COMMITTED))
++ ri->i_size = cpu_to_le64(i_size_read(inode));
++
+ if (et) {
+ read_lock(&et->lock);
+ set_raw_extent(&et->largest, &ri->i_ext);
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index af9a3b7996b4d..60d79e427f988 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -192,14 +192,18 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean)
+ if (!f2fs_is_atomic_file(inode))
+ return;
+
+- if (clean)
+- truncate_inode_pages_final(inode->i_mapping);
+ clear_inode_flag(fi->cow_inode, FI_COW_FILE);
+ iput(fi->cow_inode);
+ fi->cow_inode = NULL;
+ release_atomic_write_cnt(inode);
++ clear_inode_flag(inode, FI_ATOMIC_COMMITTED);
+ clear_inode_flag(inode, FI_ATOMIC_FILE);
+ stat_dec_atomic_inode(inode);
++
++ if (clean) {
++ truncate_inode_pages_final(inode->i_mapping);
++ f2fs_i_size_write(inode, fi->original_i_size);
++ }
+ }
+
+ static int __replace_atomic_write_block(struct inode *inode, pgoff_t index,
+@@ -338,10 +342,12 @@ static int __f2fs_commit_atomic_write(struct inode *inode)
+ }
+
+ out:
+- if (ret)
++ if (ret) {
+ sbi->revoked_atomic_block += fi->atomic_write_cnt;
+- else
++ } else {
+ sbi->committed_atomic_block += fi->atomic_write_cnt;
++ set_inode_flag(inode, FI_ATOMIC_COMMITTED);
++ }
+
+ __complete_revoke_list(inode, &revoke_list, ret ? true : false);
+
+--
+2.39.2
+
--- /dev/null
+From 4a4365838d5139d8f810ed86b3813bb900c9773d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 10:15:09 +0100
+Subject: f2fs: don't rely on F2FS_MAP_* in f2fs_iomap_begin
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 8d3c1fa3fa5eacfd14f5b018eddb6c1a91c57783 ]
+
+When testing with a mixed zoned / convention device combination, there
+are regular but not 100% reproducible failures in xfstests generic/113
+where the __is_valid_data_blkaddr assert hits due to finding a hole.
+
+This seems to be because f2fs_map_blocks can set this flag on a hole
+when it was found in the extent cache.
+
+Rework f2fs_iomap_begin to just check the special block numbers directly.
+This has the added benefits of the WARN_ON showing which invalid block
+address we found, and being properly error out on delalloc blocks that
+are confusingly called unwritten but not actually suitable for direct
+I/O.
+
+Fixes: 1517c1a7a445 ("f2fs: implement iomap operations")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 5f4519af98214..f92899bfcbd5e 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -4138,20 +4138,24 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
+ */
+ map.m_len = fscrypt_limit_io_blocks(inode, map.m_lblk, map.m_len);
+
+- if (map.m_flags & (F2FS_MAP_MAPPED | F2FS_MAP_UNWRITTEN)) {
+- iomap->length = blks_to_bytes(inode, map.m_len);
+- if (map.m_flags & F2FS_MAP_MAPPED) {
+- iomap->type = IOMAP_MAPPED;
+- iomap->flags |= IOMAP_F_MERGED;
+- } else {
+- iomap->type = IOMAP_UNWRITTEN;
+- }
+- if (WARN_ON_ONCE(!__is_valid_data_blkaddr(map.m_pblk)))
+- return -EINVAL;
++ /*
++ * We should never see delalloc or compressed extents here based on
++ * prior flushing and checks.
++ */
++ if (WARN_ON_ONCE(map.m_pblk == NEW_ADDR))
++ return -EINVAL;
++ if (WARN_ON_ONCE(map.m_pblk == COMPRESS_ADDR))
++ return -EINVAL;
+
++ if (map.m_pblk != NULL_ADDR) {
++ iomap->length = blks_to_bytes(inode, map.m_len);
++ iomap->type = IOMAP_MAPPED;
++ iomap->flags |= IOMAP_F_MERGED;
+ iomap->bdev = map.m_bdev;
+ iomap->addr = blks_to_bytes(inode, map.m_pblk);
+ } else {
++ if (flags & IOMAP_WRITE)
++ return -ENOTBLK;
+ iomap->length = blks_to_bytes(inode, next_pgofs) -
+ iomap->offset;
+ iomap->type = IOMAP_HOLE;
+--
+2.39.2
+
--- /dev/null
+From 579dc9f31ef5d1a37ad70421267438f10e217dd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 11:44:51 +0800
+Subject: f2fs: fix to abort atomic write only during do_exist()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit ae267fc1cfe9f941afcb90dc963ee6448dae73cf ]
+
+Commit 7a10f0177e11 ("f2fs: don't give partially written atomic data
+from process crash") attempted to drop atomic write data after process
+crash, however, f2fs_abort_atomic_write() may be called from noncrash
+case, fix it by adding missed PF_EXITING check condition
+f2fs_file_flush().
+
+- application crashs
+ - do_exit
+ - exit_signals -- sets PF_EXITING
+ - exit_files
+ - put_files_struct
+ - close_files
+ - filp_close
+ - flush (f2fs_file_flush)
+ - check atomic_write_task && PF_EXITING
+ - f2fs_abort_atomic_write
+
+Fixes: 7a10f0177e11 ("f2fs: don't give partially written atomic data from process crash")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 88eecd7149cd5..8a576c004b72a 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1879,7 +1879,8 @@ static int f2fs_file_flush(struct file *file, fl_owner_t id)
+ * until all the writers close its file. Since this should be done
+ * before dropping file lock, it needs to do in ->flush.
+ */
+- if (F2FS_I(inode)->atomic_write_task == current)
++ if (F2FS_I(inode)->atomic_write_task == current &&
++ (current->flags & PF_EXITING))
+ f2fs_abort_atomic_write(inode, true);
+ return 0;
+ }
+--
+2.39.2
+
--- /dev/null
+From 25aa1c87e6d81d386b05dffcad01405f9586ea86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Dec 2022 23:50:00 +0800
+Subject: f2fs: fix to avoid potential deadlock
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 5eaac835f27f2de6b73412d7c24e755733b49de0 ]
+
+There is a potential deadlock reported by syzbot as below:
+
+F2FS-fs (loop2): invalid crc value
+F2FS-fs (loop2): Found nat_bits in checkpoint
+F2FS-fs (loop2): Mounted with checkpoint version = 48b305e4
+======================================================
+WARNING: possible circular locking dependency detected
+6.1.0-rc8-syzkaller-33330-ga5541c0811a0 #0 Not tainted
+------------------------------------------------------
+syz-executor.2/32123 is trying to acquire lock:
+ffff0000c0e1a608 (&mm->mmap_lock){++++}-{3:3}, at: __might_fault+0x54/0xb4 mm/memory.c:5644
+
+but task is already holding lock:
+ffff0001317c6088 (&sbi->sb_lock){++++}-{3:3}, at: f2fs_down_write fs/f2fs/f2fs.h:2205 [inline]
+ffff0001317c6088 (&sbi->sb_lock){++++}-{3:3}, at: f2fs_ioc_get_encryption_pwsalt fs/f2fs/file.c:2334 [inline]
+ffff0001317c6088 (&sbi->sb_lock){++++}-{3:3}, at: __f2fs_ioctl+0x1370/0x3318 fs/f2fs/file.c:4151
+
+which lock already depends on the new lock.
+
+Chain exists of:
+ &mm->mmap_lock --> &nm_i->nat_tree_lock --> &sbi->sb_lock
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(&sbi->sb_lock);
+ lock(&nm_i->nat_tree_lock);
+ lock(&sbi->sb_lock);
+ lock(&mm->mmap_lock);
+
+Let's try to avoid above deadlock condition by moving __might_fault()
+out of sbi->sb_lock coverage.
+
+Fixes: 95fa90c9e5a7 ("f2fs: support recording errors into superblock")
+Link: https://lore.kernel.org/linux-f2fs-devel/000000000000cd5fe305ef617fe2@google.com/T/#u
+Reported-by: syzbot+4793f6096d174c90b4f7@syzkaller.appspotmail.com
+Signed-off-by: Chao Yu <chao@kernel.org>
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index f96bbfa8b3991..a03c61bd70165 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -2326,6 +2326,7 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg)
+ {
+ struct inode *inode = file_inode(filp);
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
++ u8 encrypt_pw_salt[16];
+ int err;
+
+ if (!f2fs_sb_has_encrypt(sbi))
+@@ -2350,12 +2351,14 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg)
+ goto out_err;
+ }
+ got_it:
+- if (copy_to_user((__u8 __user *)arg, sbi->raw_super->encrypt_pw_salt,
+- 16))
+- err = -EFAULT;
++ memcpy(encrypt_pw_salt, sbi->raw_super->encrypt_pw_salt, 16);
+ out_err:
+ f2fs_up_write(&sbi->sb_lock);
+ mnt_drop_write_file(filp);
++
++ if (!err && copy_to_user((__u8 __user *)arg, encrypt_pw_salt, 16))
++ err = -EFAULT;
++
+ return err;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From dcca5b4e2d5e346711aa8f20f2a36ee40099233d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Jan 2023 00:16:55 +0800
+Subject: f2fs: fix to avoid potential memory corruption in
+ __update_iostat_latency()
+
+From: Yangtao Li <frank.li@vivo.com>
+
+[ Upstream commit 0dbbf0fb38d5ec5d4138d1aeaeb43d9217b9a592 ]
+
+Add iotype sanity check to avoid potential memory corruption.
+This is to fix the compile error below:
+
+fs/f2fs/iostat.c:231 __update_iostat_latency() error: buffer overflow
+'io_lat->peak_lat[type]' 3 <= 3
+
+vim +228 fs/f2fs/iostat.c
+
+ 211 static inline void __update_iostat_latency(struct bio_iostat_ctx
+ *iostat_ctx,
+ 212 enum iostat_lat_type type)
+ 213 {
+ 214 unsigned long ts_diff;
+ 215 unsigned int page_type = iostat_ctx->type;
+ 216 struct f2fs_sb_info *sbi = iostat_ctx->sbi;
+ 217 struct iostat_lat_info *io_lat = sbi->iostat_io_lat;
+ 218 unsigned long flags;
+ 219
+ 220 if (!sbi->iostat_enable)
+ 221 return;
+ 222
+ 223 ts_diff = jiffies - iostat_ctx->submit_ts;
+ 224 if (page_type >= META_FLUSH)
+ ^^^^^^^^^^
+
+ 225 page_type = META;
+ 226
+ 227 spin_lock_irqsave(&sbi->iostat_lat_lock, flags);
+ @228 io_lat->sum_lat[type][page_type] += ts_diff;
+ ^^^^^^^^^
+Mixup between META_FLUSH and NR_PAGE_TYPE leads to memory corruption.
+
+Fixes: a4b6817625e7 ("f2fs: introduce periodic iostat io latency traces")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <error27@gmail.com>
+Suggested-by: Chao Yu <chao@kernel.org>
+Suggested-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Yangtao Li <frank.li@vivo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/iostat.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/iostat.c b/fs/f2fs/iostat.c
+index 3166a8939ed4f..02393c95c9f86 100644
+--- a/fs/f2fs/iostat.c
++++ b/fs/f2fs/iostat.c
+@@ -227,8 +227,12 @@ static inline void __update_iostat_latency(struct bio_iostat_ctx *iostat_ctx,
+ return;
+
+ ts_diff = jiffies - iostat_ctx->submit_ts;
+- if (iotype >= META_FLUSH)
++ if (iotype == META_FLUSH) {
+ iotype = META;
++ } else if (iotype >= NR_PAGE_TYPE) {
++ f2fs_warn(sbi, "%s: %d over NR_PAGE_TYPE", __func__, iotype);
++ return;
++ }
+
+ if (rw == 0) {
+ idx = READ_IO;
+--
+2.39.2
+
--- /dev/null
+From ab006a6608c5f4f79e903021bc4baf00531c69e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 11:44:49 +0800
+Subject: f2fs: introduce trace_f2fs_replace_atomic_write_block
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 2f3a9ae990a7881c9a57a073bb52ebe34fdc3160 ]
+
+Commit 3db1de0e582c ("f2fs: change the current atomic write way")
+removed old tracepoints, but it missed to add new one, this patch
+fixes to introduce trace_f2fs_replace_atomic_write_block to trace
+atomic_write commit flow.
+
+Fixes: 3db1de0e582c ("f2fs: change the current atomic write way")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 3 +++
+ include/trace/events/f2fs.h | 37 +++++++++++++++++++++++++++++++++++++
+ 2 files changed, 40 insertions(+)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index c1d0713666ee5..af9a3b7996b4d 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -250,6 +250,9 @@ static int __replace_atomic_write_block(struct inode *inode, pgoff_t index,
+ }
+
+ f2fs_put_dnode(&dn);
++
++ trace_f2fs_replace_atomic_write_block(inode, F2FS_I(inode)->cow_inode,
++ index, *old_addr, new_addr, recover);
+ return 0;
+ }
+
+diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
+index ff57e7f9914cc..e57f867191ef1 100644
+--- a/include/trace/events/f2fs.h
++++ b/include/trace/events/f2fs.h
+@@ -1286,6 +1286,43 @@ DEFINE_EVENT(f2fs__page, f2fs_vm_page_mkwrite,
+ TP_ARGS(page, type)
+ );
+
++TRACE_EVENT(f2fs_replace_atomic_write_block,
++
++ TP_PROTO(struct inode *inode, struct inode *cow_inode, pgoff_t index,
++ block_t old_addr, block_t new_addr, bool recovery),
++
++ TP_ARGS(inode, cow_inode, index, old_addr, new_addr, recovery),
++
++ TP_STRUCT__entry(
++ __field(dev_t, dev)
++ __field(ino_t, ino)
++ __field(ino_t, cow_ino)
++ __field(pgoff_t, index)
++ __field(block_t, old_addr)
++ __field(block_t, new_addr)
++ __field(bool, recovery)
++ ),
++
++ TP_fast_assign(
++ __entry->dev = inode->i_sb->s_dev;
++ __entry->ino = inode->i_ino;
++ __entry->cow_ino = cow_inode->i_ino;
++ __entry->index = index;
++ __entry->old_addr = old_addr;
++ __entry->new_addr = new_addr;
++ __entry->recovery = recovery;
++ ),
++
++ TP_printk("dev = (%d,%d), ino = %lu, cow_ino = %lu, index = %lu, "
++ "old_addr = 0x%llx, new_addr = 0x%llx, recovery = %d",
++ show_dev_ino(__entry),
++ __entry->cow_ino,
++ (unsigned long)__entry->index,
++ (unsigned long long)__entry->old_addr,
++ (unsigned long long)__entry->new_addr,
++ __entry->recovery)
++);
++
+ TRACE_EVENT(f2fs_filemap_fault,
+
+ TP_PROTO(struct inode *inode, pgoff_t index, unsigned long ret),
+--
+2.39.2
+
--- /dev/null
+From 2311dc52f7e11f33f660b0fa11e544c5d352f24e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 10:18:19 -0800
+Subject: f2fs: synchronize atomic write aborts
+
+From: Daeho Jeong <daehojeong@google.com>
+
+[ Upstream commit a46bebd502fe1a3bd1d22f64cedd93e7e7702693 ]
+
+To fix a race condition between atomic write aborts, I use the inode
+lock and make COW inode to be re-usable thoroughout the whole
+atomic file inode lifetime.
+
+Reported-by: syzbot+823000d23b3400619f7c@syzkaller.appspotmail.com
+Fixes: 3db1de0e582c ("f2fs: change the current atomic write way")
+Signed-off-by: Daeho Jeong <daehojeong@google.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 44 +++++++++++++++++++++++++++++---------------
+ fs/f2fs/inode.c | 11 +++++++++--
+ fs/f2fs/segment.c | 3 ---
+ fs/f2fs/super.c | 2 --
+ 4 files changed, 38 insertions(+), 22 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 8a576c004b72a..773b3ddc2cd72 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1865,7 +1865,10 @@ static int f2fs_release_file(struct inode *inode, struct file *filp)
+ atomic_read(&inode->i_writecount) != 1)
+ return 0;
+
++ inode_lock(inode);
+ f2fs_abort_atomic_write(inode, true);
++ inode_unlock(inode);
++
+ return 0;
+ }
+
+@@ -1880,8 +1883,12 @@ static int f2fs_file_flush(struct file *file, fl_owner_t id)
+ * before dropping file lock, it needs to do in ->flush.
+ */
+ if (F2FS_I(inode)->atomic_write_task == current &&
+- (current->flags & PF_EXITING))
++ (current->flags & PF_EXITING)) {
++ inode_lock(inode);
+ f2fs_abort_atomic_write(inode, true);
++ inode_unlock(inode);
++ }
++
+ return 0;
+ }
+
+@@ -2087,19 +2094,28 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ goto out;
+ }
+
+- /* Create a COW inode for atomic write */
+- pinode = f2fs_iget(inode->i_sb, fi->i_pino);
+- if (IS_ERR(pinode)) {
+- f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
+- ret = PTR_ERR(pinode);
+- goto out;
+- }
++ /* Check if the inode already has a COW inode */
++ if (fi->cow_inode == NULL) {
++ /* Create a COW inode for atomic write */
++ pinode = f2fs_iget(inode->i_sb, fi->i_pino);
++ if (IS_ERR(pinode)) {
++ f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
++ ret = PTR_ERR(pinode);
++ goto out;
++ }
+
+- ret = f2fs_get_tmpfile(mnt_userns, pinode, &fi->cow_inode);
+- iput(pinode);
+- if (ret) {
+- f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
+- goto out;
++ ret = f2fs_get_tmpfile(mnt_userns, pinode, &fi->cow_inode);
++ iput(pinode);
++ if (ret) {
++ f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
++ goto out;
++ }
++
++ set_inode_flag(fi->cow_inode, FI_COW_FILE);
++ clear_inode_flag(fi->cow_inode, FI_INLINE_DATA);
++ } else {
++ /* Reuse the already created COW inode */
++ f2fs_do_truncate_blocks(fi->cow_inode, 0, true);
+ }
+
+ f2fs_write_inode(inode, NULL);
+@@ -2111,8 +2127,6 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ stat_inc_atomic_inode(inode);
+
+ set_inode_flag(inode, FI_ATOMIC_FILE);
+- set_inode_flag(fi->cow_inode, FI_COW_FILE);
+- clear_inode_flag(fi->cow_inode, FI_INLINE_DATA);
+ f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
+
+ f2fs_update_time(sbi, REQ_TIME);
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index e8413b080e0a7..229ddc2f7b079 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -764,11 +764,18 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ void f2fs_evict_inode(struct inode *inode)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+- nid_t xnid = F2FS_I(inode)->i_xattr_nid;
++ struct f2fs_inode_info *fi = F2FS_I(inode);
++ nid_t xnid = fi->i_xattr_nid;
+ int err = 0;
+
+ f2fs_abort_atomic_write(inode, true);
+
++ if (fi->cow_inode) {
++ clear_inode_flag(fi->cow_inode, FI_COW_FILE);
++ iput(fi->cow_inode);
++ fi->cow_inode = NULL;
++ }
++
+ trace_f2fs_evict_inode(inode);
+ truncate_inode_pages_final(&inode->i_data);
+
+@@ -855,7 +862,7 @@ void f2fs_evict_inode(struct inode *inode)
+ stat_dec_inline_inode(inode);
+ stat_dec_compr_inode(inode);
+ stat_sub_compr_blocks(inode,
+- atomic_read(&F2FS_I(inode)->i_compr_blocks));
++ atomic_read(&fi->i_compr_blocks));
+
+ if (likely(!f2fs_cp_error(sbi) &&
+ !is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 63c6894099799..8d1e8c537daf0 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -192,9 +192,6 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean)
+ if (!f2fs_is_atomic_file(inode))
+ return;
+
+- clear_inode_flag(fi->cow_inode, FI_COW_FILE);
+- iput(fi->cow_inode);
+- fi->cow_inode = NULL;
+ release_atomic_write_cnt(inode);
+ clear_inode_flag(inode, FI_ATOMIC_COMMITTED);
+ clear_inode_flag(inode, FI_ATOMIC_FILE);
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index eaabb85cb4ddb..14c87399efea2 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1416,8 +1416,6 @@ static int f2fs_drop_inode(struct inode *inode)
+ atomic_inc(&inode->i_count);
+ spin_unlock(&inode->i_lock);
+
+- f2fs_abort_atomic_write(inode, true);
+-
+ /* should remain fi->extent_tree for writepage */
+ f2fs_destroy_extent_node(inode);
+
+--
+2.39.2
+
--- /dev/null
+From 9515f6151fca059ecb347ec9343caabd77c63d8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 11:50:45 +0000
+Subject: firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3
+
+From: Darrell Kavanagh <darrell.kavanagh@gmail.com>
+
+[ Upstream commit e1d447157f232c650e6f32c9fb89ff3d0207c69a ]
+
+Another Lenovo convertable which reports a landscape resolution of
+1920x1200 with a pitch of (1920 * 4) bytes, while the actual framebuffer
+has a resolution of 1200x1920 with a pitch of (1200 * 4) bytes.
+
+Signed-off-by: Darrell Kavanagh <darrell.kavanagh@gmail.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/sysfb_efi.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c
+index 7882d4b3f2be4..f06fdacc9bc83 100644
+--- a/drivers/firmware/efi/sysfb_efi.c
++++ b/drivers/firmware/efi/sysfb_efi.c
+@@ -264,6 +264,14 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = {
+ "Lenovo ideapad D330-10IGM"),
+ },
+ },
++ {
++ /* Lenovo IdeaPad Duet 3 10IGL5 with 1200x1920 portrait screen */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
++ "IdeaPad Duet 3 10IGL5"),
++ },
++ },
+ {},
+ };
+
+--
+2.39.2
+
--- /dev/null
+From caa8326ac19002f6b093a74efe77b0c3f3f1b569 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 12:21:32 +0100
+Subject: fs: f2fs: initialize fsdata in pagecache_write()
+
+From: Alexander Potapenko <glider@google.com>
+
+[ Upstream commit b1b9896718bc1a212dc288ad66a5fa2fef11353d ]
+
+When aops->write_begin() does not initialize fsdata, KMSAN may report
+an error passing the latter to aops->write_end().
+
+Fix this by unconditionally initializing fsdata.
+
+Suggested-by: Eric Biggers <ebiggers@kernel.org>
+Fixes: 95ae251fe828 ("f2fs: add fs-verity support")
+Signed-off-by: Alexander Potapenko <glider@google.com>
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/verity.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
+index c352fff88a5e6..3f4f3295f1c66 100644
+--- a/fs/f2fs/verity.c
++++ b/fs/f2fs/verity.c
+@@ -81,7 +81,7 @@ static int pagecache_write(struct inode *inode, const void *buf, size_t count,
+ size_t n = min_t(size_t, count,
+ PAGE_SIZE - offset_in_page(pos));
+ struct page *page;
+- void *fsdata;
++ void *fsdata = NULL;
+ int res;
+
+ res = aops->write_begin(NULL, mapping, pos, n, &page, &fsdata);
+--
+2.39.2
+
--- /dev/null
+From a09bb318b30d1e2376f7acc0bdc6f24e25891c93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Nov 2022 11:01:59 +0800
+Subject: fs/jfs: fix shift exponent db_agl2size negative
+
+From: Liu Shixin via Jfs-discussion <jfs-discussion@lists.sourceforge.net>
+
+[ Upstream commit fad376fce0af58deebc5075b8539dc05bf639af3 ]
+
+As a shift exponent, db_agl2size can not be less than 0. Add the missing
+check to fix the shift-out-of-bounds bug reported by syzkaller:
+
+ UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:2227:15
+ shift exponent -744642816 is negative
+
+Reported-by: syzbot+0be96567042453c0c820@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_dmap.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index 765838578a722..a3eb1e8269477 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -193,7 +193,8 @@ int dbMount(struct inode *ipbmap)
+ bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
+ bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
+ bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
+- if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) {
++ if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG ||
++ bmp->db_agl2size < 0) {
+ err = -EINVAL;
+ goto err_release_metapage;
+ }
+--
+2.39.2
+
--- /dev/null
+From ad8d453b512fb5fee97681f97d74b24be92bec5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Aug 2022 23:00:45 +0300
+Subject: genirq/ipi: Fix NULL pointer deref in irq_data_get_affinity_mask()
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit feabecaff5902f896531dde90646ca5dfa9d4f7d ]
+
+If ipi_send_{mask|single}() is called with an invalid interrupt number, all
+the local variables there will be NULL. ipi_send_verify() which is invoked
+from these functions does verify its 'data' parameter, resulting in a
+kernel oops in irq_data_get_affinity_mask() as the passed NULL pointer gets
+dereferenced.
+
+Add a missing NULL pointer check in ipi_send_verify()...
+
+Found by Linux Verification Center (linuxtesting.org) with the SVACE static
+analysis tool.
+
+Fixes: 3b8e29a82dd1 ("genirq: Implement ipi_send_mask/single()")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/b541232d-c2b6-1fe9-79b4-a7129459e4d0@omp.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/ipi.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c
+index bbd945bacef08..961d4af76af37 100644
+--- a/kernel/irq/ipi.c
++++ b/kernel/irq/ipi.c
+@@ -188,9 +188,9 @@ EXPORT_SYMBOL_GPL(ipi_get_hwirq);
+ static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data,
+ const struct cpumask *dest, unsigned int cpu)
+ {
+- const struct cpumask *ipimask = irq_data_get_affinity_mask(data);
++ const struct cpumask *ipimask;
+
+- if (!chip || !ipimask)
++ if (!chip || !data)
+ return -EINVAL;
+
+ if (!chip->ipi_send_single && !chip->ipi_send_mask)
+@@ -199,6 +199,10 @@ static int ipi_send_verify(struct irq_chip *chip, struct irq_data *data,
+ if (cpu >= nr_cpu_ids)
+ return -EINVAL;
+
++ ipimask = irq_data_get_affinity_mask(data);
++ if (!ipimask)
++ return -EINVAL;
++
+ if (dest) {
+ if (!cpumask_subset(dest, ipimask))
+ return -EINVAL;
+--
+2.39.2
+
--- /dev/null
+From 20c02650a414853b50965693a20c91f05dfd9e97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Jan 2023 14:04:29 -0500
+Subject: IB/hfi1: Update RMT size calculation
+
+From: Dean Luick <dean.luick@cornelisnetworks.com>
+
+[ Upstream commit 892ede5a77f337831609fb9c248ac60948061894 ]
+
+Fix possible RMT overflow: Use the correct netdev size.
+Don't allow adjusted user contexts to go negative.
+
+Fix QOS calculation: Send kernel context count as an argument since
+dd->n_krcv_queues is not yet set up in earliest call. Do not include
+the control context in the QOS calculation. Use the same sized
+variable to find the max of krcvq[] entries.
+
+Update the RMT count explanation to make more sense.
+
+Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Link: https://lore.kernel.org/r/167329106946.1472990.18385495251650939054.stgit@awfm-02.cornelisnetworks.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/chip.c | 59 +++++++++++++++++--------------
+ 1 file changed, 32 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
+index ebe970f76232d..90b672feed83d 100644
+--- a/drivers/infiniband/hw/hfi1/chip.c
++++ b/drivers/infiniband/hw/hfi1/chip.c
+@@ -1056,7 +1056,7 @@ static void read_link_down_reason(struct hfi1_devdata *dd, u8 *ldr);
+ static void handle_temp_err(struct hfi1_devdata *dd);
+ static void dc_shutdown(struct hfi1_devdata *dd);
+ static void dc_start(struct hfi1_devdata *dd);
+-static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp,
++static int qos_rmt_entries(unsigned int n_krcv_queues, unsigned int *mp,
+ unsigned int *np);
+ static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd);
+ static int wait_link_transfer_active(struct hfi1_devdata *dd, int wait_ms);
+@@ -13362,7 +13362,6 @@ static int set_up_context_variables(struct hfi1_devdata *dd)
+ int ret;
+ unsigned ngroups;
+ int rmt_count;
+- int user_rmt_reduced;
+ u32 n_usr_ctxts;
+ u32 send_contexts = chip_send_contexts(dd);
+ u32 rcv_contexts = chip_rcv_contexts(dd);
+@@ -13421,28 +13420,34 @@ static int set_up_context_variables(struct hfi1_devdata *dd)
+ (num_kernel_contexts + n_usr_ctxts),
+ &node_affinity.real_cpu_mask);
+ /*
+- * The RMT entries are currently allocated as shown below:
+- * 1. QOS (0 to 128 entries);
+- * 2. FECN (num_kernel_context - 1 + num_user_contexts +
+- * num_netdev_contexts);
+- * 3. netdev (num_netdev_contexts).
+- * It should be noted that FECN oversubscribe num_netdev_contexts
+- * entries of RMT because both netdev and PSM could allocate any receive
+- * context between dd->first_dyn_alloc_text and dd->num_rcv_contexts,
+- * and PSM FECN must reserve an RMT entry for each possible PSM receive
+- * context.
++ * RMT entries are allocated as follows:
++ * 1. QOS (0 to 128 entries)
++ * 2. FECN (num_kernel_context - 1 [a] + num_user_contexts +
++ * num_netdev_contexts [b])
++ * 3. netdev (NUM_NETDEV_MAP_ENTRIES)
++ *
++ * Notes:
++ * [a] Kernel contexts (except control) are included in FECN if kernel
++ * TID_RDMA is active.
++ * [b] Netdev and user contexts are randomly allocated from the same
++ * context pool, so FECN must cover all contexts in the pool.
+ */
+- rmt_count = qos_rmt_entries(dd, NULL, NULL) + (num_netdev_contexts * 2);
+- if (HFI1_CAP_IS_KSET(TID_RDMA))
+- rmt_count += num_kernel_contexts - 1;
+- if (rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) {
+- user_rmt_reduced = NUM_MAP_ENTRIES - rmt_count;
+- dd_dev_err(dd,
+- "RMT size is reducing the number of user receive contexts from %u to %d\n",
+- n_usr_ctxts,
+- user_rmt_reduced);
+- /* recalculate */
+- n_usr_ctxts = user_rmt_reduced;
++ rmt_count = qos_rmt_entries(num_kernel_contexts - 1, NULL, NULL)
++ + (HFI1_CAP_IS_KSET(TID_RDMA) ? num_kernel_contexts - 1
++ : 0)
++ + n_usr_ctxts
++ + num_netdev_contexts
++ + NUM_NETDEV_MAP_ENTRIES;
++ if (rmt_count > NUM_MAP_ENTRIES) {
++ int over = rmt_count - NUM_MAP_ENTRIES;
++ /* try to squish user contexts, minimum of 1 */
++ if (over >= n_usr_ctxts) {
++ dd_dev_err(dd, "RMT overflow: reduce the requested number of contexts\n");
++ return -EINVAL;
++ }
++ dd_dev_err(dd, "RMT overflow: reducing # user contexts from %u to %u\n",
++ n_usr_ctxts, n_usr_ctxts - over);
++ n_usr_ctxts -= over;
+ }
+
+ /* the first N are kernel contexts, the rest are user/netdev contexts */
+@@ -14299,15 +14304,15 @@ static void clear_rsm_rule(struct hfi1_devdata *dd, u8 rule_index)
+ }
+
+ /* return the number of RSM map table entries that will be used for QOS */
+-static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp,
++static int qos_rmt_entries(unsigned int n_krcv_queues, unsigned int *mp,
+ unsigned int *np)
+ {
+ int i;
+ unsigned int m, n;
+- u8 max_by_vl = 0;
++ uint max_by_vl = 0;
+
+ /* is QOS active at all? */
+- if (dd->n_krcv_queues <= MIN_KERNEL_KCTXTS ||
++ if (n_krcv_queues < MIN_KERNEL_KCTXTS ||
+ num_vls == 1 ||
+ krcvqsset <= 1)
+ goto no_qos;
+@@ -14365,7 +14370,7 @@ static void init_qos(struct hfi1_devdata *dd, struct rsm_map_table *rmt)
+
+ if (!rmt)
+ goto bail;
+- rmt_entries = qos_rmt_entries(dd, &m, &n);
++ rmt_entries = qos_rmt_entries(dd->n_krcv_queues - 1, &m, &n);
+ if (rmt_entries == 0)
+ goto bail;
+ qpns_per_vl = 1 << m;
+--
+2.39.2
+
--- /dev/null
+From 1a349f7c04877c3281d9f1bcd59ce62b4e621250 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 07:21:46 -0800
+Subject: iio: accel: mma9551_core: Prevent uninitialized variable in
+ mma9551_read_status_word()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit e56d2c34ce9dc122b1a618172ec0e05e50adb9e9 ]
+
+Smatch Warns: drivers/iio/accel/mma9551_core.c:357
+ mma9551_read_status_word() error: uninitialized symbol 'v'.
+
+When (offset >= 1 << 12) is true mma9551_transfer() will return -EINVAL
+without 'v' being initialized, so check for the error and return.
+
+Note: Not a bug as such because the caller checks return value and
+doesn't not use this parameter in the problem case.
+
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Link: https://lore.kernel.org/r/20230126152147.3585874-1-harshit.m.mogalapalli@oracle.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/mma9551_core.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c
+index 64ca7d7a9673d..86437ddc5ca18 100644
+--- a/drivers/iio/accel/mma9551_core.c
++++ b/drivers/iio/accel/mma9551_core.c
+@@ -354,9 +354,12 @@ int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
+
+ ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
+ reg, NULL, 0, (u8 *)&v, 2);
++ if (ret < 0)
++ return ret;
++
+ *val = be16_to_cpu(v);
+
+- return ret;
++ return 0;
+ }
+ EXPORT_SYMBOL_NS(mma9551_read_status_word, IIO_MMA9551);
+
+--
+2.39.2
+
--- /dev/null
+From d823de2d18cee520c224f04beb8c7132cb577574 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Jan 2023 07:36:09 -0800
+Subject: iio: accel: mma9551_core: Prevent uninitialized variable in
+ mma9551_read_config_word()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 64a68158738ec8f520347144352f7a09bdb9e169 ]
+
+Smatch Warns:
+drivers/iio/accel/mma9551_core.c:299
+ mma9551_read_config_word() error: uninitialized symbol 'v'.
+
+When (offset >= 1 << 12) is true mma9551_transfer() will return -EINVAL
+without 'v' being initialized, so check for the error and return.
+
+Note: No actual bug as caller checks the return value and does not
+use the parameter in the problem case.
+
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Link: https://lore.kernel.org/r/20230126153610.3586243-1-harshit.m.mogalapalli@oracle.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/mma9551_core.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c
+index 86437ddc5ca18..b898f865fb875 100644
+--- a/drivers/iio/accel/mma9551_core.c
++++ b/drivers/iio/accel/mma9551_core.c
+@@ -296,9 +296,12 @@ int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
+
+ ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
+ reg, NULL, 0, (u8 *)&v, 2);
++ if (ret < 0)
++ return ret;
++
+ *val = be16_to_cpu(v);
+
+- return ret;
++ return 0;
+ }
+ EXPORT_SYMBOL_NS(mma9551_read_config_word, IIO_MMA9551);
+
+--
+2.39.2
+
--- /dev/null
+From 35d0425c2b8f16587427bb993f4174438781cf54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Feb 2023 18:41:41 +0000
+Subject: io_uring: fix size calculation when registering buf ring
+
+From: Wojciech Lukowicz <wlukowicz01@gmail.com>
+
+[ Upstream commit 48ba08374e779421ca34bd14b4834aae19fc3e6a ]
+
+Using struct_size() to calculate the size of io_uring_buf_ring will sum
+the size of the struct and of the bufs array. However, the struct's fields
+are overlaid with the array making the calculated size larger than it
+should be.
+
+When registering a ring with N * PAGE_SIZE / sizeof(struct io_uring_buf)
+entries, i.e. with fully filled pages, the calculated size will span one
+more page than it should and io_uring will try to pin the following page.
+Depending on how the application allocated the ring, it might succeed
+using an unrelated page or fail returning EFAULT.
+
+The size of the ring should be the product of ring_entries and the size
+of io_uring_buf, i.e. the size of the bufs array only.
+
+Fixes: c7fb19428d67 ("io_uring: add support for ring mapped supplied buffers")
+Signed-off-by: Wojciech Lukowicz <wlukowicz01@gmail.com>
+Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
+Link: https://lore.kernel.org/r/20230218184141.70891-1-wlukowicz01@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/kbuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
+index e2c46889d5fab..746b137b96e9b 100644
+--- a/io_uring/kbuf.c
++++ b/io_uring/kbuf.c
+@@ -509,7 +509,7 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
+ }
+
+ pages = io_pin_pages(reg.ring_addr,
+- struct_size(br, bufs, reg.ring_entries),
++ flex_array_size(br, bufs, reg.ring_entries),
+ &nr_pages);
+ if (IS_ERR(pages)) {
+ kfree(free_bl);
+--
+2.39.2
+
--- /dev/null
+From 18d5aeff967392614ff4926ebff6c5a769ce25a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 12:15:03 +0000
+Subject: iommu/amd: Fix error handling for pdev_pri_ats_enable()
+
+From: Vasant Hegde <vasant.hegde@amd.com>
+
+[ Upstream commit 080920e52148b4fbbf9360d5345fdcd7846e4841 ]
+
+Current code throws kernel warning if it fails to enable pasid/pri [1].
+Do not call pci_disable_[pasid/pri] if pci_enable_[pasid/pri] failed.
+
+[1] https://lore.kernel.org/linux-iommu/15d0f9ff-2a56-b3e9-5b45-e6b23300ae3b@leemhuis.info/
+
+Reported-by: Matt Fagnani <matt.fagnani@bell.net>
+Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
+Reviewed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Link: https://lore.kernel.org/r/20230111121503.5931-1-vasant.hegde@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/iommu.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
+index 968e5e6668b26..20adb9b323d82 100644
+--- a/drivers/iommu/amd/iommu.c
++++ b/drivers/iommu/amd/iommu.c
+@@ -1712,27 +1712,29 @@ static int pdev_pri_ats_enable(struct pci_dev *pdev)
+ /* Only allow access to user-accessible pages */
+ ret = pci_enable_pasid(pdev, 0);
+ if (ret)
+- goto out_err;
++ return ret;
+
+ /* First reset the PRI state of the device */
+ ret = pci_reset_pri(pdev);
+ if (ret)
+- goto out_err;
++ goto out_err_pasid;
+
+ /* Enable PRI */
+ /* FIXME: Hardcode number of outstanding requests for now */
+ ret = pci_enable_pri(pdev, 32);
+ if (ret)
+- goto out_err;
++ goto out_err_pasid;
+
+ ret = pci_enable_ats(pdev, PAGE_SHIFT);
+ if (ret)
+- goto out_err;
++ goto out_err_pri;
+
+ return 0;
+
+-out_err:
++out_err_pri:
+ pci_disable_pri(pdev);
++
++out_err_pasid:
+ pci_disable_pasid(pdev);
+
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From c2914e324f4a06a5b27074485d0b92df9601a9ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 05:26:40 +0000
+Subject: iommu: Attach device group to old domain in error path
+
+From: Vasant Hegde <vasant.hegde@amd.com>
+
+[ Upstream commit 2cc73c5712f97de98c38c2fafc1f288354a9f3c3 ]
+
+iommu_attach_group() attaches all devices in a group to domain and then
+sets group domain (group->domain). Current code (__iommu_attach_group())
+does not handle error path. This creates problem as devices to domain
+attachment is in inconsistent state.
+
+Flow:
+ - During boot iommu attach devices to default domain
+ - Later some device driver (like amd/iommu_v2 or vfio) tries to attach
+ device to new domain.
+ - In iommu_attach_group() path we detach device from current domain.
+ Then it tries to attach devices to new domain.
+ - If it fails to attach device to new domain then device to domain link
+ is broken.
+ - iommu_attach_group() returns error.
+ - At this stage iommu_attach_group() caller thinks, attaching device to
+ new domain failed and devices are still attached to old domain.
+ - But in reality device to old domain link is broken. It will result
+ in all sort of failures (like IO page fault) later.
+
+To recover from this situation, we need to attach all devices back to the
+old domain. Also log warning if it fails attach device back to old domain.
+
+Suggested-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reported-by: Matt Fagnani <matt.fagnani@bell.net>
+Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Tested-by: Matt Fagnani <matt.fagnani@bell.net>
+Link: https://lore.kernel.org/r/20230215052642.6016-1-vasant.hegde@amd.com
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216865
+Link: https://lore.kernel.org/lkml/15d0f9ff-2a56-b3e9-5b45-e6b23300ae3b@leemhuis.info/
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommu.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
+index fd8c8aeb3c504..bfb2f163c6914 100644
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -2089,8 +2089,22 @@ static int __iommu_attach_group(struct iommu_domain *domain,
+
+ ret = __iommu_group_for_each_dev(group, domain,
+ iommu_group_do_attach_device);
+- if (ret == 0)
++ if (ret == 0) {
+ group->domain = domain;
++ } else {
++ /*
++ * To recover from the case when certain device within the
++ * group fails to attach to the new domain, we need force
++ * attaching all devices back to the old domain. The old
++ * domain is compatible for all devices in the group,
++ * hence the iommu driver should always return success.
++ */
++ struct iommu_domain *old_domain = group->domain;
++
++ group->domain = NULL;
++ WARN(__iommu_group_set_domain(group, old_domain),
++ "iommu driver failed to attach a compatible domain");
++ }
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From 2532173f34ae1cf3d8e5478d03b893a6add0d97c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Feb 2023 16:36:28 +0800
+Subject: ipv6: Add lwtunnel encap size of all siblings in nexthop calculation
+
+From: Lu Wei <luwei32@huawei.com>
+
+[ Upstream commit 4cc59f386991ec9374cb4bc83dbe1c0b5a95033f ]
+
+In function rt6_nlmsg_size(), the length of nexthop is calculated
+by multipling the nexthop length of fib6_info and the number of
+siblings. However if the fib6_info has no lwtunnel but the siblings
+have lwtunnels, the nexthop length is less than it should be, and
+it will trigger a warning in inet6_rt_notify() as follows:
+
+WARNING: CPU: 0 PID: 6082 at net/ipv6/route.c:6180 inet6_rt_notify+0x120/0x130
+......
+Call Trace:
+ <TASK>
+ fib6_add_rt2node+0x685/0xa30
+ fib6_add+0x96/0x1b0
+ ip6_route_add+0x50/0xd0
+ inet6_rtm_newroute+0x97/0xa0
+ rtnetlink_rcv_msg+0x156/0x3d0
+ netlink_rcv_skb+0x5a/0x110
+ netlink_unicast+0x246/0x350
+ netlink_sendmsg+0x250/0x4c0
+ sock_sendmsg+0x66/0x70
+ ___sys_sendmsg+0x7c/0xd0
+ __sys_sendmsg+0x5d/0xb0
+ do_syscall_64+0x3f/0x90
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+This bug can be reproduced by script:
+
+ip -6 addr add 2002::2/64 dev ens2
+ip -6 route add 100::/64 via 2002::1 dev ens2 metric 100
+
+for i in 10 20 30 40 50 60 70;
+do
+ ip link add link ens2 name ipv_$i type ipvlan
+ ip -6 addr add 2002::$i/64 dev ipv_$i
+ ifconfig ipv_$i up
+done
+
+for i in 10 20 30 40 50 60;
+do
+ ip -6 route append 100::/64 encap ip6 dst 2002::$i via 2002::1
+dev ipv_$i metric 100
+done
+
+ip -6 route append 100::/64 via 2002::1 dev ipv_70 metric 100
+
+This patch fixes it by adding nexthop_len of every siblings using
+rt6_nh_nlmsg_size().
+
+Fixes: beb1afac518d ("net: ipv6: Add support to dump multipath routes via RTA_MULTIPATH attribute")
+Signed-off-by: Lu Wei <luwei32@huawei.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://lore.kernel.org/r/20230222083629.335683-2-luwei32@huawei.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 2f355f0ec32ac..0b060cb8681f0 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -5540,16 +5540,17 @@ static size_t rt6_nlmsg_size(struct fib6_info *f6i)
+ nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_nlmsg_size,
+ &nexthop_len);
+ } else {
++ struct fib6_info *sibling, *next_sibling;
+ struct fib6_nh *nh = f6i->fib6_nh;
+
+ nexthop_len = 0;
+ if (f6i->fib6_nsiblings) {
+- nexthop_len = nla_total_size(0) /* RTA_MULTIPATH */
+- + NLA_ALIGN(sizeof(struct rtnexthop))
+- + nla_total_size(16) /* RTA_GATEWAY */
+- + lwtunnel_get_encap_size(nh->fib_nh_lws);
++ rt6_nh_nlmsg_size(nh, &nexthop_len);
+
+- nexthop_len *= f6i->fib6_nsiblings;
++ list_for_each_entry_safe(sibling, next_sibling,
++ &f6i->fib6_siblings, fib6_siblings) {
++ rt6_nh_nlmsg_size(sibling->fib6_nh, &nexthop_len);
++ }
+ }
+ nexthop_len += lwtunnel_get_encap_size(nh->fib_nh_lws);
+ }
+--
+2.39.2
+
--- /dev/null
+From cc56e07dc2d3290e895aa5818024688f504f6c41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:16:33 +0100
+Subject: kernel/fail_function: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 2bb3669f576559db273efe49e0e69f82450efbca ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Reviewed-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20230202151633.2310897-1-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fail_function.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/kernel/fail_function.c b/kernel/fail_function.c
+index a7ccd2930c5f4..d971a01893197 100644
+--- a/kernel/fail_function.c
++++ b/kernel/fail_function.c
+@@ -163,10 +163,7 @@ static void fei_debugfs_add_attr(struct fei_attr *attr)
+
+ static void fei_debugfs_remove_attr(struct fei_attr *attr)
+ {
+- struct dentry *dir;
+-
+- dir = debugfs_lookup(attr->kp.symbol_name, fei_debugfs_dir);
+- debugfs_remove_recursive(dir);
++ debugfs_lookup_and_remove(attr->kp.symbol_name, fei_debugfs_dir);
+ }
+
+ static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs)
+--
+2.39.2
+
--- /dev/null
+From 14261ee34f3718fa925c8f373aa0625bc4cba96a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:14:11 +0100
+Subject: kernel/printk/index.c: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 55bf243c514553e907efcf2bda92ba090eca8c64 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Chris Down <chris@chrisdown.name>
+Cc: Petr Mladek <pmladek@suse.com>
+Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: John Ogness <john.ogness@linutronix.de>
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Reviewed-by: John Ogness <john.ogness@linutronix.de>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20230202151411.2308576-1-gregkh@linuxfoundation.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/printk/index.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/printk/index.c b/kernel/printk/index.c
+index c85be186a7832..a6b27526baaf6 100644
+--- a/kernel/printk/index.c
++++ b/kernel/printk/index.c
+@@ -145,7 +145,7 @@ static void pi_create_file(struct module *mod)
+ #ifdef CONFIG_MODULES
+ static void pi_remove_file(struct module *mod)
+ {
+- debugfs_remove(debugfs_lookup(pi_get_module_name(mod), dfs_index));
++ debugfs_lookup_and_remove(pi_get_module_name(mod), dfs_index);
+ }
+
+ static int pi_module_notify(struct notifier_block *nb, unsigned long op,
+--
+2.39.2
+
--- /dev/null
+From 93cb4e662fa135abd13da1e73deeae5e6abe923c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Feb 2023 17:50:27 +0800
+Subject: loop: loop_set_status_from_info() check before assignment
+
+From: Zhong Jinghua <zhongjinghua@huawei.com>
+
+[ Upstream commit 9f6ad5d533d1c71e51bdd06a5712c4fbc8768dfa ]
+
+In loop_set_status_from_info(), lo->lo_offset and lo->lo_sizelimit should
+be checked before reassignment, because if an overflow error occurs, the
+original correct value will be changed to the wrong value, and it will not
+be changed back.
+
+More, the original patch did not solve the problem, the value was set and
+ioctl returned an error, but the subsequent io used the value in the loop
+driver, which still caused an alarm:
+
+loop_handle_cmd
+ do_req_filebacked
+ loff_t pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset;
+ lo_rw_aio
+ cmd->iocb.ki_pos = pos
+
+Fixes: c490a0b5a4f3 ("loop: Check for overflow while configuring loop")
+Signed-off-by: Zhong Jinghua <zhongjinghua@huawei.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Link: https://lore.kernel.org/r/20230221095027.3656193-1-zhongjinghua@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/loop.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index df628e30bca41..981464e561df1 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -977,13 +977,13 @@ loop_set_status_from_info(struct loop_device *lo,
+ return -EINVAL;
+ }
+
++ /* Avoid assigning overflow values */
++ if (info->lo_offset > LLONG_MAX || info->lo_sizelimit > LLONG_MAX)
++ return -EOVERFLOW;
++
+ lo->lo_offset = info->lo_offset;
+ lo->lo_sizelimit = info->lo_sizelimit;
+
+- /* loff_t vars have been assigned __u64 */
+- if (lo->lo_offset < 0 || lo->lo_sizelimit < 0)
+- return -EOVERFLOW;
+-
+ memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE);
+ lo->lo_file_name[LO_NAME_SIZE-1] = 0;
+ lo->lo_flags = info->lo_flags;
+--
+2.39.2
+
--- /dev/null
+From 42560117d4ba587584c38d69adfde150c5903be4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jan 2023 00:14:52 +0100
+Subject: media: uvcvideo: Add GUID for BGRA/X 8:8:8:8
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 015d44c2b700ba9639dd29672ba362796cc0be54 ]
+
+The Cypress EZUSB FX3 UVC example can be configured to report pixel
+format "e436eb7e-524f-11ce-9f53-0020af0ba770". This is its GUID for
+BGRA/X 8:8:8:8.
+
+The UVC 1.5 spec [1] only defines GUIDs for YUY2, NV12, M420 and I420.
+This seems to be an extension documented in the Microsoft Windows Media
+Format SDK[2]. This Media Format SDK defines this GUID as corresponding
+to `MEDIASUBTYPE_RGB32`, which is confirmed by [4] as `MEDIASUBTYPE_ARGB32`
+has different GUID.
+
+Note that in my case, the FX3 UVC can output either channel order,
+BGR or RGB or any other mix for that matter. Since Linux commit
+1b8dc32286a1a ("[media] uvcvideo: Add GUID for BGR 8:8:8")
+defined a GUID for `MEDIASUBTYPE_RGB24` channel order as BGR, keep
+this change consistent and define `MEDIASUBTYPE_RGB32` as BGR as well.
+Document [3] also indicates the channel order is BGR.
+
+[1] https://www.usb.org/document-library/video-class-v15-document-set
+[2] https://learn.microsoft.com/en-us/windows/win32/wmformat/media-type-identifiers
+[3] https://learn.microsoft.com/en-us/windows/win32/directshow/uncompressed-rgb-video-subtypes
+[4] https://gix.github.io/media-types/
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Ricardo Ribalda <ricardo@ribalda.com>
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Link: https://lore.kernel.org/r/20230126231456.3402323-2-m.grzeschik@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/media/v4l2-uvc.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/include/media/v4l2-uvc.h b/include/media/v4l2-uvc.h
+index f83e31661333b..b010a36fc1d95 100644
+--- a/include/media/v4l2-uvc.h
++++ b/include/media/v4l2-uvc.h
+@@ -99,6 +99,9 @@
+ #define UVC_GUID_FORMAT_BGR3 \
+ { 0x7d, 0xeb, 0x36, 0xe4, 0x4f, 0x52, 0xce, 0x11, \
+ 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}
++#define UVC_GUID_FORMAT_BGR4 \
++ { 0x7e, 0xeb, 0x36, 0xe4, 0x4f, 0x52, 0xce, 0x11, \
++ 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}
+ #define UVC_GUID_FORMAT_M420 \
+ { 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+@@ -266,6 +269,11 @@ static struct uvc_format_desc uvc_fmts[] = {
+ .guid = UVC_GUID_FORMAT_BGR3,
+ .fcc = V4L2_PIX_FMT_BGR24,
+ },
++ {
++ .name = "BGRA/X 8:8:8:8 (BGR4)",
++ .guid = UVC_GUID_FORMAT_BGR4,
++ .fcc = V4L2_PIX_FMT_XBGR32,
++ },
+ {
+ .name = "H.264",
+ .guid = UVC_GUID_FORMAT_H264,
+--
+2.39.2
+
--- /dev/null
+From 4445e0c3098c38ce51d6a30d2c529477bc8f2ac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Sep 2022 16:04:55 +0200
+Subject: media: uvcvideo: Handle cameras with invalid descriptors
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit 41ddb251c68ac75c101d3a50a68c4629c9055e4c ]
+
+If the source entity does not contain any pads, do not create a link.
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_entity.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
+index 7c4d2f93d3513..cc68dd24eb42d 100644
+--- a/drivers/media/usb/uvc/uvc_entity.c
++++ b/drivers/media/usb/uvc/uvc_entity.c
+@@ -37,7 +37,7 @@ static int uvc_mc_create_links(struct uvc_video_chain *chain,
+ continue;
+
+ remote = uvc_entity_by_id(chain->dev, entity->baSourceID[i]);
+- if (remote == NULL)
++ if (remote == NULL || remote->num_pads == 0)
+ return -EINVAL;
+
+ source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING)
+--
+2.39.2
+
--- /dev/null
+From abc593a5f2a9f72b47bea1162a001af0a1ae2507 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 16:41:01 +0200
+Subject: media: uvcvideo: Handle errors from calls to usb_string
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 4867bb590ae445bcfaa711a86b603c97e94574b3 ]
+
+On a Webcam from Quanta, we see the following error.
+
+usb 3-5: New USB device found, idVendor=0408, idProduct=30d2, bcdDevice= 0.03
+usb 3-5: New USB device strings: Mfr=3, Product=1, SerialNumber=2
+usb 3-5: Product: USB2.0 HD UVC WebCam
+usb 3-5: Manufacturer: Quanta
+usb 3-5: SerialNumber: 0x0001
+...
+uvcvideo: Found UVC 1.10 device USB2.0 HD UVC WebCam (0408:30d2)
+uvcvideo: Failed to initialize entity for entity 5
+uvcvideo: Failed to register entities (-22).
+
+The Webcam reports an entity of type UVC_VC_EXTENSION_UNIT. It reports a
+string index of '7' associated with that entity. The attempt to read that
+string from the camera fails with error -32 (-EPIPE). usb_string() returns
+that error, but it is ignored. As result, the entity name is empty. This
+later causes v4l2_device_register_subdev() to return -EINVAL, and no
+entities are registered as result.
+
+While this appears to be a firmware problem with the camera, the kernel
+should still handle the situation gracefully. To do that, check the return
+value from usb_string(). If it reports an error, assign the entity's
+default name.
+
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_driver.c | 48 ++++++++++++------------------
+ 1 file changed, 19 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index 16c75b8635455..ef08e5f51ede9 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -860,10 +860,8 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
+ + n;
+ memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
+
+- if (buffer[24+p+2*n] != 0)
+- usb_string(udev, buffer[24+p+2*n], unit->name,
+- sizeof(unit->name));
+- else
++ if (buffer[24+p+2*n] == 0 ||
++ usb_string(udev, buffer[24+p+2*n], unit->name, sizeof(unit->name)) < 0)
+ sprintf(unit->name, "Extension %u", buffer[3]);
+
+ list_add_tail(&unit->list, &dev->entities);
+@@ -987,15 +985,15 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+ memcpy(term->media.bmTransportModes, &buffer[10+n], p);
+ }
+
+- if (buffer[7] != 0)
+- usb_string(udev, buffer[7], term->name,
+- sizeof(term->name));
+- else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
+- sprintf(term->name, "Camera %u", buffer[3]);
+- else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
+- sprintf(term->name, "Media %u", buffer[3]);
+- else
+- sprintf(term->name, "Input %u", buffer[3]);
++ if (buffer[7] == 0 ||
++ usb_string(udev, buffer[7], term->name, sizeof(term->name)) < 0) {
++ if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
++ sprintf(term->name, "Camera %u", buffer[3]);
++ if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
++ sprintf(term->name, "Media %u", buffer[3]);
++ else
++ sprintf(term->name, "Input %u", buffer[3]);
++ }
+
+ list_add_tail(&term->list, &dev->entities);
+ break;
+@@ -1028,10 +1026,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+
+ memcpy(term->baSourceID, &buffer[7], 1);
+
+- if (buffer[8] != 0)
+- usb_string(udev, buffer[8], term->name,
+- sizeof(term->name));
+- else
++ if (buffer[8] == 0 ||
++ usb_string(udev, buffer[8], term->name, sizeof(term->name)) < 0)
+ sprintf(term->name, "Output %u", buffer[3]);
+
+ list_add_tail(&term->list, &dev->entities);
+@@ -1053,10 +1049,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+
+ memcpy(unit->baSourceID, &buffer[5], p);
+
+- if (buffer[5+p] != 0)
+- usb_string(udev, buffer[5+p], unit->name,
+- sizeof(unit->name));
+- else
++ if (buffer[5+p] == 0 ||
++ usb_string(udev, buffer[5+p], unit->name, sizeof(unit->name)) < 0)
+ sprintf(unit->name, "Selector %u", buffer[3]);
+
+ list_add_tail(&unit->list, &dev->entities);
+@@ -1086,10 +1080,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+ if (dev->uvc_version >= 0x0110)
+ unit->processing.bmVideoStandards = buffer[9+n];
+
+- if (buffer[8+n] != 0)
+- usb_string(udev, buffer[8+n], unit->name,
+- sizeof(unit->name));
+- else
++ if (buffer[8+n] == 0 ||
++ usb_string(udev, buffer[8+n], unit->name, sizeof(unit->name)) < 0)
+ sprintf(unit->name, "Processing %u", buffer[3]);
+
+ list_add_tail(&unit->list, &dev->entities);
+@@ -1117,10 +1109,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
+ unit->extension.bmControls = (u8 *)unit + sizeof(*unit);
+ memcpy(unit->extension.bmControls, &buffer[23+p], n);
+
+- if (buffer[23+p+n] != 0)
+- usb_string(udev, buffer[23+p+n], unit->name,
+- sizeof(unit->name));
+- else
++ if (buffer[23+p+n] == 0 ||
++ usb_string(udev, buffer[23+p+n], unit->name, sizeof(unit->name)) < 0)
+ sprintf(unit->name, "Extension %u", buffer[3]);
+
+ list_add_tail(&unit->list, &dev->entities);
+--
+2.39.2
+
--- /dev/null
+From d9e9d31099d994493fad8b687bed523dde4198ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 11:45:23 +0100
+Subject: media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit 136effa754b57632f99574fc4a3433e0cfc031d9 ]
+
+Logitech B910 and C910 firmware are unable to recover from a USB
+autosuspend. When it resumes, the device is in a state where it only
+produces invalid frames. Eg:
+
+$ echo 0xFFFF > /sys/module/uvcvideo/parameters/trace # enable verbose log
+$ yavta -c1 -n1 --file='frame#.jpg' --format MJPEG --size=1920x1080 /dev/video1
+[350438.435219] uvcvideo: uvc_v4l2_open
+[350438.529794] uvcvideo: Resuming interface 2
+[350438.529801] uvcvideo: Resuming interface 3
+[350438.529991] uvcvideo: Trying format 0x47504a4d (MJPG): 1920x1080.
+[350438.529996] uvcvideo: Using default frame interval 33333.3 us (30.0 fps).
+[350438.551496] uvcvideo: uvc_v4l2_mmap
+[350438.555890] uvcvideo: Device requested 3060 B/frame bandwidth.
+[350438.555896] uvcvideo: Selecting alternate setting 11 (3060 B/frame bandwidth).
+[350438.556362] uvcvideo: Allocated 5 URB buffers of 32x3060 bytes each.
+[350439.316468] uvcvideo: Marking buffer as bad (error bit set).
+[350439.316475] uvcvideo: Frame complete (EOF found).
+[350439.316477] uvcvideo: EOF in empty payload.
+[350439.316484] uvcvideo: frame 1 stats: 149/261/417 packets, 1/149/417 pts (early initial), 416/417 scr, last pts/stc/sof 2976325734/2978107243/249
+[350439.384510] uvcvideo: Marking buffer as bad (error bit set).
+[350439.384516] uvcvideo: Frame complete (EOF found).
+[350439.384518] uvcvideo: EOF in empty payload.
+[350439.384525] uvcvideo: frame 2 stats: 265/379/533 packets, 1/265/533 pts (early initial), 532/533 scr, last pts/stc/sof 2979524454/2981305193/316
+[350439.448472] uvcvideo: Marking buffer as bad (error bit set).
+[350439.448478] uvcvideo: Frame complete (EOF found).
+[350439.448480] uvcvideo: EOF in empty payload.
+[350439.448487] uvcvideo: frame 3 stats: 265/377/533 packets, 1/265/533 pts (early initial), 532/533 scr, last pts/stc/sof 2982723174/2984503144/382
+...(loop)...
+
+The devices can leave this invalid state if the alternate setting of
+the streaming interface is toggled.
+
+This patch adds a quirk for this device so it can be autosuspended
+properly.
+
+lsusb -v:
+Bus 001 Device 049: ID 046d:0821 Logitech, Inc. HD Webcam C910
+Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 2.00
+ bDeviceClass 239 Miscellaneous Device
+ bDeviceSubClass 2
+ bDeviceProtocol 1 Interface Association
+ bMaxPacketSize0 64
+ idVendor 0x046d Logitech, Inc.
+ idProduct 0x0821 HD Webcam C910
+ bcdDevice 0.10
+ iManufacturer 0
+ iProduct 0
+ iSerial 1 390022B0
+ bNumConfigurations 1
+
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_driver.c | 18 ++++++++++++++++++
+ drivers/media/usb/uvc/uvc_video.c | 11 +++++++++++
+ drivers/media/usb/uvc/uvcvideo.h | 1 +
+ 3 files changed, 30 insertions(+)
+
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index ef08e5f51ede9..a9cdef07e6b14 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -2453,6 +2453,24 @@ static const struct usb_device_id uvc_ids[] = {
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
++ /* Logitech, Webcam C910 */
++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
++ | USB_DEVICE_ID_MATCH_INT_INFO,
++ .idVendor = 0x046d,
++ .idProduct = 0x0821,
++ .bInterfaceClass = USB_CLASS_VIDEO,
++ .bInterfaceSubClass = 1,
++ .bInterfaceProtocol = 0,
++ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)},
++ /* Logitech, Webcam B910 */
++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
++ | USB_DEVICE_ID_MATCH_INT_INFO,
++ .idVendor = 0x046d,
++ .idProduct = 0x0823,
++ .bInterfaceClass = USB_CLASS_VIDEO,
++ .bInterfaceSubClass = 1,
++ .bInterfaceProtocol = 0,
++ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)},
+ /* Logitech Quickcam Fusion */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index d2eb9066e4dcc..53ea225972478 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -1965,6 +1965,17 @@ static int uvc_video_start_transfer(struct uvc_streaming *stream,
+ "Selecting alternate setting %u (%u B/frame bandwidth)\n",
+ altsetting, best_psize);
+
++ /*
++ * Some devices, namely the Logitech C910 and B910, are unable
++ * to recover from a USB autosuspend, unless the alternate
++ * setting of the streaming interface is toggled.
++ */
++ if (stream->dev->quirks & UVC_QUIRK_WAKE_AUTOSUSPEND) {
++ usb_set_interface(stream->dev->udev, intfnum,
++ altsetting);
++ usb_set_interface(stream->dev->udev, intfnum, 0);
++ }
++
+ ret = usb_set_interface(stream->dev->udev, intfnum, altsetting);
+ if (ret < 0)
+ return ret;
+diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
+index 4c89bf08171f2..b0937703c7254 100644
+--- a/drivers/media/usb/uvc/uvcvideo.h
++++ b/drivers/media/usb/uvc/uvcvideo.h
+@@ -74,6 +74,7 @@
+ #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400
+ #define UVC_QUIRK_FORCE_Y8 0x00000800
+ #define UVC_QUIRK_FORCE_BPP 0x00001000
++#define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000
+
+ /* Format flags */
+ #define UVC_FMT_FLAG_COMPRESSED 0x00000001
+--
+2.39.2
+
--- /dev/null
+From 92a2a0635157e4acf002d9295fcdc10b62f31fa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2016 18:44:29 +0200
+Subject: media: uvcvideo: Remove format descriptions
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit 50459f103edfe47c9a599d766a850ef6014936c5 ]
+
+The V4L2 core overwrites format descriptions in v4l_fill_fmtdesc(),
+there's no need to manually set the descriptions in the driver. This
+prepares for removal of the format descriptions from the uvc_fmts table.
+
+Unlike V4L2, UVC makes a distinction between the SD-DV, SDL-DV and HD-DV
+formats. It also indicates whether the DV format uses 50Hz or 60Hz. This
+information is parsed by the driver to construct a format name string
+that is printed in a debug message, but serves no other purpose as V4L2
+has a single V4L2_PIX_FMT_DV pixel format that covers all those cases.
+
+As the information is available in the UVC descriptors, and thus
+accessible to users with lsusb if they really care, don't log it in a
+debug message and drop the format name string to simplify the code.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
+Reviewed-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_driver.c | 24 ++----------------------
+ drivers/media/usb/uvc/uvc_v4l2.c | 2 --
+ drivers/media/usb/uvc/uvcvideo.h | 2 --
+ 3 files changed, 2 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index abfe735f6ea30..16c75b8635455 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -252,14 +252,10 @@ static int uvc_parse_format(struct uvc_device *dev,
+ fmtdesc = uvc_format_by_guid(&buffer[5]);
+
+ if (fmtdesc != NULL) {
+- strscpy(format->name, fmtdesc->name,
+- sizeof(format->name));
+ format->fcc = fmtdesc->fcc;
+ } else {
+ dev_info(&streaming->intf->dev,
+ "Unknown video format %pUl\n", &buffer[5]);
+- snprintf(format->name, sizeof(format->name), "%pUl\n",
+- &buffer[5]);
+ format->fcc = 0;
+ }
+
+@@ -271,8 +267,6 @@ static int uvc_parse_format(struct uvc_device *dev,
+ */
+ if (dev->quirks & UVC_QUIRK_FORCE_Y8) {
+ if (format->fcc == V4L2_PIX_FMT_YUYV) {
+- strscpy(format->name, "Greyscale 8-bit (Y8 )",
+- sizeof(format->name));
+ format->fcc = V4L2_PIX_FMT_GREY;
+ format->bpp = 8;
+ width_multiplier = 2;
+@@ -313,7 +307,6 @@ static int uvc_parse_format(struct uvc_device *dev,
+ return -EINVAL;
+ }
+
+- strscpy(format->name, "MJPEG", sizeof(format->name));
+ format->fcc = V4L2_PIX_FMT_MJPEG;
+ format->flags = UVC_FMT_FLAG_COMPRESSED;
+ format->bpp = 0;
+@@ -329,17 +322,7 @@ static int uvc_parse_format(struct uvc_device *dev,
+ return -EINVAL;
+ }
+
+- switch (buffer[8] & 0x7f) {
+- case 0:
+- strscpy(format->name, "SD-DV", sizeof(format->name));
+- break;
+- case 1:
+- strscpy(format->name, "SDL-DV", sizeof(format->name));
+- break;
+- case 2:
+- strscpy(format->name, "HD-DV", sizeof(format->name));
+- break;
+- default:
++ if ((buffer[8] & 0x7f) > 2) {
+ uvc_dbg(dev, DESCR,
+ "device %d videostreaming interface %d: unknown DV format %u\n",
+ dev->udev->devnum,
+@@ -347,9 +330,6 @@ static int uvc_parse_format(struct uvc_device *dev,
+ return -EINVAL;
+ }
+
+- strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
+- sizeof(format->name));
+-
+ format->fcc = V4L2_PIX_FMT_DV;
+ format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM;
+ format->bpp = 0;
+@@ -376,7 +356,7 @@ static int uvc_parse_format(struct uvc_device *dev,
+ return -EINVAL;
+ }
+
+- uvc_dbg(dev, DESCR, "Found format %s\n", format->name);
++ uvc_dbg(dev, DESCR, "Found format %p4cc", &format->fcc);
+
+ buflen -= buffer[0];
+ buffer += buffer[0];
+diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
+index 0774a11360c03..950b42d78a107 100644
+--- a/drivers/media/usb/uvc/uvc_v4l2.c
++++ b/drivers/media/usb/uvc/uvc_v4l2.c
+@@ -661,8 +661,6 @@ static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream,
+ fmt->flags = 0;
+ if (format->flags & UVC_FMT_FLAG_COMPRESSED)
+ fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+- strscpy(fmt->description, format->name, sizeof(fmt->description));
+- fmt->description[sizeof(fmt->description) - 1] = 0;
+ fmt->pixelformat = format->fcc;
+ return 0;
+ }
+diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
+index 1227ae63f85b7..4c89bf08171f2 100644
+--- a/drivers/media/usb/uvc/uvcvideo.h
++++ b/drivers/media/usb/uvc/uvcvideo.h
+@@ -264,8 +264,6 @@ struct uvc_format {
+ u32 fcc;
+ u32 flags;
+
+- char name[32];
+-
+ unsigned int nframes;
+ struct uvc_frame *frame;
+ };
+--
+2.39.2
+
--- /dev/null
+From 11a349366c9836374a2337c67f42bda2a88a841f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jan 2023 22:17:04 -0800
+Subject: media: uvcvideo: Silence memcpy() run-time false positive warnings
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit b839212988575c701aab4d3d9ca15e44c87e383c ]
+
+The memcpy() in uvc_video_decode_meta() intentionally copies across the
+length and flags members and into the trailing buf flexible array.
+Split the copy so that the compiler can better reason about (the lack
+of) buffer overflows here. Avoid the run-time false positive warning:
+
+ memcpy: detected field-spanning write (size 12) of single field "&meta->length" at drivers/media/usb/uvc/uvc_video.c:1355 (size 1)
+
+Additionally fix a typo in the documentation for struct uvc_meta_buf.
+
+Reported-by: ionut_n2001@yahoo.com
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216810
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_video.c | 4 +++-
+ include/uapi/linux/uvcvideo.h | 2 +-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
+index 53ea225972478..0d3a3b697b2d8 100644
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -1352,7 +1352,9 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream,
+ if (has_scr)
+ memcpy(stream->clock.last_scr, scr, 6);
+
+- memcpy(&meta->length, mem, length);
++ meta->length = mem[0];
++ meta->flags = mem[1];
++ memcpy(meta->buf, &mem[2], length - 2);
+ meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof);
+
+ uvc_dbg(stream->dev, FRAME,
+diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
+index 8288137387c0d..a9d0a64007ba5 100644
+--- a/include/uapi/linux/uvcvideo.h
++++ b/include/uapi/linux/uvcvideo.h
+@@ -86,7 +86,7 @@ struct uvc_xu_control_query {
+ * struct. The first two fields are added by the driver, they can be used for
+ * clock synchronisation. The rest is an exact copy of a UVC payload header.
+ * Only complete objects with complete buffers are included. Therefore it's
+- * always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large.
++ * always sizeof(meta->ns) + sizeof(meta->sof) + meta->length bytes large.
+ */
+ struct uvc_meta_buf {
+ __u64 ns;
+--
+2.39.2
+
--- /dev/null
+From 5f1b531e5b41dbf57d72c5b951b371edfe7b4e43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Dec 2022 23:49:33 +0200
+Subject: mei: bus-fixup:upon error print return values of send and receive
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+[ Upstream commit 4b8659e2c258e4fdac9ccdf06cc20c0677894ef9 ]
+
+For easier debugging, upon error, print also return values
+from __mei_cl_recv() and __mei_cl_send() functions.
+
+Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Link: https://lore.kernel.org/r/20221212214933.275434-1-tomas.winkler@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/mei/bus-fixup.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
+index 71fbf0bc84532..5eeb4d04c0962 100644
+--- a/drivers/misc/mei/bus-fixup.c
++++ b/drivers/misc/mei/bus-fixup.c
+@@ -151,7 +151,7 @@ static int mei_fwver(struct mei_cl_device *cldev)
+ ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), 0,
+ MEI_CL_IO_TX_BLOCKING);
+ if (ret < 0) {
+- dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n");
++ dev_err(&cldev->dev, "Could not send ReqFWVersion cmd ret = %d\n", ret);
+ return ret;
+ }
+
+@@ -163,7 +163,7 @@ static int mei_fwver(struct mei_cl_device *cldev)
+ * Should be at least one version block,
+ * error out if nothing found
+ */
+- dev_err(&cldev->dev, "Could not read FW version\n");
++ dev_err(&cldev->dev, "Could not read FW version ret = %d\n", bytes_recv);
+ return -EIO;
+ }
+
+@@ -376,7 +376,7 @@ static int mei_nfc_if_version(struct mei_cl *cl,
+ ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), 0,
+ MEI_CL_IO_TX_BLOCKING);
+ if (ret < 0) {
+- dev_err(bus->dev, "Could not send IF version cmd\n");
++ dev_err(bus->dev, "Could not send IF version cmd ret = %d\n", ret);
+ return ret;
+ }
+
+@@ -391,7 +391,7 @@ static int mei_nfc_if_version(struct mei_cl *cl,
+ bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, &vtag,
+ 0, 0);
+ if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) {
+- dev_err(bus->dev, "Could not read IF version\n");
++ dev_err(bus->dev, "Could not read IF version ret = %d\n", bytes_recv);
+ ret = -EIO;
+ goto err;
+ }
+--
+2.39.2
+
--- /dev/null
+From a1412e54e59ebc3f52183ae184e9f6a9580ea832 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 15:41:18 +0100
+Subject: memory: renesas-rpc-if: Move resource acquisition to .probe()
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 8b3580df15f53045fda3ffae53f74575c96aa77e ]
+
+While the acquired resources are tied to the lifetime of the RPC-IF core
+device (through the use of managed resource functions), the actual
+resource acquisition is triggered from the HyperBus and SPI child
+drivers. Due to this mismatch, unbinding and rebinding the child
+drivers manually fails with -EBUSY:
+
+ # echo rpc-if-hyperflash > /sys/bus/platform/drivers/rpc-if-hyperflash/unbind
+ # echo rpc-if-hyperflash > /sys/bus/platform/drivers/rpc-if-hyperflash/bind
+ rpc-if ee200000.spi: can't request region for resource [mem 0xee200000-0xee2001ff]
+ rpc-if-hyperflash: probe of rpc-if-hyperflash failed with error -16
+
+The same is true for rpc-if-spi.
+
+Fix this by moving all resource acquisition to the core driver's probe
+routine.
+
+Fixes: ca7d8b980b67 ("memory: add Renesas RPC-IF driver")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/c1012ef1de799e08a70817ab7313794e2d8d7bfb.1669213027.git.geert+renesas@glider.be
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memory/renesas-rpc-if.c | 49 ++++++++++++++++-----------------
+ 1 file changed, 24 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
+index 309c0b59f3a2f..7343dbb79c9f7 100644
+--- a/drivers/memory/renesas-rpc-if.c
++++ b/drivers/memory/renesas-rpc-if.c
+@@ -276,32 +276,7 @@ static const struct regmap_config rpcif_regmap_config = {
+
+ int rpcif_sw_init(struct rpcif *rpcif, struct device *dev)
+ {
+- struct platform_device *pdev = to_platform_device(dev);
+ struct rpcif_priv *rpc = dev_get_drvdata(dev);
+- struct resource *res;
+-
+- rpc->base = devm_platform_ioremap_resource_byname(pdev, "regs");
+- if (IS_ERR(rpc->base))
+- return PTR_ERR(rpc->base);
+-
+- rpc->regmap = devm_regmap_init(&pdev->dev, NULL, rpc, &rpcif_regmap_config);
+- if (IS_ERR(rpc->regmap)) {
+- dev_err(&pdev->dev,
+- "failed to init regmap for rpcif, error %ld\n",
+- PTR_ERR(rpc->regmap));
+- return PTR_ERR(rpc->regmap);
+- }
+-
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap");
+- rpc->dirmap = devm_ioremap_resource(&pdev->dev, res);
+- if (IS_ERR(rpc->dirmap))
+- return PTR_ERR(rpc->dirmap);
+- rpc->size = resource_size(res);
+-
+- rpc->type = (uintptr_t)of_device_get_match_data(dev);
+- rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+- if (IS_ERR(rpc->rstc))
+- return PTR_ERR(rpc->rstc);
+
+ rpcif->dev = dev;
+ rpcif->dirmap = rpc->dirmap;
+@@ -701,9 +676,11 @@ EXPORT_SYMBOL(rpcif_dirmap_read);
+
+ static int rpcif_probe(struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
+ struct platform_device *vdev;
+ struct device_node *flash;
+ struct rpcif_priv *rpc;
++ struct resource *res;
+ const char *name;
+ int ret;
+
+@@ -728,6 +705,28 @@ static int rpcif_probe(struct platform_device *pdev)
+ if (!rpc)
+ return -ENOMEM;
+
++ rpc->base = devm_platform_ioremap_resource_byname(pdev, "regs");
++ if (IS_ERR(rpc->base))
++ return PTR_ERR(rpc->base);
++
++ rpc->regmap = devm_regmap_init(dev, NULL, rpc, &rpcif_regmap_config);
++ if (IS_ERR(rpc->regmap)) {
++ dev_err(dev, "failed to init regmap for rpcif, error %ld\n",
++ PTR_ERR(rpc->regmap));
++ return PTR_ERR(rpc->regmap);
++ }
++
++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap");
++ rpc->dirmap = devm_ioremap_resource(dev, res);
++ if (IS_ERR(rpc->dirmap))
++ return PTR_ERR(rpc->dirmap);
++ rpc->size = resource_size(res);
++
++ rpc->type = (uintptr_t)of_device_get_match_data(dev);
++ rpc->rstc = devm_reset_control_get_exclusive(dev, NULL);
++ if (IS_ERR(rpc->rstc))
++ return PTR_ERR(rpc->rstc);
++
+ vdev = platform_device_alloc(name, pdev->id);
+ if (!vdev)
+ return -ENOMEM;
+--
+2.39.2
+
--- /dev/null
+From 58fde57b53241aa843ededf34f7a97110650face Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 15:41:17 +0100
+Subject: memory: renesas-rpc-if: Split-off private data from struct rpcif
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 51de3fc9a84d8e99dd3f02536a623f9fb95d0c0a ]
+
+The rpcif structure is used as a common data structure, shared by the
+RPC-IF core driver and by the HyperBus and SPI child drivers.
+This poses several problems:
+ - Most structure members describe private core driver state, which
+ should not be accessible by the child drivers,
+ - The structure's lifetime is controlled by the child drivers,
+ complicating use by the core driver.
+
+Fix this by moving the private core driver state to its own structure,
+managed by the RPC-IF core driver, and store it in the core driver's
+private data field. This requires absorbing the child's platform
+device, as that was stored in the driver's private data field before.
+
+Fixes: ca7d8b980b67 ("memory: add Renesas RPC-IF driver")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/09fbb6fa67d5a8cd48a08808c9afa2f6a499aa42.1669213027.git.geert+renesas@glider.be
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memory/renesas-rpc-if.c | 75 +++++++++++++++++++++++++--------
+ include/memory/renesas-rpc-if.h | 16 -------
+ 2 files changed, 57 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
+index 61c288d403750..309c0b59f3a2f 100644
+--- a/drivers/memory/renesas-rpc-if.c
++++ b/drivers/memory/renesas-rpc-if.c
+@@ -162,14 +162,36 @@ static const struct regmap_access_table rpcif_volatile_table = {
+ .n_yes_ranges = ARRAY_SIZE(rpcif_volatile_ranges),
+ };
+
++struct rpcif_priv {
++ struct device *dev;
++ void __iomem *base;
++ void __iomem *dirmap;
++ struct regmap *regmap;
++ struct reset_control *rstc;
++ struct platform_device *vdev;
++ size_t size;
++ enum rpcif_type type;
++ enum rpcif_data_dir dir;
++ u8 bus_size;
++ u8 xfer_size;
++ void *buffer;
++ u32 xferlen;
++ u32 smcr;
++ u32 smadr;
++ u32 command; /* DRCMR or SMCMR */
++ u32 option; /* DROPR or SMOPR */
++ u32 enable; /* DRENR or SMENR */
++ u32 dummy; /* DRDMCR or SMDMCR */
++ u32 ddr; /* DRDRENR or SMDRENR */
++};
+
+ /*
+ * Custom accessor functions to ensure SM[RW]DR[01] are always accessed with
+- * proper width. Requires rpcif.xfer_size to be correctly set before!
++ * proper width. Requires rpcif_priv.xfer_size to be correctly set before!
+ */
+ static int rpcif_reg_read(void *context, unsigned int reg, unsigned int *val)
+ {
+- struct rpcif *rpc = context;
++ struct rpcif_priv *rpc = context;
+
+ switch (reg) {
+ case RPCIF_SMRDR0:
+@@ -205,7 +227,7 @@ static int rpcif_reg_read(void *context, unsigned int reg, unsigned int *val)
+
+ static int rpcif_reg_write(void *context, unsigned int reg, unsigned int val)
+ {
+- struct rpcif *rpc = context;
++ struct rpcif_priv *rpc = context;
+
+ switch (reg) {
+ case RPCIF_SMWDR0:
+@@ -252,13 +274,12 @@ static const struct regmap_config rpcif_regmap_config = {
+ .volatile_table = &rpcif_volatile_table,
+ };
+
+-int rpcif_sw_init(struct rpcif *rpc, struct device *dev)
++int rpcif_sw_init(struct rpcif *rpcif, struct device *dev)
+ {
+ struct platform_device *pdev = to_platform_device(dev);
++ struct rpcif_priv *rpc = dev_get_drvdata(dev);
+ struct resource *res;
+
+- rpc->dev = dev;
+-
+ rpc->base = devm_platform_ioremap_resource_byname(pdev, "regs");
+ if (IS_ERR(rpc->base))
+ return PTR_ERR(rpc->base);
+@@ -279,12 +300,17 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev)
+
+ rpc->type = (uintptr_t)of_device_get_match_data(dev);
+ rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
++ if (IS_ERR(rpc->rstc))
++ return PTR_ERR(rpc->rstc);
+
+- return PTR_ERR_OR_ZERO(rpc->rstc);
++ rpcif->dev = dev;
++ rpcif->dirmap = rpc->dirmap;
++ rpcif->size = rpc->size;
++ return 0;
+ }
+ EXPORT_SYMBOL(rpcif_sw_init);
+
+-static void rpcif_rzg2l_timing_adjust_sdr(struct rpcif *rpc)
++static void rpcif_rzg2l_timing_adjust_sdr(struct rpcif_priv *rpc)
+ {
+ regmap_write(rpc->regmap, RPCIF_PHYWR, 0xa5390000);
+ regmap_write(rpc->regmap, RPCIF_PHYADD, 0x80000000);
+@@ -298,8 +324,9 @@ static void rpcif_rzg2l_timing_adjust_sdr(struct rpcif *rpc)
+ regmap_write(rpc->regmap, RPCIF_PHYADD, 0x80000032);
+ }
+
+-int rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
++int rpcif_hw_init(struct rpcif *rpcif, bool hyperflash)
+ {
++ struct rpcif_priv *rpc = dev_get_drvdata(rpcif->dev);
+ u32 dummy;
+
+ pm_runtime_get_sync(rpc->dev);
+@@ -360,7 +387,7 @@ int rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
+ }
+ EXPORT_SYMBOL(rpcif_hw_init);
+
+-static int wait_msg_xfer_end(struct rpcif *rpc)
++static int wait_msg_xfer_end(struct rpcif_priv *rpc)
+ {
+ u32 sts;
+
+@@ -369,7 +396,7 @@ static int wait_msg_xfer_end(struct rpcif *rpc)
+ USEC_PER_SEC);
+ }
+
+-static u8 rpcif_bits_set(struct rpcif *rpc, u32 nbytes)
++static u8 rpcif_bits_set(struct rpcif_priv *rpc, u32 nbytes)
+ {
+ if (rpc->bus_size == 2)
+ nbytes /= 2;
+@@ -382,9 +409,11 @@ static u8 rpcif_bit_size(u8 buswidth)
+ return buswidth > 4 ? 2 : ilog2(buswidth);
+ }
+
+-void rpcif_prepare(struct rpcif *rpc, const struct rpcif_op *op, u64 *offs,
++void rpcif_prepare(struct rpcif *rpcif, const struct rpcif_op *op, u64 *offs,
+ size_t *len)
+ {
++ struct rpcif_priv *rpc = dev_get_drvdata(rpcif->dev);
++
+ rpc->smcr = 0;
+ rpc->smadr = 0;
+ rpc->enable = 0;
+@@ -468,8 +497,9 @@ void rpcif_prepare(struct rpcif *rpc, const struct rpcif_op *op, u64 *offs,
+ }
+ EXPORT_SYMBOL(rpcif_prepare);
+
+-int rpcif_manual_xfer(struct rpcif *rpc)
++int rpcif_manual_xfer(struct rpcif *rpcif)
+ {
++ struct rpcif_priv *rpc = dev_get_drvdata(rpcif->dev);
+ u32 smenr, smcr, pos = 0, max = rpc->bus_size == 2 ? 8 : 4;
+ int ret = 0;
+
+@@ -589,7 +619,7 @@ int rpcif_manual_xfer(struct rpcif *rpc)
+ err_out:
+ if (reset_control_reset(rpc->rstc))
+ dev_err(rpc->dev, "Failed to reset HW\n");
+- rpcif_hw_init(rpc, rpc->bus_size == 2);
++ rpcif_hw_init(rpcif, rpc->bus_size == 2);
+ goto exit;
+ }
+ EXPORT_SYMBOL(rpcif_manual_xfer);
+@@ -636,8 +666,9 @@ static void memcpy_fromio_readw(void *to,
+ }
+ }
+
+-ssize_t rpcif_dirmap_read(struct rpcif *rpc, u64 offs, size_t len, void *buf)
++ssize_t rpcif_dirmap_read(struct rpcif *rpcif, u64 offs, size_t len, void *buf)
+ {
++ struct rpcif_priv *rpc = dev_get_drvdata(rpcif->dev);
+ loff_t from = offs & (rpc->size - 1);
+ size_t size = rpc->size - from;
+
+@@ -672,6 +703,7 @@ static int rpcif_probe(struct platform_device *pdev)
+ {
+ struct platform_device *vdev;
+ struct device_node *flash;
++ struct rpcif_priv *rpc;
+ const char *name;
+ int ret;
+
+@@ -692,11 +724,18 @@ static int rpcif_probe(struct platform_device *pdev)
+ }
+ of_node_put(flash);
+
++ rpc = devm_kzalloc(&pdev->dev, sizeof(*rpc), GFP_KERNEL);
++ if (!rpc)
++ return -ENOMEM;
++
+ vdev = platform_device_alloc(name, pdev->id);
+ if (!vdev)
+ return -ENOMEM;
+ vdev->dev.parent = &pdev->dev;
+- platform_set_drvdata(pdev, vdev);
++
++ rpc->dev = &pdev->dev;
++ rpc->vdev = vdev;
++ platform_set_drvdata(pdev, rpc);
+
+ ret = platform_device_add(vdev);
+ if (ret) {
+@@ -709,9 +748,9 @@ static int rpcif_probe(struct platform_device *pdev)
+
+ static int rpcif_remove(struct platform_device *pdev)
+ {
+- struct platform_device *vdev = platform_get_drvdata(pdev);
++ struct rpcif_priv *rpc = platform_get_drvdata(pdev);
+
+- platform_device_unregister(vdev);
++ platform_device_unregister(rpc->vdev);
+
+ return 0;
+ }
+diff --git a/include/memory/renesas-rpc-if.h b/include/memory/renesas-rpc-if.h
+index 9c0ad64b8d292..ddf94356752d3 100644
+--- a/include/memory/renesas-rpc-if.h
++++ b/include/memory/renesas-rpc-if.h
+@@ -64,24 +64,8 @@ enum rpcif_type {
+
+ struct rpcif {
+ struct device *dev;
+- void __iomem *base;
+ void __iomem *dirmap;
+- struct regmap *regmap;
+- struct reset_control *rstc;
+ size_t size;
+- enum rpcif_type type;
+- enum rpcif_data_dir dir;
+- u8 bus_size;
+- u8 xfer_size;
+- void *buffer;
+- u32 xferlen;
+- u32 smcr;
+- u32 smadr;
+- u32 command; /* DRCMR or SMCMR */
+- u32 option; /* DROPR or SMOPR */
+- u32 enable; /* DRENR or SMENR */
+- u32 dummy; /* DRDMCR or SMDMCR */
+- u32 ddr; /* DRDRENR or SMDRENR */
+ };
+
+ int rpcif_sw_init(struct rpcif *rpc, struct device *dev);
+--
+2.39.2
+
--- /dev/null
+From 2db1a037a3b39c3c209c7c0141a987c0f1fcc083 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jan 2023 14:10:55 +0800
+Subject: mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 4414a7ab80cebf715045e3c4d465feefbad21139 ]
+
+In arizona_clk32k_enable(), we should use pm_runtime_resume_and_get()
+as pm_runtime_get_sync() will increase the refcnt even when it
+returns an error.
+
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20230105061055.1509261-1-windhl@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/arizona-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
+index cbf1dd90b70d5..b1c53e0407710 100644
+--- a/drivers/mfd/arizona-core.c
++++ b/drivers/mfd/arizona-core.c
+@@ -45,7 +45,7 @@ int arizona_clk32k_enable(struct arizona *arizona)
+ if (arizona->clk32k_ref == 1) {
+ switch (arizona->pdata.clk32k_src) {
+ case ARIZONA_32KZ_MCLK1:
+- ret = pm_runtime_get_sync(arizona->dev);
++ ret = pm_runtime_resume_and_get(arizona->dev);
+ if (ret != 0)
+ goto err_ref;
+ ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
+--
+2.39.2
+
--- /dev/null
+From 25341322e5b6a4c7bea9a337e7a42904d85fdced Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 15:11:00 +0100
+Subject: misc: vmw_balloon: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 209cdbd07cfaa4b7385bad4eeb47e5ec1887d33d ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic at
+once.
+
+Cc: Nadav Amit <namit@vmware.com>
+Cc: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20230202141100.2291188-1-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/vmw_balloon.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
+index 61a2be712bf7b..9ce9b9e0e9b63 100644
+--- a/drivers/misc/vmw_balloon.c
++++ b/drivers/misc/vmw_balloon.c
+@@ -1709,7 +1709,7 @@ static void __init vmballoon_debugfs_init(struct vmballoon *b)
+ static void __exit vmballoon_debugfs_exit(struct vmballoon *b)
+ {
+ static_key_disable(&balloon_stat_enabled.key);
+- debugfs_remove(debugfs_lookup("vmmemctl", NULL));
++ debugfs_lookup_and_remove("vmmemctl", NULL);
+ kfree(b->stats);
+ b->stats = NULL;
+ }
+--
+2.39.2
+
--- /dev/null
+From 2da38657bd7998181e780916bc0187020bf9021d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 09:13:55 -0800
+Subject: mlx5: fix possible ptp queue fifo use-after-free
+
+From: Vadim Fedorenko <vadfed@meta.com>
+
+[ Upstream commit 3a50cf1e8e5157b82268eee7e330dbe5736a0948 ]
+
+Fifo indexes are not checked during pop operations and it leads to
+potential use-after-free when poping from empty queue. Such case was
+possible during re-sync action. WARN_ON_ONCE covers future cases.
+
+There were out-of-order cqe spotted which lead to drain of the queue and
+use-after-free because of lack of fifo pointers check. Special check and
+counter are added to avoid resync operation if SKB could not exist in the
+fifo because of OOO cqe (skb_id must be between consumer and producer
+index).
+
+Fixes: 58a518948f60 ("net/mlx5e: Add resiliency for PTP TX port timestamp")
+Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 19 ++++++++++++++++++-
+ .../net/ethernet/mellanox/mlx5/core/en/txrx.h | 2 ++
+ .../ethernet/mellanox/mlx5/core/en_stats.c | 1 +
+ .../ethernet/mellanox/mlx5/core/en_stats.h | 1 +
+ 4 files changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+index b72de2b520ecb..ae75e230170b5 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+@@ -86,6 +86,17 @@ static bool mlx5e_ptp_ts_cqe_drop(struct mlx5e_ptpsq *ptpsq, u16 skb_cc, u16 skb
+ return (ptpsq->ts_cqe_ctr_mask && (skb_cc != skb_id));
+ }
+
++static bool mlx5e_ptp_ts_cqe_ooo(struct mlx5e_ptpsq *ptpsq, u16 skb_id)
++{
++ u16 skb_cc = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_cc);
++ u16 skb_pc = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_pc);
++
++ if (PTP_WQE_CTR2IDX(skb_id - skb_cc) >= PTP_WQE_CTR2IDX(skb_pc - skb_cc))
++ return true;
++
++ return false;
++}
++
+ static void mlx5e_ptp_skb_fifo_ts_cqe_resync(struct mlx5e_ptpsq *ptpsq, u16 skb_cc,
+ u16 skb_id, int budget)
+ {
+@@ -120,8 +131,14 @@ static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq,
+ goto out;
+ }
+
+- if (mlx5e_ptp_ts_cqe_drop(ptpsq, skb_cc, skb_id))
++ if (mlx5e_ptp_ts_cqe_drop(ptpsq, skb_cc, skb_id)) {
++ if (mlx5e_ptp_ts_cqe_ooo(ptpsq, skb_id)) {
++ /* already handled by a previous resync */
++ ptpsq->cq_stats->ooo_cqe_drop++;
++ return;
++ }
+ mlx5e_ptp_skb_fifo_ts_cqe_resync(ptpsq, skb_cc, skb_id, budget);
++ }
+
+ skb = mlx5e_skb_fifo_pop(&ptpsq->skb_fifo);
+ hwtstamp = mlx5e_cqe_ts_to_ns(sq->ptp_cyc2time, sq->clock, get_cqe_ts(cqe));
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+index 15a5a57b47b85..1b3a65325ece1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+@@ -297,6 +297,8 @@ void mlx5e_skb_fifo_push(struct mlx5e_skb_fifo *fifo, struct sk_buff *skb)
+ static inline
+ struct sk_buff *mlx5e_skb_fifo_pop(struct mlx5e_skb_fifo *fifo)
+ {
++ WARN_ON_ONCE(*fifo->pc == *fifo->cc);
++
+ return *mlx5e_skb_fifo_get(fifo, (*fifo->cc)++);
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+index 03c1841970f14..f7f54550a8bbc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+@@ -2121,6 +2121,7 @@ static const struct counter_desc ptp_cq_stats_desc[] = {
+ { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, abort_abs_diff_ns) },
+ { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, resync_cqe) },
+ { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, resync_event) },
++ { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, ooo_cqe_drop) },
+ };
+
+ static const struct counter_desc ptp_rq_stats_desc[] = {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
+index 9f781085be471..52a67efafcd37 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
+@@ -459,6 +459,7 @@ struct mlx5e_ptp_cq_stats {
+ u64 abort_abs_diff_ns;
+ u64 resync_cqe;
+ u64 resync_event;
++ u64 ooo_cqe_drop;
+ };
+
+ struct mlx5e_stats {
+--
+2.39.2
+
--- /dev/null
+From 24f573cd416080a7a167ecae2af4c444f2ad74f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 09:13:54 -0800
+Subject: mlx5: fix skb leak while fifo resync and push
+
+From: Vadim Fedorenko <vadfed@meta.com>
+
+[ Upstream commit e435941b1da1a0be4ff8a7ae425774c76a5ac514 ]
+
+During ptp resync operation SKBs were poped from the fifo but were never
+freed neither by napi_consume nor by dev_kfree_skb_any. Add call to
+napi_consume_skb to properly free SKBs.
+
+Another leak was happening because mlx5e_skb_fifo_has_room() had an error
+in the check. Comparing free running counters works well unless C promotes
+the types to something wider than the counter. In this case counters are
+u16 but the result of the substraction is promouted to int and it causes
+wrong result (negative value) of the check when producer have already
+overlapped but consumer haven't yet. Explicit cast to u16 fixes the issue.
+
+Fixes: 58a518948f60 ("net/mlx5e: Add resiliency for PTP TX port timestamp")
+Reviewed-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c | 6 ++++--
+ drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h | 2 +-
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+index 8469e9c386706..b72de2b520ecb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+@@ -86,7 +86,8 @@ static bool mlx5e_ptp_ts_cqe_drop(struct mlx5e_ptpsq *ptpsq, u16 skb_cc, u16 skb
+ return (ptpsq->ts_cqe_ctr_mask && (skb_cc != skb_id));
+ }
+
+-static void mlx5e_ptp_skb_fifo_ts_cqe_resync(struct mlx5e_ptpsq *ptpsq, u16 skb_cc, u16 skb_id)
++static void mlx5e_ptp_skb_fifo_ts_cqe_resync(struct mlx5e_ptpsq *ptpsq, u16 skb_cc,
++ u16 skb_id, int budget)
+ {
+ struct skb_shared_hwtstamps hwts = {};
+ struct sk_buff *skb;
+@@ -98,6 +99,7 @@ static void mlx5e_ptp_skb_fifo_ts_cqe_resync(struct mlx5e_ptpsq *ptpsq, u16 skb_
+ hwts.hwtstamp = mlx5e_skb_cb_get_hwts(skb)->cqe_hwtstamp;
+ skb_tstamp_tx(skb, &hwts);
+ ptpsq->cq_stats->resync_cqe++;
++ napi_consume_skb(skb, budget);
+ skb_cc = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_cc);
+ }
+ }
+@@ -119,7 +121,7 @@ static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq,
+ }
+
+ if (mlx5e_ptp_ts_cqe_drop(ptpsq, skb_cc, skb_id))
+- mlx5e_ptp_skb_fifo_ts_cqe_resync(ptpsq, skb_cc, skb_id);
++ mlx5e_ptp_skb_fifo_ts_cqe_resync(ptpsq, skb_cc, skb_id, budget);
+
+ skb = mlx5e_skb_fifo_pop(&ptpsq->skb_fifo);
+ hwtstamp = mlx5e_cqe_ts_to_ns(sq->ptp_cyc2time, sq->clock, get_cqe_ts(cqe));
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+index 853f312cd7572..15a5a57b47b85 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+@@ -81,7 +81,7 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
+ static inline bool
+ mlx5e_skb_fifo_has_room(struct mlx5e_skb_fifo *fifo)
+ {
+- return (*fifo->pc - *fifo->cc) < fifo->mask;
++ return (u16)(*fifo->pc - *fifo->cc) < fifo->mask;
+ }
+
+ static inline bool
+--
+2.39.2
+
--- /dev/null
+From e98ffc2645117a6a2b339db3888a40b7a26582df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 17:52:34 +0200
+Subject: net: dsa: felix: fix internal MDIO controller resource length
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 940af261321307cd1dd0fe8f9c34a6129f9d4bdc ]
+
+The blamed commit did not properly convert the resource start/end format
+into the DEFINE_RES_MEM_NAMED() start/length format, resulting in a
+resource for vsc9959_imdio_res which is much longer than expected:
+
+$ cat /proc/iomem
+1f8000000-1f815ffff : pcie@1f0000000
+ 1f8140000-1f815ffff : 0000:00:00.5
+ 1f8148030-1f815006f : imdio
+
+vs (correct)
+
+$ cat /proc/iomem
+1f8000000-1f815ffff : pcie@1f0000000
+ 1f8140000-1f815ffff : 0000:00:00.5
+ 1f8148030-1f814803f : imdio
+
+Luckily it's not big enough to exceed the size of the parent resource
+(pci_resource_end(pdev, VSC9959_IMDIO_PCI_BAR)), and it doesn't overlap
+with anything else that the Linux driver uses currently, so the larger
+than expected size isn't a practical problem that I can see. Although it
+is clearly wrong in the /proc/iomem output.
+
+Fixes: 044d447a801f ("net: dsa: felix: use DEFINE_RES_MEM_NAMED for resources")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/felix_vsc9959.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
+index 26a35ae322d10..cc89cff029e1f 100644
+--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
+@@ -513,7 +513,7 @@ static const char * const vsc9959_resource_names[TARGET_MAX] = {
+ * SGMII/QSGMII MAC PCS can be found.
+ */
+ static const struct resource vsc9959_imdio_res =
+- DEFINE_RES_MEM_NAMED(0x8030, 0x8040, "imdio");
++ DEFINE_RES_MEM_NAMED(0x8030, 0x10, "imdio");
+
+ static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {
+ [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 6, 6),
+--
+2.39.2
+
--- /dev/null
+From 9c627210e7177ad215828b69bbf1ea7150c1b995 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 17:52:33 +0200
+Subject: net: dsa: seville: ignore mscc-miim read errors from Lynx PCS
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 0322ef49c1ac6f0e2ef37b146c0bf8440873072c ]
+
+During the refactoring in the commit below, vsc9953_mdio_read() was
+replaced with mscc_miim_read(), which has one extra step: it checks for
+the MSCC_MIIM_DATA_ERROR bits before returning the result.
+
+On T1040RDB, there are 8 QSGMII PCSes belonging to the switch, and they
+are organized in 2 groups. First group responds to MDIO addresses 4-7
+because QSGMIIACR1[MDEV_PORT] is 1, and the second group responds to
+MDIO addresses 8-11 because QSGMIIBCR1[MDEV_PORT] is 2. I have double
+checked that these values are correctly set in the SERDES, as well as
+PCCR1[QSGMA_CFG] and PCCR1[QSGMB_CFG] are both 0b01.
+
+mscc_miim_read: phyad 8 reg 0x1 MIIM_DATA 0x2d
+mscc_miim_read: phyad 8 reg 0x5 MIIM_DATA 0x5801
+mscc_miim_read: phyad 8 reg 0x1 MIIM_DATA 0x2d
+mscc_miim_read: phyad 8 reg 0x5 MIIM_DATA 0x5801
+mscc_miim_read: phyad 9 reg 0x1 MIIM_DATA 0x2d
+mscc_miim_read: phyad 9 reg 0x5 MIIM_DATA 0x5801
+mscc_miim_read: phyad 9 reg 0x1 MIIM_DATA 0x2d
+mscc_miim_read: phyad 9 reg 0x5 MIIM_DATA 0x5801
+mscc_miim_read: phyad 10 reg 0x1 MIIM_DATA 0x2d
+mscc_miim_read: phyad 10 reg 0x5 MIIM_DATA 0x5801
+mscc_miim_read: phyad 10 reg 0x1 MIIM_DATA 0x2d
+mscc_miim_read: phyad 10 reg 0x5 MIIM_DATA 0x5801
+mscc_miim_read: phyad 11 reg 0x1 MIIM_DATA 0x2d
+mscc_miim_read: phyad 11 reg 0x5 MIIM_DATA 0x5801
+mscc_miim_read: phyad 11 reg 0x1 MIIM_DATA 0x2d
+mscc_miim_read: phyad 11 reg 0x5 MIIM_DATA 0x5801
+mscc_miim_read: phyad 4 reg 0x1 MIIM_DATA 0x3002d, ERROR
+mscc_miim_read: phyad 4 reg 0x5 MIIM_DATA 0x3da01, ERROR
+mscc_miim_read: phyad 5 reg 0x1 MIIM_DATA 0x3002d, ERROR
+mscc_miim_read: phyad 5 reg 0x5 MIIM_DATA 0x35801, ERROR
+mscc_miim_read: phyad 5 reg 0x1 MIIM_DATA 0x3002d, ERROR
+mscc_miim_read: phyad 5 reg 0x5 MIIM_DATA 0x35801, ERROR
+mscc_miim_read: phyad 6 reg 0x1 MIIM_DATA 0x3002d, ERROR
+mscc_miim_read: phyad 6 reg 0x5 MIIM_DATA 0x35801, ERROR
+mscc_miim_read: phyad 6 reg 0x1 MIIM_DATA 0x3002d, ERROR
+mscc_miim_read: phyad 6 reg 0x5 MIIM_DATA 0x35801, ERROR
+mscc_miim_read: phyad 7 reg 0x1 MIIM_DATA 0x3002d, ERROR
+mscc_miim_read: phyad 7 reg 0x5 MIIM_DATA 0x35801, ERROR
+mscc_miim_read: phyad 7 reg 0x1 MIIM_DATA 0x3002d, ERROR
+mscc_miim_read: phyad 7 reg 0x5 MIIM_DATA 0x35801, ERROR
+
+As can be seen, the data in MIIM_DATA is still valid despite having the
+MSCC_MIIM_DATA_ERROR bits set. The driver as introduced in commit
+84705fc16552 ("net: dsa: felix: introduce support for Seville VSC9953
+switch") was ignoring these bits, perhaps deliberately (although
+unbeknownst to me).
+
+This is an old IP and the hardware team cannot seem to be able to help
+me track down a plausible reason for these failures. I'll keep
+investigating, but in the meantime, this is a direct regression which
+must be restored to a working state.
+
+The only thing I can do is keep ignoring the errors as before.
+
+Fixes: b99658452355 ("net: dsa: ocelot: felix: utilize shared mscc-miim driver for indirect MDIO access")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/seville_vsc9953.c | 4 ++--
+ drivers/net/mdio/mdio-mscc-miim.c | 9 ++++++---
+ include/linux/mdio/mdio-mscc-miim.h | 2 +-
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
+index 7af33b2c685da..c2863d6d870fb 100644
+--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
++++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
+@@ -923,8 +923,8 @@ static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
+
+ rc = mscc_miim_setup(dev, &bus, "VSC9953 internal MDIO bus",
+ ocelot->targets[GCB],
+- ocelot->map[GCB][GCB_MIIM_MII_STATUS & REG_MASK]);
+-
++ ocelot->map[GCB][GCB_MIIM_MII_STATUS & REG_MASK],
++ true);
+ if (rc) {
+ dev_err(dev, "failed to setup MDIO bus\n");
+ return rc;
+diff --git a/drivers/net/mdio/mdio-mscc-miim.c b/drivers/net/mdio/mdio-mscc-miim.c
+index 51f68daac152f..34b87389788bb 100644
+--- a/drivers/net/mdio/mdio-mscc-miim.c
++++ b/drivers/net/mdio/mdio-mscc-miim.c
+@@ -52,6 +52,7 @@ struct mscc_miim_info {
+ struct mscc_miim_dev {
+ struct regmap *regs;
+ int mii_status_offset;
++ bool ignore_read_errors;
+ struct regmap *phy_regs;
+ const struct mscc_miim_info *info;
+ struct clk *clk;
+@@ -138,7 +139,7 @@ static int mscc_miim_read(struct mii_bus *bus, int mii_id, int regnum)
+ goto out;
+ }
+
+- if (val & MSCC_MIIM_DATA_ERROR) {
++ if (!miim->ignore_read_errors && !!(val & MSCC_MIIM_DATA_ERROR)) {
+ ret = -EIO;
+ goto out;
+ }
+@@ -218,7 +219,8 @@ static const struct regmap_config mscc_miim_phy_regmap_config = {
+ };
+
+ int mscc_miim_setup(struct device *dev, struct mii_bus **pbus, const char *name,
+- struct regmap *mii_regmap, int status_offset)
++ struct regmap *mii_regmap, int status_offset,
++ bool ignore_read_errors)
+ {
+ struct mscc_miim_dev *miim;
+ struct mii_bus *bus;
+@@ -240,6 +242,7 @@ int mscc_miim_setup(struct device *dev, struct mii_bus **pbus, const char *name,
+
+ miim->regs = mii_regmap;
+ miim->mii_status_offset = status_offset;
++ miim->ignore_read_errors = ignore_read_errors;
+
+ *pbus = bus;
+
+@@ -291,7 +294,7 @@ static int mscc_miim_probe(struct platform_device *pdev)
+ return dev_err_probe(dev, PTR_ERR(phy_regmap),
+ "Unable to create phy register regmap\n");
+
+- ret = mscc_miim_setup(dev, &bus, "mscc_miim", mii_regmap, 0);
++ ret = mscc_miim_setup(dev, &bus, "mscc_miim", mii_regmap, 0, false);
+ if (ret < 0) {
+ dev_err(dev, "Unable to setup the MDIO bus\n");
+ return ret;
+diff --git a/include/linux/mdio/mdio-mscc-miim.h b/include/linux/mdio/mdio-mscc-miim.h
+index 5b4ed2c3cbb9a..1ce699740af63 100644
+--- a/include/linux/mdio/mdio-mscc-miim.h
++++ b/include/linux/mdio/mdio-mscc-miim.h
+@@ -14,6 +14,6 @@
+
+ int mscc_miim_setup(struct device *device, struct mii_bus **bus,
+ const char *name, struct regmap *mii_regmap,
+- int status_offset);
++ int status_offset, bool ignore_read_errors);
+
+ #endif
+--
+2.39.2
+
--- /dev/null
+From 421abfa2259f5c53ca3c164fca716e17b03c3d5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Feb 2023 08:38:45 +0000
+Subject: net: fix __dev_kfree_skb_any() vs drop monitor
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ac3ad19584b26fae9ac86e4faebe790becc74491 ]
+
+dev_kfree_skb() is aliased to consume_skb().
+
+When a driver is dropping a packet by calling dev_kfree_skb_any()
+we should propagate the drop reason instead of pretending
+the packet was consumed.
+
+Note: Now we have enum skb_drop_reason we could remove
+enum skb_free_reason (for linux-6.4)
+
+v2: added an unlikely(), suggested by Yunsheng Lin.
+
+Fixes: e6247027e517 ("net: introduce dev_consume_skb_any()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Yunsheng Lin <linyunsheng@huawei.com>
+Reviewed-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 7a2a4650a8988..24eae99dfe05a 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3146,8 +3146,10 @@ void __dev_kfree_skb_any(struct sk_buff *skb, enum skb_free_reason reason)
+ {
+ if (in_hardirq() || irqs_disabled())
+ __dev_kfree_skb_irq(skb, reason);
++ else if (unlikely(reason == SKB_REASON_DROPPED))
++ kfree_skb(skb);
+ else
+- dev_kfree_skb(skb);
++ consume_skb(skb);
+ }
+ EXPORT_SYMBOL(__dev_kfree_skb_any);
+
+--
+2.39.2
+
--- /dev/null
+From f5e49d7472b4690478678031e0ee5bd155618444 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 20:12:05 +0200
+Subject: net/mlx5: ECPF, wait for VF pages only after disabling host PFs
+
+From: Maher Sanalla <msanalla@nvidia.com>
+
+[ Upstream commit e1ed30c8c09abc85a01c897845bdbd08c0333353 ]
+
+Currently, during the early stages of their unloading, particularly
+during SRIOV disablement, PFs/ECPFs wait on the release of all of
+their VFs memory pages. Furthermore, ECPFs are considered the page
+supplier for host VFs, hence the host VFs memory pages are freed only
+during ECPF cleanup when host interfaces get disabled.
+
+Thus, disabling SRIOV early in unload timeline causes the DPU ECPF
+to stall on driver unload while waiting on the release of host VF pages
+that won't be freed before host interfaces get disabled later on.
+
+Therefore, for ECPFs, wait on the release of VFs pages only after the
+disablement of host PFs during ECPF cleanup flow. Then, host PFs and VFs
+are disabled and their memory shall be freed accordingly.
+
+Fixes: 143a41d7623d ("net/mlx5: Disable SRIOV before PF removal")
+Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/ecpf.c | 4 ++++
+ drivers/net/ethernet/mellanox/mlx5/core/sriov.c | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ecpf.c b/drivers/net/ethernet/mellanox/mlx5/core/ecpf.c
+index cdc87ecae5d39..d000236ddbac5 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/ecpf.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/ecpf.c
+@@ -90,4 +90,8 @@ void mlx5_ec_cleanup(struct mlx5_core_dev *dev)
+ err = mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_HOST_PF]);
+ if (err)
+ mlx5_core_warn(dev, "Timeout reclaiming external host PF pages err(%d)\n", err);
++
++ err = mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_VF]);
++ if (err)
++ mlx5_core_warn(dev, "Timeout reclaiming external host VFs pages err(%d)\n", err);
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
+index 3008e9ce2bbff..20d7662c10fb6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
+@@ -147,6 +147,10 @@ mlx5_device_disable_sriov(struct mlx5_core_dev *dev, int num_vfs, bool clear_vf)
+
+ mlx5_eswitch_disable_sriov(dev->priv.eswitch, clear_vf);
+
++ /* For ECPFs, skip waiting for host VF pages until ECPF is destroyed */
++ if (mlx5_core_is_ecpf(dev))
++ return;
++
+ if (mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_VF]))
+ mlx5_core_warn(dev, "timeout reclaiming VFs pages\n");
+ }
+--
+2.39.2
+
--- /dev/null
+From 75d0d83444f50ed654fc0ddbf622a98e2473800d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 17:44:06 +0200
+Subject: net/mlx5: Geneve, Fix handling of Geneve object id as error code
+
+From: Maor Dickman <maord@nvidia.com>
+
+[ Upstream commit d28a06d7dbedc598a06bd1e53a28125f87ca5d0c ]
+
+On success, mlx5_geneve_tlv_option_create returns non negative
+Geneve object id. In case the object id is positive value the
+caller functions will handle it as an error (non zero) and
+will fail to offload the Geneve rule.
+
+Fix this by changing caller function ,mlx5_geneve_tlv_option_add,
+to return 0 in case valid non negative object id was provided.
+
+Fixes: 0ccc171ea6a2 ("net/mlx5: Geneve, Manage Geneve TLV options")
+Signed-off-by: Maor Dickman <maord@nvidia.com>
+Reviewed-by: Raed Salem <raeds@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c
+index 23361a9ae4fa0..6dc83e871cd76 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c
+@@ -105,6 +105,7 @@ int mlx5_geneve_tlv_option_add(struct mlx5_geneve *geneve, struct geneve_opt *op
+ geneve->opt_type = opt->type;
+ geneve->obj_id = res;
+ geneve->refcount++;
++ res = 0;
+ }
+
+ unlock:
+--
+2.39.2
+
--- /dev/null
+From 6a10b77191e706e61597a0ac54cad577fac19cc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 12:04:30 +0200
+Subject: net/mlx5e: Verify flow_source cap before using it
+
+From: Roi Dayan <roid@nvidia.com>
+
+[ Upstream commit 1bf8b0dae8dde6f02520a5ea34fdaa3b39342e69 ]
+
+When adding send to vport rule verify flow_source matching is
+supported by checking the flow_source cap.
+
+Fixes: d04442540372 ("net/mlx5: E-Switch, set flow source for send to uplink rule")
+Signed-off-by: Roi Dayan <roid@nvidia.com>
+Reviewed-by: Maor Dickman <maord@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index b4e263e8cfb87..235f6f0a70523 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -1043,7 +1043,8 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *on_esw,
+ dest.vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID;
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+
+- if (rep->vport == MLX5_VPORT_UPLINK)
++ if (MLX5_CAP_ESW_FLOWTABLE(on_esw->dev, flow_source) &&
++ rep->vport == MLX5_VPORT_UPLINK)
+ spec->flow_context.flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT;
+
+ flow_rule = mlx5_add_flow_rules(on_esw->fdb_table.offloads.slow_fdb,
+--
+2.39.2
+
--- /dev/null
+From 321eeda077da8b9a42666e7e55b42f367042bc7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 12:00:57 -0300
+Subject: net/sched: act_mpls: fix action bind logic
+
+From: Pedro Tammela <pctammela@mojatatu.com>
+
+[ Upstream commit e88d78a773cb5242e933930c8855bf4b2e8c2397 ]
+
+The TC architecture allows filters and actions to be created independently.
+In filters the user can reference action objects using:
+tc action add action mpls ... index 1
+tc filter add ... action mpls index 1
+
+In the current code for act_mpls this is broken as it checks netlink
+attributes for create/update before actually checking if we are binding to an
+existing action.
+
+tdc results:
+1..53
+ok 1 a933 - Add MPLS dec_ttl action with pipe opcode
+ok 2 08d1 - Add mpls dec_ttl action with pass opcode
+ok 3 d786 - Add mpls dec_ttl action with drop opcode
+ok 4 f334 - Add mpls dec_ttl action with reclassify opcode
+ok 5 29bd - Add mpls dec_ttl action with continue opcode
+ok 6 48df - Add mpls dec_ttl action with jump opcode
+ok 7 62eb - Add mpls dec_ttl action with trap opcode
+ok 8 09d2 - Add mpls dec_ttl action with opcode and cookie
+ok 9 c170 - Add mpls dec_ttl action with opcode and cookie of max length
+ok 10 9118 - Add mpls dec_ttl action with invalid opcode
+ok 11 6ce1 - Add mpls dec_ttl action with label (invalid)
+ok 12 352f - Add mpls dec_ttl action with tc (invalid)
+ok 13 fa1c - Add mpls dec_ttl action with ttl (invalid)
+ok 14 6b79 - Add mpls dec_ttl action with bos (invalid)
+ok 15 d4c4 - Add mpls pop action with ip proto
+ok 16 91fb - Add mpls pop action with ip proto and cookie
+ok 17 92fe - Add mpls pop action with mpls proto
+ok 18 7e23 - Add mpls pop action with no protocol (invalid)
+ok 19 6182 - Add mpls pop action with label (invalid)
+ok 20 6475 - Add mpls pop action with tc (invalid)
+ok 21 067b - Add mpls pop action with ttl (invalid)
+ok 22 7316 - Add mpls pop action with bos (invalid)
+ok 23 38cc - Add mpls push action with label
+ok 24 c281 - Add mpls push action with mpls_mc protocol
+ok 25 5db4 - Add mpls push action with label, tc and ttl
+ok 26 7c34 - Add mpls push action with label, tc ttl and cookie of max length
+ok 27 16eb - Add mpls push action with label and bos
+ok 28 d69d - Add mpls push action with no label (invalid)
+ok 29 e8e4 - Add mpls push action with ipv4 protocol (invalid)
+ok 30 ecd0 - Add mpls push action with out of range label (invalid)
+ok 31 d303 - Add mpls push action with out of range tc (invalid)
+ok 32 fd6e - Add mpls push action with ttl of 0 (invalid)
+ok 33 19e9 - Add mpls mod action with mpls label
+ok 34 1fde - Add mpls mod action with max mpls label
+ok 35 0c50 - Add mpls mod action with mpls label exceeding max (invalid)
+ok 36 10b6 - Add mpls mod action with mpls label of MPLS_LABEL_IMPLNULL (invalid)
+ok 37 57c9 - Add mpls mod action with mpls min tc
+ok 38 6872 - Add mpls mod action with mpls max tc
+ok 39 a70a - Add mpls mod action with mpls tc exceeding max (invalid)
+ok 40 6ed5 - Add mpls mod action with mpls ttl
+ok 41 77c1 - Add mpls mod action with mpls ttl and cookie
+ok 42 b80f - Add mpls mod action with mpls max ttl
+ok 43 8864 - Add mpls mod action with mpls min ttl
+ok 44 6c06 - Add mpls mod action with mpls ttl of 0 (invalid)
+ok 45 b5d8 - Add mpls mod action with mpls ttl exceeding max (invalid)
+ok 46 451f - Add mpls mod action with mpls max bos
+ok 47 a1ed - Add mpls mod action with mpls min bos
+ok 48 3dcf - Add mpls mod action with mpls bos exceeding max (invalid)
+ok 49 db7c - Add mpls mod action with protocol (invalid)
+ok 50 b070 - Replace existing mpls push action with new ID
+ok 51 95a9 - Replace existing mpls push action with new label, tc, ttl and cookie
+ok 52 6cce - Delete mpls pop action
+ok 53 d138 - Flush mpls actions
+
+Fixes: 2a2ea50870ba ("net: sched: add mpls manipulation actions to TC")
+Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_mpls.c | 66 +++++++++++++++++++++++++-------------------
+ 1 file changed, 37 insertions(+), 29 deletions(-)
+
+diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c
+index ea5959094adb0..f24f997a7aaf9 100644
+--- a/net/sched/act_mpls.c
++++ b/net/sched/act_mpls.c
+@@ -188,40 +188,67 @@ static int tcf_mpls_init(struct net *net, struct nlattr *nla,
+ parm = nla_data(tb[TCA_MPLS_PARMS]);
+ index = parm->index;
+
++ err = tcf_idr_check_alloc(tn, &index, a, bind);
++ if (err < 0)
++ return err;
++ exists = err;
++ if (exists && bind)
++ return 0;
++
++ if (!exists) {
++ ret = tcf_idr_create(tn, index, est, a, &act_mpls_ops, bind,
++ true, flags);
++ if (ret) {
++ tcf_idr_cleanup(tn, index);
++ return ret;
++ }
++
++ ret = ACT_P_CREATED;
++ } else if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
++ tcf_idr_release(*a, bind);
++ return -EEXIST;
++ }
++
+ /* Verify parameters against action type. */
+ switch (parm->m_action) {
+ case TCA_MPLS_ACT_POP:
+ if (!tb[TCA_MPLS_PROTO]) {
+ NL_SET_ERR_MSG_MOD(extack, "Protocol must be set for MPLS pop");
+- return -EINVAL;
++ err = -EINVAL;
++ goto release_idr;
+ }
+ if (!eth_proto_is_802_3(nla_get_be16(tb[TCA_MPLS_PROTO]))) {
+ NL_SET_ERR_MSG_MOD(extack, "Invalid protocol type for MPLS pop");
+- return -EINVAL;
++ err = -EINVAL;
++ goto release_idr;
+ }
+ if (tb[TCA_MPLS_LABEL] || tb[TCA_MPLS_TTL] || tb[TCA_MPLS_TC] ||
+ tb[TCA_MPLS_BOS]) {
+ NL_SET_ERR_MSG_MOD(extack, "Label, TTL, TC or BOS cannot be used with MPLS pop");
+- return -EINVAL;
++ err = -EINVAL;
++ goto release_idr;
+ }
+ break;
+ case TCA_MPLS_ACT_DEC_TTL:
+ if (tb[TCA_MPLS_PROTO] || tb[TCA_MPLS_LABEL] ||
+ tb[TCA_MPLS_TTL] || tb[TCA_MPLS_TC] || tb[TCA_MPLS_BOS]) {
+ NL_SET_ERR_MSG_MOD(extack, "Label, TTL, TC, BOS or protocol cannot be used with MPLS dec_ttl");
+- return -EINVAL;
++ err = -EINVAL;
++ goto release_idr;
+ }
+ break;
+ case TCA_MPLS_ACT_PUSH:
+ case TCA_MPLS_ACT_MAC_PUSH:
+ if (!tb[TCA_MPLS_LABEL]) {
+ NL_SET_ERR_MSG_MOD(extack, "Label is required for MPLS push");
+- return -EINVAL;
++ err = -EINVAL;
++ goto release_idr;
+ }
+ if (tb[TCA_MPLS_PROTO] &&
+ !eth_p_mpls(nla_get_be16(tb[TCA_MPLS_PROTO]))) {
+ NL_SET_ERR_MSG_MOD(extack, "Protocol must be an MPLS type for MPLS push");
+- return -EPROTONOSUPPORT;
++ err = -EPROTONOSUPPORT;
++ goto release_idr;
+ }
+ /* Push needs a TTL - if not specified, set a default value. */
+ if (!tb[TCA_MPLS_TTL]) {
+@@ -236,33 +263,14 @@ static int tcf_mpls_init(struct net *net, struct nlattr *nla,
+ case TCA_MPLS_ACT_MODIFY:
+ if (tb[TCA_MPLS_PROTO]) {
+ NL_SET_ERR_MSG_MOD(extack, "Protocol cannot be used with MPLS modify");
+- return -EINVAL;
++ err = -EINVAL;
++ goto release_idr;
+ }
+ break;
+ default:
+ NL_SET_ERR_MSG_MOD(extack, "Unknown MPLS action");
+- return -EINVAL;
+- }
+-
+- err = tcf_idr_check_alloc(tn, &index, a, bind);
+- if (err < 0)
+- return err;
+- exists = err;
+- if (exists && bind)
+- return 0;
+-
+- if (!exists) {
+- ret = tcf_idr_create(tn, index, est, a,
+- &act_mpls_ops, bind, true, flags);
+- if (ret) {
+- tcf_idr_cleanup(tn, index);
+- return ret;
+- }
+-
+- ret = ACT_P_CREATED;
+- } else if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
+- tcf_idr_release(*a, bind);
+- return -EEXIST;
++ err = -EINVAL;
++ goto release_idr;
+ }
+
+ err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
+--
+2.39.2
+
--- /dev/null
+From 138edb6022de3c68427f2efdb7bd3a3a81f19865 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 12:00:56 -0300
+Subject: net/sched: act_pedit: fix action bind logic
+
+From: Pedro Tammela <pctammela@mojatatu.com>
+
+[ Upstream commit e9e42292ea76a8358b0c02ffd530d78e133a1b73 ]
+
+The TC architecture allows filters and actions to be created independently.
+In filters the user can reference action objects using:
+tc action add action pedit ... index 1
+tc filter add ... action pedit index 1
+
+In the current code for act_pedit this is broken as it checks netlink
+attributes for create/update before actually checking if we are binding to an
+existing action.
+
+tdc results:
+1..69
+ok 1 319a - Add pedit action that mangles IP TTL
+ok 2 7e67 - Replace pedit action with invalid goto chain
+ok 3 377e - Add pedit action with RAW_OP offset u32
+ok 4 a0ca - Add pedit action with RAW_OP offset u32 (INVALID)
+ok 5 dd8a - Add pedit action with RAW_OP offset u16 u16
+ok 6 53db - Add pedit action with RAW_OP offset u16 (INVALID)
+ok 7 5c7e - Add pedit action with RAW_OP offset u8 add value
+ok 8 2893 - Add pedit action with RAW_OP offset u8 quad
+ok 9 3a07 - Add pedit action with RAW_OP offset u8-u16-u8
+ok 10 ab0f - Add pedit action with RAW_OP offset u16-u8-u8
+ok 11 9d12 - Add pedit action with RAW_OP offset u32 set u16 clear u8 invert
+ok 12 ebfa - Add pedit action with RAW_OP offset overflow u32 (INVALID)
+ok 13 f512 - Add pedit action with RAW_OP offset u16 at offmask shift set
+ok 14 c2cb - Add pedit action with RAW_OP offset u32 retain value
+ok 15 1762 - Add pedit action with RAW_OP offset u8 clear value
+ok 16 bcee - Add pedit action with RAW_OP offset u8 retain value
+ok 17 e89f - Add pedit action with RAW_OP offset u16 retain value
+ok 18 c282 - Add pedit action with RAW_OP offset u32 clear value
+ok 19 c422 - Add pedit action with RAW_OP offset u16 invert value
+ok 20 d3d3 - Add pedit action with RAW_OP offset u32 invert value
+ok 21 57e5 - Add pedit action with RAW_OP offset u8 preserve value
+ok 22 99e0 - Add pedit action with RAW_OP offset u16 preserve value
+ok 23 1892 - Add pedit action with RAW_OP offset u32 preserve value
+ok 24 4b60 - Add pedit action with RAW_OP negative offset u16/u32 set value
+ok 25 a5a7 - Add pedit action with LAYERED_OP eth set src
+ok 26 86d4 - Add pedit action with LAYERED_OP eth set src & dst
+ok 27 f8a9 - Add pedit action with LAYERED_OP eth set dst
+ok 28 c715 - Add pedit action with LAYERED_OP eth set src (INVALID)
+ok 29 8131 - Add pedit action with LAYERED_OP eth set dst (INVALID)
+ok 30 ba22 - Add pedit action with LAYERED_OP eth type set/clear sequence
+ok 31 dec4 - Add pedit action with LAYERED_OP eth set type (INVALID)
+ok 32 ab06 - Add pedit action with LAYERED_OP eth add type
+ok 33 918d - Add pedit action with LAYERED_OP eth invert src
+ok 34 a8d4 - Add pedit action with LAYERED_OP eth invert dst
+ok 35 ee13 - Add pedit action with LAYERED_OP eth invert type
+ok 36 7588 - Add pedit action with LAYERED_OP ip set src
+ok 37 0fa7 - Add pedit action with LAYERED_OP ip set dst
+ok 38 5810 - Add pedit action with LAYERED_OP ip set src & dst
+ok 39 1092 - Add pedit action with LAYERED_OP ip set ihl & dsfield
+ok 40 02d8 - Add pedit action with LAYERED_OP ip set ttl & protocol
+ok 41 3e2d - Add pedit action with LAYERED_OP ip set ttl (INVALID)
+ok 42 31ae - Add pedit action with LAYERED_OP ip ttl clear/set
+ok 43 486f - Add pedit action with LAYERED_OP ip set duplicate fields
+ok 44 e790 - Add pedit action with LAYERED_OP ip set ce, df, mf, firstfrag, nofrag fields
+ok 45 cc8a - Add pedit action with LAYERED_OP ip set tos
+ok 46 7a17 - Add pedit action with LAYERED_OP ip set precedence
+ok 47 c3b6 - Add pedit action with LAYERED_OP ip add tos
+ok 48 43d3 - Add pedit action with LAYERED_OP ip add precedence
+ok 49 438e - Add pedit action with LAYERED_OP ip clear tos
+ok 50 6b1b - Add pedit action with LAYERED_OP ip clear precedence
+ok 51 824a - Add pedit action with LAYERED_OP ip invert tos
+ok 52 106f - Add pedit action with LAYERED_OP ip invert precedence
+ok 53 6829 - Add pedit action with LAYERED_OP beyond ip set dport & sport
+ok 54 afd8 - Add pedit action with LAYERED_OP beyond ip set icmp_type & icmp_code
+ok 55 3143 - Add pedit action with LAYERED_OP beyond ip set dport (INVALID)
+ok 56 815c - Add pedit action with LAYERED_OP ip6 set src
+ok 57 4dae - Add pedit action with LAYERED_OP ip6 set dst
+ok 58 fc1f - Add pedit action with LAYERED_OP ip6 set src & dst
+ok 59 6d34 - Add pedit action with LAYERED_OP ip6 dst retain value (INVALID)
+ok 60 94bb - Add pedit action with LAYERED_OP ip6 traffic_class
+ok 61 6f5e - Add pedit action with LAYERED_OP ip6 flow_lbl
+ok 62 6795 - Add pedit action with LAYERED_OP ip6 set payload_len, nexthdr, hoplimit
+ok 63 1442 - Add pedit action with LAYERED_OP tcp set dport & sport
+ok 64 b7ac - Add pedit action with LAYERED_OP tcp sport set (INVALID)
+ok 65 cfcc - Add pedit action with LAYERED_OP tcp flags set
+ok 66 3bc4 - Add pedit action with LAYERED_OP tcp set dport, sport & flags fields
+ok 67 f1c8 - Add pedit action with LAYERED_OP udp set dport & sport
+ok 68 d784 - Add pedit action with mixed RAW/LAYERED_OP #1
+ok 69 70ca - Add pedit action with mixed RAW/LAYERED_OP #2
+
+Fixes: 71d0ed7079df ("net/act_pedit: Support using offset relative to the conventional network headers")
+Fixes: f67169fef8db ("net/sched: act_pedit: fix WARN() in the traffic path")
+Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_pedit.c | 58 +++++++++++++++++++++++--------------------
+ 1 file changed, 31 insertions(+), 27 deletions(-)
+
+diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
+index 655addb31b7f3..238759c3192e8 100644
+--- a/net/sched/act_pedit.c
++++ b/net/sched/act_pedit.c
+@@ -180,26 +180,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ }
+
+ parm = nla_data(pattr);
+- if (!parm->nkeys) {
+- NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed");
+- return -EINVAL;
+- }
+- ksize = parm->nkeys * sizeof(struct tc_pedit_key);
+- if (nla_len(pattr) < sizeof(*parm) + ksize) {
+- NL_SET_ERR_MSG_ATTR(extack, pattr, "Length of TCA_PEDIT_PARMS or TCA_PEDIT_PARMS_EX pedit attribute is invalid");
+- return -EINVAL;
+- }
+-
+- nparms = kzalloc(sizeof(*nparms), GFP_KERNEL);
+- if (!nparms)
+- return -ENOMEM;
+-
+- nparms->tcfp_keys_ex =
+- tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys);
+- if (IS_ERR(nparms->tcfp_keys_ex)) {
+- ret = PTR_ERR(nparms->tcfp_keys_ex);
+- goto out_free;
+- }
+
+ index = parm->index;
+ err = tcf_idr_check_alloc(tn, &index, a, bind);
+@@ -208,25 +188,49 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ &act_pedit_ops, bind, flags);
+ if (ret) {
+ tcf_idr_cleanup(tn, index);
+- goto out_free_ex;
++ return ret;
+ }
+ ret = ACT_P_CREATED;
+ } else if (err > 0) {
+ if (bind)
+- goto out_free;
++ return 0;
+ if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
+ ret = -EEXIST;
+ goto out_release;
+ }
+ } else {
+- ret = err;
+- goto out_free_ex;
++ return err;
++ }
++
++ if (!parm->nkeys) {
++ NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed");
++ ret = -EINVAL;
++ goto out_release;
++ }
++ ksize = parm->nkeys * sizeof(struct tc_pedit_key);
++ if (nla_len(pattr) < sizeof(*parm) + ksize) {
++ NL_SET_ERR_MSG_ATTR(extack, pattr, "Length of TCA_PEDIT_PARMS or TCA_PEDIT_PARMS_EX pedit attribute is invalid");
++ ret = -EINVAL;
++ goto out_release;
++ }
++
++ nparms = kzalloc(sizeof(*nparms), GFP_KERNEL);
++ if (!nparms) {
++ ret = -ENOMEM;
++ goto out_release;
++ }
++
++ nparms->tcfp_keys_ex =
++ tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys);
++ if (IS_ERR(nparms->tcfp_keys_ex)) {
++ ret = PTR_ERR(nparms->tcfp_keys_ex);
++ goto out_free;
+ }
+
+ err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
+ if (err < 0) {
+ ret = err;
+- goto out_release;
++ goto out_free_ex;
+ }
+
+ nparms->tcfp_off_max_hint = 0;
+@@ -277,12 +281,12 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ put_chain:
+ if (goto_ch)
+ tcf_chain_put_by_act(goto_ch);
+-out_release:
+- tcf_idr_release(*a, bind);
+ out_free_ex:
+ kfree(nparms->tcfp_keys_ex);
+ out_free:
+ kfree(nparms);
++out_release:
++ tcf_idr_release(*a, bind);
+ return ret;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 6ab2c1dd08808a8f2fb551611a165a9bc82d0bb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 12:00:58 -0300
+Subject: net/sched: act_sample: fix action bind logic
+
+From: Pedro Tammela <pctammela@mojatatu.com>
+
+[ Upstream commit 4a20056a49a1854966562241922f68197f950539 ]
+
+The TC architecture allows filters and actions to be created independently.
+In filters the user can reference action objects using:
+tc action add action sample ... index 1
+tc filter add ... action pedit index 1
+
+In the current code for act_sample this is broken as it checks netlink
+attributes for create/update before actually checking if we are binding to an
+existing action.
+
+tdc results:
+1..29
+ok 1 9784 - Add valid sample action with mandatory arguments
+ok 2 5c91 - Add valid sample action with mandatory arguments and continue control action
+ok 3 334b - Add valid sample action with mandatory arguments and drop control action
+ok 4 da69 - Add valid sample action with mandatory arguments and reclassify control action
+ok 5 13ce - Add valid sample action with mandatory arguments and pipe control action
+ok 6 1886 - Add valid sample action with mandatory arguments and jump control action
+ok 7 7571 - Add sample action with invalid rate
+ok 8 b6d4 - Add sample action with mandatory arguments and invalid control action
+ok 9 a874 - Add invalid sample action without mandatory arguments
+ok 10 ac01 - Add invalid sample action without mandatory argument rate
+ok 11 4203 - Add invalid sample action without mandatory argument group
+ok 12 14a7 - Add invalid sample action without mandatory argument group
+ok 13 8f2e - Add valid sample action with trunc argument
+ok 14 45f8 - Add sample action with maximum rate argument
+ok 15 ad0c - Add sample action with maximum trunc argument
+ok 16 83a9 - Add sample action with maximum group argument
+ok 17 ed27 - Add sample action with invalid rate argument
+ok 18 2eae - Add sample action with invalid group argument
+ok 19 6ff3 - Add sample action with invalid trunc size
+ok 20 2b2a - Add sample action with invalid index
+ok 21 dee2 - Add sample action with maximum allowed index
+ok 22 560e - Add sample action with cookie
+ok 23 704a - Replace existing sample action with new rate argument
+ok 24 60eb - Replace existing sample action with new group argument
+ok 25 2cce - Replace existing sample action with new trunc argument
+ok 26 59d1 - Replace existing sample action with new control argument
+ok 27 0a6e - Replace sample action with invalid goto chain control
+ok 28 3872 - Delete sample action with valid index
+ok 29 a394 - Delete sample action with invalid index
+
+Fixes: 5c5670fae430 ("net/sched: Introduce sample tc action")
+Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_sample.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
+index 7a25477f5d996..09735a33e57e2 100644
+--- a/net/sched/act_sample.c
++++ b/net/sched/act_sample.c
+@@ -54,8 +54,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
+ sample_policy, NULL);
+ if (ret < 0)
+ return ret;
+- if (!tb[TCA_SAMPLE_PARMS] || !tb[TCA_SAMPLE_RATE] ||
+- !tb[TCA_SAMPLE_PSAMPLE_GROUP])
++
++ if (!tb[TCA_SAMPLE_PARMS])
+ return -EINVAL;
+
+ parm = nla_data(tb[TCA_SAMPLE_PARMS]);
+@@ -79,6 +79,13 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
+ tcf_idr_release(*a, bind);
+ return -EEXIST;
+ }
++
++ if (!tb[TCA_SAMPLE_RATE] || !tb[TCA_SAMPLE_PSAMPLE_GROUP]) {
++ NL_SET_ERR_MSG(extack, "sample rate and group are required");
++ err = -EINVAL;
++ goto release_idr;
++ }
++
+ err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
+ if (err < 0)
+ goto release_idr;
+--
+2.39.2
+
--- /dev/null
+From 0b7701602d1c638232a6ced3e4fc7a25d4f820a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 16:05:11 -0300
+Subject: net/sched: transition act_pedit to rcu and percpu stats
+
+From: Pedro Tammela <pctammela@mojatatu.com>
+
+[ Upstream commit 52cf89f78c01bf39973f3e70d366921d70faff7a ]
+
+The software pedit action didn't get the same love as some of the
+other actions and it's still using spinlocks and shared stats in the
+datapath.
+Transition the action to rcu and percpu stats as this improves the
+action's performance dramatically on multiple cpu deployments.
+
+Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: e9e42292ea76 ("net/sched: act_pedit: fix action bind logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tc_act/tc_pedit.h | 81 +++++++++++++++----
+ net/sched/act_pedit.c | 148 ++++++++++++++++++++--------------
+ 2 files changed, 153 insertions(+), 76 deletions(-)
+
+diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h
+index 3e02709a1df65..83fe399317818 100644
+--- a/include/net/tc_act/tc_pedit.h
++++ b/include/net/tc_act/tc_pedit.h
+@@ -4,22 +4,29 @@
+
+ #include <net/act_api.h>
+ #include <linux/tc_act/tc_pedit.h>
++#include <linux/types.h>
+
+ struct tcf_pedit_key_ex {
+ enum pedit_header_type htype;
+ enum pedit_cmd cmd;
+ };
+
+-struct tcf_pedit {
+- struct tc_action common;
+- unsigned char tcfp_nkeys;
+- unsigned char tcfp_flags;
+- u32 tcfp_off_max_hint;
++struct tcf_pedit_parms {
+ struct tc_pedit_key *tcfp_keys;
+ struct tcf_pedit_key_ex *tcfp_keys_ex;
++ u32 tcfp_off_max_hint;
++ unsigned char tcfp_nkeys;
++ unsigned char tcfp_flags;
++ struct rcu_head rcu;
++};
++
++struct tcf_pedit {
++ struct tc_action common;
++ struct tcf_pedit_parms __rcu *parms;
+ };
+
+ #define to_pedit(a) ((struct tcf_pedit *)a)
++#define to_pedit_parms(a) (rcu_dereference(to_pedit(a)->parms))
+
+ static inline bool is_tcf_pedit(const struct tc_action *a)
+ {
+@@ -32,37 +39,81 @@ static inline bool is_tcf_pedit(const struct tc_action *a)
+
+ static inline int tcf_pedit_nkeys(const struct tc_action *a)
+ {
+- return to_pedit(a)->tcfp_nkeys;
++ struct tcf_pedit_parms *parms;
++ int nkeys;
++
++ rcu_read_lock();
++ parms = to_pedit_parms(a);
++ nkeys = parms->tcfp_nkeys;
++ rcu_read_unlock();
++
++ return nkeys;
+ }
+
+ static inline u32 tcf_pedit_htype(const struct tc_action *a, int index)
+ {
+- if (to_pedit(a)->tcfp_keys_ex)
+- return to_pedit(a)->tcfp_keys_ex[index].htype;
++ u32 htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
++ struct tcf_pedit_parms *parms;
++
++ rcu_read_lock();
++ parms = to_pedit_parms(a);
++ if (parms->tcfp_keys_ex)
++ htype = parms->tcfp_keys_ex[index].htype;
++ rcu_read_unlock();
+
+- return TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
++ return htype;
+ }
+
+ static inline u32 tcf_pedit_cmd(const struct tc_action *a, int index)
+ {
+- if (to_pedit(a)->tcfp_keys_ex)
+- return to_pedit(a)->tcfp_keys_ex[index].cmd;
++ struct tcf_pedit_parms *parms;
++ u32 cmd = __PEDIT_CMD_MAX;
+
+- return __PEDIT_CMD_MAX;
++ rcu_read_lock();
++ parms = to_pedit_parms(a);
++ if (parms->tcfp_keys_ex)
++ cmd = parms->tcfp_keys_ex[index].cmd;
++ rcu_read_unlock();
++
++ return cmd;
+ }
+
+ static inline u32 tcf_pedit_mask(const struct tc_action *a, int index)
+ {
+- return to_pedit(a)->tcfp_keys[index].mask;
++ struct tcf_pedit_parms *parms;
++ u32 mask;
++
++ rcu_read_lock();
++ parms = to_pedit_parms(a);
++ mask = parms->tcfp_keys[index].mask;
++ rcu_read_unlock();
++
++ return mask;
+ }
+
+ static inline u32 tcf_pedit_val(const struct tc_action *a, int index)
+ {
+- return to_pedit(a)->tcfp_keys[index].val;
++ struct tcf_pedit_parms *parms;
++ u32 val;
++
++ rcu_read_lock();
++ parms = to_pedit_parms(a);
++ val = parms->tcfp_keys[index].val;
++ rcu_read_unlock();
++
++ return val;
+ }
+
+ static inline u32 tcf_pedit_offset(const struct tc_action *a, int index)
+ {
+- return to_pedit(a)->tcfp_keys[index].off;
++ struct tcf_pedit_parms *parms;
++ u32 off;
++
++ rcu_read_lock();
++ parms = to_pedit_parms(a);
++ off = parms->tcfp_keys[index].off;
++ rcu_read_unlock();
++
++ return off;
+ }
+ #endif /* __NET_TC_PED_H */
+diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
+index 94ed5857ce678..655addb31b7f3 100644
+--- a/net/sched/act_pedit.c
++++ b/net/sched/act_pedit.c
+@@ -133,6 +133,17 @@ static int tcf_pedit_key_ex_dump(struct sk_buff *skb,
+ return -EINVAL;
+ }
+
++static void tcf_pedit_cleanup_rcu(struct rcu_head *head)
++{
++ struct tcf_pedit_parms *parms =
++ container_of(head, struct tcf_pedit_parms, rcu);
++
++ kfree(parms->tcfp_keys_ex);
++ kfree(parms->tcfp_keys);
++
++ kfree(parms);
++}
++
+ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ struct nlattr *est, struct tc_action **a,
+ struct tcf_proto *tp, u32 flags,
+@@ -140,10 +151,9 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ {
+ struct tc_action_net *tn = net_generic(net, act_pedit_ops.net_id);
+ bool bind = flags & TCA_ACT_FLAGS_BIND;
+- struct nlattr *tb[TCA_PEDIT_MAX + 1];
+ struct tcf_chain *goto_ch = NULL;
+- struct tc_pedit_key *keys = NULL;
+- struct tcf_pedit_key_ex *keys_ex;
++ struct tcf_pedit_parms *oparms, *nparms;
++ struct nlattr *tb[TCA_PEDIT_MAX + 1];
+ struct tc_pedit *parm;
+ struct nlattr *pattr;
+ struct tcf_pedit *p;
+@@ -180,18 +190,25 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ return -EINVAL;
+ }
+
+- keys_ex = tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys);
+- if (IS_ERR(keys_ex))
+- return PTR_ERR(keys_ex);
++ nparms = kzalloc(sizeof(*nparms), GFP_KERNEL);
++ if (!nparms)
++ return -ENOMEM;
++
++ nparms->tcfp_keys_ex =
++ tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys);
++ if (IS_ERR(nparms->tcfp_keys_ex)) {
++ ret = PTR_ERR(nparms->tcfp_keys_ex);
++ goto out_free;
++ }
+
+ index = parm->index;
+ err = tcf_idr_check_alloc(tn, &index, a, bind);
+ if (!err) {
+- ret = tcf_idr_create(tn, index, est, a,
+- &act_pedit_ops, bind, false, flags);
++ ret = tcf_idr_create_from_flags(tn, index, est, a,
++ &act_pedit_ops, bind, flags);
+ if (ret) {
+ tcf_idr_cleanup(tn, index);
+- goto out_free;
++ goto out_free_ex;
+ }
+ ret = ACT_P_CREATED;
+ } else if (err > 0) {
+@@ -203,7 +220,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ }
+ } else {
+ ret = err;
+- goto out_free;
++ goto out_free_ex;
+ }
+
+ err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
+@@ -211,48 +228,50 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ ret = err;
+ goto out_release;
+ }
+- p = to_pedit(*a);
+- spin_lock_bh(&p->tcf_lock);
+
+- if (ret == ACT_P_CREATED ||
+- (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys)) {
+- keys = kmalloc(ksize, GFP_ATOMIC);
+- if (!keys) {
+- spin_unlock_bh(&p->tcf_lock);
+- ret = -ENOMEM;
+- goto put_chain;
+- }
+- kfree(p->tcfp_keys);
+- p->tcfp_keys = keys;
+- p->tcfp_nkeys = parm->nkeys;
++ nparms->tcfp_off_max_hint = 0;
++ nparms->tcfp_flags = parm->flags;
++ nparms->tcfp_nkeys = parm->nkeys;
++
++ nparms->tcfp_keys = kmalloc(ksize, GFP_KERNEL);
++ if (!nparms->tcfp_keys) {
++ ret = -ENOMEM;
++ goto put_chain;
+ }
+- memcpy(p->tcfp_keys, parm->keys, ksize);
+- p->tcfp_off_max_hint = 0;
+- for (i = 0; i < p->tcfp_nkeys; ++i) {
+- u32 cur = p->tcfp_keys[i].off;
++
++ memcpy(nparms->tcfp_keys, parm->keys, ksize);
++
++ for (i = 0; i < nparms->tcfp_nkeys; ++i) {
++ u32 cur = nparms->tcfp_keys[i].off;
+
+ /* sanitize the shift value for any later use */
+- p->tcfp_keys[i].shift = min_t(size_t, BITS_PER_TYPE(int) - 1,
+- p->tcfp_keys[i].shift);
++ nparms->tcfp_keys[i].shift = min_t(size_t,
++ BITS_PER_TYPE(int) - 1,
++ nparms->tcfp_keys[i].shift);
+
+ /* The AT option can read a single byte, we can bound the actual
+ * value with uchar max.
+ */
+- cur += (0xff & p->tcfp_keys[i].offmask) >> p->tcfp_keys[i].shift;
++ cur += (0xff & nparms->tcfp_keys[i].offmask) >> nparms->tcfp_keys[i].shift;
+
+ /* Each key touches 4 bytes starting from the computed offset */
+- p->tcfp_off_max_hint = max(p->tcfp_off_max_hint, cur + 4);
++ nparms->tcfp_off_max_hint =
++ max(nparms->tcfp_off_max_hint, cur + 4);
+ }
+
+- p->tcfp_flags = parm->flags;
++ p = to_pedit(*a);
++
++ spin_lock_bh(&p->tcf_lock);
+ goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
++ oparms = rcu_replace_pointer(p->parms, nparms, 1);
++ spin_unlock_bh(&p->tcf_lock);
+
+- kfree(p->tcfp_keys_ex);
+- p->tcfp_keys_ex = keys_ex;
++ if (oparms)
++ call_rcu(&oparms->rcu, tcf_pedit_cleanup_rcu);
+
+- spin_unlock_bh(&p->tcf_lock);
+ if (goto_ch)
+ tcf_chain_put_by_act(goto_ch);
++
+ return ret;
+
+ put_chain:
+@@ -260,19 +279,22 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
+ tcf_chain_put_by_act(goto_ch);
+ out_release:
+ tcf_idr_release(*a, bind);
++out_free_ex:
++ kfree(nparms->tcfp_keys_ex);
+ out_free:
+- kfree(keys_ex);
++ kfree(nparms);
+ return ret;
+-
+ }
+
+ static void tcf_pedit_cleanup(struct tc_action *a)
+ {
+ struct tcf_pedit *p = to_pedit(a);
+- struct tc_pedit_key *keys = p->tcfp_keys;
++ struct tcf_pedit_parms *parms;
+
+- kfree(keys);
+- kfree(p->tcfp_keys_ex);
++ parms = rcu_dereference_protected(p->parms, 1);
++
++ if (parms)
++ call_rcu(&parms->rcu, tcf_pedit_cleanup_rcu);
+ }
+
+ static bool offset_valid(struct sk_buff *skb, int offset)
+@@ -323,28 +345,30 @@ static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a,
+ struct tcf_result *res)
+ {
+ struct tcf_pedit *p = to_pedit(a);
++ struct tcf_pedit_parms *parms;
+ u32 max_offset;
+ int i;
+
+- spin_lock(&p->tcf_lock);
++ parms = rcu_dereference_bh(p->parms);
+
+ max_offset = (skb_transport_header_was_set(skb) ?
+ skb_transport_offset(skb) :
+ skb_network_offset(skb)) +
+- p->tcfp_off_max_hint;
++ parms->tcfp_off_max_hint;
+ if (skb_ensure_writable(skb, min(skb->len, max_offset)))
+- goto unlock;
++ goto done;
+
+ tcf_lastuse_update(&p->tcf_tm);
++ tcf_action_update_bstats(&p->common, skb);
+
+- if (p->tcfp_nkeys > 0) {
+- struct tc_pedit_key *tkey = p->tcfp_keys;
+- struct tcf_pedit_key_ex *tkey_ex = p->tcfp_keys_ex;
++ if (parms->tcfp_nkeys > 0) {
++ struct tc_pedit_key *tkey = parms->tcfp_keys;
++ struct tcf_pedit_key_ex *tkey_ex = parms->tcfp_keys_ex;
+ enum pedit_header_type htype =
+ TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
+ enum pedit_cmd cmd = TCA_PEDIT_KEY_EX_CMD_SET;
+
+- for (i = p->tcfp_nkeys; i > 0; i--, tkey++) {
++ for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) {
+ u32 *ptr, hdata;
+ int offset = tkey->off;
+ int hoffset;
+@@ -420,11 +444,10 @@ static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a,
+ }
+
+ bad:
++ spin_lock(&p->tcf_lock);
+ p->tcf_qstats.overlimits++;
+-done:
+- bstats_update(&p->tcf_bstats, skb);
+-unlock:
+ spin_unlock(&p->tcf_lock);
++done:
+ return p->tcf_action;
+ }
+
+@@ -443,30 +466,33 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
+ {
+ unsigned char *b = skb_tail_pointer(skb);
+ struct tcf_pedit *p = to_pedit(a);
++ struct tcf_pedit_parms *parms;
+ struct tc_pedit *opt;
+ struct tcf_t t;
+ int s;
+
+- s = struct_size(opt, keys, p->tcfp_nkeys);
++ spin_lock_bh(&p->tcf_lock);
++ parms = rcu_dereference_protected(p->parms, 1);
++ s = struct_size(opt, keys, parms->tcfp_nkeys);
+
+- /* netlink spinlocks held above us - must use ATOMIC */
+ opt = kzalloc(s, GFP_ATOMIC);
+- if (unlikely(!opt))
++ if (unlikely(!opt)) {
++ spin_unlock_bh(&p->tcf_lock);
+ return -ENOBUFS;
++ }
+
+- spin_lock_bh(&p->tcf_lock);
+- memcpy(opt->keys, p->tcfp_keys, flex_array_size(opt, keys, p->tcfp_nkeys));
++ memcpy(opt->keys, parms->tcfp_keys,
++ flex_array_size(opt, keys, parms->tcfp_nkeys));
+ opt->index = p->tcf_index;
+- opt->nkeys = p->tcfp_nkeys;
+- opt->flags = p->tcfp_flags;
++ opt->nkeys = parms->tcfp_nkeys;
++ opt->flags = parms->tcfp_flags;
+ opt->action = p->tcf_action;
+ opt->refcnt = refcount_read(&p->tcf_refcnt) - ref;
+ opt->bindcnt = atomic_read(&p->tcf_bindcnt) - bind;
+
+- if (p->tcfp_keys_ex) {
+- if (tcf_pedit_key_ex_dump(skb,
+- p->tcfp_keys_ex,
+- p->tcfp_nkeys))
++ if (parms->tcfp_keys_ex) {
++ if (tcf_pedit_key_ex_dump(skb, parms->tcfp_keys_ex,
++ parms->tcfp_nkeys))
+ goto nla_put_failure;
+
+ if (nla_put(skb, TCA_PEDIT_PARMS_EX, s, opt))
+--
+2.39.2
+
--- /dev/null
+From 74d05a1fb2d3a3f777a11490004926c158ed97cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Feb 2023 15:42:41 -0500
+Subject: net: sunhme: Fix region request
+
+From: Sean Anderson <seanga2@gmail.com>
+
+[ Upstream commit ee0a735fd97ccde766ab557d1fc722c92cebacda ]
+
+devm_request_region is for I/O regions. Use devm_request_mem_region
+instead. This fixes the driver failing to probe since 99df45c9e0a4
+("sunhme: fix an IS_ERR() vs NULL check in probe"), which checked the
+result.
+
+Fixes: 914d9b2711dd ("sunhme: switch to devres")
+Signed-off-by: Sean Anderson <seanga2@gmail.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Link: https://lore.kernel.org/r/20230222204242.2658247-1-seanga2@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/sun/sunhme.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
+index 1c16548415cdd..b0c7ab74a82ed 100644
+--- a/drivers/net/ethernet/sun/sunhme.c
++++ b/drivers/net/ethernet/sun/sunhme.c
+@@ -2894,8 +2894,10 @@ static int happy_meal_pci_probe(struct pci_dev *pdev,
+ goto err_out_clear_quattro;
+ }
+
+- hpreg_res = devm_request_region(&pdev->dev, pci_resource_start(pdev, 0),
+- pci_resource_len(pdev, 0), DRV_NAME);
++ hpreg_res = devm_request_mem_region(&pdev->dev,
++ pci_resource_start(pdev, 0),
++ pci_resource_len(pdev, 0),
++ DRV_NAME);
+ if (!hpreg_res) {
+ err = -EBUSY;
+ dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting.\n");
+--
+2.39.2
+
--- /dev/null
+From bdb64914ab09c77dba1682633091852ad8f39af0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 17:23:59 +0100
+Subject: netfilter: conntrack: fix rmmod double-free race
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit e6d57e9ff0aec323717ee36fc9ea34ad89217151 ]
+
+nf_conntrack_hash_check_insert() callers free the ct entry directly, via
+nf_conntrack_free.
+
+This isn't safe anymore because
+nf_conntrack_hash_check_insert() might place the entry into the conntrack
+table and then delteted the entry again because it found that a conntrack
+extension has been removed at the same time.
+
+In this case, the just-added entry is removed again and an error is
+returned to the caller.
+
+Problem is that another cpu might have picked up this entry and
+incremented its reference count.
+
+This results in a use-after-free/double-free, once by the other cpu and
+once by the caller of nf_conntrack_hash_check_insert().
+
+Fix this by making nf_conntrack_hash_check_insert() not fail anymore
+after the insertion, just like before the 'Fixes' commit.
+
+This is safe because a racing nf_ct_iterate() has to wait for us
+to release the conntrack hash spinlocks.
+
+While at it, make the function return -EAGAIN in the rmmod (genid
+changed) case, this makes nfnetlink replay the command (suggested
+by Pablo Neira).
+
+Fixes: c56716c69ce1 ("netfilter: extensions: introduce extension genid count")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_bpf.c | 1 -
+ net/netfilter/nf_conntrack_core.c | 25 +++++++++++++++----------
+ net/netfilter/nf_conntrack_netlink.c | 3 ---
+ 3 files changed, 15 insertions(+), 14 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_bpf.c b/net/netfilter/nf_conntrack_bpf.c
+index 8639e7efd0e22..adae86e8e02e8 100644
+--- a/net/netfilter/nf_conntrack_bpf.c
++++ b/net/netfilter/nf_conntrack_bpf.c
+@@ -384,7 +384,6 @@ struct nf_conn *bpf_ct_insert_entry(struct nf_conn___init *nfct_i)
+ struct nf_conn *nfct = (struct nf_conn *)nfct_i;
+ int err;
+
+- nfct->status |= IPS_CONFIRMED;
+ err = nf_conntrack_hash_check_insert(nfct);
+ if (err < 0) {
+ nf_conntrack_free(nfct);
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 23b3fedd619a5..7f0f3bcaae031 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -890,10 +890,8 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
+
+ zone = nf_ct_zone(ct);
+
+- if (!nf_ct_ext_valid_pre(ct->ext)) {
+- NF_CT_STAT_INC_ATOMIC(net, insert_failed);
+- return -ETIMEDOUT;
+- }
++ if (!nf_ct_ext_valid_pre(ct->ext))
++ return -EAGAIN;
+
+ local_bh_disable();
+ do {
+@@ -928,6 +926,19 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
+ goto chaintoolong;
+ }
+
++ /* If genid has changed, we can't insert anymore because ct
++ * extensions could have stale pointers and nf_ct_iterate_destroy
++ * might have completed its table scan already.
++ *
++ * Increment of the ext genid right after this check is fine:
++ * nf_ct_iterate_destroy blocks until locks are released.
++ */
++ if (!nf_ct_ext_valid_post(ct->ext)) {
++ err = -EAGAIN;
++ goto out;
++ }
++
++ ct->status |= IPS_CONFIRMED;
+ smp_wmb();
+ /* The caller holds a reference to this object */
+ refcount_set(&ct->ct_general.use, 2);
+@@ -936,12 +947,6 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
+ NF_CT_STAT_INC(net, insert);
+ local_bh_enable();
+
+- if (!nf_ct_ext_valid_post(ct->ext)) {
+- nf_ct_kill(ct);
+- NF_CT_STAT_INC_ATOMIC(net, drop);
+- return -ETIMEDOUT;
+- }
+-
+ return 0;
+ chaintoolong:
+ NF_CT_STAT_INC(net, chaintoolong);
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index ca4d5bb1ea524..733bb56950c14 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -2316,9 +2316,6 @@ ctnetlink_create_conntrack(struct net *net,
+ nfct_seqadj_ext_add(ct);
+ nfct_synproxy_ext_add(ct);
+
+- /* we must add conntrack extensions before confirmation. */
+- ct->status |= IPS_CONFIRMED;
+-
+ if (cda[CTA_STATUS]) {
+ err = ctnetlink_change_status(ct, cda);
+ if (err < 0)
+--
+2.39.2
+
--- /dev/null
+From ca227d1ea93e9a30c22958e71cbdd69012e6d669 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 15:17:30 +0800
+Subject: netfilter: ctnetlink: fix possible refcount leak in
+ ctnetlink_create_conntrack()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit ac4893980bbe79ce383daf9a0885666a30fe4c83 ]
+
+nf_ct_put() needs to be called to put the refcount got by
+nf_conntrack_find_get() to avoid refcount leak when
+nf_conntrack_hash_check_insert() fails.
+
+Fixes: 7d367e06688d ("netfilter: ctnetlink: fix soft lockup when netlink adds new entries (v2)")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Acked-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_netlink.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index 1286ae7d46096..ca4d5bb1ea524 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -2375,12 +2375,15 @@ ctnetlink_create_conntrack(struct net *net,
+
+ err = nf_conntrack_hash_check_insert(ct);
+ if (err < 0)
+- goto err2;
++ goto err3;
+
+ rcu_read_unlock();
+
+ return ct;
+
++err3:
++ if (ct->master)
++ nf_ct_put(ct->master);
+ err2:
+ rcu_read_unlock();
+ err1:
+--
+2.39.2
+
--- /dev/null
+From 15e3c5a951052b86d3aa166bb35e4e83ec8b2ba8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Feb 2023 17:24:00 +0100
+Subject: netfilter: ctnetlink: make event listener tracking global
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit fdf6491193e411087ae77bcbc6468e3e1cff99ed ]
+
+pernet tracking doesn't work correctly because other netns might have
+set NETLINK_LISTEN_ALL_NSID on its event socket.
+
+In this case its expected that events originating in other net
+namespaces are also received.
+
+Making pernet-tracking work while also honoring NETLINK_LISTEN_ALL_NSID
+requires much more intrusive changes both in netlink and nfnetlink,
+f.e. adding a 'setsockopt' callback that lets nfnetlink know that the
+event socket entered (or left) ALL_NSID mode.
+
+Move to global tracking instead: if there is an event socket anywhere
+on the system, all net namespaces which have conntrack enabled and
+use autobind mode will allocate the ecache extension.
+
+netlink_has_listeners() returns false only if the given group has no
+subscribers in any net namespace, the 'net' argument passed to
+nfnetlink_has_listeners is only used to derive the protocol (nfnetlink),
+it has no other effect.
+
+For proper NETLINK_LISTEN_ALL_NSID-aware pernet tracking of event
+listeners a new netlink_has_net_listeners() is also needed.
+
+Fixes: 90d1daa45849 ("netfilter: conntrack: add nf_conntrack_events autodetect mode")
+Reported-by: Bryce Kahle <bryce.kahle@datadoghq.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netfilter.h | 5 +++++
+ include/net/netns/conntrack.h | 1 -
+ net/netfilter/core.c | 3 +++
+ net/netfilter/nf_conntrack_ecache.c | 2 +-
+ net/netfilter/nfnetlink.c | 9 +++++----
+ 5 files changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
+index d8817d381c14b..bef8db9d6c085 100644
+--- a/include/linux/netfilter.h
++++ b/include/linux/netfilter.h
+@@ -488,4 +488,9 @@ extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook;
+ */
+ DECLARE_PER_CPU(bool, nf_skb_duplicated);
+
++/**
++ * Contains bitmask of ctnetlink event subscribers, if any.
++ * Can't be pernet due to NETLINK_LISTEN_ALL_NSID setsockopt flag.
++ */
++extern u8 nf_ctnetlink_has_listener;
+ #endif /*__LINUX_NETFILTER_H*/
+diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
+index e1290c159184a..1f463b3957c78 100644
+--- a/include/net/netns/conntrack.h
++++ b/include/net/netns/conntrack.h
+@@ -95,7 +95,6 @@ struct nf_ip_net {
+
+ struct netns_ct {
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
+- u8 ctnetlink_has_listener;
+ bool ecache_dwork_pending;
+ #endif
+ u8 sysctl_log_invalid; /* Log invalid packets */
+diff --git a/net/netfilter/core.c b/net/netfilter/core.c
+index 5a6705a0e4ecf..6e80f0f6149ea 100644
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -669,6 +669,9 @@ const struct nf_ct_hook __rcu *nf_ct_hook __read_mostly;
+ EXPORT_SYMBOL_GPL(nf_ct_hook);
+
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK)
++u8 nf_ctnetlink_has_listener;
++EXPORT_SYMBOL_GPL(nf_ctnetlink_has_listener);
++
+ const struct nf_nat_hook __rcu *nf_nat_hook __read_mostly;
+ EXPORT_SYMBOL_GPL(nf_nat_hook);
+
+diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
+index 8698b34246460..69948e1d6974e 100644
+--- a/net/netfilter/nf_conntrack_ecache.c
++++ b/net/netfilter/nf_conntrack_ecache.c
+@@ -309,7 +309,7 @@ bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp
+ break;
+ return true;
+ case 2: /* autodetect: no event listener, don't allocate extension. */
+- if (!READ_ONCE(net->ct.ctnetlink_has_listener))
++ if (!READ_ONCE(nf_ctnetlink_has_listener))
+ return true;
+ fallthrough;
+ case 1:
+diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
+index 6d18fb3468683..81c7737c803a6 100644
+--- a/net/netfilter/nfnetlink.c
++++ b/net/netfilter/nfnetlink.c
+@@ -29,6 +29,7 @@
+
+ #include <net/netlink.h>
+ #include <net/netns/generic.h>
++#include <linux/netfilter.h>
+ #include <linux/netfilter/nfnetlink.h>
+
+ MODULE_LICENSE("GPL");
+@@ -685,12 +686,12 @@ static void nfnetlink_bind_event(struct net *net, unsigned int group)
+ group_bit = (1 << group);
+
+ spin_lock(&nfnl_grp_active_lock);
+- v = READ_ONCE(net->ct.ctnetlink_has_listener);
++ v = READ_ONCE(nf_ctnetlink_has_listener);
+ if ((v & group_bit) == 0) {
+ v |= group_bit;
+
+ /* read concurrently without nfnl_grp_active_lock held. */
+- WRITE_ONCE(net->ct.ctnetlink_has_listener, v);
++ WRITE_ONCE(nf_ctnetlink_has_listener, v);
+ }
+
+ spin_unlock(&nfnl_grp_active_lock);
+@@ -744,12 +745,12 @@ static void nfnetlink_unbind(struct net *net, int group)
+
+ spin_lock(&nfnl_grp_active_lock);
+ if (!nfnetlink_has_listeners(net, group)) {
+- u8 v = READ_ONCE(net->ct.ctnetlink_has_listener);
++ u8 v = READ_ONCE(nf_ctnetlink_has_listener);
+
+ v &= ~group_bit;
+
+ /* read concurrently without nfnl_grp_active_lock held. */
+- WRITE_ONCE(net->ct.ctnetlink_has_listener, v);
++ WRITE_ONCE(nf_ctnetlink_has_listener, v);
+ }
+ spin_unlock(&nfnl_grp_active_lock);
+ #endif
+--
+2.39.2
+
--- /dev/null
+From 76eb65b00b5dae4fb8a53cbeb6e83612c753b974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Feb 2023 23:20:06 +0100
+Subject: netfilter: ebtables: fix table blob use-after-free
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit e58a171d35e32e6e8c37cfe0e8a94406732a331f ]
+
+We are not allowed to return an error at this point.
+Looking at the code it looks like ret is always 0 at this
+point, but its not.
+
+t = find_table_lock(net, repl->name, &ret, &ebt_mutex);
+
+... this can return a valid table, with ret != 0.
+
+This bug causes update of table->private with the new
+blob, but then frees the blob right away in the caller.
+
+Syzbot report:
+
+BUG: KASAN: vmalloc-out-of-bounds in __ebt_unregister_table+0xc00/0xcd0 net/bridge/netfilter/ebtables.c:1168
+Read of size 4 at addr ffffc90005425000 by task kworker/u4:4/74
+Workqueue: netns cleanup_net
+Call Trace:
+ kasan_report+0xbf/0x1f0 mm/kasan/report.c:517
+ __ebt_unregister_table+0xc00/0xcd0 net/bridge/netfilter/ebtables.c:1168
+ ebt_unregister_table+0x35/0x40 net/bridge/netfilter/ebtables.c:1372
+ ops_exit_list+0xb0/0x170 net/core/net_namespace.c:169
+ cleanup_net+0x4ee/0xb10 net/core/net_namespace.c:613
+...
+
+ip(6)tables appears to be ok (ret should be 0 at this point) but make
+this more obvious.
+
+Fixes: c58dd2dd443c ("netfilter: Can't fail and free after table replacement")
+Reported-by: syzbot+f61594de72d6705aea03@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/ebtables.c | 2 +-
+ net/ipv4/netfilter/ip_tables.c | 3 +--
+ net/ipv6/netfilter/ip6_tables.c | 3 +--
+ 3 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index ce5dfa3babd26..757ec46fc45a0 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1090,7 +1090,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
+
+ audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
+ AUDIT_XT_OP_REPLACE, GFP_KERNEL);
+- return ret;
++ return 0;
+
+ free_unlock:
+ mutex_unlock(&ebt_mutex);
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index 2ed7c58b471ac..aae5fd51dfd74 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -1045,7 +1045,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
+ struct xt_counters *counters;
+ struct ipt_entry *iter;
+
+- ret = 0;
+ counters = xt_counters_alloc(num_counters);
+ if (!counters) {
+ ret = -ENOMEM;
+@@ -1091,7 +1090,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
+ net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n");
+ }
+ vfree(counters);
+- return ret;
++ return 0;
+
+ put_module:
+ module_put(t->me);
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index 2d816277f2c5a..ac902f7bca477 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -1062,7 +1062,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
+ struct xt_counters *counters;
+ struct ip6t_entry *iter;
+
+- ret = 0;
+ counters = xt_counters_alloc(num_counters);
+ if (!counters) {
+ ret = -ENOMEM;
+@@ -1108,7 +1107,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
+ net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n");
+ }
+ vfree(counters);
+- return ret;
++ return 0;
+
+ put_module:
+ module_put(t->me);
+--
+2.39.2
+
--- /dev/null
+From dce0313afbb98052a6c6198c250353c0db36bc75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Feb 2023 17:05:36 +0100
+Subject: netfilter: ip6t_rpfilter: Fix regression with VRF interfaces
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit efb056e5f1f0036179b2f92c1c15f5ea7a891d70 ]
+
+When calling ip6_route_lookup() for the packet arriving on the VRF
+interface, the result is always the real (slave) interface. Expect this
+when validating the result.
+
+Fixes: acc641ab95b66 ("netfilter: rpfilter/fib: Populate flowic_l3mdev field")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/ip6t_rpfilter.c | 4 ++-
+ tools/testing/selftests/netfilter/rpath.sh | 32 ++++++++++++++++++----
+ 2 files changed, 29 insertions(+), 7 deletions(-)
+
+diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
+index a01d9b842bd07..67c87a88cde4f 100644
+--- a/net/ipv6/netfilter/ip6t_rpfilter.c
++++ b/net/ipv6/netfilter/ip6t_rpfilter.c
+@@ -72,7 +72,9 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
+ goto out;
+ }
+
+- if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE))
++ if (rt->rt6i_idev->dev == dev ||
++ l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == dev->ifindex ||
++ (flags & XT_RPFILTER_LOOSE))
+ ret = true;
+ out:
+ ip6_rt_put(rt);
+diff --git a/tools/testing/selftests/netfilter/rpath.sh b/tools/testing/selftests/netfilter/rpath.sh
+index f7311e66d2193..5289c8447a419 100755
+--- a/tools/testing/selftests/netfilter/rpath.sh
++++ b/tools/testing/selftests/netfilter/rpath.sh
+@@ -62,10 +62,16 @@ ip -net "$ns1" a a fec0:42::2/64 dev v0 nodad
+ ip -net "$ns2" a a fec0:42::1/64 dev d0 nodad
+
+ # firewall matches to test
+-[ -n "$iptables" ] && ip netns exec "$ns2" \
+- "$iptables" -t raw -A PREROUTING -s 192.168.0.0/16 -m rpfilter
+-[ -n "$ip6tables" ] && ip netns exec "$ns2" \
+- "$ip6tables" -t raw -A PREROUTING -s fec0::/16 -m rpfilter
++[ -n "$iptables" ] && {
++ common='-t raw -A PREROUTING -s 192.168.0.0/16'
++ ip netns exec "$ns2" "$iptables" $common -m rpfilter
++ ip netns exec "$ns2" "$iptables" $common -m rpfilter --invert
++}
++[ -n "$ip6tables" ] && {
++ common='-t raw -A PREROUTING -s fec0::/16'
++ ip netns exec "$ns2" "$ip6tables" $common -m rpfilter
++ ip netns exec "$ns2" "$ip6tables" $common -m rpfilter --invert
++}
+ [ -n "$nft" ] && ip netns exec "$ns2" $nft -f - <<EOF
+ table inet t {
+ chain c {
+@@ -89,6 +95,11 @@ ipt_zero_rule() { # (command)
+ [ -n "$1" ] || return 0
+ ip netns exec "$ns2" "$1" -t raw -vS | grep -q -- "-m rpfilter -c 0 0"
+ }
++ipt_zero_reverse_rule() { # (command)
++ [ -n "$1" ] || return 0
++ ip netns exec "$ns2" "$1" -t raw -vS | \
++ grep -q -- "-m rpfilter --invert -c 0 0"
++}
+ nft_zero_rule() { # (family)
+ [ -n "$nft" ] || return 0
+ ip netns exec "$ns2" "$nft" list chain inet t c | \
+@@ -101,8 +112,7 @@ netns_ping() { # (netns, args...)
+ ip netns exec "$netns" ping -q -c 1 -W 1 "$@" >/dev/null
+ }
+
+-testrun() {
+- # clear counters first
++clear_counters() {
+ [ -n "$iptables" ] && ip netns exec "$ns2" "$iptables" -t raw -Z
+ [ -n "$ip6tables" ] && ip netns exec "$ns2" "$ip6tables" -t raw -Z
+ if [ -n "$nft" ]; then
+@@ -111,6 +121,10 @@ testrun() {
+ ip netns exec "$ns2" $nft -s list table inet t;
+ ) | ip netns exec "$ns2" $nft -f -
+ fi
++}
++
++testrun() {
++ clear_counters
+
+ # test 1: martian traffic should fail rpfilter matches
+ netns_ping "$ns1" -I v0 192.168.42.1 && \
+@@ -120,9 +134,13 @@ testrun() {
+
+ ipt_zero_rule "$iptables" || die "iptables matched martian"
+ ipt_zero_rule "$ip6tables" || die "ip6tables matched martian"
++ ipt_zero_reverse_rule "$iptables" && die "iptables not matched martian"
++ ipt_zero_reverse_rule "$ip6tables" && die "ip6tables not matched martian"
+ nft_zero_rule ip || die "nft IPv4 matched martian"
+ nft_zero_rule ip6 || die "nft IPv6 matched martian"
+
++ clear_counters
++
+ # test 2: rpfilter match should pass for regular traffic
+ netns_ping "$ns1" 192.168.23.1 || \
+ die "regular ping 192.168.23.1 failed"
+@@ -131,6 +149,8 @@ testrun() {
+
+ ipt_zero_rule "$iptables" && die "iptables match not effective"
+ ipt_zero_rule "$ip6tables" && die "ip6tables match not effective"
++ ipt_zero_reverse_rule "$iptables" || die "iptables match over-effective"
++ ipt_zero_reverse_rule "$ip6tables" || die "ip6tables match over-effective"
+ nft_zero_rule ip && die "nft IPv4 match not effective"
+ nft_zero_rule ip6 && die "nft IPv6 match not effective"
+
+--
+2.39.2
+
--- /dev/null
+From a5a6a3ae42c9c58df4b4cb75e45872e73c0d29a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 11:34:27 +0100
+Subject: netfilter: nf_tables: allow to fetch set elements when table has an
+ owner
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 92f3e96d642f5e05b9dc710c06fedc669f1b4f00 ]
+
+NFT_MSG_GETSETELEM returns -EPERM when fetching set elements that belong
+to table that has an owner. This results in empty set/map listing from
+userspace.
+
+Fixes: 6001a930ce03 ("netfilter: nftables: introduce table ownership")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index dca5352bdf3d7..1a9d759d0a026 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5439,7 +5439,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ int rem, err = 0;
+
+ table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family,
+- genmask, NETLINK_CB(skb).portid);
++ genmask, 0);
+ if (IS_ERR(table)) {
+ NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_TABLE]);
+ return PTR_ERR(table);
+--
+2.39.2
+
--- /dev/null
+From c988735b8e74fa1500f10303c94b2785c34a0f00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Feb 2023 12:25:05 +0800
+Subject: netfilter: x_tables: fix percpu counter block leak on error path when
+ creating new netns
+
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+
+[ Upstream commit 0af8c09c896810879387decfba8c942994bb61f5 ]
+
+Here is the stack where we allocate percpu counter block:
+
+ +-< __alloc_percpu
+ +-< xt_percpu_counter_alloc
+ +-< find_check_entry # {arp,ip,ip6}_tables.c
+ +-< translate_table
+
+And it can be leaked on this code path:
+
+ +-> ip6t_register_table
+ +-> translate_table # allocates percpu counter block
+ +-> xt_register_table # fails
+
+there is no freeing of the counter block on xt_register_table fail.
+Note: xt_percpu_counter_free should be called to free it like we do in
+do_replace through cleanup_entry helper (or in __ip6t_unregister_table).
+
+Probability of hitting this error path is low AFAICS (xt_register_table
+can only return ENOMEM here, as it is not replacing anything, as we are
+creating new netns, and it is hard to imagine that all previous
+allocations succeeded and after that one in xt_register_table failed).
+But it's worth fixing even the rare leak.
+
+Fixes: 71ae0dff02d7 ("netfilter: xtables: use percpu rule counters")
+Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/netfilter/arp_tables.c | 4 ++++
+ net/ipv4/netfilter/ip_tables.c | 4 ++++
+ net/ipv6/netfilter/ip6_tables.c | 4 ++++
+ 3 files changed, 12 insertions(+)
+
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index ffc0cab7cf189..2407066b0fec1 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -1525,6 +1525,10 @@ int arpt_register_table(struct net *net,
+
+ new_table = xt_register_table(net, table, &bootstrap, newinfo);
+ if (IS_ERR(new_table)) {
++ struct arpt_entry *iter;
++
++ xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
++ cleanup_entry(iter, net);
+ xt_free_table_info(newinfo);
+ return PTR_ERR(new_table);
+ }
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index aae5fd51dfd74..da5998011ab9b 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -1741,6 +1741,10 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
+
+ new_table = xt_register_table(net, table, &bootstrap, newinfo);
+ if (IS_ERR(new_table)) {
++ struct ipt_entry *iter;
++
++ xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
++ cleanup_entry(iter, net);
+ xt_free_table_info(newinfo);
+ return PTR_ERR(new_table);
+ }
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index ac902f7bca477..0ce0ed17c7583 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -1750,6 +1750,10 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
+
+ new_table = xt_register_table(net, table, &bootstrap, newinfo);
+ if (IS_ERR(new_table)) {
++ struct ip6t_entry *iter;
++
++ xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
++ cleanup_entry(iter, net);
+ xt_free_table_info(newinfo);
+ return PTR_ERR(new_table);
+ }
+--
+2.39.2
+
--- /dev/null
+From 7808e5221c4a060b6e8399976977499a9ae5e295 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Feb 2023 18:22:57 -0500
+Subject: netfilter: xt_length: use skb len to match in length_mt6
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 05c07c0c6cc8ec2278ace9871618c41f1365d1f5 ]
+
+For IPv6 Jumbo packets, the ipv6_hdr(skb)->payload_len is always 0,
+and its real payload_len ( > 65535) is saved in hbh exthdr. With 0
+length for the jumbo packets, it may mismatch.
+
+To fix this, we can just use skb->len instead of parsing exthdrs, as
+the hbh exthdr parsing has been done before coming to length_mt6 in
+ip6_rcv_core() and br_validate_ipv6() and also the packet has been
+trimmed according to the correct IPv6 (ext)hdr length there, and skb
+len is trustable in length_mt6().
+
+Note that this patch is especially needed after the IPv6 BIG TCP was
+supported in kernel, which is using IPv6 Jumbo packets. Besides, to
+match the packets greater than 65535 more properly, a v1 revision of
+xt_length may be needed to extend "min, max" to u32 in the future,
+and for now the IPv6 Jumbo packets can be matched by:
+
+ # ip6tables -m length ! --length 0:65535
+
+Fixes: 7c4e983c4f3c ("net: allow gso_max_size to exceed 65536")
+Fixes: 0fe79f28bfaf ("net: allow gro_max_size to exceed 65536")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_length.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c
+index 1873da3a945ab..9fbfad13176f0 100644
+--- a/net/netfilter/xt_length.c
++++ b/net/netfilter/xt_length.c
+@@ -30,8 +30,7 @@ static bool
+ length_mt6(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+ const struct xt_length_info *info = par->matchinfo;
+- const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
+- sizeof(struct ipv6hdr);
++ u32 pktlen = skb->len;
+
+ return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
+ }
+--
+2.39.2
+
--- /dev/null
+From a3e0dc8d9f9bf936d7ef19ba4a13dad93f4f588a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Feb 2023 13:56:14 +0300
+Subject: nfc: fix memory leak of se_io context in nfc_genl_se_io
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 25ff6f8a5a3b8dc48e8abda6f013e8cc4b14ffea ]
+
+The callback context for sending/receiving APDUs to/from the selected
+secure element is allocated inside nfc_genl_se_io and supposed to be
+eventually freed in se_io_cb callback function. However, there are several
+error paths where the bwi_timer is not charged to call se_io_cb later, and
+the cb_context is leaked.
+
+The patch proposes to free the cb_context explicitly on those error paths.
+
+At the moment we can't simply check 'dev->ops->se_io()' return value as it
+may be negative in both cases: when the timer was charged and was not.
+
+Fixes: 5ce3f32b5264 ("NFC: netlink: SE API implementation")
+Reported-by: syzbot+df64c0a2e8d68e78a4fa@syzkaller.appspotmail.com
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/st-nci/se.c | 6 ++++++
+ drivers/nfc/st21nfca/se.c | 6 ++++++
+ net/nfc/netlink.c | 4 ++++
+ 3 files changed, 16 insertions(+)
+
+diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c
+index ec87dd21e054a..b2f1ced8e6dd2 100644
+--- a/drivers/nfc/st-nci/se.c
++++ b/drivers/nfc/st-nci/se.c
+@@ -672,6 +672,12 @@ int st_nci_se_io(struct nci_dev *ndev, u32 se_idx,
+ ST_NCI_EVT_TRANSMIT_DATA, apdu,
+ apdu_length);
+ default:
++ /* Need to free cb_context here as at the moment we can't
++ * clearly indicate to the caller if the callback function
++ * would be called (and free it) or not. In both cases a
++ * negative value may be returned to the caller.
++ */
++ kfree(cb_context);
+ return -ENODEV;
+ }
+ }
+diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c
+index df8d27cf2956b..dae288bebcb5a 100644
+--- a/drivers/nfc/st21nfca/se.c
++++ b/drivers/nfc/st21nfca/se.c
+@@ -236,6 +236,12 @@ int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx,
+ ST21NFCA_EVT_TRANSMIT_DATA,
+ apdu, apdu_length);
+ default:
++ /* Need to free cb_context here as at the moment we can't
++ * clearly indicate to the caller if the callback function
++ * would be called (and free it) or not. In both cases a
++ * negative value may be returned to the caller.
++ */
++ kfree(cb_context);
+ return -ENODEV;
+ }
+ }
+diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
+index 1fc339084d897..348bf561bc9fb 100644
+--- a/net/nfc/netlink.c
++++ b/net/nfc/netlink.c
+@@ -1442,7 +1442,11 @@ static int nfc_se_io(struct nfc_dev *dev, u32 se_idx,
+ rc = dev->ops->se_io(dev, se_idx, apdu,
+ apdu_length, cb, cb_context);
+
++ device_unlock(&dev->dev);
++ return rc;
++
+ error:
++ kfree(cb_context);
+ device_unlock(&dev->dev);
+ return rc;
+ }
+--
+2.39.2
+
--- /dev/null
+From 2b9d7428cf3e0cb605ed68f2d5fffa85c25cb262 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Feb 2023 14:02:25 -0800
+Subject: nvme: bring back auto-removal of deleted namespaces during sequential
+ scan
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 0dd6fff2aad4e35633fef1ea72838bec5b47559a ]
+
+Bring back the check of the Identify Namespace return value for the
+legacy NVMe 1.0-style sequential scanning. While NVMe 1.0 does not
+support namespace management, there are "modern" cloud solutions like
+Google Cloud Platform that claim the obsolete 1.0 compliance for no
+good reason while supporting proprietary sideband namespace management.
+
+Fixes: 1a893c2bfef4 ("nvme: refactor namespace probing")
+Reported-by: Nils Hanke <nh@edgeless.systems>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Tested-by: Nils Hanke <nh@edgeless.systems>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 35 ++++++++++++++++++-----------------
+ 1 file changed, 18 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 5acc9ae225df3..2031fd960549c 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -38,6 +38,7 @@ struct nvme_ns_info {
+ bool is_shared;
+ bool is_readonly;
+ bool is_ready;
++ bool is_removed;
+ };
+
+ unsigned int admin_timeout = 60;
+@@ -1439,16 +1440,8 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
+ error = nvme_submit_sync_cmd(ctrl->admin_q, &c, *id, sizeof(**id));
+ if (error) {
+ dev_warn(ctrl->device, "Identify namespace failed (%d)\n", error);
+- goto out_free_id;
++ kfree(*id);
+ }
+-
+- error = NVME_SC_INVALID_NS | NVME_SC_DNR;
+- if ((*id)->ncap == 0) /* namespace not allocated or attached */
+- goto out_free_id;
+- return 0;
+-
+-out_free_id:
+- kfree(*id);
+ return error;
+ }
+
+@@ -1462,6 +1455,13 @@ static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl,
+ ret = nvme_identify_ns(ctrl, info->nsid, &id);
+ if (ret)
+ return ret;
++
++ if (id->ncap == 0) {
++ /* namespace not allocated or attached */
++ info->is_removed = true;
++ return -ENODEV;
++ }
++
+ info->anagrpid = id->anagrpid;
+ info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
+ info->is_readonly = id->nsattr & NVME_NS_ATTR_RO;
+@@ -4388,6 +4388,7 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+ {
+ struct nvme_ns_info info = { .nsid = nsid };
+ struct nvme_ns *ns;
++ int ret;
+
+ if (nvme_identify_ns_descs(ctrl, &info))
+ return;
+@@ -4404,19 +4405,19 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+ * set up a namespace. If not fall back to the legacy version.
+ */
+ if ((ctrl->cap & NVME_CAP_CRMS_CRIMS) ||
+- (info.ids.csi != NVME_CSI_NVM && info.ids.csi != NVME_CSI_ZNS)) {
+- if (nvme_ns_info_from_id_cs_indep(ctrl, &info))
+- return;
+- } else {
+- if (nvme_ns_info_from_identify(ctrl, &info))
+- return;
+- }
++ (info.ids.csi != NVME_CSI_NVM && info.ids.csi != NVME_CSI_ZNS))
++ ret = nvme_ns_info_from_id_cs_indep(ctrl, &info);
++ else
++ ret = nvme_ns_info_from_identify(ctrl, &info);
++
++ if (info.is_removed)
++ nvme_ns_remove_by_nsid(ctrl, nsid);
+
+ /*
+ * Ignore the namespace if it is not ready. We will get an AEN once it
+ * becomes ready and restart the scan.
+ */
+- if (!info.is_ready)
++ if (ret || !info.is_ready)
+ return;
+
+ ns = nvme_find_get_ns(ctrl, nsid);
+--
+2.39.2
+
--- /dev/null
+From e99d78f3d32b9609ac80f6e83eca5dcaea52de9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Feb 2023 17:51:06 +0100
+Subject: nvme-fabrics: show well known discovery name
+
+From: Daniel Wagner <dwagner@suse.de>
+
+[ Upstream commit 26a57cb35548ae67c14871cccbf50da3edb01ea4 ]
+
+The kernel always logs the unique subsystem name for a discovery
+controller, even in the case user space asked for the well known.
+
+This has lead to confusion as the logs of nvme-cli and the kernel
+logs didn't match.
+
+First, nvme-cli connects to the well known discovery controller to
+figure out if it supports TP8013. If so then nvme-cli disconnects and
+connects to the unique discovery controller. Currently, the kernel show
+that user space connected twice to the unique one.
+
+To avoid further confusion, show the well known discovery controller if
+user space asked for it:
+
+ $ nvme connect-all -v -t tcp -a 192.168.0.1
+ nvme0: nqn.2014-08.org.nvmexpress.discovery connected
+ nvme0: nqn.2014-08.org.nvmexpress.discovery disconnected
+ nvme0: nqn.discovery connected
+
+ kernel log:
+ nvme nvme0: new ctrl: NQN "nqn.2014-08.org.nvmexpress.discovery", addr 192.168.0.1:8009
+ nvme nvme0: Removing ctrl: NQN "nqn.2014-08.org.nvmexpress.discovery"
+ nvme nvme0: new ctrl: NQN "nqn.discovery", addr 192.168.0.1:8009
+
+Fixes: e5ea42faa773 ("nvme: display correct subsystem NQN")
+Signed-off-by: Daniel Wagner <dwagner@suse.de>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/fabrics.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h
+index a6e22116e1396..dcac3df8a5f76 100644
+--- a/drivers/nvme/host/fabrics.h
++++ b/drivers/nvme/host/fabrics.h
+@@ -189,7 +189,8 @@ nvmf_ctlr_matches_baseopts(struct nvme_ctrl *ctrl,
+
+ static inline char *nvmf_ctrl_subsysnqn(struct nvme_ctrl *ctrl)
+ {
+- if (!ctrl->subsys)
++ if (!ctrl->subsys ||
++ !strcmp(ctrl->opts->subsysnqn, NVME_DISC_SUBSYS_NAME))
+ return ctrl->opts->subsysnqn;
+ return ctrl->subsys->subnqn;
+ }
+--
+2.39.2
+
--- /dev/null
+From 9025cf24beed1ee643f94dc25962e03b818fe588 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Feb 2023 21:42:54 +0900
+Subject: nvme-tcp: don't access released socket during error recovery
+
+From: Akinobu Mita <akinobu.mita@gmail.com>
+
+[ Upstream commit 76d54bf20cdcc1ed7569a89885e09636e9a8d71d ]
+
+While the error recovery work is temporarily failing reconnect attempts,
+running the 'nvme list' command causes a kernel NULL pointer dereference
+by calling getsockname() with a released socket.
+
+During error recovery work, the nvme tcp socket is released and a new one
+created, so it is not safe to access the socket without proper check.
+
+Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
+Fixes: 02c57a82c008 ("nvme-tcp: print actual source IP address through sysfs "address" attr")
+Reviewed-by: Martin Belanger <martin.belanger@dell.com>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 1dc7c733c7e39..bb80192c16b6b 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -2488,6 +2488,10 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
+
+ len = nvmf_get_address(ctrl, buf, size);
+
++ mutex_lock(&queue->queue_lock);
++
++ if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags))
++ goto done;
+ ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr);
+ if (ret > 0) {
+ if (len > 0)
+@@ -2495,6 +2499,8 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
+ len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n",
+ (len) ? "," : "", &src_addr);
+ }
++done:
++ mutex_unlock(&queue->queue_lock);
+
+ return len;
+ }
+--
+2.39.2
+
--- /dev/null
+From 6fa47fb7eb76537a0cbee214371c47fd7f022313 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 12:06:42 +0400
+Subject: objtool: Fix memory leak in create_static_call_sections()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 3da73f102309fe29150e5c35acd20dd82063ff67 ]
+
+strdup() allocates memory for key_name. We need to release the memory in
+the following error paths. Add free() to avoid memory leak.
+
+Fixes: 1e7e47883830 ("x86/static_call: Add inline static call implementation for x86-64")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20221205080642.558583-1-linmq006@gmail.com
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 0c1b6acad141f..730b49e255e44 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -668,6 +668,7 @@ static int create_static_call_sections(struct objtool_file *file)
+ if (strncmp(key_name, STATIC_CALL_TRAMP_PREFIX_STR,
+ STATIC_CALL_TRAMP_PREFIX_LEN)) {
+ WARN("static_call: trampoline name malformed: %s", key_name);
++ free(key_name);
+ return -1;
+ }
+ tmp = key_name + STATIC_CALL_TRAMP_PREFIX_LEN - STATIC_CALL_KEY_PREFIX_LEN;
+@@ -677,6 +678,7 @@ static int create_static_call_sections(struct objtool_file *file)
+ if (!key_sym) {
+ if (!opts.module) {
+ WARN("static_call: can't find static_call_key symbol: %s", tmp);
++ free(key_name);
+ return -1;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From dc6feae5a01318afb03a945ef55456af1722dd10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Feb 2023 17:06:00 +0530
+Subject: octeontx2-pf: Recalculate UDP checksum for ptp 1-step sync packet
+
+From: Geetha sowjanya <gakula@marvell.com>
+
+[ Upstream commit edea0c5a994b7829c9ada8f5bc762c4e32f4f797 ]
+
+When checksum offload is disabled in the driver via ethtool,
+the PTP 1-step sync packets contain incorrect checksum, since
+the stack calculates the checksum before driver updates
+PTP timestamp field in the packet. This results in PTP packets
+getting dropped at the other end. This patch fixes the issue by
+re-calculating the UDP checksum after updating PTP
+timestamp field in the driver.
+
+Fixes: 2958d17a8984 ("octeontx2-pf: Add support for ptp 1-step mode on CN10K silicon")
+Signed-off-by: Geetha sowjanya <gakula@marvell.com>
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
+Signed-off-by: Sai Krishna <saikrishnag@marvell.com>
+Link: https://lore.kernel.org/r/20230222113600.1965116-1-saikrishnag@marvell.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../marvell/octeontx2/nic/otx2_txrx.c | 76 ++++++++++++++-----
+ 1 file changed, 57 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+index ef10aef3cda02..7045fedfd73a0 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+@@ -10,6 +10,7 @@
+ #include <net/tso.h>
+ #include <linux/bpf.h>
+ #include <linux/bpf_trace.h>
++#include <net/ip6_checksum.h>
+
+ #include "otx2_reg.h"
+ #include "otx2_common.h"
+@@ -699,7 +700,7 @@ static void otx2_sqe_add_ext(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
+
+ static void otx2_sqe_add_mem(struct otx2_snd_queue *sq, int *offset,
+ int alg, u64 iova, int ptp_offset,
+- u64 base_ns, int udp_csum)
++ u64 base_ns, bool udp_csum_crt)
+ {
+ struct nix_sqe_mem_s *mem;
+
+@@ -711,7 +712,7 @@ static void otx2_sqe_add_mem(struct otx2_snd_queue *sq, int *offset,
+
+ if (ptp_offset) {
+ mem->start_offset = ptp_offset;
+- mem->udp_csum_crt = udp_csum;
++ mem->udp_csum_crt = !!udp_csum_crt;
+ mem->base_ns = base_ns;
+ mem->step_type = 1;
+ }
+@@ -986,10 +987,11 @@ static bool otx2_validate_network_transport(struct sk_buff *skb)
+ return false;
+ }
+
+-static bool otx2_ptp_is_sync(struct sk_buff *skb, int *offset, int *udp_csum)
++static bool otx2_ptp_is_sync(struct sk_buff *skb, int *offset, bool *udp_csum_crt)
+ {
+ struct ethhdr *eth = (struct ethhdr *)(skb->data);
+ u16 nix_offload_hlen = 0, inner_vhlen = 0;
++ bool udp_hdr_present = false, is_sync;
+ u8 *data = skb->data, *msgtype;
+ __be16 proto = eth->h_proto;
+ int network_depth = 0;
+@@ -1029,45 +1031,81 @@ static bool otx2_ptp_is_sync(struct sk_buff *skb, int *offset, int *udp_csum)
+ if (!otx2_validate_network_transport(skb))
+ return false;
+
+- *udp_csum = 1;
+ *offset = nix_offload_hlen + skb_transport_offset(skb) +
+ sizeof(struct udphdr);
++ udp_hdr_present = true;
++
+ }
+
+ msgtype = data + *offset;
+-
+ /* Check PTP messageId is SYNC or not */
+- return (*msgtype & 0xf) == 0;
++ is_sync = !(*msgtype & 0xf);
++ if (is_sync)
++ *udp_csum_crt = udp_hdr_present;
++ else
++ *offset = 0;
++
++ return is_sync;
+ }
+
+ static void otx2_set_txtstamp(struct otx2_nic *pfvf, struct sk_buff *skb,
+ struct otx2_snd_queue *sq, int *offset)
+ {
++ struct ethhdr *eth = (struct ethhdr *)(skb->data);
+ struct ptpv2_tstamp *origin_tstamp;
+- int ptp_offset = 0, udp_csum = 0;
++ bool udp_csum_crt = false;
++ unsigned int udphoff;
+ struct timespec64 ts;
++ int ptp_offset = 0;
++ __wsum skb_csum;
+ u64 iova;
+
+ if (unlikely(!skb_shinfo(skb)->gso_size &&
+ (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) {
+- if (unlikely(pfvf->flags & OTX2_FLAG_PTP_ONESTEP_SYNC)) {
+- if (otx2_ptp_is_sync(skb, &ptp_offset, &udp_csum)) {
+- origin_tstamp = (struct ptpv2_tstamp *)
+- ((u8 *)skb->data + ptp_offset +
+- PTP_SYNC_SEC_OFFSET);
+- ts = ns_to_timespec64(pfvf->ptp->tstamp);
+- origin_tstamp->seconds_msb = htons((ts.tv_sec >> 32) & 0xffff);
+- origin_tstamp->seconds_lsb = htonl(ts.tv_sec & 0xffffffff);
+- origin_tstamp->nanoseconds = htonl(ts.tv_nsec);
+- /* Point to correction field in PTP packet */
+- ptp_offset += 8;
++ if (unlikely(pfvf->flags & OTX2_FLAG_PTP_ONESTEP_SYNC &&
++ otx2_ptp_is_sync(skb, &ptp_offset, &udp_csum_crt))) {
++ origin_tstamp = (struct ptpv2_tstamp *)
++ ((u8 *)skb->data + ptp_offset +
++ PTP_SYNC_SEC_OFFSET);
++ ts = ns_to_timespec64(pfvf->ptp->tstamp);
++ origin_tstamp->seconds_msb = htons((ts.tv_sec >> 32) & 0xffff);
++ origin_tstamp->seconds_lsb = htonl(ts.tv_sec & 0xffffffff);
++ origin_tstamp->nanoseconds = htonl(ts.tv_nsec);
++ /* Point to correction field in PTP packet */
++ ptp_offset += 8;
++
++ /* When user disables hw checksum, stack calculates the csum,
++ * but it does not cover ptp timestamp which is added later.
++ * Recalculate the checksum manually considering the timestamp.
++ */
++ if (udp_csum_crt) {
++ struct udphdr *uh = udp_hdr(skb);
++
++ if (skb->ip_summed != CHECKSUM_PARTIAL && uh->check != 0) {
++ udphoff = skb_transport_offset(skb);
++ uh->check = 0;
++ skb_csum = skb_checksum(skb, udphoff, skb->len - udphoff,
++ 0);
++ if (ntohs(eth->h_proto) == ETH_P_IPV6)
++ uh->check = csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
++ &ipv6_hdr(skb)->daddr,
++ skb->len - udphoff,
++ ipv6_hdr(skb)->nexthdr,
++ skb_csum);
++ else
++ uh->check = csum_tcpudp_magic(ip_hdr(skb)->saddr,
++ ip_hdr(skb)->daddr,
++ skb->len - udphoff,
++ IPPROTO_UDP,
++ skb_csum);
++ }
+ }
+ } else {
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+ }
+ iova = sq->timestamps->iova + (sq->head * sizeof(u64));
+ otx2_sqe_add_mem(sq, offset, NIX_SENDMEMALG_E_SETTSTMP, iova,
+- ptp_offset, pfvf->ptp->base_ns, udp_csum);
++ ptp_offset, pfvf->ptp->base_ns, udp_csum_crt);
+ } else {
+ skb_tx_timestamp(skb);
+ }
+--
+2.39.2
+
--- /dev/null
+From d0b11c76080a91ad824b3a4b4e4a7cd0ff2d5d3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Feb 2023 18:58:48 +0530
+Subject: octeontx2-pf: Use correct struct reference in test condition
+
+From: Deepak R Varma <drv@mailo.com>
+
+[ Upstream commit 3acd9db9293f3b33ac04e8d44ed05b604ad1ac26 ]
+
+Fix the typo/copy-paste error by replacing struct variable ah_esp_mask name
+by ah_esp_hdr.
+Issue identified using doublebitand.cocci Coccinelle semantic patch.
+
+Fixes: b7cf966126eb ("octeontx2-pf: Add flow classification using IP next level protocol")
+Link: https://lore.kernel.org/all/20210111112537.3277-1-naveenm@marvell.com/
+Signed-off-by: Deepak R Varma <drv@mailo.com>
+Link: https://lore.kernel.org/r/Y/YYkKddeHOt80cO@ubun2204.myguest.virtualbox.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
+index 709fc0114fbd2..0f7345a96965b 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
+@@ -765,7 +765,7 @@ static int otx2_prepare_ipv6_flow(struct ethtool_rx_flow_spec *fsp,
+
+ /* NPC profile doesn't extract AH/ESP header fields */
+ if ((ah_esp_mask->spi & ah_esp_hdr->spi) ||
+- (ah_esp_mask->tclass & ah_esp_mask->tclass))
++ (ah_esp_mask->tclass & ah_esp_hdr->tclass))
+ return -EOPNOTSUPP;
+
+ if (flow_type == AH_V6_FLOW)
+--
+2.39.2
+
--- /dev/null
+From e2688e02fb2c5050c6ad5cbce9bb0d5f6899f506 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Jan 2023 21:56:55 +0000
+Subject: parport_pc: Set up mode and ECR masks for Oxford Semiconductor
+ devices
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+[ Upstream commit c087df8d1e7dc2e764d11234d84b5af46d500f16 ]
+
+No Oxford Semiconductor PCI or PCIe parallel port device supports the
+Parallel Port FIFO mode. All support the PS/2 Parallel Port mode and
+the Enhanced Parallel Port mode via the ECR register. The original 5V
+PCI OX16PCI954 device does not support the Extended Capabilities Port
+mode, the Test mode or the Configuration mode, but all the other OxSemi
+devices do, including in particular the 3.3V PCI OXmPCI954 device and
+the universal voltage PCI OXuPCI954 device. All the unsupported modes
+are marked reserved in the relevant datasheets.
+
+Accordingly enable the `base_hi' BAR for the 954 devices to enable PS2
+and EPP mode support via the ECR register, however mask the COMPAT mode
+and, until we have a way to determine what chip variant it is that we
+poke at, also the ECP mode, and mask the COMPAT mode only for all the
+remaining OxSemi devices, fixing errors like:
+
+parport0: FIFO is stuck
+FIFO write timed out
+
+and a non-functional port when the Parallel Port FIFO mode is selected.
+
+Complementing the fix apply an ECR mask for all these devices, which are
+documented to only permit writing to the mode field of the ECR register
+with a bit pattern of 00001 required to be written to bits 4:0 on mode
+field writes. No nFault or service interrupts are implemented, which
+will therefore never have to be enabled, though bit 2 does report the
+FIFO threshold status to be polled for in the ECP mode where supported.
+
+We have a documented case of writing 1 to bit 2 causing a lock-up with
+at least one OX12PCI840 device (from old drivers/parport/ChangeLog):
+
+2001-10-10 Tim Waugh <twaugh@redhat.com>
+
+ * parport_pc.c: Support for OX12PCI840 PCI card (reported by
+ mk@daveg.com). Lock-ups diagnosed by Ronnie Arosa (and now we
+ just don't trust its ECR).
+
+which commit adbd321a17cc ("parport_pc: add base_hi BAR for oxsemi_840")
+must have broken and by applying an ECR mask here we prevent the lock-up
+from triggering. This could have been the reason for requiring 00001 to
+be written to bits 4:0 of ECR.
+
+Update the inline comment accordingly; it has come from Linux 2.4.12
+back in 2001 and predates the introduction of OXmPCI954 and OXuPCI954
+devices that do support ECP.
+
+References:
+
+[1] "OX16PCI954 Integrated Quad UART and PCI interface", Oxford
+ Semiconductor Ltd., Data Sheet Revision 1.3, Feb. 1999, Chapter 9
+ "Bidirectional Parallel Port", pp. 53-55
+
+[2] "OX16PCI952 Data Sheet, Integrated High Performance Dual UARTs,
+ Parallel Port and 5.0v PCI interface", Oxford Semiconductor Ltd.,
+ DS_B008A_00, Datasheet rev 1.1, June 2001, Chapter 8 "Bi-directional
+ Parallel Port", pp. 52-56
+
+[3] "OXmPCI954 DATA SHEET Integrated High Performance Quad UARTs, 8-bit
+ Local Bus/Parallel Port. 3.3v PCI/miniPCI interface.", Oxford
+ Semiconductor Ltd., DS-0019, June 2005, Chapter 10 "Bidirectional
+ Parallel Port", pp. 86-90
+
+[4] "OXmPCI952 Data Sheet, Integrated High Performance Dual UARTs, 8-bit
+ Local Bus/Parallel Port. 3.3v PCI/miniPCI interface.", Oxford
+ Semiconductor Ltd., DS-0020, June 2005, Chapter 8 "Bidirectional
+ Parallel Port", pp. 73-77
+
+[5] "OX12PCI840 Integrated Parallel Port and PCI interface", Oxford
+ Semiconductor Ltd., DS-0021, Jun 2005, Chapter 5 "Bi-directional
+ Parallel Port", pp. 18-21
+
+[6] "OXPCIe952 PCI Express Bridge to Dual Serial & Parallel Port",
+ Oxford Semiconductor, Inc., DS-0046, Mar 06 08, Chapter "Parallel
+ Port Function", pp. 59-62
+
+[7] "OXPCIe840 PCI Express Bridge to Parallel Port", Oxford
+ Semiconductor, Inc., DS-0049, Mar 06 08, Chapter "Parallel Port
+ Function", pp. 15-18
+
+[8] "OXuPCI954 Data Sheet, Integrated High Performance Quad UARTs, 8-bit
+ Local Bus/Parallel Port, 3.3 V and 5 V (Universal Voltage) PCI
+ Interface.", Oxford Semiconductor, Inc., DS-0058, 26 Jan 2009,
+ Chapter 8 "Bidirectional Parallel Port", pp. 62-65
+
+[9] "OXuPCI952 Data Sheet, Integrated High Performance Dual UARTs, 8-bit
+ Local Bus/Parallel Port, 3.3 V and 5.0 V Universal Voltage PCI
+ Interface.", Oxford Semiconductor, Inc., DS-0059, Sep 2007, Chapter
+ 8 "Bidirectional Parallel Port", pp. 61-64
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Link: https://lore.kernel.org/r/20230108215656.6433-6-sudipm.mukherjee@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/parport/parport_pc.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
+index 5784dc20fb382..d6c63c7044608 100644
+--- a/drivers/parport/parport_pc.c
++++ b/drivers/parport/parport_pc.c
+@@ -2658,12 +2658,19 @@ static struct parport_pc_pci {
+ /* titan_010l */ { 1, { { 3, -1 }, } },
+ /* avlab_1p */ { 1, { { 0, 1}, } },
+ /* avlab_2p */ { 2, { { 0, 1}, { 2, 3 },} },
+- /* The Oxford Semi cards are unusual: 954 doesn't support ECP,
+- * and 840 locks up if you write 1 to bit 2! */
+- /* oxsemi_952 */ { 1, { { 0, 1 }, } },
+- /* oxsemi_954 */ { 1, { { 0, -1 }, } },
+- /* oxsemi_840 */ { 1, { { 0, 1 }, } },
+- /* oxsemi_pcie_pport */ { 1, { { 0, 1 }, } },
++ /* The Oxford Semi cards are unusual: older variants of 954 don't
++ * support ECP, and 840 locks up if you write 1 to bit 2! None
++ * implement nFault or service interrupts and all require 00001
++ * bit pattern to be used for bits 4:0 with ECR writes. */
++ /* oxsemi_952 */ { 1, { { 0, 1 }, },
++ PARPORT_MODE_COMPAT, ECR_MODE_MASK },
++ /* oxsemi_954 */ { 1, { { 0, 1 }, },
++ PARPORT_MODE_ECP |
++ PARPORT_MODE_COMPAT, ECR_MODE_MASK },
++ /* oxsemi_840 */ { 1, { { 0, 1 }, },
++ PARPORT_MODE_COMPAT, ECR_MODE_MASK },
++ /* oxsemi_pcie_pport */ { 1, { { 0, 1 }, },
++ PARPORT_MODE_COMPAT, ECR_MODE_MASK },
+ /* aks_0100 */ { 1, { { 0, -1 }, } },
+ /* mobility_pp */ { 1, { { 0, 1 }, } },
+ /* netmos_9900 */ { 1, { { 0, -1 }, } },
+--
+2.39.2
+
--- /dev/null
+From 8c445143619afa525b1eb9b01874d1f381c3412c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Jan 2023 21:51:24 +0100
+Subject: PCI/ACPI: Account for _S0W of the target bridge in
+ acpi_pci_bridge_d3()
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 8133844a8f2434be9576850c6978179d7cca5c81 ]
+
+It is questionable to allow a PCI bridge to go into D3 if it has _S0W
+returning D2 or a shallower power state, so modify acpi_pci_bridge_d3(() to
+always take the return value of _S0W for the target bridge into account.
+That is, make it return 'false' if _S0W returns D2 or a shallower power
+state for the target bridge regardless of its ancestor Root Port
+properties. Of course, this also causes 'false' to be returned if the Root
+Port itself is the target and its _S0W returns D2 or a shallower power
+state.
+
+However, still allow bridges without _S0W that are power-manageable via
+ACPI to enter D3 to retain the current code behavior in that case.
+
+This fixes problems where a hotplug notification is missed because a bridge
+is in D3. That means hot-added devices such as USB4 docks (and the devices
+they contain) and Thunderbolt 3 devices may not work.
+
+Link: https://lore.kernel.org/linux-pci/20221031223356.32570-1-mario.limonciello@amd.com/
+Link: https://lore.kernel.org/r/12155458.O9o76ZdvQC@kreacher
+Reported-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/device_pm.c | 19 +++++++++++++++++
+ drivers/pci/pci-acpi.c | 45 +++++++++++++++++++++++++++-------------
+ include/acpi/acpi_bus.h | 1 +
+ 3 files changed, 51 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
+index 97450f4003cc9..f007116a84276 100644
+--- a/drivers/acpi/device_pm.c
++++ b/drivers/acpi/device_pm.c
+@@ -484,6 +484,25 @@ void acpi_dev_power_up_children_with_adr(struct acpi_device *adev)
+ acpi_dev_for_each_child(adev, acpi_power_up_if_adr_present, NULL);
+ }
+
++/**
++ * acpi_dev_power_state_for_wake - Deepest power state for wakeup signaling
++ * @adev: ACPI companion of the target device.
++ *
++ * Evaluate _S0W for @adev and return the value produced by it or return
++ * ACPI_STATE_UNKNOWN on errors (including _S0W not present).
++ */
++u8 acpi_dev_power_state_for_wake(struct acpi_device *adev)
++{
++ unsigned long long state;
++ acpi_status status;
++
++ status = acpi_evaluate_integer(adev->handle, "_S0W", NULL, &state);
++ if (ACPI_FAILURE(status))
++ return ACPI_STATE_UNKNOWN;
++
++ return state;
++}
++
+ #ifdef CONFIG_PM
+ static DEFINE_MUTEX(acpi_pm_notifier_lock);
+ static DEFINE_MUTEX(acpi_pm_notifier_install_lock);
+diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
+index a46fec776ad77..1698205dd73cb 100644
+--- a/drivers/pci/pci-acpi.c
++++ b/drivers/pci/pci-acpi.c
+@@ -976,24 +976,41 @@ bool acpi_pci_power_manageable(struct pci_dev *dev)
+ bool acpi_pci_bridge_d3(struct pci_dev *dev)
+ {
+ struct pci_dev *rpdev;
+- struct acpi_device *adev;
+- acpi_status status;
+- unsigned long long state;
++ struct acpi_device *adev, *rpadev;
+ const union acpi_object *obj;
+
+ if (acpi_pci_disabled || !dev->is_hotplug_bridge)
+ return false;
+
+- /* Assume D3 support if the bridge is power-manageable by ACPI. */
+- if (acpi_pci_power_manageable(dev))
+- return true;
++ adev = ACPI_COMPANION(&dev->dev);
++ if (adev) {
++ /*
++ * If the bridge has _S0W, whether or not it can go into D3
++ * depends on what is returned by that object. In particular,
++ * if the power state returned by _S0W is D2 or shallower,
++ * entering D3 should not be allowed.
++ */
++ if (acpi_dev_power_state_for_wake(adev) <= ACPI_STATE_D2)
++ return false;
++
++ /*
++ * Otherwise, assume that the bridge can enter D3 so long as it
++ * is power-manageable via ACPI.
++ */
++ if (acpi_device_power_manageable(adev))
++ return true;
++ }
+
+ rpdev = pcie_find_root_port(dev);
+ if (!rpdev)
+ return false;
+
+- adev = ACPI_COMPANION(&rpdev->dev);
+- if (!adev)
++ if (rpdev == dev)
++ rpadev = adev;
++ else
++ rpadev = ACPI_COMPANION(&rpdev->dev);
++
++ if (!rpadev)
+ return false;
+
+ /*
+@@ -1001,15 +1018,15 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev)
+ * doesn't supply a wakeup GPE via _PRW, it cannot signal hotplug
+ * events from low-power states including D3hot and D3cold.
+ */
+- if (!adev->wakeup.flags.valid)
++ if (!rpadev->wakeup.flags.valid)
+ return false;
+
+ /*
+- * If the Root Port cannot wake itself from D3hot or D3cold, we
+- * can't use D3.
++ * In the bridge-below-a-Root-Port case, evaluate _S0W for the Root Port
++ * to verify whether or not it can signal wakeup from D3.
+ */
+- status = acpi_evaluate_integer(adev->handle, "_S0W", NULL, &state);
+- if (ACPI_SUCCESS(status) && state < ACPI_STATE_D3_HOT)
++ if (rpadev != adev &&
++ acpi_dev_power_state_for_wake(rpadev) <= ACPI_STATE_D2)
+ return false;
+
+ /*
+@@ -1018,7 +1035,7 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev)
+ * bridges *below* that Root Port can also signal hotplug events
+ * while in D3.
+ */
+- if (!acpi_dev_get_property(adev, "HotPlugSupportInD3",
++ if (!acpi_dev_get_property(rpadev, "HotPlugSupportInD3",
+ ACPI_TYPE_INTEGER, &obj) &&
+ obj->integer.value == 1)
+ return true;
+diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
+index ab2d6266038a0..6badc50ec4e66 100644
+--- a/include/acpi/acpi_bus.h
++++ b/include/acpi/acpi_bus.h
+@@ -534,6 +534,7 @@ int acpi_bus_update_power(acpi_handle handle, int *state_p);
+ int acpi_device_update_power(struct acpi_device *device, int *state_p);
+ bool acpi_bus_power_manageable(acpi_handle handle);
+ void acpi_dev_power_up_children_with_adr(struct acpi_device *adev);
++u8 acpi_dev_power_state_for_wake(struct acpi_device *adev);
+ int acpi_device_power_add_dependent(struct acpi_device *adev,
+ struct device *dev);
+ void acpi_device_power_remove_dependent(struct acpi_device *adev,
+--
+2.39.2
+
--- /dev/null
+From 32e03d33b58cda9579c0ba35fbdfd3d3c35418f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Feb 2023 18:24:19 +0800
+Subject: PCI: Add ACS quirk for Wangxun NICs
+
+From: Mengyuan Lou <mengyuanlou@net-swift.com>
+
+[ Upstream commit a2b9b123ccac913e9f9b80337d687a2fe786a634 ]
+
+Wangxun has verified there is no peer-to-peer between functions for the
+below selection of SFxxx, RP1000 and RP2000 NICS. They may be
+multi-function devices, but the hardware does not advertise ACS capability.
+
+Add an ACS quirk for these devices so the functions can be in independent
+IOMMU groups.
+
+Link: https://lore.kernel.org/r/20230207102419.44326-1-mengyuanlou@net-swift.com
+Signed-off-by: Mengyuan Lou <mengyuanlou@net-swift.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/quirks.c | 22 ++++++++++++++++++++++
+ include/linux/pci_ids.h | 2 ++
+ 2 files changed, 24 insertions(+)
+
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 20ac67d590348..494fa46f57671 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -4835,6 +4835,26 @@ static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags)
+ PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
+ }
+
++/*
++ * Wangxun 10G/1G NICs have no ACS capability, and on multi-function
++ * devices, peer-to-peer transactions are not be used between the functions.
++ * So add an ACS quirk for below devices to isolate functions.
++ * SFxxx 1G NICs(em).
++ * RP1000/RP2000 10G NICs(sp).
++ */
++static int pci_quirk_wangxun_nic_acs(struct pci_dev *dev, u16 acs_flags)
++{
++ switch (dev->device) {
++ case 0x0100 ... 0x010F:
++ case 0x1001:
++ case 0x2001:
++ return pci_acs_ctrl_enabled(acs_flags,
++ PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
++ }
++
++ return false;
++}
++
+ static const struct pci_dev_acs_enabled {
+ u16 vendor;
+ u16 device;
+@@ -4980,6 +5000,8 @@ static const struct pci_dev_acs_enabled {
+ { PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs },
+ /* Zhaoxin Root/Downstream Ports */
+ { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs },
++ /* Wangxun nics */
++ { PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs },
+ { 0 }
+ };
+
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index b362d90eb9b0b..bc8f484cdcf3b 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -3012,6 +3012,8 @@
+ #define PCI_DEVICE_ID_INTEL_VMD_9A0B 0x9a0b
+ #define PCI_DEVICE_ID_INTEL_S21152BB 0xb152
+
++#define PCI_VENDOR_ID_WANGXUN 0x8088
++
+ #define PCI_VENDOR_ID_SCALEMP 0x8686
+ #define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010
+
+--
+2.39.2
+
--- /dev/null
+From 33a89c4daf188503632c301161ff94e2f67c2e32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 11:24:03 +0200
+Subject: PCI: Align extra resources for hotplug bridges properly
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 08f0a15ee8adb4846b08ca5d5c175fbf0f652bc9 ]
+
+After division the extra resource space per hotplug bridge may not be
+aligned according to the window alignment, so align it before passing it
+down for further distribution.
+
+Link: https://lore.kernel.org/r/20230131092405.29121-2-mika.westerberg@linux.intel.com
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index b4096598dbcbb..e440f264accb8 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -1891,6 +1891,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
+ * resource space between hotplug bridges.
+ */
+ for_each_pci_bridge(dev, bus) {
++ struct resource *res;
+ struct pci_bus *b;
+
+ b = dev->subordinate;
+@@ -1902,16 +1903,28 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
+ * hotplug-capable downstream ports taking alignment into
+ * account.
+ */
+- io.end = io.start + io_per_hp - 1;
+- mmio.end = mmio.start + mmio_per_hp - 1;
+- mmio_pref.end = mmio_pref.start + mmio_pref_per_hp - 1;
++ res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
++ align = pci_resource_alignment(dev, res);
++ io.end = align ? io.start + ALIGN_DOWN(io_per_hp, align) - 1
++ : io.start + io_per_hp - 1;
++
++ res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
++ align = pci_resource_alignment(dev, res);
++ mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_hp, align) - 1
++ : mmio.start + mmio_per_hp - 1;
++
++ res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
++ align = pci_resource_alignment(dev, res);
++ mmio_pref.end = align ? mmio_pref.start +
++ ALIGN_DOWN(mmio_pref_per_hp, align) - 1
++ : mmio_pref.start + mmio_pref_per_hp - 1;
+
+ pci_bus_distribute_available_resources(b, add_list, io, mmio,
+ mmio_pref);
+
+- io.start += io_per_hp;
+- mmio.start += mmio_per_hp;
+- mmio_pref.start += mmio_pref_per_hp;
++ io.start += io.end + 1;
++ mmio.start += mmio.end + 1;
++ mmio_pref.start += mmio_pref.end + 1;
+ }
+ }
+
+--
+2.39.2
+
--- /dev/null
+From a2d6de708140c5b8b073e5831d9feeb85d29af61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 11:24:05 +0200
+Subject: PCI: Distribute available resources for root buses, too
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 7180c1d08639f28e63110ad35815f7a1785b8a19 ]
+
+Previously we distributed spare resources only upon hot-add, so if the
+initial root bus scan found devices that had not been fully configured by
+the BIOS, we allocated only enough resources to cover what was then
+present. If some of those devices were hotplug bridges, we did not leave
+any additional resource space for future expansion.
+
+Distribute the available resources for root buses, too, to make this work
+the same way as the normal hotplug case.
+
+A previous commit to do this was reverted due to a regression reported by
+Jonathan Cameron:
+
+ e96e27fc6f79 ("PCI: Distribute available resources for root buses, too")
+ 5632e2beaf9d ("Revert "PCI: Distribute available resources for root buses, too"")
+
+This commit changes pci_bridge_resources_not_assigned() to work with
+bridges that do not have all the resource windows programmed by the boot
+firmware (previously we expected all I/O, memory and prefetchable memory
+were programmed).
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216000
+Link: https://lore.kernel.org/r/20220905080232.36087-5-mika.westerberg@linux.intel.com
+Link: https://lore.kernel.org/r/20230131092405.29121-4-mika.westerberg@linux.intel.com
+Reported-by: Chris Chiu <chris.chiu@canonical.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 57 ++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 56 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index b7b8dddb77722..c690572b10ce7 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -1770,7 +1770,10 @@ static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res,
+ }
+
+ res->end = res->start + new_size - 1;
+- remove_from_list(add_list, res);
++
++ /* If the resource is part of the add_list, remove it now */
++ if (add_list)
++ remove_from_list(add_list, res);
+ }
+
+ static void remove_dev_resource(struct resource *avail, struct pci_dev *dev,
+@@ -1972,6 +1975,8 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge,
+ if (!bridge->is_hotplug_bridge)
+ return;
+
++ pci_dbg(bridge, "distributing available resources\n");
++
+ /* Take the initial extra resources from the hotplug port */
+ available_io = bridge->resource[PCI_BRIDGE_IO_WINDOW];
+ available_mmio = bridge->resource[PCI_BRIDGE_MEM_WINDOW];
+@@ -1983,6 +1988,54 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge,
+ available_mmio_pref);
+ }
+
++static bool pci_bridge_resources_not_assigned(struct pci_dev *dev)
++{
++ const struct resource *r;
++
++ /*
++ * If the child device's resources are not yet assigned it means we
++ * are configuring them (not the boot firmware), so we should be
++ * able to extend the upstream bridge resources in the same way we
++ * do with the normal hotplug case.
++ */
++ r = &dev->resource[PCI_BRIDGE_IO_WINDOW];
++ if (r->flags && !(r->flags & IORESOURCE_STARTALIGN))
++ return false;
++ r = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
++ if (r->flags && !(r->flags & IORESOURCE_STARTALIGN))
++ return false;
++ r = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
++ if (r->flags && !(r->flags & IORESOURCE_STARTALIGN))
++ return false;
++
++ return true;
++}
++
++static void
++pci_root_bus_distribute_available_resources(struct pci_bus *bus,
++ struct list_head *add_list)
++{
++ struct pci_dev *dev, *bridge = bus->self;
++
++ for_each_pci_bridge(dev, bus) {
++ struct pci_bus *b;
++
++ b = dev->subordinate;
++ if (!b)
++ continue;
++
++ /*
++ * Need to check "bridge" here too because it is NULL
++ * in case of root bus.
++ */
++ if (bridge && pci_bridge_resources_not_assigned(dev))
++ pci_bridge_distribute_available_resources(bridge,
++ add_list);
++ else
++ pci_root_bus_distribute_available_resources(b, add_list);
++ }
++}
++
+ /*
+ * First try will not touch PCI bridge res.
+ * Second and later try will clear small leaf bridge res.
+@@ -2022,6 +2075,8 @@ void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus)
+ */
+ __pci_bus_size_bridges(bus, add_list);
+
++ pci_root_bus_distribute_available_resources(bus, add_list);
++
+ /* Depth last, allocate resources and update the hardware. */
+ __pci_bus_assign_resources(bus, add_list, &fail_head);
+ if (add_list)
+--
+2.39.2
+
--- /dev/null
+From 2ae00559bb40360fac50197b1d7723666596ed95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Feb 2023 10:33:21 +0800
+Subject: PCI: loongson: Add more devices that need MRRS quirk
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+[ Upstream commit c768f8c5f40fcdc6f058cc2f02592163d6c6716c ]
+
+Loongson-2K SOC and LS7A2000 chipset add new PCI IDs that need MRRS
+quirk. Add them.
+
+Link: https://lore.kernel.org/r/20230211023321.3530080-1-chenhuacai@loongson.cn
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pci-loongson.c | 33 +++++++++++++++++++--------
+ 1 file changed, 24 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c
+index 759ec211c17bf..fe0f732f6e434 100644
+--- a/drivers/pci/controller/pci-loongson.c
++++ b/drivers/pci/controller/pci-loongson.c
+@@ -15,9 +15,14 @@
+ #include "../pci.h"
+
+ /* Device IDs */
+-#define DEV_PCIE_PORT_0 0x7a09
+-#define DEV_PCIE_PORT_1 0x7a19
+-#define DEV_PCIE_PORT_2 0x7a29
++#define DEV_LS2K_PCIE_PORT0 0x1a05
++#define DEV_LS7A_PCIE_PORT0 0x7a09
++#define DEV_LS7A_PCIE_PORT1 0x7a19
++#define DEV_LS7A_PCIE_PORT2 0x7a29
++#define DEV_LS7A_PCIE_PORT3 0x7a39
++#define DEV_LS7A_PCIE_PORT4 0x7a49
++#define DEV_LS7A_PCIE_PORT5 0x7a59
++#define DEV_LS7A_PCIE_PORT6 0x7a69
+
+ #define DEV_LS2K_APB 0x7a02
+ #define DEV_LS7A_GMAC 0x7a03
+@@ -53,11 +58,11 @@ static void bridge_class_quirk(struct pci_dev *dev)
+ dev->class = PCI_CLASS_BRIDGE_PCI_NORMAL;
+ }
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
+- DEV_PCIE_PORT_0, bridge_class_quirk);
++ DEV_LS7A_PCIE_PORT0, bridge_class_quirk);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
+- DEV_PCIE_PORT_1, bridge_class_quirk);
++ DEV_LS7A_PCIE_PORT1, bridge_class_quirk);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
+- DEV_PCIE_PORT_2, bridge_class_quirk);
++ DEV_LS7A_PCIE_PORT2, bridge_class_quirk);
+
+ static void system_bus_quirk(struct pci_dev *pdev)
+ {
+@@ -87,11 +92,21 @@ static void loongson_mrrs_quirk(struct pci_dev *pdev)
+ bridge->no_inc_mrrs = 1;
+ }
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
+- DEV_PCIE_PORT_0, loongson_mrrs_quirk);
++ DEV_LS2K_PCIE_PORT0, loongson_mrrs_quirk);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
+- DEV_PCIE_PORT_1, loongson_mrrs_quirk);
++ DEV_LS7A_PCIE_PORT0, loongson_mrrs_quirk);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
+- DEV_PCIE_PORT_2, loongson_mrrs_quirk);
++ DEV_LS7A_PCIE_PORT1, loongson_mrrs_quirk);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
++ DEV_LS7A_PCIE_PORT2, loongson_mrrs_quirk);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
++ DEV_LS7A_PCIE_PORT3, loongson_mrrs_quirk);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
++ DEV_LS7A_PCIE_PORT4, loongson_mrrs_quirk);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
++ DEV_LS7A_PCIE_PORT5, loongson_mrrs_quirk);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
++ DEV_LS7A_PCIE_PORT6, loongson_mrrs_quirk);
+
+ static void loongson_pci_pin_quirk(struct pci_dev *pdev)
+ {
+--
+2.39.2
+
--- /dev/null
+From fd83124ecd7bb74b4c54d2b206a3656b85e151b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Feb 2023 12:30:18 +0800
+Subject: PCI: loongson: Prevent LS7A MRRS increases
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+[ Upstream commit 8b3517f88ff2983f52698893519227c10aac90b2 ]
+
+Except for isochronous-configured devices, software may set
+Max_Read_Request_Size (MRRS) to any value up to 4096. If a device issues a
+read request with size greater than the completer's Max_Payload_Size (MPS),
+the completer is required to break the response into multiple completions.
+
+Instead of correctly responding with multiple completions to a large read
+request, some LS7A Root Ports respond with a Completer Abort. To prevent
+this, the MRRS must be limited to an implementation-specific value.
+
+The OS cannot detect that value, so rely on BIOS to configure MRRS before
+booting, and quirk the Root Ports so we never set an MRRS larger than that
+BIOS value for any downstream device.
+
+N.B. Hot-added devices are not configured by BIOS, and they power up with
+MRRS = 512 bytes, so these devices will be limited to 512 bytes. If the
+LS7A limit is smaller, those hot-added devices may not work correctly, but
+per [1], hotplug is not supported with this chipset revision.
+
+[1] https://lore.kernel.org/r/073638a7-ae68-2847-ac3d-29e5e760d6af@loongson.cn
+
+[bhelgaas: commit log]
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216884
+Link: https://lore.kernel.org/r/20230201043018.778499-3-chenhuacai@loongson.cn
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pci-loongson.c | 44 +++++++++------------------
+ drivers/pci/pci.c | 10 ++++++
+ include/linux/pci.h | 1 +
+ 3 files changed, 26 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c
+index 05c50408f13b7..759ec211c17bf 100644
+--- a/drivers/pci/controller/pci-loongson.c
++++ b/drivers/pci/controller/pci-loongson.c
+@@ -75,37 +75,23 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
+ DEV_LS7A_LPC, system_bus_quirk);
+
+-static void loongson_mrrs_quirk(struct pci_dev *dev)
++static void loongson_mrrs_quirk(struct pci_dev *pdev)
+ {
+- struct pci_bus *bus = dev->bus;
+- struct pci_dev *bridge;
+- static const struct pci_device_id bridge_devids[] = {
+- { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_0) },
+- { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_1) },
+- { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_2) },
+- { 0, },
+- };
+-
+- /* look for the matching bridge */
+- while (!pci_is_root_bus(bus)) {
+- bridge = bus->self;
+- bus = bus->parent;
+- /*
+- * Some Loongson PCIe ports have a h/w limitation of
+- * 256 bytes maximum read request size. They can't handle
+- * anything larger than this. So force this limit on
+- * any devices attached under these ports.
+- */
+- if (pci_match_id(bridge_devids, bridge)) {
+- if (pcie_get_readrq(dev) > 256) {
+- pci_info(dev, "limiting MRRS to 256\n");
+- pcie_set_readrq(dev, 256);
+- }
+- break;
+- }
+- }
++ /*
++ * Some Loongson PCIe ports have h/w limitations of maximum read
++ * request size. They can't handle anything larger than this. So
++ * force this limit on any devices attached under these ports.
++ */
++ struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
++
++ bridge->no_inc_mrrs = 1;
+ }
+-DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_mrrs_quirk);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
++ DEV_PCIE_PORT_0, loongson_mrrs_quirk);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
++ DEV_PCIE_PORT_1, loongson_mrrs_quirk);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON,
++ DEV_PCIE_PORT_2, loongson_mrrs_quirk);
+
+ static void loongson_pci_pin_quirk(struct pci_dev *pdev)
+ {
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index c20e95fd48cee..98d841a7b45bb 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -6017,6 +6017,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq)
+ {
+ u16 v;
+ int ret;
++ struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus);
+
+ if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
+ return -EINVAL;
+@@ -6035,6 +6036,15 @@ int pcie_set_readrq(struct pci_dev *dev, int rq)
+
+ v = (ffs(rq) - 8) << 12;
+
++ if (bridge->no_inc_mrrs) {
++ int max_mrrs = pcie_get_readrq(dev);
++
++ if (rq > max_mrrs) {
++ pci_info(dev, "can't set Max_Read_Request_Size to %d; max is %d\n", rq, max_mrrs);
++ return -EINVAL;
++ }
++ }
++
+ ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_READRQ, v);
+
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 2bda4a4e47e81..cb538bc579710 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -570,6 +570,7 @@ struct pci_host_bridge {
+ void *release_data;
+ unsigned int ignore_reset_delay:1; /* For entire hierarchy */
+ unsigned int no_ext_tags:1; /* No Extended Tags */
++ unsigned int no_inc_mrrs:1; /* No Increase MRRS */
+ unsigned int native_aer:1; /* OS may use PCIe AER */
+ unsigned int native_pcie_hotplug:1; /* OS may use PCIe hotplug */
+ unsigned int native_shpc_hotplug:1; /* OS may use SHPC hotplug */
+--
+2.39.2
+
--- /dev/null
+From 9a3397483eda49b09df12e8ba3c5fd1abddfb851 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Feb 2023 20:19:22 +0530
+Subject: PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 82b34b0800af8c9fc9988c290cdc813e0ca0df31 ]
+
+The Qualcomm PCI bridge device (Device ID 0x010e) found in chipsets such as
+SC8280XP used in Lenovo Thinkpad X13s, does not set the Command Completed
+bit unless writes to the Slot Command register change "Control" bits.
+
+This results in timeouts like below during boot and resume from suspend:
+
+ pcieport 0002:00:00.0: pciehp: Timeout on hotplug command 0x03c0 (issued 2020 msec ago)
+ ...
+ pcieport 0002:00:00.0: pciehp: Timeout on hotplug command 0x13f1 (issued 107724 msec ago)
+
+Add the device to the Command Completed quirk to mark commands "completed"
+immediately unless they change the "Control" bits.
+
+Link: https://lore.kernel.org/r/20230213144922.89982-1-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/pciehp_hpc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index 040ae076ec0e9..112c8f401ac4e 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -1086,6 +1086,8 @@ static void quirk_cmd_compl(struct pci_dev *pdev)
+ }
+ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+ PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
++DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x010e,
++ PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
+ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0110,
+ PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
+ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0400,
+--
+2.39.2
+
--- /dev/null
+From e6e80b687fe6c4b9dc30d1bc5bccabae13a6c495 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 11:24:04 +0200
+Subject: PCI: Take other bus devices into account when distributing resources
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 9db0b9b6a14249ef65a5f1e5e3b37762af96f425 ]
+
+A PCI bridge may reside on a bus with other devices as well. The resource
+distribution code does not take this into account and therefore it expands
+the bridge resource windows too much, not leaving space for the other
+devices (or functions of a multifunction device). This leads to an issue
+that Jonathan reported when running QEMU with the following topology (QEMU
+parameters):
+
+ -device pcie-root-port,port=0,id=root_port13,chassis=0,slot=2 \
+ -device x3130-upstream,id=sw1,bus=root_port13,multifunction=on \
+ -device e1000,bus=root_port13,addr=0.1 \
+ -device xio3130-downstream,id=fun1,bus=sw1,chassis=0,slot=3 \
+ -device e1000,bus=fun1
+
+The first e1000 NIC here is another function in the switch upstream port.
+This leads to following errors:
+
+ pci 0000:00:04.0: bridge window [mem 0x10200000-0x103fffff] to [bus 02-04]
+ pci 0000:02:00.0: bridge window [mem 0x10200000-0x103fffff] to [bus 03-04]
+ pci 0000:02:00.1: BAR 0: failed to assign [mem size 0x00020000]
+ e1000 0000:02:00.1: can't ioremap BAR 0: [??? 0x00000000 flags 0x0]
+
+Fix this by taking into account bridge windows, device BARs and SR-IOV PF
+BARs on the bus (PF BARs include space for VF BARS so only account PF
+BARs), including the ones belonging to bridges themselves if it has any.
+
+Link: https://lore.kernel.org/linux-pci/20221014124553.0000696f@huawei.com/
+Link: https://lore.kernel.org/linux-pci/6053736d-1923-41e7-def9-7585ce1772d9@ixsystems.com/
+Link: https://lore.kernel.org/r/20230131092405.29121-3-mika.westerberg@linux.intel.com
+Reported-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reported-by: Alexander Motin <mav@ixsystems.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 176 ++++++++++++++++++++++++----------------
+ 1 file changed, 106 insertions(+), 70 deletions(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index e440f264accb8..b7b8dddb77722 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -1765,12 +1765,67 @@ static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res,
+ add_size = size - new_size;
+ pci_dbg(bridge, "bridge window %pR shrunken by %pa\n", res,
+ &add_size);
++ } else {
++ return;
+ }
+
+ res->end = res->start + new_size - 1;
+ remove_from_list(add_list, res);
+ }
+
++static void remove_dev_resource(struct resource *avail, struct pci_dev *dev,
++ struct resource *res)
++{
++ resource_size_t size, align, tmp;
++
++ size = resource_size(res);
++ if (!size)
++ return;
++
++ align = pci_resource_alignment(dev, res);
++ align = align ? ALIGN(avail->start, align) - avail->start : 0;
++ tmp = align + size;
++ avail->start = min(avail->start + tmp, avail->end + 1);
++}
++
++static void remove_dev_resources(struct pci_dev *dev, struct resource *io,
++ struct resource *mmio,
++ struct resource *mmio_pref)
++{
++ int i;
++
++ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
++ struct resource *res = &dev->resource[i];
++
++ if (resource_type(res) == IORESOURCE_IO) {
++ remove_dev_resource(io, dev, res);
++ } else if (resource_type(res) == IORESOURCE_MEM) {
++
++ /*
++ * Make sure prefetchable memory is reduced from
++ * the correct resource. Specifically we put 32-bit
++ * prefetchable memory in non-prefetchable window
++ * if there is an 64-bit pretchable window.
++ *
++ * See comments in __pci_bus_size_bridges() for
++ * more information.
++ */
++ if ((res->flags & IORESOURCE_PREFETCH) &&
++ ((res->flags & IORESOURCE_MEM_64) ==
++ (mmio_pref->flags & IORESOURCE_MEM_64)))
++ remove_dev_resource(mmio_pref, dev, res);
++ else
++ remove_dev_resource(mmio, dev, res);
++ }
++ }
++}
++
++/*
++ * io, mmio and mmio_pref contain the total amount of bridge window space
++ * available. This includes the minimal space needed to cover all the
++ * existing devices on the bus and the possible extra space that can be
++ * shared with the bridges.
++ */
+ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
+ struct list_head *add_list,
+ struct resource io,
+@@ -1780,7 +1835,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
+ unsigned int normal_bridges = 0, hotplug_bridges = 0;
+ struct resource *io_res, *mmio_res, *mmio_pref_res;
+ struct pci_dev *dev, *bridge = bus->self;
+- resource_size_t io_per_hp, mmio_per_hp, mmio_pref_per_hp, align;
++ resource_size_t io_per_b, mmio_per_b, mmio_pref_per_b, align;
+
+ io_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
+ mmio_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW];
+@@ -1824,100 +1879,81 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
+ normal_bridges++;
+ }
+
+- /*
+- * There is only one bridge on the bus so it gets all available
+- * resources which it can then distribute to the possible hotplug
+- * bridges below.
+- */
+- if (hotplug_bridges + normal_bridges == 1) {
+- dev = list_first_entry(&bus->devices, struct pci_dev, bus_list);
+- if (dev->subordinate)
+- pci_bus_distribute_available_resources(dev->subordinate,
+- add_list, io, mmio, mmio_pref);
+- return;
+- }
+-
+- if (hotplug_bridges == 0)
++ if (!(hotplug_bridges + normal_bridges))
+ return;
+
+ /*
+- * Calculate the total amount of extra resource space we can
+- * pass to bridges below this one. This is basically the
+- * extra space reduced by the minimal required space for the
+- * non-hotplug bridges.
++ * Calculate the amount of space we can forward from "bus" to any
++ * downstream buses, i.e., the space left over after assigning the
++ * BARs and windows on "bus".
+ */
+- for_each_pci_bridge(dev, bus) {
+- resource_size_t used_size;
+- struct resource *res;
+-
+- if (dev->is_hotplug_bridge)
+- continue;
+-
+- /*
+- * Reduce the available resource space by what the
+- * bridge and devices below it occupy.
+- */
+- res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
+- align = pci_resource_alignment(dev, res);
+- align = align ? ALIGN(io.start, align) - io.start : 0;
+- used_size = align + resource_size(res);
+- if (!res->parent)
+- io.start = min(io.start + used_size, io.end + 1);
+-
+- res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
+- align = pci_resource_alignment(dev, res);
+- align = align ? ALIGN(mmio.start, align) - mmio.start : 0;
+- used_size = align + resource_size(res);
+- if (!res->parent)
+- mmio.start = min(mmio.start + used_size, mmio.end + 1);
+-
+- res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
+- align = pci_resource_alignment(dev, res);
+- align = align ? ALIGN(mmio_pref.start, align) -
+- mmio_pref.start : 0;
+- used_size = align + resource_size(res);
+- if (!res->parent)
+- mmio_pref.start = min(mmio_pref.start + used_size,
+- mmio_pref.end + 1);
++ list_for_each_entry(dev, &bus->devices, bus_list) {
++ if (!dev->is_virtfn)
++ remove_dev_resources(dev, &io, &mmio, &mmio_pref);
+ }
+
+- io_per_hp = div64_ul(resource_size(&io), hotplug_bridges);
+- mmio_per_hp = div64_ul(resource_size(&mmio), hotplug_bridges);
+- mmio_pref_per_hp = div64_ul(resource_size(&mmio_pref),
+- hotplug_bridges);
+-
+ /*
+- * Go over devices on this bus and distribute the remaining
+- * resource space between hotplug bridges.
++ * If there is at least one hotplug bridge on this bus it gets all
++ * the extra resource space that was left after the reductions
++ * above.
++ *
++ * If there are no hotplug bridges the extra resource space is
++ * split between non-hotplug bridges. This is to allow possible
++ * hotplug bridges below them to get the extra space as well.
+ */
++ if (hotplug_bridges) {
++ io_per_b = div64_ul(resource_size(&io), hotplug_bridges);
++ mmio_per_b = div64_ul(resource_size(&mmio), hotplug_bridges);
++ mmio_pref_per_b = div64_ul(resource_size(&mmio_pref),
++ hotplug_bridges);
++ } else {
++ io_per_b = div64_ul(resource_size(&io), normal_bridges);
++ mmio_per_b = div64_ul(resource_size(&mmio), normal_bridges);
++ mmio_pref_per_b = div64_ul(resource_size(&mmio_pref),
++ normal_bridges);
++ }
++
+ for_each_pci_bridge(dev, bus) {
+ struct resource *res;
+ struct pci_bus *b;
+
+ b = dev->subordinate;
+- if (!b || !dev->is_hotplug_bridge)
++ if (!b)
+ continue;
++ if (hotplug_bridges && !dev->is_hotplug_bridge)
++ continue;
++
++ res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
+
+ /*
+- * Distribute available extra resources equally between
+- * hotplug-capable downstream ports taking alignment into
+- * account.
++ * Make sure the split resource space is properly aligned
++ * for bridge windows (align it down to avoid going above
++ * what is available).
+ */
+- res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
+ align = pci_resource_alignment(dev, res);
+- io.end = align ? io.start + ALIGN_DOWN(io_per_hp, align) - 1
+- : io.start + io_per_hp - 1;
++ io.end = align ? io.start + ALIGN_DOWN(io_per_b, align) - 1
++ : io.start + io_per_b - 1;
++
++ /*
++ * The x_per_b holds the extra resource space that can be
++ * added for each bridge but there is the minimal already
++ * reserved as well so adjust x.start down accordingly to
++ * cover the whole space.
++ */
++ io.start -= resource_size(res);
+
+ res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
+ align = pci_resource_alignment(dev, res);
+- mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_hp, align) - 1
+- : mmio.start + mmio_per_hp - 1;
++ mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_b, align) - 1
++ : mmio.start + mmio_per_b - 1;
++ mmio.start -= resource_size(res);
+
+ res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
+ align = pci_resource_alignment(dev, res);
+ mmio_pref.end = align ? mmio_pref.start +
+- ALIGN_DOWN(mmio_pref_per_hp, align) - 1
+- : mmio_pref.start + mmio_pref_per_hp - 1;
++ ALIGN_DOWN(mmio_pref_per_b, align) - 1
++ : mmio_pref.start + mmio_pref_per_b - 1;
++ mmio_pref.start -= resource_size(res);
+
+ pci_bus_distribute_available_resources(b, add_list, io, mmio,
+ mmio_pref);
+--
+2.39.2
+
--- /dev/null
+From 70919a2c78c967e214be6349a633793431f6979c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Feb 2023 11:57:09 +0800
+Subject: phy: rockchip-typec: Fix unsigned comparison with less than zero
+
+From: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+
+[ Upstream commit f765c59c5a72546a2d74a92ae5d0eb0329d8e247 ]
+
+The dp and ufp are defined as bool type, the return value type of
+function extcon_get_state should be int, so the type of dp and ufp
+are modified to int.
+
+./drivers/phy/rockchip/phy-rockchip-typec.c:827:12-14: WARNING: Unsigned expression compared with zero: dp > 0.
+
+Reported-by: Abaci Robot <abaci@linux.alibaba.com>
+Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3962
+Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20230213035709.99027-1-jiapeng.chong@linux.alibaba.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-typec.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
+index 6aea512e5d4ee..39db8acde61af 100644
+--- a/drivers/phy/rockchip/phy-rockchip-typec.c
++++ b/drivers/phy/rockchip/phy-rockchip-typec.c
+@@ -808,9 +808,8 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
+ struct extcon_dev *edev = tcphy->extcon;
+ union extcon_property_value property;
+ unsigned int id;
+- bool ufp, dp;
+ u8 mode;
+- int ret;
++ int ret, ufp, dp;
+
+ if (!edev)
+ return MODE_DFP_USB;
+--
+2.39.2
+
--- /dev/null
+From 2d573dbd8acca835b3b6dfa32a67ace2d50ac619 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Feb 2023 14:06:16 +0100
+Subject: ptp: vclock: use mutex to fix "sleep on atomic" bug
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Íñigo Huguet <ihuguet@redhat.com>
+
+[ Upstream commit 67d93ffc0f3c47094750bde6d62e7c5765dc47a6 ]
+
+vclocks were using spinlocks to protect access to its timecounter and
+cyclecounter. Access to timecounter/cyclecounter is backed by the same
+driver callbacks that are used for non-virtual PHCs, but the usage of
+the spinlock imposes a new limitation that didn't exist previously: now
+they're called in atomic context so they mustn't sleep.
+
+Some drivers like sfc or ice may sleep on these callbacks, causing
+errors like "BUG: scheduling while atomic: ptp5/25223/0x00000002"
+
+Fix it replacing the vclock's spinlock by a mutex. It fix the mentioned
+bug and it doesn't introduce longer delays.
+
+I've tested synchronizing various different combinations of clocks:
+- vclock->sysclock
+- sysclock->vclock
+- vclock->vclock
+- hardware PHC in different NIC -> vclock
+- created 4 vclocks and launch 4 parallel phc2sys processes with
+ lockdep enabled
+
+In all cases, comparing the delays reported by phc2sys, they are in the
+same range of values than before applying the patch.
+
+Link: https://lore.kernel.org/netdev/69d0ff33-bd32-6aa5-d36c-fbdc3c01337c@redhat.com/
+Fixes: 5d43f951b1ac ("ptp: add ptp virtual clock driver framework")
+Reported-by: Yalin Li <yalli@redhat.com>
+Suggested-by: Richard Cochran <richardcochran@gmail.com>
+Tested-by: Miroslav Lichvar <mlichvar@redhat.com>
+Signed-off-by: Íñigo Huguet <ihuguet@redhat.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://lore.kernel.org/r/20230221130616.21837-1-ihuguet@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_private.h | 2 +-
+ drivers/ptp/ptp_vclock.c | 44 +++++++++++++++++++--------------------
+ 2 files changed, 23 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
+index 77918a2c67018..75f58fc468a71 100644
+--- a/drivers/ptp/ptp_private.h
++++ b/drivers/ptp/ptp_private.h
+@@ -66,7 +66,7 @@ struct ptp_vclock {
+ struct hlist_node vclock_hash_node;
+ struct cyclecounter cc;
+ struct timecounter tc;
+- spinlock_t lock; /* protects tc/cc */
++ struct mutex lock; /* protects tc/cc */
+ };
+
+ /*
+diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c
+index 1c0ed4805c0aa..dcf752c9e0450 100644
+--- a/drivers/ptp/ptp_vclock.c
++++ b/drivers/ptp/ptp_vclock.c
+@@ -43,16 +43,16 @@ static void ptp_vclock_hash_del(struct ptp_vclock *vclock)
+ static int ptp_vclock_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+ {
+ struct ptp_vclock *vclock = info_to_vclock(ptp);
+- unsigned long flags;
+ s64 adj;
+
+ adj = (s64)scaled_ppm << PTP_VCLOCK_FADJ_SHIFT;
+ adj = div_s64(adj, PTP_VCLOCK_FADJ_DENOMINATOR);
+
+- spin_lock_irqsave(&vclock->lock, flags);
++ if (mutex_lock_interruptible(&vclock->lock))
++ return -EINTR;
+ timecounter_read(&vclock->tc);
+ vclock->cc.mult = PTP_VCLOCK_CC_MULT + adj;
+- spin_unlock_irqrestore(&vclock->lock, flags);
++ mutex_unlock(&vclock->lock);
+
+ return 0;
+ }
+@@ -60,11 +60,11 @@ static int ptp_vclock_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+ static int ptp_vclock_adjtime(struct ptp_clock_info *ptp, s64 delta)
+ {
+ struct ptp_vclock *vclock = info_to_vclock(ptp);
+- unsigned long flags;
+
+- spin_lock_irqsave(&vclock->lock, flags);
++ if (mutex_lock_interruptible(&vclock->lock))
++ return -EINTR;
+ timecounter_adjtime(&vclock->tc, delta);
+- spin_unlock_irqrestore(&vclock->lock, flags);
++ mutex_unlock(&vclock->lock);
+
+ return 0;
+ }
+@@ -73,12 +73,12 @@ static int ptp_vclock_gettime(struct ptp_clock_info *ptp,
+ struct timespec64 *ts)
+ {
+ struct ptp_vclock *vclock = info_to_vclock(ptp);
+- unsigned long flags;
+ u64 ns;
+
+- spin_lock_irqsave(&vclock->lock, flags);
++ if (mutex_lock_interruptible(&vclock->lock))
++ return -EINTR;
+ ns = timecounter_read(&vclock->tc);
+- spin_unlock_irqrestore(&vclock->lock, flags);
++ mutex_unlock(&vclock->lock);
+ *ts = ns_to_timespec64(ns);
+
+ return 0;
+@@ -91,7 +91,6 @@ static int ptp_vclock_gettimex(struct ptp_clock_info *ptp,
+ struct ptp_vclock *vclock = info_to_vclock(ptp);
+ struct ptp_clock *pptp = vclock->pclock;
+ struct timespec64 pts;
+- unsigned long flags;
+ int err;
+ u64 ns;
+
+@@ -99,9 +98,10 @@ static int ptp_vclock_gettimex(struct ptp_clock_info *ptp,
+ if (err)
+ return err;
+
+- spin_lock_irqsave(&vclock->lock, flags);
++ if (mutex_lock_interruptible(&vclock->lock))
++ return -EINTR;
+ ns = timecounter_cyc2time(&vclock->tc, timespec64_to_ns(&pts));
+- spin_unlock_irqrestore(&vclock->lock, flags);
++ mutex_unlock(&vclock->lock);
+
+ *ts = ns_to_timespec64(ns);
+
+@@ -113,11 +113,11 @@ static int ptp_vclock_settime(struct ptp_clock_info *ptp,
+ {
+ struct ptp_vclock *vclock = info_to_vclock(ptp);
+ u64 ns = timespec64_to_ns(ts);
+- unsigned long flags;
+
+- spin_lock_irqsave(&vclock->lock, flags);
++ if (mutex_lock_interruptible(&vclock->lock))
++ return -EINTR;
+ timecounter_init(&vclock->tc, &vclock->cc, ns);
+- spin_unlock_irqrestore(&vclock->lock, flags);
++ mutex_unlock(&vclock->lock);
+
+ return 0;
+ }
+@@ -127,7 +127,6 @@ static int ptp_vclock_getcrosststamp(struct ptp_clock_info *ptp,
+ {
+ struct ptp_vclock *vclock = info_to_vclock(ptp);
+ struct ptp_clock *pptp = vclock->pclock;
+- unsigned long flags;
+ int err;
+ u64 ns;
+
+@@ -135,9 +134,10 @@ static int ptp_vclock_getcrosststamp(struct ptp_clock_info *ptp,
+ if (err)
+ return err;
+
+- spin_lock_irqsave(&vclock->lock, flags);
++ if (mutex_lock_interruptible(&vclock->lock))
++ return -EINTR;
+ ns = timecounter_cyc2time(&vclock->tc, ktime_to_ns(xtstamp->device));
+- spin_unlock_irqrestore(&vclock->lock, flags);
++ mutex_unlock(&vclock->lock);
+
+ xtstamp->device = ns_to_ktime(ns);
+
+@@ -205,7 +205,7 @@ struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock)
+
+ INIT_HLIST_NODE(&vclock->vclock_hash_node);
+
+- spin_lock_init(&vclock->lock);
++ mutex_init(&vclock->lock);
+
+ vclock->clock = ptp_clock_register(&vclock->info, &pclock->dev);
+ if (IS_ERR_OR_NULL(vclock->clock)) {
+@@ -269,7 +269,6 @@ ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index)
+ {
+ unsigned int hash = vclock_index % HASH_SIZE(vclock_hash);
+ struct ptp_vclock *vclock;
+- unsigned long flags;
+ u64 ns;
+ u64 vclock_ns = 0;
+
+@@ -281,9 +280,10 @@ ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index)
+ if (vclock->clock->index != vclock_index)
+ continue;
+
+- spin_lock_irqsave(&vclock->lock, flags);
++ if (mutex_lock_interruptible(&vclock->lock))
++ break;
+ vclock_ns = timecounter_cyc2time(&vclock->tc, ns);
+- spin_unlock_irqrestore(&vclock->lock, flags);
++ mutex_unlock(&vclock->lock);
+ break;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 79e9b0fd60f528b78108966cdd31a88347664557 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 12:37:24 +0100
+Subject: pwm: sifive: Always let the first pwm_apply_state succeed
+
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+
+[ Upstream commit 334c7b13d38321e47d1a51dba0bef9f4c403ec75 ]
+
+Commit 2cfe9bbec56ea579135cdd92409fff371841904f added support for the
+RGB and green PWM controlled LEDs on the HiFive Unmatched board
+managed by the leds-pwm-multicolor and leds-pwm drivers respectively.
+All three colours of the RGB LED and the green LED run from different
+lines of the same PWM, but with the same period so this works fine when
+the LED drivers are loaded one after the other.
+
+Unfortunately it does expose a race in the PWM driver when both LED
+drivers are loaded at roughly the same time. Here is an example:
+
+ | Thread A | Thread B |
+ | led_pwm_mc_probe | led_pwm_probe |
+ | devm_fwnode_pwm_get | |
+ | pwm_sifive_request | |
+ | ddata->user_count++ | |
+ | | devm_fwnode_pwm_get |
+ | | pwm_sifive_request |
+ | | ddata->user_count++ |
+ | ... | ... |
+ | pwm_state_apply | pwm_state_apply |
+ | pwm_sifive_apply | pwm_sifive_apply |
+
+Now both calls to pwm_sifive_apply will see that ddata->approx_period,
+initially 0, is different from the requested period and the clock needs
+to be updated. But since ddata->user_count >= 2 both calls will fail
+with -EBUSY, which will then cause both LED drivers to fail to probe.
+
+Fix it by letting the first call to pwm_sifive_apply update the clock
+even when ddata->user_count != 1.
+
+Fixes: 9e37a53eb051 ("pwm: sifive: Add a driver for SiFive SoC PWM")
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sifive.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index bb72393134016..89d53a0f91e65 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -159,7 +159,13 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+
+ mutex_lock(&ddata->lock);
+ if (state->period != ddata->approx_period) {
+- if (ddata->user_count != 1) {
++ /*
++ * Don't let a 2nd user change the period underneath the 1st user.
++ * However if ddate->approx_period == 0 this is the first time we set
++ * any period, so let whoever gets here first set the period so other
++ * users who agree on the period won't fail.
++ */
++ if (ddata->user_count != 1 && ddata->approx_period) {
+ mutex_unlock(&ddata->lock);
+ return -EBUSY;
+ }
+--
+2.39.2
+
--- /dev/null
+From 3161a1da080e79d91f054a80fffb10bc4173af91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 14:36:52 +0100
+Subject: pwm: stm32-lp: fix the check on arr and cmp registers update
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+
+[ Upstream commit 3066bc2d58be31275afb51a589668f265e419c37 ]
+
+The ARR (auto reload register) and CMP (compare) registers are
+successively written. The status bits to check the update of these
+registers are polled together with regmap_read_poll_timeout().
+The condition to end the loop may become true, even if one of the
+register isn't correctly updated.
+So ensure both status bits are set before clearing them.
+
+Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver")
+Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-stm32-lp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c
+index 3115abb3f52ab..61a1c87cd5016 100644
+--- a/drivers/pwm/pwm-stm32-lp.c
++++ b/drivers/pwm/pwm-stm32-lp.c
+@@ -127,7 +127,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+
+ /* ensure CMP & ARR registers are properly written */
+ ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
+- (val & STM32_LPTIM_CMPOK_ARROK),
++ (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
+ 100, 1000);
+ if (ret) {
+ dev_err(priv->chip.dev, "ARR/CMP registers write issue\n");
+--
+2.39.2
+
--- /dev/null
+From 590d6efa316bdbb62202b87f18af9a4a22ceb244 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Feb 2023 15:25:53 -0800
+Subject: RDMA/cma: Distinguish between sockaddr_in and sockaddr_in6 by size
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 876e480da2f74715fc70e37723e77ca16a631e35 ]
+
+Clang can do some aggressive inlining, which provides it with greater
+visibility into the sizes of various objects that are passed into
+helpers. Specifically, compare_netdev_and_ip() can see through the type
+given to the "sa" argument, which means it can generate code for "struct
+sockaddr_in" that would have been passed to ipv6_addr_cmp() (that expects
+to operate on the larger "struct sockaddr_in6"), which would result in a
+compile-time buffer overflow condition detected by memcmp(). Logically,
+this state isn't reachable due to the sa_family assignment two callers
+above and the check in compare_netdev_and_ip(). Instead, provide a
+compile-time check on sizes so the size-mismatched code will be elided
+when inlining. Avoids the following warning from Clang:
+
+../include/linux/fortify-string.h:652:4: error: call to '__read_overflow' declared with 'error' attribute: detected read beyond size of object (1st parameter)
+ __read_overflow();
+ ^
+note: In function 'cma_netevent_callback'
+note: which inlined function 'node_from_ndev_ip'
+1 error generated.
+
+When the underlying object size is not known (e.g. with GCC and older
+Clang), the result of __builtin_object_size() is SIZE_MAX, which will also
+compile away, leaving the code as it was originally.
+
+Link: https://lore.kernel.org/r/20230208232549.never.139-kees@kernel.org
+Link: https://github.com/ClangBuiltLinux/linux/issues/1687
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Tested-by: Nathan Chancellor <nathan@kernel.org> # build
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index 26d1772179b8f..8730674ceb2e1 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -479,13 +479,20 @@ static int compare_netdev_and_ip(int ifindex_a, struct sockaddr *sa,
+ if (sa->sa_family != sb->sa_family)
+ return sa->sa_family - sb->sa_family;
+
+- if (sa->sa_family == AF_INET)
+- return memcmp((char *)&((struct sockaddr_in *)sa)->sin_addr,
+- (char *)&((struct sockaddr_in *)sb)->sin_addr,
++ if (sa->sa_family == AF_INET &&
++ __builtin_object_size(sa, 0) >= sizeof(struct sockaddr_in)) {
++ return memcmp(&((struct sockaddr_in *)sa)->sin_addr,
++ &((struct sockaddr_in *)sb)->sin_addr,
+ sizeof(((struct sockaddr_in *)sa)->sin_addr));
++ }
++
++ if (sa->sa_family == AF_INET6 &&
++ __builtin_object_size(sa, 0) >= sizeof(struct sockaddr_in6)) {
++ return ipv6_addr_cmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
++ &((struct sockaddr_in6 *)sb)->sin6_addr);
++ }
+
+- return ipv6_addr_cmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
+- &((struct sockaddr_in6 *)sb)->sin6_addr);
++ return -1;
+ }
+
+ static int cma_add_id_to_tree(struct rdma_id_private *node_id_priv)
+--
+2.39.2
+
--- /dev/null
+From 1659bda01afda1f9fec22a17a65850b58e76b47d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 23:27:53 +0100
+Subject: rtc: allow rtc_read_alarm without read_alarm callback
+
+From: Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+[ Upstream commit a783c962619271a8b905efad1d89adfec11ae0c8 ]
+
+.read_alarm is not necessary to read the current alarm because it is
+recorded in the aie_timer and so rtc_read_alarm() will never call
+rtc_read_alarm_internal() which is the only function calling the callback.
+
+Reported-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
+Reported-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Fixes: 7ae41220ef58 ("rtc: introduce features bitfield")
+Tested-by: Philippe Schenker <philippe.schenker@toradex.com>
+Link: https://lore.kernel.org/r/20230214222754.582582-1-alexandre.belloni@bootlin.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/interface.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
+index 9edd662c69ace..3d0fbc644f578 100644
+--- a/drivers/rtc/interface.c
++++ b/drivers/rtc/interface.c
+@@ -392,7 +392,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
+ return err;
+ if (!rtc->ops) {
+ err = -ENODEV;
+- } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->read_alarm) {
++ } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features)) {
+ err = -EINVAL;
+ } else {
+ memset(alarm, 0, sizeof(struct rtc_wkalrm));
+--
+2.39.2
+
--- /dev/null
+From 53abf71481b06a372db0b9d38cc9ce1754a85f07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Dec 2022 15:53:19 -0600
+Subject: rtc: sun6i: Always export the internal oscillator
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 344f4030f6c50a9db2d03021884c4bf36191b53a ]
+
+On all variants of the hardware, the internal oscillator is one possible
+parent for the AR100 clock. It needs to be exported so we can model that
+relationship correctly in the devicetree.
+
+Fixes: c56afc1844d6 ("rtc: sun6i: Expose internal oscillator through device tree")
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20221229215319.14145-1-samuel@sholland.org
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-sun6i.c | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
+index ed5516089e9a0..7038f47d77ff4 100644
+--- a/drivers/rtc/rtc-sun6i.c
++++ b/drivers/rtc/rtc-sun6i.c
+@@ -136,7 +136,6 @@ struct sun6i_rtc_clk_data {
+ unsigned int fixed_prescaler : 16;
+ unsigned int has_prescaler : 1;
+ unsigned int has_out_clk : 1;
+- unsigned int export_iosc : 1;
+ unsigned int has_losc_en : 1;
+ unsigned int has_auto_swt : 1;
+ };
+@@ -271,10 +270,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
+ /* Yes, I know, this is ugly. */
+ sun6i_rtc = rtc;
+
+- /* Only read IOSC name from device tree if it is exported */
+- if (rtc->data->export_iosc)
+- of_property_read_string_index(node, "clock-output-names", 2,
+- &iosc_name);
++ of_property_read_string_index(node, "clock-output-names", 2,
++ &iosc_name);
+
+ rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
+ iosc_name,
+@@ -315,13 +312,10 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
+ goto err_register;
+ }
+
+- clk_data->num = 2;
++ clk_data->num = 3;
+ clk_data->hws[0] = &rtc->hw;
+ clk_data->hws[1] = __clk_get_hw(rtc->ext_losc);
+- if (rtc->data->export_iosc) {
+- clk_data->hws[2] = rtc->int_osc;
+- clk_data->num = 3;
+- }
++ clk_data->hws[2] = rtc->int_osc;
+ of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ return;
+
+@@ -361,7 +355,6 @@ static const struct sun6i_rtc_clk_data sun8i_h3_rtc_data = {
+ .fixed_prescaler = 32,
+ .has_prescaler = 1,
+ .has_out_clk = 1,
+- .export_iosc = 1,
+ };
+
+ static void __init sun8i_h3_rtc_clk_init(struct device_node *node)
+@@ -379,7 +372,6 @@ static const struct sun6i_rtc_clk_data sun50i_h6_rtc_data = {
+ .fixed_prescaler = 32,
+ .has_prescaler = 1,
+ .has_out_clk = 1,
+- .export_iosc = 1,
+ .has_losc_en = 1,
+ .has_auto_swt = 1,
+ };
+--
+2.39.2
+
--- /dev/null
+From d0f822dc0cdd197fae1a63fbabf14757108cff88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 14:28:08 +0100
+Subject: scsi: ipr: Work around fortify-string warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit ee4e7dfe4ffc9ca50c6875757bd119abfe22b5c5 ]
+
+The ipr_log_vpd_compact() function triggers a fortified memcpy() warning
+about a potential string overflow with all versions of clang:
+
+In file included from drivers/scsi/ipr.c:43:
+In file included from include/linux/string.h:254:
+include/linux/fortify-string.h:520:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
+ __write_overflow_field(p_size_field, size);
+ ^
+include/linux/fortify-string.h:520:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
+2 errors generated.
+
+I don't see anything actually wrong with the function, but this is the only
+instance I can reproduce of the fortification going wrong in the kernel at
+the moment, so the easiest solution may be to rewrite the function into
+something that does not trigger the warning.
+
+Instead of having a combined buffer for vendor/device/serial strings, use
+three separate local variables and just truncate the whitespace
+individually.
+
+Link: https://lore.kernel.org/r/20230214132831.2118392-1-arnd@kernel.org
+Cc: Kees Cook <keescook@chromium.org>
+Fixes: 8cf093e275d0 ("[SCSI] ipr: Improved dual adapter errors")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Acked-by: Brian King <brking@linux.vnet.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ipr.c | 41 +++++++++++++++++++++--------------------
+ 1 file changed, 21 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+index 2022ffb450417..8c062afb2918d 100644
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -1516,23 +1516,22 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd)
+ }
+
+ /**
+- * strip_and_pad_whitespace - Strip and pad trailing whitespace.
+- * @i: index into buffer
+- * @buf: string to modify
++ * strip_whitespace - Strip and pad trailing whitespace.
++ * @i: size of buffer
++ * @buf: string to modify
+ *
+- * This function will strip all trailing whitespace, pad the end
+- * of the string with a single space, and NULL terminate the string.
++ * This function will strip all trailing whitespace and
++ * NUL terminate the string.
+ *
+- * Return value:
+- * new length of string
+ **/
+-static int strip_and_pad_whitespace(int i, char *buf)
++static void strip_whitespace(int i, char *buf)
+ {
++ if (i < 1)
++ return;
++ i--;
+ while (i && buf[i] == ' ')
+ i--;
+- buf[i+1] = ' ';
+- buf[i+2] = '\0';
+- return i + 2;
++ buf[i+1] = '\0';
+ }
+
+ /**
+@@ -1547,19 +1546,21 @@ static int strip_and_pad_whitespace(int i, char *buf)
+ static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb,
+ struct ipr_vpd *vpd)
+ {
+- char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN + 3];
+- int i = 0;
++ char vendor_id[IPR_VENDOR_ID_LEN + 1];
++ char product_id[IPR_PROD_ID_LEN + 1];
++ char sn[IPR_SERIAL_NUM_LEN + 1];
+
+- memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
+- i = strip_and_pad_whitespace(IPR_VENDOR_ID_LEN - 1, buffer);
++ memcpy(vendor_id, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
++ strip_whitespace(IPR_VENDOR_ID_LEN, vendor_id);
+
+- memcpy(&buffer[i], vpd->vpids.product_id, IPR_PROD_ID_LEN);
+- i = strip_and_pad_whitespace(i + IPR_PROD_ID_LEN - 1, buffer);
++ memcpy(product_id, vpd->vpids.product_id, IPR_PROD_ID_LEN);
++ strip_whitespace(IPR_PROD_ID_LEN, product_id);
+
+- memcpy(&buffer[i], vpd->sn, IPR_SERIAL_NUM_LEN);
+- buffer[IPR_SERIAL_NUM_LEN + i] = '\0';
++ memcpy(sn, vpd->sn, IPR_SERIAL_NUM_LEN);
++ strip_whitespace(IPR_SERIAL_NUM_LEN, sn);
+
+- ipr_hcam_err(hostrcb, "%s VPID/SN: %s\n", prefix, buffer);
++ ipr_hcam_err(hostrcb, "%s VPID/SN: %s %s %s\n", prefix,
++ vendor_id, product_id, sn);
+ }
+
+ /**
+--
+2.39.2
+
--- /dev/null
+From b30843fdad0c039fb5ec5295584b77cadc638726 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Feb 2023 20:37:52 +0100
+Subject: scsi: mpi3mr: Fix an issue found by KASAN
+
+From: Tomas Henzl <thenzl@redhat.com>
+
+[ Upstream commit ae7d45f5283d30274039b95d3e6d53d33c66e991 ]
+
+Write only correct size (32 instead of 64 bytes).
+
+Link: https://lore.kernel.org/r/20230213193752.6859-1-thenzl@redhat.com
+Fixes: 42fc9fee116f ("scsi: mpi3mr: Add helper functions to manage device's port")
+Signed-off-by: Tomas Henzl <thenzl@redhat.com>
+Acked-by: Sathya Prakash Veerichetty <sathya.prakash@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c
+index 3fc897336b5e0..3b61815979dab 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_transport.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c
+@@ -1280,7 +1280,7 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc)
+
+ if (mrioc->sas_hba.enclosure_handle) {
+ if (!(mpi3mr_cfg_get_enclosure_pg0(mrioc, &ioc_status,
+- &encl_pg0, sizeof(dev_pg0),
++ &encl_pg0, sizeof(encl_pg0),
+ MPI3_ENCLOS_PGAD_FORM_HANDLE,
+ mrioc->sas_hba.enclosure_handle)) &&
+ (ioc_status == MPI3_IOCSTATUS_SUCCESS))
+--
+2.39.2
+
--- /dev/null
+From 3016f2abff1307f623829438077ac18dc03352c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 09:50:18 +0900
+Subject: scsi: mpi3mr: Use number of bits to manage bitmap sizes
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+[ Upstream commit 339e61565f81a6534afdc18fd854b2e2628bf5db ]
+
+To allocate bitmaps, the mpi3mr driver calculates sizes of bitmaps using
+byte as unit. However, bitmap helper functions assume that bitmaps are
+allocated using unsigned long as unit. This gap causes memory access beyond
+the bitmap sizes and results in "BUG: KASAN: slab-out-of-bounds". The BUG
+was observed at firmware download to eHBA-9600. Call trace indicated that
+the out-of-bounds access happened in find_first_zero_bit() called from
+mpi3mr_send_event_ack() for miroc->evtack_cmds_bitmap.
+
+To fix the BUG, do not use bytes to manage bitmap sizes. Instead, use
+number of bits, and call bitmap helper functions which take number of bits
+as arguments. For memory allocation, call bitmap_zalloc() instead of
+kzalloc() and krealloc(). For memory free, call bitmap_free() instead of
+kfree(). For zero clear, call bitmap_clear() instead of memset().
+
+Remove three fields for bitmap byte sizes in struct scmd_priv which are no
+longer required. Replace the field dev_handle_bitmap_sz with
+dev_handle_bitmap_bits to keep number of bits of removepend_bitmap across
+resize.
+
+Link: https://lore.kernel.org/r/20230214005019.1897251-4-shinichiro.kawasaki@wdc.com
+Fixes: c5758fc72b92 ("scsi: mpi3mr: Gracefully handle online FW update operation")
+Fixes: e844adb1fbdc ("scsi: mpi3mr: Implement SCSI error handler hooks")
+Fixes: c1af985d27da ("scsi: mpi3mr: Add Event acknowledgment logic")
+Fixes: 824a156633df ("scsi: mpi3mr: Base driver code")
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Acked-by: Sathya Prakash Veerichetty <sathya.prakash@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr.h | 10 +----
+ drivers/scsi/mpi3mr/mpi3mr_fw.c | 75 ++++++++++++++-------------------
+ 2 files changed, 33 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
+index def4c5e15cd89..8a438f248a820 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr.h
++++ b/drivers/scsi/mpi3mr/mpi3mr.h
+@@ -955,19 +955,16 @@ struct scmd_priv {
+ * @chain_buf_count: Chain buffer count
+ * @chain_buf_pool: Chain buffer pool
+ * @chain_sgl_list: Chain SGL list
+- * @chain_bitmap_sz: Chain buffer allocator bitmap size
+ * @chain_bitmap: Chain buffer allocator bitmap
+ * @chain_buf_lock: Chain buffer list lock
+ * @bsg_cmds: Command tracker for BSG command
+ * @host_tm_cmds: Command tracker for task management commands
+ * @dev_rmhs_cmds: Command tracker for device removal commands
+ * @evtack_cmds: Command tracker for event ack commands
+- * @devrem_bitmap_sz: Device removal bitmap size
+ * @devrem_bitmap: Device removal bitmap
+- * @dev_handle_bitmap_sz: Device handle bitmap size
++ * @dev_handle_bitmap_bits: Number of bits in device handle bitmap
+ * @removepend_bitmap: Remove pending bitmap
+ * @delayed_rmhs_list: Delayed device removal list
+- * @evtack_cmds_bitmap_sz: Event Ack bitmap size
+ * @evtack_cmds_bitmap: Event Ack bitmap
+ * @delayed_evtack_cmds_list: Delayed event acknowledgment list
+ * @ts_update_counter: Timestamp update counter
+@@ -1128,7 +1125,6 @@ struct mpi3mr_ioc {
+ u32 chain_buf_count;
+ struct dma_pool *chain_buf_pool;
+ struct chain_element *chain_sgl_list;
+- u16 chain_bitmap_sz;
+ void *chain_bitmap;
+ spinlock_t chain_buf_lock;
+
+@@ -1136,12 +1132,10 @@ struct mpi3mr_ioc {
+ struct mpi3mr_drv_cmd host_tm_cmds;
+ struct mpi3mr_drv_cmd dev_rmhs_cmds[MPI3MR_NUM_DEVRMCMD];
+ struct mpi3mr_drv_cmd evtack_cmds[MPI3MR_NUM_EVTACKCMD];
+- u16 devrem_bitmap_sz;
+ void *devrem_bitmap;
+- u16 dev_handle_bitmap_sz;
++ u16 dev_handle_bitmap_bits;
+ void *removepend_bitmap;
+ struct list_head delayed_rmhs_list;
+- u16 evtack_cmds_bitmap_sz;
+ void *evtack_cmds_bitmap;
+ struct list_head delayed_evtack_cmds_list;
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
+index 0c4aabaefdcc4..1e4467ea8472a 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
+@@ -1128,7 +1128,6 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc,
+ static int
+ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
+ {
+- u16 dev_handle_bitmap_sz;
+ void *removepend_bitmap;
+
+ if (mrioc->facts.reply_sz > mrioc->reply_sz) {
+@@ -1160,25 +1159,23 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
+ "\tcontroller while sas transport support is enabled at the\n"
+ "\tdriver, please reboot the system or reload the driver\n");
+
+- dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
+- if (mrioc->facts.max_devhandle % 8)
+- dev_handle_bitmap_sz++;
+- if (dev_handle_bitmap_sz > mrioc->dev_handle_bitmap_sz) {
+- removepend_bitmap = krealloc(mrioc->removepend_bitmap,
+- dev_handle_bitmap_sz, GFP_KERNEL);
++ if (mrioc->facts.max_devhandle > mrioc->dev_handle_bitmap_bits) {
++ removepend_bitmap = bitmap_zalloc(mrioc->facts.max_devhandle,
++ GFP_KERNEL);
+ if (!removepend_bitmap) {
+ ioc_err(mrioc,
+- "failed to increase removepend_bitmap sz from: %d to %d\n",
+- mrioc->dev_handle_bitmap_sz, dev_handle_bitmap_sz);
++ "failed to increase removepend_bitmap bits from %d to %d\n",
++ mrioc->dev_handle_bitmap_bits,
++ mrioc->facts.max_devhandle);
+ return -EPERM;
+ }
+- memset(removepend_bitmap + mrioc->dev_handle_bitmap_sz, 0,
+- dev_handle_bitmap_sz - mrioc->dev_handle_bitmap_sz);
++ bitmap_free(mrioc->removepend_bitmap);
+ mrioc->removepend_bitmap = removepend_bitmap;
+ ioc_info(mrioc,
+- "increased dev_handle_bitmap_sz from %d to %d\n",
+- mrioc->dev_handle_bitmap_sz, dev_handle_bitmap_sz);
+- mrioc->dev_handle_bitmap_sz = dev_handle_bitmap_sz;
++ "increased bits of dev_handle_bitmap from %d to %d\n",
++ mrioc->dev_handle_bitmap_bits,
++ mrioc->facts.max_devhandle);
++ mrioc->dev_handle_bitmap_bits = mrioc->facts.max_devhandle;
+ }
+
+ return 0;
+@@ -2957,27 +2954,18 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
+ if (!mrioc->pel_abort_cmd.reply)
+ goto out_failed;
+
+- mrioc->dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
+- if (mrioc->facts.max_devhandle % 8)
+- mrioc->dev_handle_bitmap_sz++;
+- mrioc->removepend_bitmap = kzalloc(mrioc->dev_handle_bitmap_sz,
+- GFP_KERNEL);
++ mrioc->dev_handle_bitmap_bits = mrioc->facts.max_devhandle;
++ mrioc->removepend_bitmap = bitmap_zalloc(mrioc->dev_handle_bitmap_bits,
++ GFP_KERNEL);
+ if (!mrioc->removepend_bitmap)
+ goto out_failed;
+
+- mrioc->devrem_bitmap_sz = MPI3MR_NUM_DEVRMCMD / 8;
+- if (MPI3MR_NUM_DEVRMCMD % 8)
+- mrioc->devrem_bitmap_sz++;
+- mrioc->devrem_bitmap = kzalloc(mrioc->devrem_bitmap_sz,
+- GFP_KERNEL);
++ mrioc->devrem_bitmap = bitmap_zalloc(MPI3MR_NUM_DEVRMCMD, GFP_KERNEL);
+ if (!mrioc->devrem_bitmap)
+ goto out_failed;
+
+- mrioc->evtack_cmds_bitmap_sz = MPI3MR_NUM_EVTACKCMD / 8;
+- if (MPI3MR_NUM_EVTACKCMD % 8)
+- mrioc->evtack_cmds_bitmap_sz++;
+- mrioc->evtack_cmds_bitmap = kzalloc(mrioc->evtack_cmds_bitmap_sz,
+- GFP_KERNEL);
++ mrioc->evtack_cmds_bitmap = bitmap_zalloc(MPI3MR_NUM_EVTACKCMD,
++ GFP_KERNEL);
+ if (!mrioc->evtack_cmds_bitmap)
+ goto out_failed;
+
+@@ -3415,10 +3403,7 @@ static int mpi3mr_alloc_chain_bufs(struct mpi3mr_ioc *mrioc)
+ if (!mrioc->chain_sgl_list[i].addr)
+ goto out_failed;
+ }
+- mrioc->chain_bitmap_sz = num_chains / 8;
+- if (num_chains % 8)
+- mrioc->chain_bitmap_sz++;
+- mrioc->chain_bitmap = kzalloc(mrioc->chain_bitmap_sz, GFP_KERNEL);
++ mrioc->chain_bitmap = bitmap_zalloc(num_chains, GFP_KERNEL);
+ if (!mrioc->chain_bitmap)
+ goto out_failed;
+ return retval;
+@@ -4190,10 +4175,11 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
+ for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)
+ memset(mrioc->evtack_cmds[i].reply, 0,
+ sizeof(*mrioc->evtack_cmds[i].reply));
+- memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
+- memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
+- memset(mrioc->evtack_cmds_bitmap, 0,
+- mrioc->evtack_cmds_bitmap_sz);
++ bitmap_clear(mrioc->removepend_bitmap, 0,
++ mrioc->dev_handle_bitmap_bits);
++ bitmap_clear(mrioc->devrem_bitmap, 0, MPI3MR_NUM_DEVRMCMD);
++ bitmap_clear(mrioc->evtack_cmds_bitmap, 0,
++ MPI3MR_NUM_EVTACKCMD);
+ }
+
+ for (i = 0; i < mrioc->num_queues; i++) {
+@@ -4319,16 +4305,16 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
+ mrioc->evtack_cmds[i].reply = NULL;
+ }
+
+- kfree(mrioc->removepend_bitmap);
++ bitmap_free(mrioc->removepend_bitmap);
+ mrioc->removepend_bitmap = NULL;
+
+- kfree(mrioc->devrem_bitmap);
++ bitmap_free(mrioc->devrem_bitmap);
+ mrioc->devrem_bitmap = NULL;
+
+- kfree(mrioc->evtack_cmds_bitmap);
++ bitmap_free(mrioc->evtack_cmds_bitmap);
+ mrioc->evtack_cmds_bitmap = NULL;
+
+- kfree(mrioc->chain_bitmap);
++ bitmap_free(mrioc->chain_bitmap);
+ mrioc->chain_bitmap = NULL;
+
+ kfree(mrioc->transport_cmds.reply);
+@@ -4887,9 +4873,10 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
+
+ mpi3mr_flush_delayed_cmd_lists(mrioc);
+ mpi3mr_flush_drv_cmds(mrioc);
+- memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
+- memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
+- memset(mrioc->evtack_cmds_bitmap, 0, mrioc->evtack_cmds_bitmap_sz);
++ bitmap_clear(mrioc->devrem_bitmap, 0, MPI3MR_NUM_DEVRMCMD);
++ bitmap_clear(mrioc->removepend_bitmap, 0,
++ mrioc->dev_handle_bitmap_bits);
++ bitmap_clear(mrioc->evtack_cmds_bitmap, 0, MPI3MR_NUM_EVTACKCMD);
+ mpi3mr_flush_host_io(mrioc);
+ mpi3mr_cleanup_fwevt_list(mrioc);
+ mpi3mr_invalidate_devhandles(mrioc);
+--
+2.39.2
+
--- /dev/null
+From d9f068b9c48d0efba4796d3d8d55c5fd596a32b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Feb 2023 12:07:21 -0500
+Subject: sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 68ba44639537de6f91fe32783766322d41848127 ]
+
+With this refcnt added in sctp_stream_priorities, we don't need to
+traverse all streams to check if the prio is used by other streams
+when freeing one stream's prio in sctp_sched_prio_free_sid(). This
+can avoid a nested loop (up to 65535 * 65535), which may cause a
+stuck as Ying reported:
+
+ watchdog: BUG: soft lockup - CPU#23 stuck for 26s! [ksoftirqd/23:136]
+ Call Trace:
+ <TASK>
+ sctp_sched_prio_free_sid+0xab/0x100 [sctp]
+ sctp_stream_free_ext+0x64/0xa0 [sctp]
+ sctp_stream_free+0x31/0x50 [sctp]
+ sctp_association_free+0xa5/0x200 [sctp]
+
+Note that it doesn't need to use refcount_t type for this counter,
+as its accessing is always protected under the sock lock.
+
+v1->v2:
+ - add a check in sctp_sched_prio_set to avoid the possible prio_head
+ refcnt overflow.
+
+Fixes: 9ed7bfc79542 ("sctp: fix memory leak in sctp_stream_outq_migrate()")
+Reported-by: Ying Xu <yinxu@redhat.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://lore.kernel.org/r/825eb0c905cb864991eba335f4a2b780e543f06b.1677085641.git.lucien.xin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sctp/structs.h | 1 +
+ net/sctp/stream_sched_prio.c | 52 +++++++++++++++---------------------
+ 2 files changed, 22 insertions(+), 31 deletions(-)
+
+diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
+index 350f250b0dc75..00ee9eb601a6f 100644
+--- a/include/net/sctp/structs.h
++++ b/include/net/sctp/structs.h
+@@ -1409,6 +1409,7 @@ struct sctp_stream_priorities {
+ /* The next stream in line */
+ struct sctp_stream_out_ext *next;
+ __u16 prio;
++ __u16 users;
+ };
+
+ struct sctp_stream_out_ext {
+diff --git a/net/sctp/stream_sched_prio.c b/net/sctp/stream_sched_prio.c
+index 4fc9f2923ed11..7dd9f8b387cca 100644
+--- a/net/sctp/stream_sched_prio.c
++++ b/net/sctp/stream_sched_prio.c
+@@ -25,6 +25,18 @@
+
+ static void sctp_sched_prio_unsched_all(struct sctp_stream *stream);
+
++static struct sctp_stream_priorities *sctp_sched_prio_head_get(struct sctp_stream_priorities *p)
++{
++ p->users++;
++ return p;
++}
++
++static void sctp_sched_prio_head_put(struct sctp_stream_priorities *p)
++{
++ if (p && --p->users == 0)
++ kfree(p);
++}
++
+ static struct sctp_stream_priorities *sctp_sched_prio_new_head(
+ struct sctp_stream *stream, int prio, gfp_t gfp)
+ {
+@@ -38,6 +50,7 @@ static struct sctp_stream_priorities *sctp_sched_prio_new_head(
+ INIT_LIST_HEAD(&p->active);
+ p->next = NULL;
+ p->prio = prio;
++ p->users = 1;
+
+ return p;
+ }
+@@ -53,7 +66,7 @@ static struct sctp_stream_priorities *sctp_sched_prio_get_head(
+ */
+ list_for_each_entry(p, &stream->prio_list, prio_sched) {
+ if (p->prio == prio)
+- return p;
++ return sctp_sched_prio_head_get(p);
+ if (p->prio > prio)
+ break;
+ }
+@@ -70,7 +83,7 @@ static struct sctp_stream_priorities *sctp_sched_prio_get_head(
+ */
+ break;
+ if (p->prio == prio)
+- return p;
++ return sctp_sched_prio_head_get(p);
+ }
+
+ /* If not even there, allocate a new one. */
+@@ -154,32 +167,21 @@ static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid,
+ struct sctp_stream_out_ext *soute = sout->ext;
+ struct sctp_stream_priorities *prio_head, *old;
+ bool reschedule = false;
+- int i;
++
++ old = soute->prio_head;
++ if (old && old->prio == prio)
++ return 0;
+
+ prio_head = sctp_sched_prio_get_head(stream, prio, gfp);
+ if (!prio_head)
+ return -ENOMEM;
+
+ reschedule = sctp_sched_prio_unsched(soute);
+- old = soute->prio_head;
+ soute->prio_head = prio_head;
+ if (reschedule)
+ sctp_sched_prio_sched(stream, soute);
+
+- if (!old)
+- /* Happens when we set the priority for the first time */
+- return 0;
+-
+- for (i = 0; i < stream->outcnt; i++) {
+- soute = SCTP_SO(stream, i)->ext;
+- if (soute && soute->prio_head == old)
+- /* It's still in use, nothing else to do here. */
+- return 0;
+- }
+-
+- /* No hits, we are good to free it. */
+- kfree(old);
+-
++ sctp_sched_prio_head_put(old);
+ return 0;
+ }
+
+@@ -206,20 +208,8 @@ static int sctp_sched_prio_init_sid(struct sctp_stream *stream, __u16 sid,
+
+ static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid)
+ {
+- struct sctp_stream_priorities *prio = SCTP_SO(stream, sid)->ext->prio_head;
+- int i;
+-
+- if (!prio)
+- return;
+-
++ sctp_sched_prio_head_put(SCTP_SO(stream, sid)->ext->prio_head);
+ SCTP_SO(stream, sid)->ext->prio_head = NULL;
+- for (i = 0; i < stream->outcnt; i++) {
+- if (SCTP_SO(stream, i)->ext &&
+- SCTP_SO(stream, i)->ext->prio_head == prio)
+- return;
+- }
+-
+- kfree(prio);
+ }
+
+ static void sctp_sched_prio_free(struct sctp_stream *stream)
+--
+2.39.2
+
--- /dev/null
+From 15fa37804c7d5fc31210b2da7c9521506ee9bbc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 11:55:30 +0100
+Subject: serial: sc16is7xx: setup GPIO controller later in probe
+
+From: Isaac True <isaac.true@canonical.com>
+
+[ Upstream commit c8f71b49ee4d28930c4a6798d1969fa91dc4ef3e ]
+
+The GPIO controller component of the sc16is7xx driver is setup too
+early, which can result in a race condition where another device tries
+to utilise the GPIO lines before the sc16is7xx device has finished
+initialising.
+
+This issue manifests itself as an Oops when the GPIO lines are configured:
+
+ Unable to handle kernel read from unreadable memory at virtual address
+ ...
+ pc : sc16is7xx_gpio_direction_output+0x68/0x108 [sc16is7xx]
+ lr : sc16is7xx_gpio_direction_output+0x4c/0x108 [sc16is7xx]
+ ...
+ Call trace:
+ sc16is7xx_gpio_direction_output+0x68/0x108 [sc16is7xx]
+ gpiod_direction_output_raw_commit+0x64/0x318
+ gpiod_direction_output+0xb0/0x170
+ create_gpio_led+0xec/0x198
+ gpio_led_probe+0x16c/0x4f0
+ platform_drv_probe+0x5c/0xb0
+ really_probe+0xe8/0x448
+ driver_probe_device+0xe8/0x138
+ __device_attach_driver+0x94/0x118
+ bus_for_each_drv+0x8c/0xe0
+ __device_attach+0x100/0x1b8
+ device_initial_probe+0x28/0x38
+ bus_probe_device+0xa4/0xb0
+ deferred_probe_work_func+0x90/0xe0
+ process_one_work+0x1c4/0x480
+ worker_thread+0x54/0x430
+ kthread+0x138/0x150
+ ret_from_fork+0x10/0x1c
+
+This patch moves the setup of the GPIO controller functions to later in the
+probe function, ensuring the sc16is7xx device has already finished
+initialising by the time other devices try to make use of the GPIO lines.
+The error handling has also been reordered to reflect the new
+initialisation order.
+
+Co-developed-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
+Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
+Signed-off-by: Isaac True <isaac.true@canonical.com>
+Link: https://lore.kernel.org/r/20221130105529.698385-1-isaac.true@canonical.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sc16is7xx.c | 51 +++++++++++++++++-----------------
+ 1 file changed, 26 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
+index 524921360ca78..93cf5f7888172 100644
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -1426,25 +1426,6 @@ static int sc16is7xx_probe(struct device *dev,
+ }
+ sched_set_fifo(s->kworker_task);
+
+-#ifdef CONFIG_GPIOLIB
+- if (devtype->nr_gpio) {
+- /* Setup GPIO cotroller */
+- s->gpio.owner = THIS_MODULE;
+- s->gpio.parent = dev;
+- s->gpio.label = dev_name(dev);
+- s->gpio.direction_input = sc16is7xx_gpio_direction_input;
+- s->gpio.get = sc16is7xx_gpio_get;
+- s->gpio.direction_output = sc16is7xx_gpio_direction_output;
+- s->gpio.set = sc16is7xx_gpio_set;
+- s->gpio.base = -1;
+- s->gpio.ngpio = devtype->nr_gpio;
+- s->gpio.can_sleep = 1;
+- ret = gpiochip_add_data(&s->gpio, s);
+- if (ret)
+- goto out_thread;
+- }
+-#endif
+-
+ /* reset device, purging any pending irq / data */
+ regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT,
+ SC16IS7XX_IOCONTROL_SRESET_BIT);
+@@ -1521,6 +1502,25 @@ static int sc16is7xx_probe(struct device *dev,
+ s->p[u].irda_mode = true;
+ }
+
++#ifdef CONFIG_GPIOLIB
++ if (devtype->nr_gpio) {
++ /* Setup GPIO cotroller */
++ s->gpio.owner = THIS_MODULE;
++ s->gpio.parent = dev;
++ s->gpio.label = dev_name(dev);
++ s->gpio.direction_input = sc16is7xx_gpio_direction_input;
++ s->gpio.get = sc16is7xx_gpio_get;
++ s->gpio.direction_output = sc16is7xx_gpio_direction_output;
++ s->gpio.set = sc16is7xx_gpio_set;
++ s->gpio.base = -1;
++ s->gpio.ngpio = devtype->nr_gpio;
++ s->gpio.can_sleep = 1;
++ ret = gpiochip_add_data(&s->gpio, s);
++ if (ret)
++ goto out_thread;
++ }
++#endif
++
+ /*
+ * Setup interrupt. We first try to acquire the IRQ line as level IRQ.
+ * If that succeeds, we can allow sharing the interrupt as well.
+@@ -1540,18 +1540,19 @@ static int sc16is7xx_probe(struct device *dev,
+ if (!ret)
+ return 0;
+
+-out_ports:
+- for (i--; i >= 0; i--) {
+- uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port);
+- clear_bit(s->p[i].port.line, &sc16is7xx_lines);
+- }
+-
+ #ifdef CONFIG_GPIOLIB
+ if (devtype->nr_gpio)
+ gpiochip_remove(&s->gpio);
+
+ out_thread:
+ #endif
++
++out_ports:
++ for (i--; i >= 0; i--) {
++ uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port);
++ clear_bit(s->p[i].port.line, &sc16is7xx_lines);
++ }
++
+ kthread_stop(s->kworker_task);
+
+ out_clk:
+--
+2.39.2
+
net-sched-retire-tcindex-classifier.patch
+auxdisplay-hd44780-fix-potential-memory-leak-in-hd44.patch
+fs-jfs-fix-shift-exponent-db_agl2size-negative.patch
+driver-soc-xilinx-fix-memory-leak-in-xlnx_add_cb_for.patch
+f2fs-don-t-rely-on-f2fs_map_-in-f2fs_iomap_begin.patch
+f2fs-fix-to-avoid-potential-deadlock.patch
+objtool-fix-memory-leak-in-create_static_call_sectio.patch
+soc-mediatek-mtk-pm-domains-allow-mt8186-adsp-defaul.patch
+memory-renesas-rpc-if-split-off-private-data-from-st.patch
+memory-renesas-rpc-if-move-resource-acquisition-to-..patch
+soc-mediatek-mtk-svs-enable-the-irq-later.patch
+pwm-sifive-always-let-the-first-pwm_apply_state-succ.patch
+pwm-stm32-lp-fix-the-check-on-arr-and-cmp-registers-.patch
+f2fs-introduce-trace_f2fs_replace_atomic_write_block.patch
+f2fs-correct-i_size-change-for-atomic-writes.patch
+f2fs-clear-atomic_write_task-in-f2fs_abort_atomic_wr.patch
+soc-mediatek-mtk-svs-restore-default-voltages-when-s.patch
+soc-mediatek-mtk-svs-reset-svs-when-svs_resume-fail.patch
+soc-mediatek-mtk-svs-use-pm_runtime_resume_and_get-i.patch
+fs-f2fs-initialize-fsdata-in-pagecache_write.patch
+f2fs-allow-set-compression-option-of-files-without-b.patch
+f2fs-fix-to-abort-atomic-write-only-during-do_exist.patch
+um-vector-fix-memory-leak-in-vector_config.patch
+ubi-ensure-that-vid-header-offset-vid-header-size-al.patch
+ubifs-fix-build-errors-as-symbol-undefined.patch
+ubifs-fix-memory-leak-in-ubifs_sysfs_init.patch
+ubifs-rectify-space-budget-for-ubifs_symlink-if-syml.patch
+ubifs-rectify-space-budget-for-ubifs_xrename.patch
+ubifs-fix-wrong-dirty-space-budget-for-dirty-inode.patch
+ubifs-do_rename-fix-wrong-space-budget-when-target-i.patch
+ubifs-reserve-one-leb-for-each-journal-head-while-do.patch
+ubi-fix-use-after-free-when-volume-resizing-failed.patch
+ubi-fix-unreferenced-object-reported-by-kmemleak-in-.patch
+ubifs-fix-memory-leak-in-alloc_wbufs.patch
+ubi-fix-possible-null-ptr-deref-in-ubi_free_volume.patch
+ubifs-re-statistic-cleaned-znode-count-if-commit-fai.patch
+ubifs-dirty_cow_znode-fix-memleak-in-error-handling-.patch
+ubifs-ubifs_writepage-mark-page-dirty-after-writing-.patch
+ubifs-ubifs_releasepage-remove-ubifs_assert-0-to-val.patch
+ubi-fastmap-fix-missed-fm_anchor-peb-in-wear-levelin.patch
+ubi-fix-uaf-wear-leveling-entry-in-eraseblk_count_se.patch
+ubi-ubi_wl_put_peb-fix-infinite-loop-when-wear-level.patch
+f2fs-fix-to-avoid-potential-memory-corruption-in-__u.patch
+soc-qcom-stats-populate-all-subsystem-debugfs-files.patch
+ext4-use-ext4_fc_tl_mem-in-fast-commit-replay-path.patch
+ext4-don-t-show-commit-interval-if-it-is-zero.patch
+netfilter-nf_tables-allow-to-fetch-set-elements-when.patch
+x86-um-vdso-add-rcx-and-r11-to-the-syscall-clobber-l.patch
+um-virtio_uml-free-command-if-adding-to-virtqueue-fa.patch
+um-virtio_uml-mark-device-as-unregistered-when-break.patch
+um-virtio_uml-move-device-breaking-into-workqueue.patch
+um-virt-pci-properly-remove-pci-device-from-bus.patch
+f2fs-synchronize-atomic-write-aborts.patch
+watchdog-rzg2l_wdt-issue-a-reset-before-we-put-the-p.patch
+watchdog-rzg2l_wdt-handle-type-b-reset-for-rz-v2m.patch
+watchdog-at91sam9_wdt-use-devm_request_irq-to-avoid-.patch
+watchdog-fix-kmemleak-in-watchdog_cdev_register.patch
+watchdog-pcwd_usb-fix-attempting-to-access-uninitial.patch
+watchdog-sbsa_wdog-make-sure-the-timeout-programming.patch
+netfilter-ctnetlink-fix-possible-refcount-leak-in-ct.patch
+netfilter-conntrack-fix-rmmod-double-free-race.patch
+netfilter-ip6t_rpfilter-fix-regression-with-vrf-inte.patch
+netfilter-ebtables-fix-table-blob-use-after-free.patch
+netfilter-xt_length-use-skb-len-to-match-in-length_m.patch
+netfilter-ctnetlink-make-event-listener-tracking-glo.patch
+netfilter-x_tables-fix-percpu-counter-block-leak-on-.patch
+ptp-vclock-use-mutex-to-fix-sleep-on-atomic-bug.patch
+drm-i915-move-a-kconfig-symbol-to-unbreak-the-menu-p.patch
+ipv6-add-lwtunnel-encap-size-of-all-siblings-in-next.patch
+octeontx2-pf-recalculate-udp-checksum-for-ptp-1-step.patch
+net-sunhme-fix-region-request.patch
+sctp-add-a-refcnt-in-sctp_stream_priorities-to-avoid.patch
+octeontx2-pf-use-correct-struct-reference-in-test-co.patch
+net-fix-__dev_kfree_skb_any-vs-drop-monitor.patch
+9p-xen-fix-version-parsing.patch
+9p-xen-fix-connection-sequence.patch
+9p-rdma-unmap-receive-dma-buffer-in-rdma_request-pos.patch
+spi-tegra210-quad-fix-validate-combined-sequence.patch
+mlx5-fix-skb-leak-while-fifo-resync-and-push.patch
+mlx5-fix-possible-ptp-queue-fifo-use-after-free.patch
+net-mlx5-ecpf-wait-for-vf-pages-only-after-disabling.patch
+net-mlx5e-verify-flow_source-cap-before-using-it.patch
+net-mlx5-geneve-fix-handling-of-geneve-object-id-as-.patch
+ext4-fix-incorrect-options-show-of-original-mount_op.patch
+nfc-fix-memory-leak-of-se_io-context-in-nfc_genl_se_.patch
+net-sched-transition-act_pedit-to-rcu-and-percpu-sta.patch
+net-sched-act_pedit-fix-action-bind-logic.patch
+net-sched-act_mpls-fix-action-bind-logic.patch
+net-sched-act_sample-fix-action-bind-logic.patch
+net-dsa-seville-ignore-mscc-miim-read-errors-from-ly.patch
+net-dsa-felix-fix-internal-mdio-controller-resource-.patch
+arm-dts-spear320-hmi-correct-stmpe-gpio-compatible.patch
+tcp-tcp_check_req-can-be-called-from-process-context.patch
+vc_screen-modify-vcs_size-handling-in-vcs_read.patch
+spi-tegra210-quad-fix-iterator-outside-loop.patch
+rtc-sun6i-always-export-the-internal-oscillator.patch
+genirq-ipi-fix-null-pointer-deref-in-irq_data_get_af.patch
+scsi-ipr-work-around-fortify-string-warning.patch
+scsi-mpi3mr-fix-an-issue-found-by-kasan.patch
+scsi-mpi3mr-use-number-of-bits-to-manage-bitmap-size.patch
+rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch
+io_uring-fix-size-calculation-when-registering-buf-r.patch
+loop-loop_set_status_from_info-check-before-assignme.patch
+asoc-adau7118-don-t-disable-regulators-on-device-unb.patch
+asoc-apple-mca-fix-final-status-read-on-serdes-reset.patch
+asoc-apple-mca-fix-serdes-reset-sequence.patch
+asoc-apple-mca-improve-handling-of-unavailable-dma-c.patch
+nvme-bring-back-auto-removal-of-deleted-namespaces-d.patch
+nvme-tcp-don-t-access-released-socket-during-error-r.patch
+nvme-fabrics-show-well-known-discovery-name.patch
+asoc-zl38060-add-gpiolib-dependency.patch
+asoc-mediatek-mt8195-add-missing-initialization.patch
+thermal-intel-quark_dts-fix-error-pointer-dereferenc.patch
+thermal-intel-bxt_pmic-select-regmap-instead-of-depe.patch
+tracing-add-null-checks-for-buffer-in-ring_buffer_fr.patch
+kernel-printk-index.c-fix-memory-leak-with-using-deb.patch
+firmware-efi-sysfb_efi-add-quirk-for-lenovo-ideapad-.patch
+bootconfig-increase-max-nodes-of-bootconfig-from-102.patch
+mfd-arizona-use-pm_runtime_resume_and_get-to-prevent.patch
+ib-hfi1-update-rmt-size-calculation.patch
+iommu-amd-fix-error-handling-for-pdev_pri_ats_enable.patch
+pci-acpi-account-for-_s0w-of-the-target-bridge-in-ac.patch
+media-uvcvideo-remove-format-descriptions.patch
+media-uvcvideo-handle-cameras-with-invalid-descripto.patch
+media-uvcvideo-handle-errors-from-calls-to-usb_strin.patch
+media-uvcvideo-quirk-for-autosuspend-in-logitech-b91.patch
+media-uvcvideo-silence-memcpy-run-time-false-positiv.patch
+usb-fix-memory-leak-with-using-debugfs_lookup.patch
+cacheinfo-fix-shared_cpu_map-to-handle-shared-caches.patch
+staging-emxx_udc-add-checks-for-dma_alloc_coherent.patch
+tty-fix-out-of-bounds-access-in-tty_driver_lookup_tt.patch
+tty-serial-fsl_lpuart-disable-the-cts-when-send-brea.patch
+serial-sc16is7xx-setup-gpio-controller-later-in-prob.patch
+mei-bus-fixup-upon-error-print-return-values-of-send.patch
+parport_pc-set-up-mode-and-ecr-masks-for-oxford-semi.patch
+tools-iio-iio_utils-fix-memory-leak.patch
+bus-mhi-ep-fix-the-debug-message-for-mhi_pkt_type_re.patch
+iio-accel-mma9551_core-prevent-uninitialized-variabl.patch
+iio-accel-mma9551_core-prevent-uninitialized-variabl.patch-31718
+media-uvcvideo-add-guid-for-bgra-x-8-8-8-8.patch
+soundwire-bus_type-avoid-lockdep-assert-in-sdw_drv_p.patch
+pci-loongson-prevent-ls7a-mrrs-increases.patch
+staging-pi433-fix-memory-leak-with-using-debugfs_loo.patch
+usb-dwc3-fix-memory-leak-with-using-debugfs_lookup.patch
+usb-chipidea-fix-memory-leak-with-using-debugfs_look.patch
+usb-ulpi-fix-memory-leak-with-using-debugfs_lookup.patch
+usb-uhci-fix-memory-leak-with-using-debugfs_lookup.patch
+usb-sl811-fix-memory-leak-with-using-debugfs_lookup.patch
+usb-fotg210-fix-memory-leak-with-using-debugfs_looku.patch
+usb-isp116x-fix-memory-leak-with-using-debugfs_looku.patch
+usb-isp1362-fix-memory-leak-with-using-debugfs_looku.patch
+usb-gadget-gr_udc-fix-memory-leak-with-using-debugfs.patch
+usb-gadget-bcm63xx_udc-fix-memory-leak-with-using-de.patch
+usb-gadget-lpc32xx_udc-fix-memory-leak-with-using-de.patch
+usb-gadget-pxa25x_udc-fix-memory-leak-with-using-deb.patch
+usb-gadget-pxa27x_udc-fix-memory-leak-with-using-deb.patch
+usb-host-xhci-mvebu-iterate-over-array-indexes-inste.patch
+usb-ene_usb6250-allocate-enough-memory-for-full-obje.patch
+usb-uvc-enumerate-valid-values-for-color-matching.patch
+usb-gadget-uvc-make-bsourceid-read-write.patch
+pci-align-extra-resources-for-hotplug-bridges-proper.patch
+pci-take-other-bus-devices-into-account-when-distrib.patch
+pci-distribute-available-resources-for-root-buses-to.patch
+tty-pcn_uart-fix-memory-leak-with-using-debugfs_look.patch
+misc-vmw_balloon-fix-memory-leak-with-using-debugfs_.patch
+drivers-base-component-fix-memory-leak-with-using-de.patch
+drivers-base-dd-fix-memory-leak-with-using-debugfs_l.patch
+kernel-fail_function-fix-memory-leak-with-using-debu.patch
+pci-loongson-add-more-devices-that-need-mrrs-quirk.patch
+pci-add-acs-quirk-for-wangxun-nics.patch
+pci-pciehp-add-qualcomm-quirk-for-command-completed-.patch
+phy-rockchip-typec-fix-unsigned-comparison-with-less.patch
+rdma-cma-distinguish-between-sockaddr_in-and-sockadd.patch
+iommu-attach-device-group-to-old-domain-in-error-pat.patch
+soundwire-cadence-remove-wasted-space-in-response_bu.patch
+soundwire-cadence-drain-the-rx-fifo-after-an-io-time.patch
--- /dev/null
+From a37518fc8eaf380666cbd5494f621ff128a6379e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Oct 2022 15:54:34 +0800
+Subject: soc: mediatek: mtk-pm-domains: Allow mt8186 ADSP default power on
+
+From: Tinghan Shen <tinghan.shen@mediatek.com>
+
+[ Upstream commit 0d08c56d97a614f56d74f490d693faf8038db125 ]
+
+In the use case of configuring the access permissions of the ADSP core,
+the mt8186 SoC ADSP power will be switched on in the bootloader because
+the permission control registers are located in the ADSP subsys.
+
+Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
+Fixes: 88590cbc1703 ("soc: mediatek: pm-domains: Add support for mt8186")
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221012075434.30009-1-tinghan.shen@mediatek.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mt8186-pm-domains.h | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mt8186-pm-domains.h b/drivers/soc/mediatek/mt8186-pm-domains.h
+index 108af61854a38..fce86f79c5055 100644
+--- a/drivers/soc/mediatek/mt8186-pm-domains.h
++++ b/drivers/soc/mediatek/mt8186-pm-domains.h
+@@ -304,7 +304,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
+ .ctl_offs = 0x9FC,
+ .pwr_sta_offs = 0x16C,
+ .pwr_sta2nd_offs = 0x170,
+- .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+ },
+ [MT8186_POWER_DOMAIN_ADSP_INFRA] = {
+ .name = "adsp_infra",
+@@ -312,7 +311,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
+ .ctl_offs = 0x9F8,
+ .pwr_sta_offs = 0x16C,
+ .pwr_sta2nd_offs = 0x170,
+- .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+ },
+ [MT8186_POWER_DOMAIN_ADSP_TOP] = {
+ .name = "adsp_top",
+@@ -332,7 +330,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
+ MT8186_TOP_AXI_PROT_EN_3_CLR,
+ MT8186_TOP_AXI_PROT_EN_3_STA),
+ },
+- .caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
++ .caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_ACTIVE_WAKEUP,
+ },
+ };
+
+--
+2.39.2
+
--- /dev/null
+From 84e5d7fa77a509c2f78fa66ecfdc6c529f06a7cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 22:35:59 +0100
+Subject: soc: mediatek: mtk-svs: Enable the IRQ later
+
+From: Ricardo Ribalda <ribalda@chromium.org>
+
+[ Upstream commit b74952aba6c3f47e7f2c5165abaeefa44c377140 ]
+
+If the system does not come from reset (like when is booted via
+kexec()), the peripheral might triger an IRQ before the data structures
+are initialised.
+
+Fixes:
+
+[ 0.227710] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000f08
+[ 0.227913] Call trace:
+[ 0.227918] svs_isr+0x8c/0x538
+
+Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
+Link: https://lore.kernel.org/r/20221127-mtk-svs-v2-0-145b07663ea8@chromium.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mtk-svs.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
+index 0469c9dfeb04e..75b2f534aa9d0 100644
+--- a/drivers/soc/mediatek/mtk-svs.c
++++ b/drivers/soc/mediatek/mtk-svs.c
+@@ -2385,14 +2385,6 @@ static int svs_probe(struct platform_device *pdev)
+ goto svs_probe_free_resource;
+ }
+
+- ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr,
+- IRQF_ONESHOT, svsp->name, svsp);
+- if (ret) {
+- dev_err(svsp->dev, "register irq(%d) failed: %d\n",
+- svsp_irq, ret);
+- goto svs_probe_free_resource;
+- }
+-
+ svsp->main_clk = devm_clk_get(svsp->dev, "main");
+ if (IS_ERR(svsp->main_clk)) {
+ dev_err(svsp->dev, "failed to get clock: %ld\n",
+@@ -2414,6 +2406,14 @@ static int svs_probe(struct platform_device *pdev)
+ goto svs_probe_clk_disable;
+ }
+
++ ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr,
++ IRQF_ONESHOT, svsp->name, svsp);
++ if (ret) {
++ dev_err(svsp->dev, "register irq(%d) failed: %d\n",
++ svsp_irq, ret);
++ goto svs_probe_iounmap;
++ }
++
+ ret = svs_start(svsp);
+ if (ret) {
+ dev_err(svsp->dev, "svs start fail: %d\n", ret);
+--
+2.39.2
+
--- /dev/null
+From c438158b5adf14faed58a940af4dfacc8c8d7120 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 15:45:16 +0800
+Subject: soc: mediatek: mtk-svs: reset svs when svs_resume() fail
+
+From: Roger Lu <roger.lu@mediatek.com>
+
+[ Upstream commit f4f8ad204a15d57c1a3e8ea7eca62157b44cbf59 ]
+
+Add svs reset when svs_resume() fail.
+
+Fixes: a825d72f74a3 ("soc: mediatek: fix missing clk_disable_unprepare() on err in svs_resume()")
+Signed-off-by: Roger Lu <roger.lu@mediatek.com>
+Link: https://lore.kernel.org/r/20230111074528.29354-3-roger.lu@mediatek.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mtk-svs.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
+index 9859e6cf6b8f9..e0b8aa75c84b6 100644
+--- a/drivers/soc/mediatek/mtk-svs.c
++++ b/drivers/soc/mediatek/mtk-svs.c
+@@ -1614,12 +1614,16 @@ static int svs_resume(struct device *dev)
+
+ ret = svs_init02(svsp);
+ if (ret)
+- goto out_of_resume;
++ goto svs_resume_reset_assert;
+
+ svs_mon_mode(svsp);
+
+ return 0;
+
++svs_resume_reset_assert:
++ dev_err(svsp->dev, "assert reset: %d\n",
++ reset_control_assert(svsp->rst));
++
+ out_of_resume:
+ clk_disable_unprepare(svsp->main_clk);
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From b0a8641c9b13c27ef87e7699bf3b4e7d2211b010 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 15:45:15 +0800
+Subject: soc: mediatek: mtk-svs: restore default voltages when svs_init02()
+ fail
+
+From: Roger Lu <roger.lu@mediatek.com>
+
+[ Upstream commit a0674cd237fc24b08c7dcb4f8e48df3ee769293a ]
+
+If svs init02 fail, it means we cannot rely on svs bank voltages anymore.
+We need to disable svs function and restore DVFS opp voltages back to the
+default voltages for making sure we have enough DVFS voltages.
+
+Fixes: 681a02e95000 ("soc: mediatek: SVS: introduce MTK SVS engine")
+Fixes: 0bbb09b2af9d ("soc: mediatek: SVS: add mt8192 SVS GPU driver")
+Signed-off-by: Roger Lu <roger.lu@mediatek.com>
+Link: https://lore.kernel.org/r/20230111074528.29354-2-roger.lu@mediatek.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mtk-svs.c | 24 ++++++++++++++++++++++--
+ 1 file changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
+index 75b2f534aa9d0..9859e6cf6b8f9 100644
+--- a/drivers/soc/mediatek/mtk-svs.c
++++ b/drivers/soc/mediatek/mtk-svs.c
+@@ -1461,6 +1461,7 @@ static int svs_init02(struct svs_platform *svsp)
+ {
+ struct svs_bank *svsb;
+ unsigned long flags, time_left;
++ int ret;
+ u32 idx;
+
+ for (idx = 0; idx < svsp->bank_max; idx++) {
+@@ -1479,7 +1480,8 @@ static int svs_init02(struct svs_platform *svsp)
+ msecs_to_jiffies(5000));
+ if (!time_left) {
+ dev_err(svsb->dev, "init02 completion timeout\n");
+- return -EBUSY;
++ ret = -EBUSY;
++ goto out_of_init02;
+ }
+ }
+
+@@ -1497,12 +1499,30 @@ static int svs_init02(struct svs_platform *svsp)
+ if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
+ if (svs_sync_bank_volts_from_opp(svsb)) {
+ dev_err(svsb->dev, "sync volt fail\n");
+- return -EPERM;
++ ret = -EPERM;
++ goto out_of_init02;
+ }
+ }
+ }
+
+ return 0;
++
++out_of_init02:
++ for (idx = 0; idx < svsp->bank_max; idx++) {
++ svsb = &svsp->banks[idx];
++
++ spin_lock_irqsave(&svs_lock, flags);
++ svsp->pbank = svsb;
++ svs_switch_bank(svsp);
++ svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN);
++ svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS);
++ spin_unlock_irqrestore(&svs_lock, flags);
++
++ svsb->phase = SVSB_PHASE_ERROR;
++ svs_adjust_pm_opp_volts(svsb);
++ }
++
++ return ret;
+ }
+
+ static void svs_mon_mode(struct svs_platform *svsp)
+--
+2.39.2
+
--- /dev/null
+From b700b23265157897dc2e1bfe3f632a13a2b38b1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jan 2023 15:45:18 +0800
+Subject: soc: mediatek: mtk-svs: Use pm_runtime_resume_and_get() in
+ svs_init01()
+
+From: Shang XiaoJing <shangxiaojing@huawei.com>
+
+[ Upstream commit 37fa2aff8fe490771f2229b0f2fcd15796b1bfca ]
+
+svs_init01() calls pm_runtime_get_sync() and added fail path as
+svs_init01_finish to put usage_counter. However, pm_runtime_get_sync()
+will increment usage_counter even it failed. Fix it by replacing it with
+pm_runtime_resume_and_get() to keep usage counter balanced.
+
+Fixes: 681a02e95000 ("soc: mediatek: SVS: introduce MTK SVS engine")
+Signed-off-by: Shang XiaoJing <shangxiaojing@huawei.com>
+Signed-off-by: Roger Lu <roger.lu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230111074528.29354-5-roger.lu@mediatek.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mtk-svs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
+index e0b8aa75c84b6..00526fd37d7b8 100644
+--- a/drivers/soc/mediatek/mtk-svs.c
++++ b/drivers/soc/mediatek/mtk-svs.c
+@@ -1324,7 +1324,7 @@ static int svs_init01(struct svs_platform *svsp)
+ svsb->pm_runtime_enabled_count++;
+ }
+
+- ret = pm_runtime_get_sync(svsb->opp_dev);
++ ret = pm_runtime_resume_and_get(svsb->opp_dev);
+ if (ret < 0) {
+ dev_err(svsb->dev, "mtcmos on fail: %d\n", ret);
+ goto svs_init01_resume_cpuidle;
+--
+2.39.2
+
--- /dev/null
+From 91bd74a8cde6fc3ca74154cb77ade6ea0ead1e60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Jan 2023 19:23:29 -0800
+Subject: soc: qcom: stats: Populate all subsystem debugfs files
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit acdbf5f9b2c492505145f6e50c65418521a547c4 ]
+
+This driver relies on SMEM to populate items for each subsystem before
+the device probes. The items in SMEM that are being looked for are
+populated by the subsystems lazily, and therefore may not exist until
+the device has booted. For example, if I build this driver into the
+kernel on Trogdor Lazor and boot up, I don't see a 'modem' debugfs file
+populated, because the modem boots and populates the SMEM item after
+this driver probes.
+
+Always populate the files for the subsystems if they're in SMEM, and
+make the qcom_subsystem_sleep_stats_show() function return 0 if the SMEM
+items still isn't there. This way we can run a simple command like
+
+ grep ^ /sys/kernel/debug/qcom_stats/*
+
+and collect the subsystem sleep stats without interspersed errors or
+missing details entirely because this driver probed first.
+
+Fixes: 1d7724690344 ("soc: qcom: Add Sleep stats driver")
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230119032329.2909383-1-swboyd@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/qcom_stats.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
+index 121ea409fafcd..b252bedf0cf10 100644
+--- a/drivers/soc/qcom/qcom_stats.c
++++ b/drivers/soc/qcom/qcom_stats.c
+@@ -92,7 +92,7 @@ static int qcom_subsystem_sleep_stats_show(struct seq_file *s, void *unused)
+ /* Items are allocated lazily, so lookup pointer each time */
+ stat = qcom_smem_get(subsystem->pid, subsystem->smem_item, NULL);
+ if (IS_ERR(stat))
+- return -EIO;
++ return 0;
+
+ qcom_print_stats(s, stat);
+
+@@ -170,20 +170,14 @@ static void qcom_create_soc_sleep_stat_files(struct dentry *root, void __iomem *
+ static void qcom_create_subsystem_stat_files(struct dentry *root,
+ const struct stats_config *config)
+ {
+- const struct sleep_stats *stat;
+ int i;
+
+ if (!config->subsystem_stats_in_smem)
+ return;
+
+- for (i = 0; i < ARRAY_SIZE(subsystems); i++) {
+- stat = qcom_smem_get(subsystems[i].pid, subsystems[i].smem_item, NULL);
+- if (IS_ERR(stat))
+- continue;
+-
++ for (i = 0; i < ARRAY_SIZE(subsystems); i++)
+ debugfs_create_file(subsystems[i].name, 0400, root, (void *)&subsystems[i],
+ &qcom_subsystem_sleep_stats_fops);
+- }
+ }
+
+ static int qcom_stats_probe(struct platform_device *pdev)
+--
+2.39.2
+
--- /dev/null
+From 1b2ab08be4702d827e21b8c95c94ae364255bf0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Jan 2023 17:25:20 +0000
+Subject: soundwire: bus_type: Avoid lockdep assert in sdw_drv_probe()
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 3dca1f89ae3455963d7b53245ecf298ea9bae857 ]
+
+Don't hold sdw_dev_lock while calling the peripheral driver
+probe() and remove() callbacks.
+
+Holding sdw_dev_lock around the probe() and remove() calls causes
+a theoretical mutex inversion which lockdep will assert on.
+
+During probe() the sdw_dev_lock mutex is taken first and then
+ASoC/ALSA locks are taken by the probe() implementation.
+
+During normal operation ASoC can take its locks and then trigger
+a runtime resume of the component. The SoundWire resume will then
+take sdw_dev_lock. This is the reverse order compared to probe().
+
+It's not necessary to hold sdw_dev_lock when calling the probe()
+and remove(), it is only used to prevent the bus core calling the
+driver callbacks if there isn't a driver or the driver is removing.
+
+All calls to the driver callbacks are guarded by the 'probed' flag.
+So if sdw_dev_lock is held while setting and clearing the 'probed'
+flag this is sufficient to guarantee the safety of callback
+functions.
+
+Removing the mutex from around the call to probe() means that it
+is now possible for a bus event (PING response) to be handled in
+parallel with the probe(). But sdw_bus_probe() already has
+handling for this by calling the device update_status() after
+the probe() has completed.
+
+Example lockdep assert:
+[ 46.098514] ======================================================
+[ 46.104736] WARNING: possible circular locking dependency detected
+[ 46.110961] 6.1.0-rc4-jamerson #1 Tainted: G E
+[ 46.116842] ------------------------------------------------------
+[ 46.123063] mpg123/1130 is trying to acquire lock:
+[ 46.127883] ffff8b445031fb80 (&slave->sdw_dev_lock){+.+.}-{3:3}, at: sdw_update_slave_status+0x26/0x70
+[ 46.137225]
+ but task is already holding lock:
+[ 46.143074] ffffffffc1455310 (&card->pcm_mutex){+.+.}-{3:3}, at: dpcm_fe_dai_open+0x49/0x830
+[ 46.151536]
+ which lock already depends on the new lock.[ 46.159732]
+ the existing dependency chain (in reverse order) is:
+[ 46.167231]
+ -> #4 (&card->pcm_mutex){+.+.}-{3:3}:
+[ 46.173428] __mutex_lock+0x94/0x920
+[ 46.177542] snd_soc_dpcm_runtime_update+0x2e/0x100
+[ 46.182958] snd_soc_dapm_put_enum_double+0x1c2/0x200
+[ 46.188548] snd_ctl_elem_write+0x10c/0x1d0
+[ 46.193268] snd_ctl_ioctl+0x126/0x850
+[ 46.197556] __x64_sys_ioctl+0x87/0xc0
+[ 46.201845] do_syscall_64+0x38/0x90
+[ 46.205959] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 46.211553]
+ -> #3 (&card->controls_rwsem){++++}-{3:3}:
+[ 46.218188] down_write+0x2b/0xd0
+[ 46.222038] snd_ctl_add_replace+0x39/0xb0
+[ 46.226672] snd_soc_add_controls+0x53/0x80
+[ 46.231393] soc_probe_component+0x1e4/0x2a0
+[ 46.236202] snd_soc_bind_card+0x51a/0xc80
+[ 46.240836] devm_snd_soc_register_card+0x43/0x90
+[ 46.246079] mc_probe+0x982/0xfe0 [snd_soc_sof_sdw]
+[ 46.251500] platform_probe+0x3c/0xa0
+[ 46.255700] really_probe+0xde/0x390
+[ 46.259814] __driver_probe_device+0x78/0x180
+[ 46.264710] driver_probe_device+0x1e/0x90
+[ 46.269347] __driver_attach+0x9f/0x1f0
+[ 46.273721] bus_for_each_dev+0x78/0xc0
+[ 46.278098] bus_add_driver+0x1ac/0x200
+[ 46.282473] driver_register+0x8f/0xf0
+[ 46.286759] do_one_initcall+0x58/0x310
+[ 46.291136] do_init_module+0x4c/0x1f0
+[ 46.295422] __do_sys_finit_module+0xb4/0x130
+[ 46.300321] do_syscall_64+0x38/0x90
+[ 46.304434] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 46.310027]
+ -> #2 (&card->mutex){+.+.}-{3:3}:
+[ 46.315883] __mutex_lock+0x94/0x920
+[ 46.320000] snd_soc_bind_card+0x3e/0xc80
+[ 46.324551] devm_snd_soc_register_card+0x43/0x90
+[ 46.329798] mc_probe+0x982/0xfe0 [snd_soc_sof_sdw]
+[ 46.335219] platform_probe+0x3c/0xa0
+[ 46.339420] really_probe+0xde/0x390
+[ 46.343532] __driver_probe_device+0x78/0x180
+[ 46.348430] driver_probe_device+0x1e/0x90
+[ 46.353065] __driver_attach+0x9f/0x1f0
+[ 46.357437] bus_for_each_dev+0x78/0xc0
+[ 46.361812] bus_add_driver+0x1ac/0x200
+[ 46.366716] driver_register+0x8f/0xf0
+[ 46.371528] do_one_initcall+0x58/0x310
+[ 46.376424] do_init_module+0x4c/0x1f0
+[ 46.381239] __do_sys_finit_module+0xb4/0x130
+[ 46.386665] do_syscall_64+0x38/0x90
+[ 46.391299] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 46.397416]
+ -> #1 (client_mutex){+.+.}-{3:3}:
+[ 46.404307] __mutex_lock+0x94/0x920
+[ 46.408941] snd_soc_add_component+0x24/0x2c0
+[ 46.414345] devm_snd_soc_register_component+0x54/0xa0
+[ 46.420522] cs35l56_common_probe+0x280/0x370 [snd_soc_cs35l56]
+[ 46.427487] cs35l56_sdw_probe+0xf4/0x170 [snd_soc_cs35l56_sdw]
+[ 46.434442] sdw_drv_probe+0x80/0x1a0
+[ 46.439136] really_probe+0xde/0x390
+[ 46.443738] __driver_probe_device+0x78/0x180
+[ 46.449120] driver_probe_device+0x1e/0x90
+[ 46.454247] __driver_attach+0x9f/0x1f0
+[ 46.459106] bus_for_each_dev+0x78/0xc0
+[ 46.463971] bus_add_driver+0x1ac/0x200
+[ 46.468825] driver_register+0x8f/0xf0
+[ 46.473592] do_one_initcall+0x58/0x310
+[ 46.478441] do_init_module+0x4c/0x1f0
+[ 46.483202] __do_sys_finit_module+0xb4/0x130
+[ 46.488572] do_syscall_64+0x38/0x90
+[ 46.493158] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 46.499229]
+ -> #0 (&slave->sdw_dev_lock){+.+.}-{3:3}:
+[ 46.506737] __lock_acquire+0x1121/0x1df0
+[ 46.511765] lock_acquire+0xd5/0x300
+[ 46.516360] __mutex_lock+0x94/0x920
+[ 46.520949] sdw_update_slave_status+0x26/0x70
+[ 46.526409] sdw_clear_slave_status+0xd8/0xe0
+[ 46.531783] intel_resume_runtime+0x139/0x2a0
+[ 46.537155] __rpm_callback+0x41/0x120
+[ 46.541919] rpm_callback+0x5d/0x70
+[ 46.546422] rpm_resume+0x531/0x7e0
+[ 46.550920] __pm_runtime_resume+0x4a/0x80
+[ 46.556024] snd_soc_pcm_component_pm_runtime_get+0x2f/0xc0
+[ 46.562611] __soc_pcm_open+0x62/0x520
+[ 46.567375] dpcm_be_dai_startup+0x116/0x210
+[ 46.572661] dpcm_fe_dai_open+0xf7/0x830
+[ 46.577597] snd_pcm_open_substream+0x54a/0x8b0
+[ 46.583145] snd_pcm_open.part.0+0xdc/0x200
+[ 46.588341] snd_pcm_playback_open+0x51/0x80
+[ 46.593625] chrdev_open+0xc0/0x250
+[ 46.598129] do_dentry_open+0x15f/0x430
+[ 46.602981] path_openat+0x75e/0xa80
+[ 46.607575] do_filp_open+0xb2/0x160
+[ 46.612162] do_sys_openat2+0x9a/0x160
+[ 46.616922] __x64_sys_openat+0x53/0xa0
+[ 46.621767] do_syscall_64+0x38/0x90
+[ 46.626352] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 46.632414]
+ other info that might help us debug this:[ 46.641862] Chain exists of:
+ &slave->sdw_dev_lock --> &card->controls_rwsem --> &card->pcm_mutex[ 46.655145] Possible unsafe locking scenario:[ 46.662048] CPU0 CPU1
+[ 46.667080] ---- ----
+[ 46.672108] lock(&card->pcm_mutex);
+[ 46.676267] lock(&card->controls_rwsem);
+[ 46.683382] lock(&card->pcm_mutex);
+[ 46.690063] lock(&slave->sdw_dev_lock);
+[ 46.694574]
+ *** DEADLOCK ***[ 46.701942] 2 locks held by mpg123/1130:
+[ 46.706356] #0: ffff8b4457b22b90 (&pcm->open_mutex){+.+.}-{3:3}, at: snd_pcm_open.part.0+0xc9/0x200
+[ 46.715999] #1: ffffffffc1455310 (&card->pcm_mutex){+.+.}-{3:3}, at: dpcm_fe_dai_open+0x49/0x830
+[ 46.725390]
+ stack backtrace:
+[ 46.730752] CPU: 0 PID: 1130 Comm: mpg123 Tainted: G E 6.1.0-rc4-jamerson #1
+[ 46.739703] Hardware name: AAEON UP-WHL01/UP-WHL01, BIOS UPW1AM19 11/10/2020
+[ 46.747270] Call Trace:
+[ 46.750239] <TASK>
+[ 46.752857] dump_stack_lvl+0x56/0x73
+[ 46.757045] check_noncircular+0x102/0x120
+[ 46.761664] __lock_acquire+0x1121/0x1df0
+[ 46.766197] lock_acquire+0xd5/0x300
+[ 46.770292] ? sdw_update_slave_status+0x26/0x70
+[ 46.775432] ? lock_is_held_type+0xe2/0x140
+[ 46.780143] __mutex_lock+0x94/0x920
+[ 46.784241] ? sdw_update_slave_status+0x26/0x70
+[ 46.789387] ? find_held_lock+0x2b/0x80
+[ 46.793750] ? sdw_update_slave_status+0x26/0x70
+[ 46.798894] ? lock_release+0x147/0x2f0
+[ 46.803262] ? lockdep_init_map_type+0x47/0x250
+[ 46.808315] ? sdw_update_slave_status+0x26/0x70
+[ 46.813456] sdw_update_slave_status+0x26/0x70
+[ 46.818422] sdw_clear_slave_status+0xd8/0xe0
+[ 46.823302] ? pm_generic_runtime_suspend+0x30/0x30
+[ 46.828706] intel_resume_runtime+0x139/0x2a0
+[ 46.833583] ? _raw_spin_unlock_irq+0x24/0x50
+[ 46.838462] ? pm_generic_runtime_suspend+0x30/0x30
+[ 46.843866] __rpm_callback+0x41/0x120
+[ 46.848142] ? pm_generic_runtime_suspend+0x30/0x30
+[ 46.853550] rpm_callback+0x5d/0x70
+[ 46.857568] rpm_resume+0x531/0x7e0
+[ 46.861578] ? _raw_spin_lock_irqsave+0x62/0x70
+[ 46.866634] __pm_runtime_resume+0x4a/0x80
+[ 46.871258] snd_soc_pcm_component_pm_runtime_get+0x2f/0xc0
+[ 46.877358] __soc_pcm_open+0x62/0x520
+[ 46.881634] ? dpcm_add_paths.isra.0+0x35d/0x4c0
+[ 46.886784] dpcm_be_dai_startup+0x116/0x210
+[ 46.891592] dpcm_fe_dai_open+0xf7/0x830
+[ 46.896046] ? debug_mutex_init+0x33/0x50
+[ 46.900591] snd_pcm_open_substream+0x54a/0x8b0
+[ 46.905658] snd_pcm_open.part.0+0xdc/0x200
+[ 46.910376] ? wake_up_q+0x90/0x90
+[ 46.914312] snd_pcm_playback_open+0x51/0x80
+[ 46.919118] chrdev_open+0xc0/0x250
+[ 46.923147] ? cdev_device_add+0x90/0x90
+[ 46.927608] do_dentry_open+0x15f/0x430
+[ 46.931976] path_openat+0x75e/0xa80
+[ 46.936086] do_filp_open+0xb2/0x160
+[ 46.940194] ? lock_release+0x147/0x2f0
+[ 46.944563] ? _raw_spin_unlock+0x29/0x50
+[ 46.949101] do_sys_openat2+0x9a/0x160
+[ 46.953377] __x64_sys_openat+0x53/0xa0
+[ 46.957733] do_syscall_64+0x38/0x90
+[ 46.961829] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[ 46.967402] RIP: 0033:0x7fa6397ccd3b
+[ 46.971506] Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0 75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00 f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
+[ 46.991413] RSP: 002b:00007fff838e8990 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
+[ 46.999580] RAX: ffffffffffffffda RBX: 0000000000080802 RCX: 00007fa6397ccd3b
+[ 47.007311] RDX: 0000000000080802 RSI: 00007fff838e8b50 RDI: 00000000ffffff9c
+[ 47.015047] RBP: 00007fff838e8b50 R08: 0000000000000000 R09: 0000000000000011
+[ 47.022787] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000080802
+[ 47.030539] R13: 0000000000000004 R14: 0000000000000000 R15: 00007fff838e8b50
+[ 47.038289] </TASK>
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20230123172520.339367-1-rf@opensource.cirrus.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/bus_type.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
+index 04b3529f89293..963498db0fd22 100644
+--- a/drivers/soundwire/bus_type.c
++++ b/drivers/soundwire/bus_type.c
+@@ -105,20 +105,19 @@ static int sdw_drv_probe(struct device *dev)
+ if (ret)
+ return ret;
+
+- mutex_lock(&slave->sdw_dev_lock);
+-
+ ret = drv->probe(slave, id);
+ if (ret) {
+ name = drv->name;
+ if (!name)
+ name = drv->driver.name;
+- mutex_unlock(&slave->sdw_dev_lock);
+
+ dev_err(dev, "Probe of %s failed: %d\n", name, ret);
+ dev_pm_domain_detach(dev, false);
+ return ret;
+ }
+
++ mutex_lock(&slave->sdw_dev_lock);
++
+ /* device is probed so let's read the properties now */
+ if (drv->ops && drv->ops->read_prop)
+ drv->ops->read_prop(slave);
+@@ -167,14 +166,12 @@ static int sdw_drv_remove(struct device *dev)
+ int ret = 0;
+
+ mutex_lock(&slave->sdw_dev_lock);
+-
+ slave->probed = false;
++ mutex_unlock(&slave->sdw_dev_lock);
+
+ if (drv->remove)
+ ret = drv->remove(slave);
+
+- mutex_unlock(&slave->sdw_dev_lock);
+-
+ dev_pm_domain_detach(dev, false);
+
+ return ret;
+--
+2.39.2
+
--- /dev/null
+From ff870f4a83d608e8c07406d2dd4ea3b3f1bc95e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 16:18:12 +0000
+Subject: soundwire: cadence: Drain the RX FIFO after an IO timeout
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 0603a47bd3a8f439d7844b841eee1819353063e0 ]
+
+If wait_for_completion_timeout() times-out in _cdns_xfer_msg() it
+is possible that something could have been written to the RX FIFO.
+In this case, we should drain the RX FIFO so that anything in it
+doesn't carry over and mess up the next transfer.
+
+Obviously, if we got to this state something went wrong, and we
+don't really know the state of everything. The cleanup in this
+situation cannot be bullet-proof but we should attempt to avoid
+breaking future transaction, if only to reduce the amount of
+error noise when debugging the failure from a kernel log.
+
+Note that this patch only implements the draining for blocking
+(non-deferred) transfers. The deferred API doesn't have any proper
+handling of error conditions and would need some re-design before
+implementing cleanup. That is a task for a separate patch...
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20221202161812.4186897-4-rf@opensource.cirrus.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/cadence_master.c | 50 ++++++++++++++++--------------
+ 1 file changed, 27 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
+index 6cd9db19758c9..e7da7d7b213fb 100644
+--- a/drivers/soundwire/cadence_master.c
++++ b/drivers/soundwire/cadence_master.c
+@@ -555,6 +555,29 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns,
+ return SDW_CMD_OK;
+ }
+
++static void cdns_read_response(struct sdw_cdns *cdns)
++{
++ u32 num_resp, cmd_base;
++ int i;
++
++ /* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */
++ BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2);
++
++ num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
++ num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
++ if (num_resp > ARRAY_SIZE(cdns->response_buf)) {
++ dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp);
++ num_resp = ARRAY_SIZE(cdns->response_buf);
++ }
++
++ cmd_base = CDNS_MCP_CMD_BASE;
++
++ for (i = 0; i < num_resp; i++) {
++ cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
++ cmd_base += CDNS_MCP_CMD_WORD_LEN;
++ }
++}
++
+ static enum sdw_command_response
+ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
+ int offset, int count, bool defer)
+@@ -596,6 +619,10 @@ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
+ dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n",
+ cmd, msg->dev_num, msg->addr, msg->len);
+ msg->len = 0;
++
++ /* Drain anything in the RX_FIFO */
++ cdns_read_response(cdns);
++
+ return SDW_CMD_TIMEOUT;
+ }
+
+@@ -769,29 +796,6 @@ EXPORT_SYMBOL(cdns_read_ping_status);
+ * IRQ handling
+ */
+
+-static void cdns_read_response(struct sdw_cdns *cdns)
+-{
+- u32 num_resp, cmd_base;
+- int i;
+-
+- /* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */
+- BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2);
+-
+- num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
+- num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
+- if (num_resp > ARRAY_SIZE(cdns->response_buf)) {
+- dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp);
+- num_resp = ARRAY_SIZE(cdns->response_buf);
+- }
+-
+- cmd_base = CDNS_MCP_CMD_BASE;
+-
+- for (i = 0; i < num_resp; i++) {
+- cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
+- cmd_base += CDNS_MCP_CMD_WORD_LEN;
+- }
+-}
+-
+ static int cdns_update_slave_status(struct sdw_cdns *cdns,
+ u64 slave_intstat)
+ {
+--
+2.39.2
+
--- /dev/null
+From 51cf8005e37329ef017a6e43d814cafaad5d5066 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Dec 2022 16:18:11 +0000
+Subject: soundwire: cadence: Remove wasted space in response_buf
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 827c32d0df4bbe0d1c47d79f6a5eabfe9ac75216 ]
+
+The response_buf was declared much larger (128 entries) than the number
+of responses that could ever be written into it. The Cadence IP is
+configurable up to a maximum of 32 entries, and the datasheet says
+that RX_FIFO_AVAIL can be 2 larger than this. So allow up to 34
+responses.
+
+Also add checking in cdns_read_response() to prevent overflowing
+reponse_buf if RX_FIFO_AVAIL contains an unexpectedly large number.
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20221202161812.4186897-3-rf@opensource.cirrus.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/cadence_master.c | 7 +++++++
+ drivers/soundwire/cadence_master.h | 13 ++++++++++++-
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
+index b65cdf2a7593e..6cd9db19758c9 100644
+--- a/drivers/soundwire/cadence_master.c
++++ b/drivers/soundwire/cadence_master.c
+@@ -774,8 +774,15 @@ static void cdns_read_response(struct sdw_cdns *cdns)
+ u32 num_resp, cmd_base;
+ int i;
+
++ /* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */
++ BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2);
++
+ num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
+ num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
++ if (num_resp > ARRAY_SIZE(cdns->response_buf)) {
++ dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp);
++ num_resp = ARRAY_SIZE(cdns->response_buf);
++ }
+
+ cmd_base = CDNS_MCP_CMD_BASE;
+
+diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
+index ca9e805bab88f..51e6ecc027cbc 100644
+--- a/drivers/soundwire/cadence_master.h
++++ b/drivers/soundwire/cadence_master.h
+@@ -8,6 +8,12 @@
+ #define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */
+ #define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000)
+
++/*
++ * The Cadence IP supports up to 32 entries in the FIFO, though implementations
++ * can configure the IP to have a smaller FIFO.
++ */
++#define CDNS_MCP_IP_MAX_CMD_LEN 32
++
+ /**
+ * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance
+ *
+@@ -114,7 +120,12 @@ struct sdw_cdns {
+ struct sdw_bus bus;
+ unsigned int instance;
+
+- u32 response_buf[0x80];
++ /*
++ * The datasheet says the RX FIFO AVAIL can be 2 entries more
++ * than the FIFO capacity, so allow for this.
++ */
++ u32 response_buf[CDNS_MCP_IP_MAX_CMD_LEN + 2];
++
+ struct completion tx_complete;
+ struct sdw_defer *defer;
+
+--
+2.39.2
+
--- /dev/null
+From 48f8419108eee9c736b2155062820bbdb9d17653 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Feb 2023 01:34:28 +0530
+Subject: spi: tegra210-quad: Fix iterator outside loop
+
+From: Krishna Yarlagadda <kyarlagadda@nvidia.com>
+
+[ Upstream commit 2449d436681d40bc63ec2c766fd51b632270d8a7 ]
+
+Fix warn: iterator used outside loop: 'xfer'. 'xfer' variable contain
+invalid value in few conditions. Complete transfer within DATA phase
+in successful case and at the end for failed transfer.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link:https://lore.kernel.org/all/202210191211.46FkzKmv-lkp@intel.com/
+Fixes: 8777dd9dff40 ("spi: tegra210-quad: Fix combined sequence")
+
+Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
+Link: https://lore.kernel.org/r/20230227200428.45832-1-kyarlagadda@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra210-quad.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index 6498948e150a5..06c54d49076ae 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -1156,6 +1156,10 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
+ ret = -EIO;
+ goto exit;
+ }
++ if (!xfer->cs_change) {
++ tegra_qspi_transfer_end(spi);
++ spi_transfer_delay_exec(xfer);
++ }
+ break;
+ default:
+ ret = -EINVAL;
+@@ -1164,14 +1168,14 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
+ msg->actual_length += xfer->len;
+ transfer_phase++;
+ }
+- if (!xfer->cs_change) {
+- tegra_qspi_transfer_end(spi);
+- spi_transfer_delay_exec(xfer);
+- }
+ ret = 0;
+
+ exit:
+ msg->status = ret;
++ if (ret < 0) {
++ tegra_qspi_transfer_end(spi);
++ spi_transfer_delay_exec(xfer);
++ }
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From 7d933c44dfa7d67ac2e944ac5aeb375c2646c5ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Feb 2023 22:10:34 +0530
+Subject: spi: tegra210-quad: Fix validate combined sequence
+
+From: Krishna Yarlagadda <kyarlagadda@nvidia.com>
+
+[ Upstream commit 047ee71ae4f412d8819e39e4b08c588fa299cfc2 ]
+
+Check for non dma transfers that do not fit in FIFO has issue and skips
+combined sequence for Tegra234 & Tegra241 which does not have GPCDMA.
+
+Fixes: 1b8342cc4a38 ("spi: tegra210-quad: combined sequence mode")
+
+Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
+Link: https://lore.kernel.org/r/20230224164034.56933-1-kyarlagadda@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra210-quad.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index 9f356612ba7e5..6498948e150a5 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -1297,7 +1297,7 @@ static bool tegra_qspi_validate_cmb_seq(struct tegra_qspi *tqspi,
+ if (xfer->len > 4 || xfer->len < 3)
+ return false;
+ xfer = list_next_entry(xfer, transfer_list);
+- if (!tqspi->soc_data->has_dma || xfer->len > (QSPI_FIFO_DEPTH << 2))
++ if (!tqspi->soc_data->has_dma && xfer->len > (QSPI_FIFO_DEPTH << 2))
+ return false;
+
+ return true;
+--
+2.39.2
+
--- /dev/null
+From b69aeca2b01403fef998fe56ae1deb15c80ccb69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Jan 2023 08:31:19 +0000
+Subject: staging: emxx_udc: Add checks for dma_alloc_coherent()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit f6510a93cfd8c6c79b4dda0f2967cdc6df42eff4 ]
+
+As the dma_alloc_coherent may return NULL, the return value needs to be
+checked to avoid NULL poineter dereference.
+
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Link: https://lore.kernel.org/r/20230119083119.16956-1-yuancan@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/emxx_udc/emxx_udc.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c
+index b6abd3770e81c..edd20a03f7a26 100644
+--- a/drivers/staging/emxx_udc/emxx_udc.c
++++ b/drivers/staging/emxx_udc/emxx_udc.c
+@@ -2590,10 +2590,15 @@ static int nbu2ss_ep_queue(struct usb_ep *_ep,
+ req->unaligned = false;
+
+ if (req->unaligned) {
+- if (!ep->virt_buf)
++ if (!ep->virt_buf) {
+ ep->virt_buf = dma_alloc_coherent(udc->dev, PAGE_SIZE,
+ &ep->phys_buf,
+ GFP_ATOMIC | GFP_DMA);
++ if (!ep->virt_buf) {
++ spin_unlock_irqrestore(&udc->lock, flags);
++ return -ENOMEM;
++ }
++ }
+ if (ep->epnum > 0) {
+ if (ep->direct == USB_DIR_IN)
+ memcpy(ep->virt_buf, req->req.buf,
+--
+2.39.2
+
--- /dev/null
+From 17b46b300ed1d560660a42055bf0232fe5936a31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 15:11:38 +0100
+Subject: staging: pi433: fix memory leak with using debugfs_lookup()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 2f36e789e540df6a9fbf471b3a2ba62a8b361586 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once. This requires saving off the root directory dentry to make
+creation of individual device subdirectories easier.
+
+Cc: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
+Cc: Dan Carpenter <error27@gmail.com>
+Cc: Sidong Yang <realwakka@gmail.com>
+Cc: Liu Shixin <liushixin2@huawei.com>
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20230202141138.2291946-1-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/pi433/pi433_if.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c
+index d4e06a3929f3d..b59f6a4cb611a 100644
+--- a/drivers/staging/pi433/pi433_if.c
++++ b/drivers/staging/pi433/pi433_if.c
+@@ -55,6 +55,7 @@
+ static dev_t pi433_dev;
+ static DEFINE_IDR(pi433_idr);
+ static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */
++static struct dentry *root_dir; /* debugfs root directory for the driver */
+
+ static struct class *pi433_class; /* mainly for udev to create /dev/pi433 */
+
+@@ -1306,8 +1307,7 @@ static int pi433_probe(struct spi_device *spi)
+ /* spi setup */
+ spi_set_drvdata(spi, device);
+
+- entry = debugfs_create_dir(dev_name(device->dev),
+- debugfs_lookup(KBUILD_MODNAME, NULL));
++ entry = debugfs_create_dir(dev_name(device->dev), root_dir);
+ debugfs_create_file("regs", 0400, entry, device, &pi433_debugfs_regs_fops);
+
+ return 0;
+@@ -1333,9 +1333,8 @@ static int pi433_probe(struct spi_device *spi)
+ static void pi433_remove(struct spi_device *spi)
+ {
+ struct pi433_device *device = spi_get_drvdata(spi);
+- struct dentry *mod_entry = debugfs_lookup(KBUILD_MODNAME, NULL);
+
+- debugfs_remove(debugfs_lookup(dev_name(device->dev), mod_entry));
++ debugfs_lookup_and_remove(dev_name(device->dev), root_dir);
+
+ /* free GPIOs */
+ free_gpio(device);
+@@ -1408,7 +1407,7 @@ static int __init pi433_init(void)
+ return PTR_ERR(pi433_class);
+ }
+
+- debugfs_create_dir(KBUILD_MODNAME, NULL);
++ root_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+ status = spi_register_driver(&pi433_spi_driver);
+ if (status < 0) {
+@@ -1427,7 +1426,7 @@ static void __exit pi433_exit(void)
+ spi_unregister_driver(&pi433_spi_driver);
+ class_destroy(pi433_class);
+ unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name);
+- debugfs_remove_recursive(debugfs_lookup(KBUILD_MODNAME, NULL));
++ debugfs_remove(root_dir);
+ }
+ module_exit(pi433_exit);
+
+--
+2.39.2
+
--- /dev/null
+From c1cfeb46ef49f343a8762ebbcf68c9580856590c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Feb 2023 08:33:36 +0000
+Subject: tcp: tcp_check_req() can be called from process context
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 580f98cc33a260bb8c6a39ae2921b29586b84fdf ]
+
+This is a follow up of commit 0a375c822497 ("tcp: tcp_rtx_synack()
+can be called from process context").
+
+Frederick Lawler reported another "__this_cpu_add() in preemptible"
+warning caused by the same reason.
+
+In my former patch I took care of tcp_rtx_synack()
+but forgot that tcp_check_req() also contained some SNMP updates.
+
+Note that some parts of tcp_check_req() always run in BH context,
+I added a comment to clarify this.
+
+Fixes: 8336886f786f ("tcp: TCP Fast Open Server - support TFO listeners")
+Link: https://lore.kernel.org/netdev/8cd33923-a21d-397c-e46b-2a068c287b03@cloudflare.com/T/
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Frederick Lawler <fred@cloudflare.com>
+Tested-by: Frederick Lawler <fred@cloudflare.com>
+Link: https://lore.kernel.org/r/20230227083336.4153089-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_minisocks.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
+index c375f603a16cf..7f37e7da64671 100644
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -580,6 +580,9 @@ EXPORT_SYMBOL(tcp_create_openreq_child);
+ * validation and inside tcp_v4_reqsk_send_ack(). Can we do better?
+ *
+ * We don't need to initialize tmp_opt.sack_ok as we don't use the results
++ *
++ * Note: If @fastopen is true, this can be called from process context.
++ * Otherwise, this is from BH context.
+ */
+
+ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
+@@ -731,7 +734,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
+ &tcp_rsk(req)->last_oow_ack_time))
+ req->rsk_ops->send_ack(sk, skb, req);
+ if (paws_reject)
+- __NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
++ NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
+ return NULL;
+ }
+
+@@ -750,7 +753,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
+ * "fourth, check the SYN bit"
+ */
+ if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) {
+- __TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS);
++ TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS);
+ goto embryonic_reset;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From ab944a691663a9da7a09845227d7815e63ae9200 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Feb 2023 21:39:52 -0800
+Subject: thermal: intel: BXT_PMIC: select REGMAP instead of depending on it
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 1467fb960349dfa5e300658f1a409dde2cfb0c51 ]
+
+REGMAP is a hidden (not user visible) symbol. Users cannot set it
+directly thru "make *config", so drivers should select it instead of
+depending on it if they need it.
+
+Consistently using "select" or "depends on" can also help reduce
+Kconfig circular dependency issues.
+
+Therefore, change the use of "depends on REGMAP" to "select REGMAP".
+
+Fixes: b474303ffd57 ("thermal: add Intel BXT WhiskeyCove PMIC thermal driver")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/intel/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/intel/Kconfig b/drivers/thermal/intel/Kconfig
+index f0c8456792509..e3cfad10d5dd4 100644
+--- a/drivers/thermal/intel/Kconfig
++++ b/drivers/thermal/intel/Kconfig
+@@ -64,7 +64,8 @@ endmenu
+
+ config INTEL_BXT_PMIC_THERMAL
+ tristate "Intel Broxton PMIC thermal driver"
+- depends on X86 && INTEL_SOC_PMIC_BXTWC && REGMAP
++ depends on X86 && INTEL_SOC_PMIC_BXTWC
++ select REGMAP
+ help
+ Select this driver for Intel Broxton PMIC with ADC channels monitoring
+ system temperature measurements and alerts.
+--
+2.39.2
+
--- /dev/null
+From 5864cb17bd5c9839a84034111c9f755848a30f27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Feb 2023 13:06:50 +0300
+Subject: thermal: intel: quark_dts: fix error pointer dereference
+
+From: Dan Carpenter <error27@gmail.com>
+
+[ Upstream commit f1b930e740811d416de4d2074da48b6633a672c8 ]
+
+If alloc_soc_dts() fails, then we can just return. Trying to free
+"soc_dts" will lead to an Oops.
+
+Fixes: 8c1876939663 ("thermal: intel Quark SoC X1000 DTS thermal driver")
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/intel/intel_quark_dts_thermal.c | 12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/thermal/intel/intel_quark_dts_thermal.c b/drivers/thermal/intel/intel_quark_dts_thermal.c
+index 3eafc6b0e6c30..b43fbd5eaa6b4 100644
+--- a/drivers/thermal/intel/intel_quark_dts_thermal.c
++++ b/drivers/thermal/intel/intel_quark_dts_thermal.c
+@@ -415,22 +415,14 @@ MODULE_DEVICE_TABLE(x86cpu, qrk_thermal_ids);
+
+ static int __init intel_quark_thermal_init(void)
+ {
+- int err = 0;
+-
+ if (!x86_match_cpu(qrk_thermal_ids) || !iosf_mbi_available())
+ return -ENODEV;
+
+ soc_dts = alloc_soc_dts();
+- if (IS_ERR(soc_dts)) {
+- err = PTR_ERR(soc_dts);
+- goto err_free;
+- }
++ if (IS_ERR(soc_dts))
++ return PTR_ERR(soc_dts);
+
+ return 0;
+-
+-err_free:
+- free_soc_dts(soc_dts);
+- return err;
+ }
+
+ static void __exit intel_quark_thermal_exit(void)
+--
+2.39.2
+
--- /dev/null
+From 780ac9553fc38a80f4e084ac01b8153db2e96cd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 10:51:47 +0800
+Subject: tools/iio/iio_utils:fix memory leak
+
+From: Yulong Zhang <yulong.zhang@metoak.net>
+
+[ Upstream commit f2edf0c819a4823cd6c288801ce737e8d4fcde06 ]
+
+1. fopen sysfs without fclose.
+2. asprintf filename without free.
+3. if asprintf return error,do not need to free the buffer.
+
+Signed-off-by: Yulong Zhang <yulong.zhang@metoak.net>
+Link: https://lore.kernel.org/r/20230117025147.69890-1-yulong.zhang@metoak.net
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/iio/iio_utils.c | 23 ++++++-----------------
+ 1 file changed, 6 insertions(+), 17 deletions(-)
+
+diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c
+index 8d35893b2fa85..6a00a6eecaef0 100644
+--- a/tools/iio/iio_utils.c
++++ b/tools/iio/iio_utils.c
+@@ -264,6 +264,7 @@ int iioutils_get_param_float(float *output, const char *param_name,
+ if (fscanf(sysfsfp, "%f", output) != 1)
+ ret = errno ? -errno : -ENODATA;
+
++ fclose(sysfsfp);
+ break;
+ }
+ error_free_filename:
+@@ -345,9 +346,9 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+ }
+
+ sysfsfp = fopen(filename, "r");
++ free(filename);
+ if (!sysfsfp) {
+ ret = -errno;
+- free(filename);
+ goto error_close_dir;
+ }
+
+@@ -357,7 +358,6 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+ if (fclose(sysfsfp))
+ perror("build_channel_array(): Failed to close file");
+
+- free(filename);
+ goto error_close_dir;
+ }
+ if (ret == 1)
+@@ -365,11 +365,9 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+
+ if (fclose(sysfsfp)) {
+ ret = -errno;
+- free(filename);
+ goto error_close_dir;
+ }
+
+- free(filename);
+ }
+
+ *ci_array = malloc(sizeof(**ci_array) * (*counter));
+@@ -395,9 +393,9 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+ }
+
+ sysfsfp = fopen(filename, "r");
++ free(filename);
+ if (!sysfsfp) {
+ ret = -errno;
+- free(filename);
+ count--;
+ goto error_cleanup_array;
+ }
+@@ -405,20 +403,17 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+ errno = 0;
+ if (fscanf(sysfsfp, "%i", ¤t_enabled) != 1) {
+ ret = errno ? -errno : -ENODATA;
+- free(filename);
+ count--;
+ goto error_cleanup_array;
+ }
+
+ if (fclose(sysfsfp)) {
+ ret = -errno;
+- free(filename);
+ count--;
+ goto error_cleanup_array;
+ }
+
+ if (!current_enabled) {
+- free(filename);
+ count--;
+ continue;
+ }
+@@ -429,7 +424,6 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+ strlen(ent->d_name) -
+ strlen("_en"));
+ if (!current->name) {
+- free(filename);
+ ret = -ENOMEM;
+ count--;
+ goto error_cleanup_array;
+@@ -439,7 +433,6 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+ ret = iioutils_break_up_name(current->name,
+ ¤t->generic_name);
+ if (ret) {
+- free(filename);
+ free(current->name);
+ count--;
+ goto error_cleanup_array;
+@@ -450,17 +443,16 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+ scan_el_dir,
+ current->name);
+ if (ret < 0) {
+- free(filename);
+ ret = -ENOMEM;
+ goto error_cleanup_array;
+ }
+
+ sysfsfp = fopen(filename, "r");
++ free(filename);
+ if (!sysfsfp) {
+ ret = -errno;
+- fprintf(stderr, "failed to open %s\n",
+- filename);
+- free(filename);
++ fprintf(stderr, "failed to open %s/%s_index\n",
++ scan_el_dir, current->name);
+ goto error_cleanup_array;
+ }
+
+@@ -470,17 +462,14 @@ int build_channel_array(const char *device_dir, int buffer_idx,
+ if (fclose(sysfsfp))
+ perror("build_channel_array(): Failed to close file");
+
+- free(filename);
+ goto error_cleanup_array;
+ }
+
+ if (fclose(sysfsfp)) {
+ ret = -errno;
+- free(filename);
+ goto error_cleanup_array;
+ }
+
+- free(filename);
+ /* Find the scale */
+ ret = iioutils_get_param_float(¤t->scale,
+ "scale",
+--
+2.39.2
+
--- /dev/null
+From ec453bc5031c07c86224da3bc464a80cbde41fcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Jan 2023 20:55:01 +0800
+Subject: tracing: Add NULL checks for buffer in ring_buffer_free_read_page()
+
+From: Jia-Ju Bai <baijiaju1990@gmail.com>
+
+[ Upstream commit 3e4272b9954094907f16861199728f14002fcaf6 ]
+
+In a previous commit 7433632c9ff6, buffer, buffer->buffers and
+buffer->buffers[cpu] in ring_buffer_wake_waiters() can be NULL,
+and thus the related checks are added.
+
+However, in the same call stack, these variables are also used in
+ring_buffer_free_read_page():
+
+tracing_buffers_release()
+ ring_buffer_wake_waiters(iter->array_buffer->buffer)
+ cpu_buffer = buffer->buffers[cpu] -> Add checks by previous commit
+ ring_buffer_free_read_page(iter->array_buffer->buffer)
+ cpu_buffer = buffer->buffers[cpu] -> No check
+
+Thus, to avod possible null-pointer derefernces, the related checks
+should be added.
+
+These results are reported by a static tool designed by myself.
+
+Link: https://lkml.kernel.org/r/20230113125501.760324-1-baijiaju1990@gmail.com
+
+Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
+Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index c35e08b74014f..361bd8beafdff 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -5588,11 +5588,16 @@ EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
+ */
+ void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu, void *data)
+ {
+- struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
++ struct ring_buffer_per_cpu *cpu_buffer;
+ struct buffer_data_page *bpage = data;
+ struct page *page = virt_to_page(bpage);
+ unsigned long flags;
+
++ if (!buffer || !buffer->buffers || !buffer->buffers[cpu])
++ return;
++
++ cpu_buffer = buffer->buffers[cpu];
++
+ /* If the page is still in use someplace else, we can't reuse it */
+ if (page_ref_count(page) > 1)
+ goto out;
+--
+2.39.2
+
--- /dev/null
+From 721a9be8a4dd02d9017a47d1e651f7e9687b641b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 12:27:36 +0100
+Subject: tty: fix out-of-bounds access in tty_driver_lookup_tty()
+
+From: Sven Schnelle <svens@linux.ibm.com>
+
+[ Upstream commit db4df8e9d79e7d37732c1a1b560958e8dadfefa1 ]
+
+When specifying an invalid console= device like console=tty3270,
+tty_driver_lookup_tty() returns the tty struct without checking
+whether index is a valid number.
+
+To reproduce:
+
+qemu-system-x86_64 -enable-kvm -nographic -serial mon:stdio \
+-kernel ../linux-build-x86/arch/x86/boot/bzImage \
+-append "console=ttyS0 console=tty3270"
+
+This crashes with:
+
+[ 0.770599] BUG: kernel NULL pointer dereference, address: 00000000000000ef
+[ 0.771265] #PF: supervisor read access in kernel mode
+[ 0.771773] #PF: error_code(0x0000) - not-present page
+[ 0.772609] Oops: 0000 [#1] PREEMPT SMP PTI
+[ 0.774878] RIP: 0010:tty_open+0x268/0x6f0
+[ 0.784013] chrdev_open+0xbd/0x230
+[ 0.784444] ? cdev_device_add+0x80/0x80
+[ 0.784920] do_dentry_open+0x1e0/0x410
+[ 0.785389] path_openat+0xca9/0x1050
+[ 0.785813] do_filp_open+0xaa/0x150
+[ 0.786240] file_open_name+0x133/0x1b0
+[ 0.786746] filp_open+0x27/0x50
+[ 0.787244] console_on_rootfs+0x14/0x4d
+[ 0.787800] kernel_init_freeable+0x1e4/0x20d
+[ 0.788383] ? rest_init+0xc0/0xc0
+[ 0.788881] kernel_init+0x11/0x120
+[ 0.789356] ret_from_fork+0x22/0x30
+
+Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
+Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20221209112737.3222509-2-svens@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index de06c3c2ff70a..1ac6784ea1f92 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -1224,14 +1224,16 @@ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
+ {
+ struct tty_struct *tty;
+
+- if (driver->ops->lookup)
++ if (driver->ops->lookup) {
+ if (!file)
+ tty = ERR_PTR(-EIO);
+ else
+ tty = driver->ops->lookup(driver, file, idx);
+- else
++ } else {
++ if (idx >= driver->num)
++ return ERR_PTR(-EINVAL);
+ tty = driver->ttys[idx];
+-
++ }
+ if (!IS_ERR(tty))
+ tty_kref_get(tty);
+ return tty;
+--
+2.39.2
+
--- /dev/null
+From bc2ad1b0ee6e4cf105c6c581f951e0fc06916259 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 15:12:21 +0100
+Subject: tty: pcn_uart: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 04a189c720aa2b6091442113ce9b9bc93552dff8 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Jiri Slaby <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20230202141221.2293012-1-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/pch_uart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
+index 83f35b7b0897c..abff1c6470f6a 100644
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -1779,7 +1779,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv)
+ char name[32];
+
+ snprintf(name, sizeof(name), "uart%d_regs", priv->port.line);
+- debugfs_remove(debugfs_lookup(name, NULL));
++ debugfs_lookup_and_remove(name, NULL);
+ uart_remove_one_port(&pch_uart_driver, &priv->port);
+ free_page((unsigned long)priv->rxbuf.buf);
+ }
+--
+2.39.2
+
--- /dev/null
+From 281be533d247a6eba3dd24abb1a1eb4ab62ca88c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Dec 2022 11:11:35 +0800
+Subject: tty: serial: fsl_lpuart: disable the CTS when send break signal
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit c4c81db5cf8bc53d6160c3abf26d382c841aa434 ]
+
+LPUART IP has a bug that it treats the CTS as higher priority than the
+break signal, which cause the break signal sending through UARTCTRL_SBK
+may impacted by the CTS input if the HW flow control is enabled.
+
+Add this workaround patch to fix the IP bug, we can disable CTS before
+asserting SBK to avoid any interference from CTS, and re-enable it when
+break off.
+
+Such as for the bluetooth chip power save feature, host can let the BT
+chip get into sleep state by sending a UART break signal, and wake it up
+by turning off the UART break. If the BT chip enters the sleep mode
+successfully, it will pull up the CTS line, if the BT chip is woken up,
+it will pull down the CTS line. If without this workaround patch, the
+UART TX pin cannot send the break signal successfully as it affected by
+the BT CTS pin. After adding this patch, the BT power save feature can
+work well.
+
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Link: https://lore.kernel.org/r/20221214031137.28815-2-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 24 ++++++++++++++++++++++--
+ 1 file changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 13a6cd0116a13..f9d667ce1619e 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -1468,12 +1468,32 @@ static void lpuart_break_ctl(struct uart_port *port, int break_state)
+
+ static void lpuart32_break_ctl(struct uart_port *port, int break_state)
+ {
+- unsigned long temp;
++ unsigned long temp, modem;
++ struct tty_struct *tty;
++ unsigned int cflag = 0;
++
++ tty = tty_port_tty_get(&port->state->port);
++ if (tty) {
++ cflag = tty->termios.c_cflag;
++ tty_kref_put(tty);
++ }
+
+ temp = lpuart32_read(port, UARTCTRL) & ~UARTCTRL_SBK;
++ modem = lpuart32_read(port, UARTMODIR);
+
+- if (break_state != 0)
++ if (break_state != 0) {
+ temp |= UARTCTRL_SBK;
++ /*
++ * LPUART CTS has higher priority than SBK, need to disable CTS before
++ * asserting SBK to avoid any interference if flow control is enabled.
++ */
++ if (cflag & CRTSCTS && modem & UARTMODIR_TXCTSE)
++ lpuart32_write(port, modem & ~UARTMODIR_TXCTSE, UARTMODIR);
++ } else {
++ /* Re-enable the CTS when break off. */
++ if (cflag & CRTSCTS && !(modem & UARTMODIR_TXCTSE))
++ lpuart32_write(port, modem | UARTMODIR_TXCTSE, UARTMODIR);
++ }
+
+ lpuart32_write(port, temp, UARTCTRL);
+ }
+--
+2.39.2
+
--- /dev/null
+From 24a76440da3eff7f8ca02058b2110b2d614a3b32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 10:14:44 -0500
+Subject: ubi: ensure that VID header offset + VID header size <= alloc, size
+
+From: George Kennedy <george.kennedy@oracle.com>
+
+[ Upstream commit 1b42b1a36fc946f0d7088425b90d491b4257ca3e ]
+
+Ensure that the VID header offset + VID header size does not exceed
+the allocated area to avoid slab OOB.
+
+BUG: KASAN: slab-out-of-bounds in crc32_body lib/crc32.c:111 [inline]
+BUG: KASAN: slab-out-of-bounds in crc32_le_generic lib/crc32.c:179 [inline]
+BUG: KASAN: slab-out-of-bounds in crc32_le_base+0x58c/0x626 lib/crc32.c:197
+Read of size 4 at addr ffff88802bb36f00 by task syz-executor136/1555
+
+CPU: 2 PID: 1555 Comm: syz-executor136 Tainted: G W
+6.0.0-1868 #1
+Hardware name: Red Hat KVM, BIOS 1.13.0-2.module+el8.3.0+7860+a7792d29
+04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x85/0xad lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:317 [inline]
+ print_report.cold.13+0xb6/0x6bb mm/kasan/report.c:433
+ kasan_report+0xa7/0x11b mm/kasan/report.c:495
+ crc32_body lib/crc32.c:111 [inline]
+ crc32_le_generic lib/crc32.c:179 [inline]
+ crc32_le_base+0x58c/0x626 lib/crc32.c:197
+ ubi_io_write_vid_hdr+0x1b7/0x472 drivers/mtd/ubi/io.c:1067
+ create_vtbl+0x4d5/0x9c4 drivers/mtd/ubi/vtbl.c:317
+ create_empty_lvol drivers/mtd/ubi/vtbl.c:500 [inline]
+ ubi_read_volume_table+0x67b/0x288a drivers/mtd/ubi/vtbl.c:812
+ ubi_attach+0xf34/0x1603 drivers/mtd/ubi/attach.c:1601
+ ubi_attach_mtd_dev+0x6f3/0x185e drivers/mtd/ubi/build.c:965
+ ctrl_cdev_ioctl+0x2db/0x347 drivers/mtd/ubi/cdev.c:1043
+ vfs_ioctl fs/ioctl.c:51 [inline]
+ __do_sys_ioctl fs/ioctl.c:870 [inline]
+ __se_sys_ioctl fs/ioctl.c:856 [inline]
+ __x64_sys_ioctl+0x193/0x213 fs/ioctl.c:856
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3e/0x86 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0x0
+RIP: 0033:0x7f96d5cf753d
+Code:
+RSP: 002b:00007fffd72206f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f96d5cf753d
+RDX: 0000000020000080 RSI: 0000000040186f40 RDI: 0000000000000003
+RBP: 0000000000400cd0 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000400be0
+R13: 00007fffd72207e0 R14: 0000000000000000 R15: 0000000000000000
+ </TASK>
+
+Allocated by task 1555:
+ kasan_save_stack+0x20/0x3d mm/kasan/common.c:38
+ kasan_set_track mm/kasan/common.c:45 [inline]
+ set_alloc_info mm/kasan/common.c:437 [inline]
+ ____kasan_kmalloc mm/kasan/common.c:516 [inline]
+ __kasan_kmalloc+0x88/0xa3 mm/kasan/common.c:525
+ kasan_kmalloc include/linux/kasan.h:234 [inline]
+ __kmalloc+0x138/0x257 mm/slub.c:4429
+ kmalloc include/linux/slab.h:605 [inline]
+ ubi_alloc_vid_buf drivers/mtd/ubi/ubi.h:1093 [inline]
+ create_vtbl+0xcc/0x9c4 drivers/mtd/ubi/vtbl.c:295
+ create_empty_lvol drivers/mtd/ubi/vtbl.c:500 [inline]
+ ubi_read_volume_table+0x67b/0x288a drivers/mtd/ubi/vtbl.c:812
+ ubi_attach+0xf34/0x1603 drivers/mtd/ubi/attach.c:1601
+ ubi_attach_mtd_dev+0x6f3/0x185e drivers/mtd/ubi/build.c:965
+ ctrl_cdev_ioctl+0x2db/0x347 drivers/mtd/ubi/cdev.c:1043
+ vfs_ioctl fs/ioctl.c:51 [inline]
+ __do_sys_ioctl fs/ioctl.c:870 [inline]
+ __se_sys_ioctl fs/ioctl.c:856 [inline]
+ __x64_sys_ioctl+0x193/0x213 fs/ioctl.c:856
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3e/0x86 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0x0
+
+The buggy address belongs to the object at ffff88802bb36e00
+ which belongs to the cache kmalloc-256 of size 256
+The buggy address is located 0 bytes to the right of
+ 256-byte region [ffff88802bb36e00, ffff88802bb36f00)
+
+The buggy address belongs to the physical page:
+page:00000000ea4d1263 refcount:1 mapcount:0 mapping:0000000000000000
+index:0x0 pfn:0x2bb36
+head:00000000ea4d1263 order:1 compound_mapcount:0 compound_pincount:0
+flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)
+raw: 000fffffc0010200 ffffea000066c300 dead000000000003 ffff888100042b40
+raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff88802bb36e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ ffff88802bb36e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+>ffff88802bb36f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ^
+ ffff88802bb36f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ffff88802bb37000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+==================================================================
+
+Fixes: 801c135ce73d ("UBI: Unsorted Block Images")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Signed-off-by: George Kennedy <george.kennedy@oracle.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/build.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
+index a901f8edfa41d..2178eb4115b36 100644
+--- a/drivers/mtd/ubi/build.c
++++ b/drivers/mtd/ubi/build.c
+@@ -663,6 +663,12 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
+ ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
+ ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);
+
++ if (ubi->vid_hdr_offset && ((ubi->vid_hdr_offset + UBI_VID_HDR_SIZE) >
++ ubi->vid_hdr_alsize)) {
++ ubi_err(ubi, "VID header offset %d too large.", ubi->vid_hdr_offset);
++ return -EINVAL;
++ }
++
+ dbg_gen("min_io_size %d", ubi->min_io_size);
+ dbg_gen("max_write_size %d", ubi->max_write_size);
+ dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
+--
+2.39.2
+
--- /dev/null
+From 71e014c04e436bb8d487532831445b097df30ddd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Aug 2022 15:06:19 +0800
+Subject: ubi: fastmap: Fix missed fm_anchor PEB in wear-leveling after
+ disabling fastmap
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 76f9476ece445a07aeb72df9d896cd563fb5b50f ]
+
+After disabling fastmap(ubi->fm_disabled = 1), fastmap won't be updated,
+fm_anchor PEB is missed being scheduled for erasing. Besides, fm_anchor
+PEB may have smallest erase count, it doesn't participate wear-leveling.
+The difference of erase count between fm_anchor PEB and other PEBs will
+be larger and larger later on.
+
+In which situation fastmap can be disabled? Initially, we have an UBI
+image with fastmap. Then the image will be atttached without module
+parameter 'fm_autoconvert', ubi turns to full scanning mode in one
+random attaching process(eg. bad fastmap caused by powercut), ubi
+fastmap is disabled since then.
+
+Fix it by not getting fm_anchor if fastmap is disabled in
+ubi_refill_pools().
+
+Fetch a reproducer in [Link].
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216341
+Fixes: 4b68bf9a69d22d ("ubi: Select fastmap anchor PEBs considering ...")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/fastmap-wl.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c
+index 0ee452275578d..863f571f1adb5 100644
+--- a/drivers/mtd/ubi/fastmap-wl.c
++++ b/drivers/mtd/ubi/fastmap-wl.c
+@@ -146,13 +146,15 @@ void ubi_refill_pools(struct ubi_device *ubi)
+ if (ubi->fm_anchor) {
+ wl_tree_add(ubi->fm_anchor, &ubi->free);
+ ubi->free_count++;
++ ubi->fm_anchor = NULL;
+ }
+
+- /*
+- * All available PEBs are in ubi->free, now is the time to get
+- * the best anchor PEBs.
+- */
+- ubi->fm_anchor = ubi_wl_get_fm_peb(ubi, 1);
++ if (!ubi->fm_disabled)
++ /*
++ * All available PEBs are in ubi->free, now is the time to get
++ * the best anchor PEBs.
++ */
++ ubi->fm_anchor = ubi_wl_get_fm_peb(ubi, 1);
+
+ for (;;) {
+ enough = 0;
+--
+2.39.2
+
--- /dev/null
+From 24813f8d0b54bfc0b7a38f2afb1ba98c1e96c186 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 18:26:24 +0800
+Subject: ubi: Fix possible null-ptr-deref in ubi_free_volume()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit c15859bfd326c10230f09cb48a17f8a35f190342 ]
+
+It willl cause null-ptr-deref in the following case:
+
+uif_init()
+ ubi_add_volume()
+ cdev_add() -> if it fails, call kill_volumes()
+ device_register()
+
+kill_volumes() -> if ubi_add_volume() fails call this function
+ ubi_free_volume()
+ cdev_del()
+ device_unregister() -> trying to delete a not added device,
+ it causes null-ptr-deref
+
+So in ubi_free_volume(), it delete devices whether they are added
+or not, it will causes null-ptr-deref.
+
+Handle the error case whlie calling ubi_add_volume() to fix this
+problem. If add volume fails, set the corresponding vol to null,
+so it can not be accessed in kill_volumes() and release the
+resource in ubi_add_volume() error path.
+
+Fixes: 801c135ce73d ("UBI: Unsorted Block Images")
+Suggested-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/build.c | 1 +
+ drivers/mtd/ubi/vmt.c | 12 ++++++------
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
+index 2178eb4115b36..7f65af1697519 100644
+--- a/drivers/mtd/ubi/build.c
++++ b/drivers/mtd/ubi/build.c
+@@ -468,6 +468,7 @@ static int uif_init(struct ubi_device *ubi)
+ err = ubi_add_volume(ubi, ubi->volumes[i]);
+ if (err) {
+ ubi_err(ubi, "cannot add volume %d", i);
++ ubi->volumes[i] = NULL;
+ goto out_volumes;
+ }
+ }
+diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
+index 9fbc64b997cef..2c867d16f89f7 100644
+--- a/drivers/mtd/ubi/vmt.c
++++ b/drivers/mtd/ubi/vmt.c
+@@ -582,6 +582,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
+ if (err) {
+ ubi_err(ubi, "cannot add character device for volume %d, error %d",
+ vol_id, err);
++ vol_release(&vol->dev);
+ return err;
+ }
+
+@@ -592,15 +593,14 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
+ vol->dev.groups = volume_dev_groups;
+ dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
+ err = device_register(&vol->dev);
+- if (err)
+- goto out_cdev;
++ if (err) {
++ cdev_del(&vol->cdev);
++ put_device(&vol->dev);
++ return err;
++ }
+
+ self_check_volumes(ubi);
+ return err;
+-
+-out_cdev:
+- cdev_del(&vol->cdev);
+- return err;
+ }
+
+ /**
+--
+2.39.2
+
--- /dev/null
+From fba3cb2fc4383fa343f07ee3813c406db5c933c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Jul 2022 19:28:37 +0800
+Subject: ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show()
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit a240bc5c43130c6aa50831d7caaa02a1d84e1bce ]
+
+Wear-leveling entry could be freed in error path, which may be accessed
+again in eraseblk_count_seq_show(), for example:
+
+__erase_worker eraseblk_count_seq_show
+ wl = ubi->lookuptbl[*block_number]
+ if (wl)
+ wl_entry_destroy
+ ubi->lookuptbl[e->pnum] = NULL
+ kmem_cache_free(ubi_wl_entry_slab, e)
+ erase_count = wl->ec // UAF!
+
+Wear-leveling entry updating/accessing in ubi->lookuptbl should be
+protected by ubi->wl_lock, fix it by adding ubi->wl_lock to serialize
+wl entry accessing between wl_entry_destroy() and
+eraseblk_count_seq_show().
+
+Fetch a reproducer in [Link].
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216305
+Fixes: 7bccd12d27b7e3 ("ubi: Add debugfs file for tracking PEB state")
+Fixes: 801c135ce73d5d ("UBI: Unsorted Block Images")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/wl.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index 68eb0f21b3fe2..f45df3b773739 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -890,8 +890,11 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
+
+ err = do_sync_erase(ubi, e1, vol_id, lnum, 0);
+ if (err) {
+- if (e2)
++ if (e2) {
++ spin_lock(&ubi->wl_lock);
+ wl_entry_destroy(ubi, e2);
++ spin_unlock(&ubi->wl_lock);
++ }
+ goto out_ro;
+ }
+
+@@ -1130,14 +1133,18 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
+ /* Re-schedule the LEB for erasure */
+ err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false);
+ if (err1) {
++ spin_lock(&ubi->wl_lock);
+ wl_entry_destroy(ubi, e);
++ spin_unlock(&ubi->wl_lock);
+ err = err1;
+ goto out_ro;
+ }
+ return err;
+ }
+
++ spin_lock(&ubi->wl_lock);
+ wl_entry_destroy(ubi, e);
++ spin_unlock(&ubi->wl_lock);
+ if (err != -EIO)
+ /*
+ * If this is not %-EIO, we have no idea what to do. Scheduling
+--
+2.39.2
+
--- /dev/null
+From aaa02ee0cdd89e00d00dbbbdf3484075a0f4bcbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 18:21:57 +0800
+Subject: ubi: Fix unreferenced object reported by kmemleak in
+ ubi_resize_volume()
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit 1e591ea072df7211f64542a09482b5f81cb3ad27 ]
+
+There is a memory leaks problem reported by kmemleak:
+
+unreferenced object 0xffff888102007a00 (size 128):
+ comm "ubirsvol", pid 32090, jiffies 4298464136 (age 2361.231s)
+ hex dump (first 32 bytes):
+ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
+ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
+ backtrace:
+[<ffffffff8176cecd>] __kmalloc+0x4d/0x150
+[<ffffffffa02a9a36>] ubi_eba_create_table+0x76/0x170 [ubi]
+[<ffffffffa029764e>] ubi_resize_volume+0x1be/0xbc0 [ubi]
+[<ffffffffa02a3321>] ubi_cdev_ioctl+0x701/0x1850 [ubi]
+[<ffffffff81975d2d>] __x64_sys_ioctl+0x11d/0x170
+[<ffffffff83c142a5>] do_syscall_64+0x35/0x80
+[<ffffffff83e0006a>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+This is due to a mismatch between create and destroy interfaces, and
+in detail that "new_eba_tbl" created by ubi_eba_create_table() but
+destroyed by kfree(), while will causing "new_eba_tbl->entries" not
+freed.
+
+Fix it by replacing kfree(new_eba_tbl) with
+ubi_eba_destroy_table(new_eba_tbl)
+
+Fixes: 799dca34ac54 ("UBI: hide EBA internals")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/vmt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
+index 74637575346e8..9fbc64b997cef 100644
+--- a/drivers/mtd/ubi/vmt.c
++++ b/drivers/mtd/ubi/vmt.c
+@@ -515,7 +515,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
+ return err;
+
+ out_free:
+- kfree(new_eba_tbl);
++ ubi_eba_destroy_table(new_eba_tbl);
+ return err;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 45227025cb8a88fbb3e12cf84a0de812209ab21a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 18:21:56 +0800
+Subject: ubi: Fix use-after-free when volume resizing failed
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit 9af31d6ec1a4be4caab2550096c6bd2ba8fba472 ]
+
+There is an use-after-free problem reported by KASAN:
+ ==================================================================
+ BUG: KASAN: use-after-free in ubi_eba_copy_table+0x11f/0x1c0 [ubi]
+ Read of size 8 at addr ffff888101eec008 by task ubirsvol/4735
+
+ CPU: 2 PID: 4735 Comm: ubirsvol
+ Not tainted 6.1.0-rc1-00003-g84fa3304a7fc-dirty #14
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
+ BIOS 1.14.0-1.fc33 04/01/2014
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x34/0x44
+ print_report+0x171/0x472
+ kasan_report+0xad/0x130
+ ubi_eba_copy_table+0x11f/0x1c0 [ubi]
+ ubi_resize_volume+0x4f9/0xbc0 [ubi]
+ ubi_cdev_ioctl+0x701/0x1850 [ubi]
+ __x64_sys_ioctl+0x11d/0x170
+ do_syscall_64+0x35/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+ </TASK>
+
+When ubi_change_vtbl_record() returns an error in ubi_resize_volume(),
+"new_eba_tbl" will be freed on error handing path, but it is holded
+by "vol->eba_tbl" in ubi_eba_replace_table(). It means that the liftcycle
+of "vol->eba_tbl" and "vol" are different, so when resizing volume in
+next time, it causing an use-after-free fault.
+
+Fix it by not freeing "new_eba_tbl" after it replaced in
+ubi_eba_replace_table(), while will be freed in next volume resizing.
+
+Fixes: 801c135ce73d ("UBI: Unsorted Block Images")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/vmt.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
+index 8fcc0bdf06358..74637575346e8 100644
+--- a/drivers/mtd/ubi/vmt.c
++++ b/drivers/mtd/ubi/vmt.c
+@@ -464,7 +464,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
+ for (i = 0; i < -pebs; i++) {
+ err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);
+ if (err)
+- goto out_acc;
++ goto out_free;
+ }
+ spin_lock(&ubi->volumes_lock);
+ ubi->rsvd_pebs += pebs;
+@@ -512,6 +512,8 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
+ ubi->avail_pebs += pebs;
+ spin_unlock(&ubi->volumes_lock);
+ }
++ return err;
++
+ out_free:
+ kfree(new_eba_tbl);
+ return err;
+--
+2.39.2
+
--- /dev/null
+From 20c2768e87e1ae46c2b18635ad29b1a0467b8e15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:59:04 +0800
+Subject: ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 4d57a7333e26040f2b583983e1970d9d460e56b0 ]
+
+Following process will trigger an infinite loop in ubi_wl_put_peb():
+
+ ubifs_bgt ubi_bgt
+ubifs_leb_unmap
+ ubi_leb_unmap
+ ubi_eba_unmap_leb
+ ubi_wl_put_peb wear_leveling_worker
+ e1 = rb_entry(rb_first(&ubi->used)
+ e2 = get_peb_for_wl(ubi)
+ ubi_io_read_vid_hdr // return err (flash fault)
+ out_error:
+ ubi->move_from = ubi->move_to = NULL
+ wl_entry_destroy(ubi, e1)
+ ubi->lookuptbl[e->pnum] = NULL
+ retry:
+ e = ubi->lookuptbl[pnum]; // return NULL
+ if (e == ubi->move_from) { // NULL == NULL gets true
+ goto retry; // infinite loop !!!
+
+$ top
+ PID USER PR NI VIRT RES SHR S %CPU %MEM COMMAND
+ 7676 root 20 0 0 0 0 R 100.0 0.0 ubifs_bgt0_0
+
+Fix it by:
+ 1) Letting ubi_wl_put_peb() returns directly if wearl leveling entry has
+ been removed from 'ubi->lookuptbl'.
+ 2) Using 'ubi->wl_lock' protecting wl entry deletion to preventing an
+ use-after-free problem for wl entry in ubi_wl_put_peb().
+
+Fetch a reproducer in [Link].
+
+Fixes: 43f9b25a9cdd7b1 ("UBI: bugfix: protect from volume removal")
+Fixes: ee59ba8b064f692 ("UBI: Fix stale pointers in ubi->lookuptbl")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216111
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/wl.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index f45df3b773739..9e14319225c97 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -976,11 +976,11 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
+ spin_lock(&ubi->wl_lock);
+ ubi->move_from = ubi->move_to = NULL;
+ ubi->move_to_put = ubi->wl_scheduled = 0;
++ wl_entry_destroy(ubi, e1);
++ wl_entry_destroy(ubi, e2);
+ spin_unlock(&ubi->wl_lock);
+
+ ubi_free_vid_buf(vidb);
+- wl_entry_destroy(ubi, e1);
+- wl_entry_destroy(ubi, e2);
+
+ out_ro:
+ ubi_ro_mode(ubi);
+@@ -1260,6 +1260,18 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum,
+ retry:
+ spin_lock(&ubi->wl_lock);
+ e = ubi->lookuptbl[pnum];
++ if (!e) {
++ /*
++ * This wl entry has been removed for some errors by other
++ * process (eg. wear leveling worker), corresponding process
++ * (except __erase_worker, which cannot concurrent with
++ * ubi_wl_put_peb) will set ubi ro_mode at the same time,
++ * just ignore this wl entry.
++ */
++ spin_unlock(&ubi->wl_lock);
++ up_read(&ubi->fm_protect);
++ return 0;
++ }
+ if (e == ubi->move_from) {
+ /*
+ * User is putting the physical eraseblock which was selected to
+--
+2.39.2
+
--- /dev/null
+From a1ae0cf2d06d817995e2f4f57ba47a211b3b9216 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 17:02:36 +0800
+Subject: ubifs: dirty_cow_znode: Fix memleak in error handling path
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 122deabfe1428bffe95e2bf364ff8a5059bdf089 ]
+
+Following process will cause a memleak for copied up znode:
+
+dirty_cow_znode
+ zn = copy_znode(c, znode);
+ err = insert_old_idx(c, zbr->lnum, zbr->offs);
+ if (unlikely(err))
+ return ERR_PTR(err); // No one refers to zn.
+
+Fix it by adding copied znode back to tnc, then it will be freed
+by ubifs_destroy_tnc_subtree() while closing tnc.
+
+Fetch a reproducer in [Link].
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216705
+Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/tnc.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
+index 2df56bbc68657..2469f72eeaabb 100644
+--- a/fs/ubifs/tnc.c
++++ b/fs/ubifs/tnc.c
+@@ -267,11 +267,18 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c,
+ if (zbr->len) {
+ err = insert_old_idx(c, zbr->lnum, zbr->offs);
+ if (unlikely(err))
+- return ERR_PTR(err);
++ /*
++ * Obsolete znodes will be freed by tnc_destroy_cnext()
++ * or free_obsolete_znodes(), copied up znodes should
++ * be added back to tnc and freed by
++ * ubifs_destroy_tnc_subtree().
++ */
++ goto out;
+ err = add_idx_dirt(c, zbr->lnum, zbr->len);
+ } else
+ err = 0;
+
++out:
+ zbr->znode = zn;
+ zbr->lnum = 0;
+ zbr->offs = 0;
+--
+2.39.2
+
--- /dev/null
+From 30dc26fcffce16cbd42145ca2e80a8c930457000 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Oct 2022 11:47:31 +0800
+Subject: ubifs: do_rename: Fix wrong space budget when target inode's nlink >
+ 1
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 25fce616a61fc2f1821e4a9ce212d0e064707093 ]
+
+If target inode is a special file (eg. block/char device) with nlink
+count greater than 1, the inode with ui->data will be re-written on
+disk. However, UBIFS losts target inode's data_len while doing space
+budget. Bad space budget may let make_reservation() return with -ENOSPC,
+which could turn ubifs to read-only mode in do_writepage() process.
+
+Fetch a reproducer in [Link].
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216494
+Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/dir.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
+index 94634b872e382..5e6bcce94e641 100644
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -1324,6 +1324,8 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
+ if (unlink) {
+ ubifs_assert(c, inode_is_locked(new_inode));
+
++ /* Budget for old inode's data when its nlink > 1. */
++ req.dirtied_ino_d = ALIGN(ubifs_inode(new_inode)->data_len, 8);
+ err = ubifs_purge_xattrs(new_inode);
+ if (err)
+ return err;
+--
+2.39.2
+
--- /dev/null
+From d20970f1cff5ee46d66317d467e8f2a2bb86f2d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 19:18:47 +0800
+Subject: ubifs: Fix build errors as symbol undefined
+
+From: Li Hua <hucool.lihua@huawei.com>
+
+[ Upstream commit aa6d148e6d6270274e3d5a529b71c54cd329d17f ]
+
+With CONFIG_UBIFS_FS_AUTHENTICATION not set, the compiler can assume that
+ubifs_node_check_hash() is never true and drops the call to ubifs_bad_hash().
+Is CONFIG_CC_OPTIMIZE_FOR_SIZE enabled this optimization does not happen anymore.
+
+So When CONFIG_UBIFS_FS and CONFIG_CC_OPTIMIZE_FOR_SIZE is enabled but
+CONFIG_UBIFS_FS_AUTHENTICATION is not set, the build errors is as followd:
+ ERROR: modpost: "ubifs_bad_hash" [fs/ubifs/ubifs.ko] undefined!
+
+Fix it by add no-op ubifs_bad_hash() for the CONFIG_UBIFS_FS_AUTHENTICATION=n case.
+
+Fixes: 16a26b20d2af ("ubifs: authentication: Add hashes to index nodes")
+Signed-off-by: Li Hua <hucool.lihua@huawei.com>
+Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/ubifs.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
+index 478bbbb5382f8..2f1f315810949 100644
+--- a/fs/ubifs/ubifs.h
++++ b/fs/ubifs/ubifs.h
+@@ -1623,8 +1623,13 @@ static inline int ubifs_check_hmac(const struct ubifs_info *c,
+ return crypto_memneq(expected, got, c->hmac_desc_len);
+ }
+
++#ifdef CONFIG_UBIFS_FS_AUTHENTICATION
+ void ubifs_bad_hash(const struct ubifs_info *c, const void *node,
+ const u8 *hash, int lnum, int offs);
++#else
++static inline void ubifs_bad_hash(const struct ubifs_info *c, const void *node,
++ const u8 *hash, int lnum, int offs) {};
++#endif
+
+ int __ubifs_node_check_hash(const struct ubifs_info *c, const void *buf,
+ const u8 *expected);
+--
+2.39.2
+
--- /dev/null
+From 7d66bc534e59f1a18072e84690098c414f4e4b73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Oct 2022 19:52:11 +0800
+Subject: ubifs: Fix memory leak in alloc_wbufs()
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit 4a1ff3c5d04b9079b4f768d9a71b51c4af578dd2 ]
+
+kmemleak reported a sequence of memory leaks, and show them as following:
+
+ unreferenced object 0xffff8881575f8400 (size 1024):
+ comm "mount", pid 19625, jiffies 4297119604 (age 20.383s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<ffffffff8176cecd>] __kmalloc+0x4d/0x150
+ [<ffffffffa0406b2b>] ubifs_mount+0x307b/0x7170 [ubifs]
+ [<ffffffff819fa8fd>] legacy_get_tree+0xed/0x1d0
+ [<ffffffff81936f2d>] vfs_get_tree+0x7d/0x230
+ [<ffffffff819b2bd4>] path_mount+0xdd4/0x17b0
+ [<ffffffff819b37aa>] __x64_sys_mount+0x1fa/0x270
+ [<ffffffff83c14295>] do_syscall_64+0x35/0x80
+ [<ffffffff83e0006a>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+ unreferenced object 0xffff8881798a6e00 (size 512):
+ comm "mount", pid 19677, jiffies 4297121912 (age 37.816s)
+ hex dump (first 32 bytes):
+ 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ backtrace:
+ [<ffffffff8176cecd>] __kmalloc+0x4d/0x150
+ [<ffffffffa0418342>] ubifs_wbuf_init+0x52/0x480 [ubifs]
+ [<ffffffffa0406ca5>] ubifs_mount+0x31f5/0x7170 [ubifs]
+ [<ffffffff819fa8fd>] legacy_get_tree+0xed/0x1d0
+ [<ffffffff81936f2d>] vfs_get_tree+0x7d/0x230
+ [<ffffffff819b2bd4>] path_mount+0xdd4/0x17b0
+ [<ffffffff819b37aa>] __x64_sys_mount+0x1fa/0x270
+ [<ffffffff83c14295>] do_syscall_64+0x35/0x80
+ [<ffffffff83e0006a>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+The problem is that the ubifs_wbuf_init() returns an error in the
+loop which in the alloc_wbufs(), then the wbuf->buf and wbuf->inodes
+that were successfully alloced before are not freed.
+
+Fix it by adding error hanging path in alloc_wbufs() which frees
+the memory alloced before when ubifs_wbuf_init() returns an error.
+
+Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/super.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
+index d0c9a09988bc7..32cb147597960 100644
+--- a/fs/ubifs/super.c
++++ b/fs/ubifs/super.c
+@@ -833,7 +833,7 @@ static int alloc_wbufs(struct ubifs_info *c)
+ INIT_LIST_HEAD(&c->jheads[i].buds_list);
+ err = ubifs_wbuf_init(c, &c->jheads[i].wbuf);
+ if (err)
+- return err;
++ goto out_wbuf;
+
+ c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback;
+ c->jheads[i].wbuf.jhead = i;
+@@ -841,7 +841,7 @@ static int alloc_wbufs(struct ubifs_info *c)
+ c->jheads[i].log_hash = ubifs_hash_get_desc(c);
+ if (IS_ERR(c->jheads[i].log_hash)) {
+ err = PTR_ERR(c->jheads[i].log_hash);
+- goto out;
++ goto out_log_hash;
+ }
+ }
+
+@@ -854,9 +854,18 @@ static int alloc_wbufs(struct ubifs_info *c)
+
+ return 0;
+
+-out:
+- while (i--)
++out_log_hash:
++ kfree(c->jheads[i].wbuf.buf);
++ kfree(c->jheads[i].wbuf.inodes);
++
++out_wbuf:
++ while (i--) {
++ kfree(c->jheads[i].wbuf.buf);
++ kfree(c->jheads[i].wbuf.inodes);
+ kfree(c->jheads[i].log_hash);
++ }
++ kfree(c->jheads);
++ c->jheads = NULL;
+
+ return err;
+ }
+--
+2.39.2
+
--- /dev/null
+From fa26bcf388742411438b9e5b650ad0cb7a59f8c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Oct 2022 12:30:31 +0800
+Subject: ubifs: Fix memory leak in ubifs_sysfs_init()
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+[ Upstream commit 203a55f04f66eea1a1ca7e5a302a7f5c99c62327 ]
+
+When insmod ubifs.ko, a kmemleak reported as below:
+
+ unreferenced object 0xffff88817fb1a780 (size 8):
+ comm "insmod", pid 25265, jiffies 4295239702 (age 100.130s)
+ hex dump (first 8 bytes):
+ 75 62 69 66 73 00 ff ff ubifs...
+ backtrace:
+ [<ffffffff81b3fc4c>] slab_post_alloc_hook+0x9c/0x3c0
+ [<ffffffff81b44bf3>] __kmalloc_track_caller+0x183/0x410
+ [<ffffffff8198d3da>] kstrdup+0x3a/0x80
+ [<ffffffff8198d486>] kstrdup_const+0x66/0x80
+ [<ffffffff83989325>] kvasprintf_const+0x155/0x190
+ [<ffffffff83bf55bb>] kobject_set_name_vargs+0x5b/0x150
+ [<ffffffff83bf576b>] kobject_set_name+0xbb/0xf0
+ [<ffffffff8100204c>] do_one_initcall+0x14c/0x5a0
+ [<ffffffff8157e380>] do_init_module+0x1f0/0x660
+ [<ffffffff815857be>] load_module+0x6d7e/0x7590
+ [<ffffffff8158644f>] __do_sys_finit_module+0x19f/0x230
+ [<ffffffff815866b3>] __x64_sys_finit_module+0x73/0xb0
+ [<ffffffff88c98e85>] do_syscall_64+0x35/0x80
+ [<ffffffff88e00087>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+When kset_register() failed, we should call kset_put to cleanup it.
+
+Fixes: 2e3cbf425804 ("ubifs: Export filesystem error counters")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/sysfs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/ubifs/sysfs.c b/fs/ubifs/sysfs.c
+index 06ad8fa1fcfb0..54270ad36321e 100644
+--- a/fs/ubifs/sysfs.c
++++ b/fs/ubifs/sysfs.c
+@@ -144,6 +144,8 @@ int __init ubifs_sysfs_init(void)
+ kobject_set_name(&ubifs_kset.kobj, "ubifs");
+ ubifs_kset.kobj.parent = fs_kobj;
+ ret = kset_register(&ubifs_kset);
++ if (ret)
++ kset_put(&ubifs_kset);
+
+ return ret;
+ }
+--
+2.39.2
+
--- /dev/null
+From a0d01391327330c9b73d173e266ac3a9e727f1f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Oct 2022 11:47:30 +0800
+Subject: ubifs: Fix wrong dirty space budget for dirty inode
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit b248eaf049d9cdc5eb76b59399e4d3de233f02ac ]
+
+Each dirty inode should reserve 'c->bi.inode_budget' bytes in space
+budget calculation. Currently, space budget for dirty inode reports
+more space than what UBIFS actually needs to write.
+
+Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/budget.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
+index e8b9b756f0aca..986e6e4081c76 100644
+--- a/fs/ubifs/budget.c
++++ b/fs/ubifs/budget.c
+@@ -400,7 +400,7 @@ static int calc_dd_growth(const struct ubifs_info *c,
+ dd_growth = req->dirtied_page ? c->bi.page_budget : 0;
+
+ if (req->dirtied_ino)
+- dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1);
++ dd_growth += c->bi.inode_budget * req->dirtied_ino;
+ if (req->mod_dent)
+ dd_growth += c->bi.dent_budget;
+ dd_growth += req->dirtied_ino_d;
+--
+2.39.2
+
--- /dev/null
+From 665ee8ac716e120f88731c43f6c76224bbfb9b8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 17:02:35 +0800
+Subject: ubifs: Re-statistic cleaned znode count if commit failed
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 944e096aa24071d3fe22822f6249d3ae309e39ea ]
+
+Dirty znodes will be written on flash in committing process with
+following states:
+
+ process A | znode state
+------------------------------------------------------
+do_commit | DIRTY_ZNODE
+ ubifs_tnc_start_commit | DIRTY_ZNODE
+ get_znodes_to_commit | DIRTY_ZNODE | COW_ZNODE
+ layout_commit | DIRTY_ZNODE | COW_ZNODE
+ fill_gap | 0
+ write master | 0 or OBSOLETE_ZNODE
+
+ process B | znode state
+------------------------------------------------------
+do_commit | DIRTY_ZNODE[1]
+ ubifs_tnc_start_commit | DIRTY_ZNODE
+ get_znodes_to_commit | DIRTY_ZNODE | COW_ZNODE
+ ubifs_tnc_end_commit | DIRTY_ZNODE | COW_ZNODE
+ write_index | 0
+ write master | 0 or OBSOLETE_ZNODE[2] or
+ | DIRTY_ZNODE[3]
+
+[1] znode is dirtied without concurrent committing process
+[2] znode is copied up (re-dirtied by other process) before cleaned
+ up in committing process
+[3] znode is re-dirtied after cleaned up in committing process
+
+Currently, the clean znode count is updated in free_obsolete_znodes(),
+which is called only in normal path. If do_commit failed, clean znode
+count won't be updated, which triggers a failure ubifs assertion[4] in
+ubifs_tnc_close():
+ ubifs_assert_failed [ubifs]: UBIFS assert failed: freed == n
+
+[4] Commit 380347e9ca7682 ("UBIFS: Add an assertion for clean_zn_cnt").
+
+Fix it by re-statisticing cleaned znode count in tnc_destroy_cnext().
+
+Fetch a reproducer in [Link].
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216704
+Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/tnc.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
+index 488f3da7a6c6c..2df56bbc68657 100644
+--- a/fs/ubifs/tnc.c
++++ b/fs/ubifs/tnc.c
+@@ -3053,6 +3053,21 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
+ cnext = cnext->cnext;
+ if (ubifs_zn_obsolete(znode))
+ kfree(znode);
++ else if (!ubifs_zn_cow(znode)) {
++ /*
++ * Don't forget to update clean znode count after
++ * committing failed, because ubifs will check this
++ * count while closing tnc. Non-obsolete znode could
++ * be re-dirtied during committing process, so dirty
++ * flag is untrustable. The flag 'COW_ZNODE' is set
++ * for each dirty znode before committing, and it is
++ * cleared as long as the znode become clean, so we
++ * can statistic clean znode count according to this
++ * flag.
++ */
++ atomic_long_inc(&c->clean_zn_cnt);
++ atomic_long_inc(&ubifs_clean_zn_cnt);
++ }
+ } while (cnext && cnext != c->cnext);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 2133e666560632ce547bfa0ddecedfd938e4d0d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Oct 2022 11:47:27 +0800
+Subject: ubifs: Rectify space budget for ubifs_symlink() if symlink is
+ encrypted
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit c2c36cc6ca23e614f9e4238d0ecf48549ee9002a ]
+
+Fix bad space budget when symlink file is encrypted. Bad space budget
+may let make_reservation() return with -ENOSPC, which could turn ubifs
+to read-only mode in do_writepage() process.
+
+Fetch a reproducer in [Link].
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216490
+Fixes: ca7f85be8d6cf9 ("ubifs: Add support for encrypted symlinks")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/dir.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
+index 0f29cf2011361..aaff3f3f0aa3b 100644
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -1151,7 +1151,6 @@ static int ubifs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
+ int err, sz_change, len = strlen(symname);
+ struct fscrypt_str disk_link;
+ struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
+- .new_ino_d = ALIGN(len, 8),
+ .dirtied_ino = 1 };
+ struct fscrypt_name nm;
+
+@@ -1167,6 +1166,7 @@ static int ubifs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
+ * Budget request settings: new inode, new direntry and changing parent
+ * directory inode.
+ */
++ req.new_ino_d = ALIGN(disk_link.len - 1, 8);
+ err = ubifs_budget_space(c, &req);
+ if (err)
+ return err;
+--
+2.39.2
+
--- /dev/null
+From 640ed9bc38bc892d99e1045c1a0a2c4c496541e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Oct 2022 11:47:28 +0800
+Subject: ubifs: Rectify space budget for ubifs_xrename()
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 1b2ba09060e41adb356b9ae58ef94a7390928004 ]
+
+There is no space budget for ubifs_xrename(). It may let
+make_reservation() return with -ENOSPC, which could turn
+ubifs to read-only mode in do_writepage() process.
+Fix it by adding space budget for ubifs_xrename().
+
+Fetch a reproducer in [Link].
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216569
+Fixes: 9ec64962afb170 ("ubifs: Implement RENAME_EXCHANGE")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/dir.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
+index aaff3f3f0aa3b..94634b872e382 100644
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -1576,6 +1576,10 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
+ return err;
+ }
+
++ err = ubifs_budget_space(c, &req);
++ if (err)
++ goto out;
++
+ lock_4_inodes(old_dir, new_dir, NULL, NULL);
+
+ time = current_time(old_dir);
+@@ -1601,6 +1605,7 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
+ unlock_4_inodes(old_dir, new_dir, NULL, NULL);
+ ubifs_release_budget(c, &req);
+
++out:
+ fscrypt_free_filename(&fst_nm);
+ fscrypt_free_filename(&snd_nm);
+ return err;
+--
+2.39.2
+
--- /dev/null
+From 0c4a5f7da1c375aa29428de2f9ab54ea0f5b0c52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Oct 2022 11:47:32 +0800
+Subject: ubifs: Reserve one leb for each journal head while doing budget
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit e874dcde1cbf82c786c0e7f2899811c02630cc52 ]
+
+UBIFS calculates available space by c->main_bytes - c->lst.total_used
+(which means non-index lebs' free and dirty space is accounted into
+total available), then index lebs and four lebs (one for gc_lnum, one
+for deletions, two for journal heads) are deducted.
+In following situation, ubifs may get -ENOSPC from make_reservation():
+ LEB 84: DATAHD free 122880 used 1920 dirty 2176 dark 6144
+ LEB 110:DELETION free 126976 used 0 dirty 0 dark 6144 (empty)
+ LEB 201:gc_lnum free 126976 used 0 dirty 0 dark 6144
+ LEB 272:GCHD free 77824 used 47672 dirty 1480 dark 6144
+ LEB 356:BASEHD free 0 used 39776 dirty 87200 dark 6144
+ OTHERS: index lebs, zero-available non-index lebs
+
+UBIFS calculates the available bytes is 6888 (How to calculate it:
+126976 * 5[remain main bytes] - 1920[used] - 47672[used] - 39776[used] -
+126976 * 1[deletions] - 126976 * 1[gc_lnum] - 126976 * 2[journal heads]
+- 6144 * 5[dark] = 6888) after doing budget, however UBIFS cannot use
+BASEHD's dirty space(87200), because UBIFS cannot find next BASEHD to
+reclaim current BASEHD. (c->bi.min_idx_lebs equals to c->lst.idx_lebs,
+the empty leb won't be found by ubifs_find_free_space(), and dirty index
+lebs won't be picked as gced lebs. All non-index lebs has dirty space
+less then c->dead_wm, non-index lebs won't be picked as gced lebs
+either. So new free lebs won't be produced.). See more details in Link.
+
+To fix it, reserve one leb for each journal head while doing budget.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216562
+Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/budget.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
+index 986e6e4081c76..d76eb7b39f564 100644
+--- a/fs/ubifs/budget.c
++++ b/fs/ubifs/budget.c
+@@ -209,11 +209,10 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs)
+ subtract_lebs += 1;
+
+ /*
+- * The GC journal head LEB is not really accessible. And since
+- * different write types go to different heads, we may count only on
+- * one head's space.
++ * Since different write types go to different heads, we should
++ * reserve one leb for each head.
+ */
+- subtract_lebs += c->jhead_cnt - 1;
++ subtract_lebs += c->jhead_cnt;
+
+ /* We also reserve one LEB for deletions, which bypass budgeting */
+ subtract_lebs += 1;
+--
+2.39.2
+
--- /dev/null
+From d4645535b33ff0f4e0c94729069a3d9d7065bfab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 11:00:00 +0800
+Subject: ubifs: ubifs_releasepage: Remove ubifs_assert(0) to valid this
+ process
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 66f4742e93523ab2f062d9d9828b3e590bc61536 ]
+
+There are two states for ubifs writing pages:
+1. Dirty, Private
+2. Not Dirty, Not Private
+
+The normal process cannot go to ubifs_releasepage() which means there
+exists pages being private but not dirty. Reproducer[1] shows that it
+could occur (which maybe related to [2]) with following process:
+
+ PA PB PC
+lock(page)[PA]
+ubifs_write_end
+ attach_page_private // set Private
+ __set_page_dirty_nobuffers // set Dirty
+unlock(page)
+
+write_cache_pages[PA]
+ lock(page)
+ clear_page_dirty_for_io(page) // clear Dirty
+ ubifs_writepage
+
+ do_truncation[PB]
+ truncate_setsize
+ i_size_write(inode, newsize) // newsize = 0
+
+ i_size = i_size_read(inode) // i_size = 0
+ end_index = i_size >> PAGE_SHIFT
+ if (page->index > end_index)
+ goto out // jump
+out:
+unlock(page) // Private, Not Dirty
+
+ generic_fadvise[PC]
+ lock(page)
+ invalidate_inode_page
+ try_to_release_page
+ ubifs_releasepage
+ ubifs_assert(c, 0)
+ // bad assertion!
+ unlock(page)
+ truncate_pagecache[PB]
+
+Then we may get following assertion failed:
+ UBIFS error (ubi0:0 pid 1683): ubifs_assert_failed [ubifs]:
+ UBIFS assert failed: 0, in fs/ubifs/file.c:1513
+ UBIFS warning (ubi0:0 pid 1683): ubifs_ro_mode [ubifs]:
+ switched to read-only mode, error -22
+ CPU: 2 PID: 1683 Comm: aa Not tainted 5.16.0-rc5-00184-g0bca5994cacc-dirty #308
+ Call Trace:
+ dump_stack+0x13/0x1b
+ ubifs_ro_mode+0x54/0x60 [ubifs]
+ ubifs_assert_failed+0x4b/0x80 [ubifs]
+ ubifs_releasepage+0x67/0x1d0 [ubifs]
+ try_to_release_page+0x57/0xe0
+ invalidate_inode_page+0xfb/0x130
+ __invalidate_mapping_pages+0xb9/0x280
+ invalidate_mapping_pagevec+0x12/0x20
+ generic_fadvise+0x303/0x3c0
+ ksys_fadvise64_64+0x4c/0xb0
+
+[1] https://bugzilla.kernel.org/show_bug.cgi?id=215373
+[2] https://linux-mtd.infradead.narkive.com/NQoBeT1u/patch-rfc-ubifs-fix-assert-failed-in-ubifs-set-page-dirty
+
+Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/file.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
+index 1f429260a85fc..10c1779af9c51 100644
+--- a/fs/ubifs/file.c
++++ b/fs/ubifs/file.c
+@@ -1472,14 +1472,23 @@ static bool ubifs_release_folio(struct folio *folio, gfp_t unused_gfp_flags)
+ struct inode *inode = folio->mapping->host;
+ struct ubifs_info *c = inode->i_sb->s_fs_info;
+
+- /*
+- * An attempt to release a dirty page without budgeting for it - should
+- * not happen.
+- */
+ if (folio_test_writeback(folio))
+ return false;
++
++ /*
++ * Page is private but not dirty, weird? There is one condition
++ * making it happened. ubifs_writepage skipped the page because
++ * page index beyonds isize (for example. truncated by other
++ * process named A), then the page is invalidated by fadvise64
++ * syscall before being truncated by process A.
++ */
+ ubifs_assert(c, folio_test_private(folio));
+- ubifs_assert(c, 0);
++ if (folio_test_checked(folio))
++ release_new_page_budget(c);
++ else
++ release_existing_page_budget(c);
++
++ atomic_long_dec(&c->dirty_pg_cnt);
+ folio_detach_private(folio);
+ folio_clear_checked(folio);
+ return true;
+--
+2.39.2
+
--- /dev/null
+From e46273a830126b6e1b4cc63281a02cbe644d4577 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 10:59:59 +0800
+Subject: ubifs: ubifs_writepage: Mark page dirty after writing inode failed
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit fb8bc4c74ae4526d9489362ab2793a936d072b84 ]
+
+There are two states for ubifs writing pages:
+1. Dirty, Private
+2. Not Dirty, Not Private
+
+There is a third possibility which maybe related to [1] that page is
+private but not dirty caused by following process:
+
+ PA
+lock(page)
+ubifs_write_end
+ attach_page_private // set Private
+ __set_page_dirty_nobuffers // set Dirty
+unlock(page)
+
+write_cache_pages
+ lock(page)
+ clear_page_dirty_for_io(page) // clear Dirty
+ ubifs_writepage
+ write_inode
+ // fail, goto out, following codes are not executed
+ // do_writepage
+ // set_page_writeback // set Writeback
+ // detach_page_private // clear Private
+ // end_page_writeback // clear Writeback
+ out:
+ unlock(page) // Private, Not Dirty
+
+ PB
+ ksys_fadvise64_64
+ generic_fadvise
+ invalidate_inode_page
+ // page is neither Dirty nor Writeback
+ invalidate_complete_page
+ // page_has_private is true
+ try_to_release_page
+ ubifs_releasepage
+ ubifs_assert(c, 0) !!!
+
+Then we may get following assertion failed:
+ UBIFS error (ubi0:0 pid 1492): ubifs_assert_failed [ubifs]:
+ UBIFS assert failed: 0, in fs/ubifs/file.c:1499
+ UBIFS warning (ubi0:0 pid 1492): ubifs_ro_mode [ubifs]:
+ switched to read-only mode, error -22
+ CPU: 2 PID: 1492 Comm: aa Not tainted 5.16.0-rc2-00012-g7bb767dee0ba-dirty
+ Call Trace:
+ dump_stack+0x13/0x1b
+ ubifs_ro_mode+0x54/0x60 [ubifs]
+ ubifs_assert_failed+0x4b/0x80 [ubifs]
+ ubifs_releasepage+0x7e/0x1e0 [ubifs]
+ try_to_release_page+0x57/0xe0
+ invalidate_inode_page+0xfb/0x130
+ invalidate_mapping_pagevec+0x12/0x20
+ generic_fadvise+0x303/0x3c0
+ vfs_fadvise+0x35/0x40
+ ksys_fadvise64_64+0x4c/0xb0
+
+Jump [2] to find a reproducer.
+
+[1] https://linux-mtd.infradead.narkive.com/NQoBeT1u/patch-rfc-ubifs-fix-assert-failed-in-ubifs-set-page-dirty
+[2] https://bugzilla.kernel.org/show_bug.cgi?id=215357
+
+Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/file.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
+index f2353dd676ef0..1f429260a85fc 100644
+--- a/fs/ubifs/file.c
++++ b/fs/ubifs/file.c
+@@ -1032,7 +1032,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
+ if (page->index >= synced_i_size >> PAGE_SHIFT) {
+ err = inode->i_sb->s_op->write_inode(inode, NULL);
+ if (err)
+- goto out_unlock;
++ goto out_redirty;
+ /*
+ * The inode has been written, but the write-buffer has
+ * not been synchronized, so in case of an unclean
+@@ -1060,11 +1060,17 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
+ if (i_size > synced_i_size) {
+ err = inode->i_sb->s_op->write_inode(inode, NULL);
+ if (err)
+- goto out_unlock;
++ goto out_redirty;
+ }
+
+ return do_writepage(page, len);
+-
++out_redirty:
++ /*
++ * redirty_page_for_writepage() won't call ubifs_dirty_inode() because
++ * it passes I_DIRTY_PAGES flag while calling __mark_inode_dirty(), so
++ * there is no need to do space budget for dirty inode.
++ */
++ redirty_page_for_writepage(wbc, page);
+ out_unlock:
+ unlock_page(page);
+ return err;
+--
+2.39.2
+
--- /dev/null
+From 5542a034807921d27daed9885ba1d7c44d6b56e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 15:32:25 +0800
+Subject: um: vector: Fix memory leak in vector_config
+
+From: Xiang Yang <xiangyang3@huawei.com>
+
+[ Upstream commit 8f88c73afe481f93d40801596927e8c0047b6d96 ]
+
+If the return value of the uml_parse_vector_ifspec function is NULL,
+we should call kfree(params) to prevent memory leak.
+
+Fixes: 49da7e64f33e ("High Performance UML Vector Network Driver")
+Signed-off-by: Xiang Yang <xiangyang3@huawei.com>
+Acked-By: Anton Ivanov <anton.ivanov@kot-begemot.co.uk>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/vector_kern.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
+index ded7c47d2fbe5..131b7cb295767 100644
+--- a/arch/um/drivers/vector_kern.c
++++ b/arch/um/drivers/vector_kern.c
+@@ -767,6 +767,7 @@ static int vector_config(char *str, char **error_out)
+
+ if (parsed == NULL) {
+ *error_out = "vector_config failed to parse parameters";
++ kfree(params);
+ return -EINVAL;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 2ce1852cab5372815c6c2d41e4337fb5d4516fab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 10:00:05 +0100
+Subject: um: virt-pci: properly remove PCI device from bus
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 339b84dcd7113dd076419ea2a47128cc53450305 ]
+
+Triggering a bus rescan will not cause the PCI device to be removed. It
+is required to explicitly stop and remove the device from the bus.
+
+Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/virt-pci.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
+index 3b637ad75ec81..5472b1a0a0398 100644
+--- a/arch/um/drivers/virt-pci.c
++++ b/arch/um/drivers/virt-pci.c
+@@ -626,22 +626,33 @@ static void um_pci_virtio_remove(struct virtio_device *vdev)
+ struct um_pci_device *dev = vdev->priv;
+ int i;
+
+- /* Stop all virtqueues */
+- virtio_reset_device(vdev);
+- vdev->config->del_vqs(vdev);
+-
+ device_set_wakeup_enable(&vdev->dev, false);
+
+ mutex_lock(&um_pci_mtx);
+ for (i = 0; i < MAX_DEVICES; i++) {
+ if (um_pci_devices[i].dev != dev)
+ continue;
++
+ um_pci_devices[i].dev = NULL;
+ irq_free_desc(dev->irq);
++
++ break;
+ }
+ mutex_unlock(&um_pci_mtx);
+
+- um_pci_rescan();
++ if (i < MAX_DEVICES) {
++ struct pci_dev *pci_dev;
++
++ pci_dev = pci_get_slot(bridge->bus, i);
++ if (pci_dev)
++ pci_stop_and_remove_bus_device_locked(pci_dev);
++ }
++
++ /* Stop all virtqueues */
++ virtio_reset_device(vdev);
++ dev->cmd_vq = NULL;
++ dev->irq_vq = NULL;
++ vdev->config->del_vqs(vdev);
+
+ kfree(dev);
+ }
+--
+2.39.2
+
--- /dev/null
+From 2e39cf7b8f86c3be306985b9b0185f46f1b10b28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 10:00:02 +0100
+Subject: um: virtio_uml: free command if adding to virtqueue failed
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 8a6ca543646f2940832665dbf4e04105262505e2 ]
+
+If adding the command fails (i.e. the virtqueue is broken) then free it
+again if the function allocated a new buffer for it.
+
+Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/virt-pci.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
+index 3ac220dafec4a..3b637ad75ec81 100644
+--- a/arch/um/drivers/virt-pci.c
++++ b/arch/um/drivers/virt-pci.c
+@@ -132,8 +132,11 @@ static int um_pci_send_cmd(struct um_pci_device *dev,
+ out ? 1 : 0,
+ posted ? cmd : HANDLE_NO_FREE(cmd),
+ GFP_ATOMIC);
+- if (ret)
++ if (ret) {
++ if (posted)
++ kfree(cmd);
+ goto out;
++ }
+
+ if (posted) {
+ virtqueue_kick(dev->cmd_vq);
+--
+2.39.2
+
--- /dev/null
+From 78ac115136b1f96358e9db532e6091b315afaf8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 10:00:03 +0100
+Subject: um: virtio_uml: mark device as unregistered when breaking it
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 8e9cd85139a2149d5a7c121b05e0cdb8287311f9 ]
+
+Mark the device as not registered anymore when scheduling the work to
+remove it. Otherwise we could end up scheduling the work multiple times
+in a row, including scheduling it while it is already running.
+
+Fixes: af9fb41ed315 ("um: virtio_uml: Fix broken device handling in time-travel")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/virtio_uml.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
+index 588930a0ced17..dcfd0ca534eef 100644
+--- a/arch/um/drivers/virtio_uml.c
++++ b/arch/um/drivers/virtio_uml.c
+@@ -168,6 +168,8 @@ static void vhost_user_check_reset(struct virtio_uml_device *vu_dev,
+ if (!vu_dev->registered)
+ return;
+
++ vu_dev->registered = 0;
++
+ virtio_break_device(&vu_dev->vdev);
+ schedule_work(&pdata->conn_broken_wk);
+ }
+--
+2.39.2
+
--- /dev/null
+From 55c1ffa0ab06dcc85f53084afed7cf225aa16858 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 10:00:04 +0100
+Subject: um: virtio_uml: move device breaking into workqueue
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit abdeb4fa5e1b5b4918034f02236fd886f40c20c1 ]
+
+We should not be calling virtio_break_device from an IRQ context.
+Move breaking the device into the workqueue so that it is done from
+a reasonable context.
+
+Fixes: af9fb41ed315 ("um: virtio_uml: Fix broken device handling in time-travel")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/virtio_uml.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
+index dcfd0ca534eef..ddd080f6dd82e 100644
+--- a/arch/um/drivers/virtio_uml.c
++++ b/arch/um/drivers/virtio_uml.c
+@@ -170,7 +170,6 @@ static void vhost_user_check_reset(struct virtio_uml_device *vu_dev,
+
+ vu_dev->registered = 0;
+
+- virtio_break_device(&vu_dev->vdev);
+ schedule_work(&pdata->conn_broken_wk);
+ }
+
+@@ -1138,6 +1137,15 @@ void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev,
+
+ static void vu_of_conn_broken(struct work_struct *wk)
+ {
++ struct virtio_uml_platform_data *pdata;
++ struct virtio_uml_device *vu_dev;
++
++ pdata = container_of(wk, struct virtio_uml_platform_data, conn_broken_wk);
++
++ vu_dev = platform_get_drvdata(pdata->pdev);
++
++ virtio_break_device(&vu_dev->vdev);
++
+ /*
+ * We can't remove the device from the devicetree so the only thing we
+ * can do is warn.
+@@ -1268,8 +1276,14 @@ static int vu_unregister_cmdline_device(struct device *dev, void *data)
+ static void vu_conn_broken(struct work_struct *wk)
+ {
+ struct virtio_uml_platform_data *pdata;
++ struct virtio_uml_device *vu_dev;
+
+ pdata = container_of(wk, struct virtio_uml_platform_data, conn_broken_wk);
++
++ vu_dev = platform_get_drvdata(pdata->pdev);
++
++ virtio_break_device(&vu_dev->vdev);
++
+ vu_unregister_cmdline_device(&pdata->pdev->dev, NULL);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 0f67b8395273e7b7939d5ae5c1e17e72be9cd184 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:23 +0100
+Subject: USB: chipidea: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit ff35f3ea3baba5b81416ac02d005cfbf6dd182fa ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20230202153235.2412790-1-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c
+index faf6b078b6c44..bbc610e5bd69c 100644
+--- a/drivers/usb/chipidea/debug.c
++++ b/drivers/usb/chipidea/debug.c
+@@ -364,5 +364,5 @@ void dbg_create_files(struct ci_hdrc *ci)
+ */
+ void dbg_remove_files(struct ci_hdrc *ci)
+ {
+- debugfs_remove(debugfs_lookup(dev_name(ci->dev), usb_debug_root));
++ debugfs_lookup_and_remove(dev_name(ci->dev), usb_debug_root);
+ }
+--
+2.39.2
+
--- /dev/null
+From 696569c5ef6bdcf7b12ab14ac0cb0d1c319a958f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:28:20 +0100
+Subject: USB: dwc3: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit be308d68785b205e483b3a0c61ba3a82da468f2c ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Note, the root dentry for the debugfs directory for the device needs to
+be saved so we don't have to keep looking it up, which required a bit
+more refactoring to properly create and remove it when needed.
+
+Reported-by: Bruce Chen <bruce.chen@unisoc.com>
+Reported-by: Cixi Geng <cixi.geng1@unisoc.com>
+Tested-by: Cixi Geng <gengcixi@gmail.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20230202152820.2409908-1-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/core.h | 2 ++
+ drivers/usb/dwc3/debug.h | 3 +++
+ drivers/usb/dwc3/debugfs.c | 19 ++++++++-----------
+ drivers/usb/dwc3/gadget.c | 4 +---
+ 4 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 8f9959ba9fd46..582ebd9cf9c2e 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -1117,6 +1117,7 @@ struct dwc3_scratchpad_array {
+ * address.
+ * @num_ep_resized: carries the current number endpoints which have had its tx
+ * fifo resized.
++ * @debug_root: root debugfs directory for this device to put its files in.
+ */
+ struct dwc3 {
+ struct work_struct drd_work;
+@@ -1332,6 +1333,7 @@ struct dwc3 {
+ int max_cfg_eps;
+ int last_fifo_depth;
+ int num_ep_resized;
++ struct dentry *debug_root;
+ };
+
+ #define INCRX_BURST_MODE 0
+diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
+index 48b44b88dc252..8bb2c9e3b9ac6 100644
+--- a/drivers/usb/dwc3/debug.h
++++ b/drivers/usb/dwc3/debug.h
+@@ -414,11 +414,14 @@ static inline const char *dwc3_gadget_generic_cmd_status_string(int status)
+
+ #ifdef CONFIG_DEBUG_FS
+ extern void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep);
++extern void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep);
+ extern void dwc3_debugfs_init(struct dwc3 *d);
+ extern void dwc3_debugfs_exit(struct dwc3 *d);
+ #else
+ static inline void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
+ { }
++static inline void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep)
++{ }
+ static inline void dwc3_debugfs_init(struct dwc3 *d)
+ { }
+ static inline void dwc3_debugfs_exit(struct dwc3 *d)
+diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
+index f2b7675c7f621..850df0e6bcabf 100644
+--- a/drivers/usb/dwc3/debugfs.c
++++ b/drivers/usb/dwc3/debugfs.c
+@@ -873,27 +873,23 @@ static const struct dwc3_ep_file_map dwc3_ep_file_map[] = {
+ { "GDBGEPINFO", &dwc3_ep_info_register_fops, },
+ };
+
+-static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep,
+- struct dentry *parent)
++void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
+ {
++ struct dentry *dir;
+ int i;
+
++ dir = debugfs_create_dir(dep->name, dep->dwc->debug_root);
+ for (i = 0; i < ARRAY_SIZE(dwc3_ep_file_map); i++) {
+ const struct file_operations *fops = dwc3_ep_file_map[i].fops;
+ const char *name = dwc3_ep_file_map[i].name;
+
+- debugfs_create_file(name, 0444, parent, dep, fops);
++ debugfs_create_file(name, 0444, dir, dep, fops);
+ }
+ }
+
+-void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
++void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep)
+ {
+- struct dentry *dir;
+- struct dentry *root;
+-
+- root = debugfs_lookup(dev_name(dep->dwc->dev), usb_debug_root);
+- dir = debugfs_create_dir(dep->name, root);
+- dwc3_debugfs_create_endpoint_files(dep, dir);
++ debugfs_lookup_and_remove(dep->name, dep->dwc->debug_root);
+ }
+
+ void dwc3_debugfs_init(struct dwc3 *dwc)
+@@ -911,6 +907,7 @@ void dwc3_debugfs_init(struct dwc3 *dwc)
+ dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
+
+ root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root);
++ dwc->debug_root = root;
+ debugfs_create_regset32("regdump", 0444, root, dwc->regset);
+ debugfs_create_file("lsp_dump", 0644, root, dwc, &dwc3_lsp_fops);
+
+@@ -929,6 +926,6 @@ void dwc3_debugfs_init(struct dwc3 *dwc)
+
+ void dwc3_debugfs_exit(struct dwc3 *dwc)
+ {
+- debugfs_remove(debugfs_lookup(dev_name(dwc->dev), usb_debug_root));
++ debugfs_lookup_and_remove(dev_name(dwc->dev), usb_debug_root);
+ kfree(dwc->regset);
+ }
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index ed958da0e1c96..df1ce96fa2281 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -3184,9 +3184,7 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
+ list_del(&dep->endpoint.ep_list);
+ }
+
+- debugfs_remove_recursive(debugfs_lookup(dep->name,
+- debugfs_lookup(dev_name(dep->dwc->dev),
+- usb_debug_root)));
++ dwc3_debugfs_remove_endpoint_dir(dep);
+ kfree(dep);
+ }
+ }
+--
+2.39.2
+
--- /dev/null
+From 342e449372156c1700f08ad86b78df1a33b54763 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Feb 2023 10:35:46 -0800
+Subject: USB: ene_usb6250: Allocate enough memory for full object
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit ce33e64c1788912976b61314b56935abd4bc97ef ]
+
+The allocation of PageBuffer is 512 bytes in size, but the dereferencing
+of struct ms_bootblock_idi (also size 512) happens at a calculated offset
+within the allocation, which means the object could potentially extend
+beyond the end of the allocation. Avoid this case by just allocating
+enough space to catch any accesses beyond the end. Seen with GCC 13:
+
+../drivers/usb/storage/ene_ub6250.c: In function 'ms_lib_process_bootblock':
+../drivers/usb/storage/ene_ub6250.c:1050:44: warning: array subscript 'struct ms_bootblock_idi[0]' is partly outside array bounds of 'unsigned char[512]' [-Warray-bounds=]
+ 1050 | if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
+ | ^~
+../include/uapi/linux/byteorder/little_endian.h:37:51: note: in definition of macro '__le16_to_cpu'
+ 37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
+ | ^
+../drivers/usb/storage/ene_ub6250.c:1050:29: note: in expansion of macro 'le16_to_cpu'
+ 1050 | if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
+ | ^~~~~~~~~~~
+In file included from ../drivers/usb/storage/ene_ub6250.c:5:
+In function 'kmalloc',
+ inlined from 'ms_lib_process_bootblock' at ../drivers/usb/storage/ene_ub6250.c:942:15:
+../include/linux/slab.h:580:24: note: at offset [256, 512] into object of size 512 allocated by 'kmalloc_trace'
+ 580 | return kmalloc_trace(
+ | ^~~~~~~~~~~~~~
+ 581 | kmalloc_caches[kmalloc_type(flags)][index],
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 582 | flags, size);
+ | ~~~~~~~~~~~~
+
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20230204183546.never.849-kees@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/storage/ene_ub6250.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
+index 6012603f3630e..97c66c0d91f4d 100644
+--- a/drivers/usb/storage/ene_ub6250.c
++++ b/drivers/usb/storage/ene_ub6250.c
+@@ -939,7 +939,7 @@ static int ms_lib_process_bootblock(struct us_data *us, u16 PhyBlock, u8 *PageDa
+ struct ms_lib_type_extdat ExtraData;
+ struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+
+- PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
++ PageBuffer = kzalloc(MS_BYTES_PER_PAGE * 2, GFP_KERNEL);
+ if (PageBuffer == NULL)
+ return (u32)-1;
+
+--
+2.39.2
+
--- /dev/null
+From 449be540726ad9a8776c630505b1c8795f4669ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jan 2023 16:28:28 +0100
+Subject: USB: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 30374434edab20e25776f8ecb4bc9d1e54309487 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic at
+once.
+
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Cc: Jilin Yuan <yuanjilin@cdjrlc.com>
+Link: https://lore.kernel.org/r/20230106152828.3790902-1-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index 11b15d7b357ad..a415206cab043 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -998,7 +998,7 @@ static void usb_debugfs_init(void)
+
+ static void usb_debugfs_cleanup(void)
+ {
+- debugfs_remove(debugfs_lookup("devices", usb_debug_root));
++ debugfs_lookup_and_remove("devices", usb_debug_root);
+ }
+
+ /*
+--
+2.39.2
+
--- /dev/null
+From 185db237fe89715928a7bbe92017b9ab7bf9139b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:27 +0100
+Subject: USB: fotg210: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 6b4040f452037a7e95472577891d57c6b18c89c5 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20230202153235.2412790-5-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/fotg210-hcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
+index 3d1dbcf4c0732..c4c1fbc12b4cd 100644
+--- a/drivers/usb/host/fotg210-hcd.c
++++ b/drivers/usb/host/fotg210-hcd.c
+@@ -862,7 +862,7 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
+ {
+ struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
+
+- debugfs_remove(debugfs_lookup(bus->bus_name, fotg210_debug_root));
++ debugfs_lookup_and_remove(bus->bus_name, fotg210_debug_root);
+ }
+
+ /* handshake - spin reading hc until handshake completes or fails
+--
+2.39.2
+
--- /dev/null
+From 255593950e898bcc98b74bed42c018ffb0f45c9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:31 +0100
+Subject: USB: gadget: bcm63xx_udc: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit a91c99b1fe5c6f7e52fb932ad9e57ec7cfe913ec ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Kevin Cernekee <cernekee@gmail.com>
+Link: https://lore.kernel.org/r/20230202153235.2412790-9-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/bcm63xx_udc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c
+index d04d72f5816e6..8d58928913007 100644
+--- a/drivers/usb/gadget/udc/bcm63xx_udc.c
++++ b/drivers/usb/gadget/udc/bcm63xx_udc.c
+@@ -2258,7 +2258,7 @@ static void bcm63xx_udc_init_debugfs(struct bcm63xx_udc *udc)
+ */
+ static void bcm63xx_udc_cleanup_debugfs(struct bcm63xx_udc *udc)
+ {
+- debugfs_remove(debugfs_lookup(udc->gadget.name, usb_debug_root));
++ debugfs_lookup_and_remove(udc->gadget.name, usb_debug_root);
+ }
+
+ /***********************************************************************
+--
+2.39.2
+
--- /dev/null
+From dcfe4029cf879ded4425aa143061ee88120f9889 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:30 +0100
+Subject: USB: gadget: gr_udc: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 73f4451368663ad28daa67980c6dd11d83b303eb ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Jakob Koschel <jakobkoschel@gmail.com>
+Link: https://lore.kernel.org/r/20230202153235.2412790-8-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/gr_udc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c
+index 85cdc0af3bf95..09762559912d3 100644
+--- a/drivers/usb/gadget/udc/gr_udc.c
++++ b/drivers/usb/gadget/udc/gr_udc.c
+@@ -215,7 +215,7 @@ static void gr_dfs_create(struct gr_udc *dev)
+
+ static void gr_dfs_delete(struct gr_udc *dev)
+ {
+- debugfs_remove(debugfs_lookup(dev_name(dev->dev), usb_debug_root));
++ debugfs_lookup_and_remove(dev_name(dev->dev), usb_debug_root);
+ }
+
+ #else /* !CONFIG_USB_GADGET_DEBUG_FS */
+--
+2.39.2
+
--- /dev/null
+From 35c3a0da9aafe2b40f4edae832f391103587cc5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:32 +0100
+Subject: USB: gadget: lpc32xx_udc: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit e3965acaf3739fde9d74ad82979b46d37c6c208f ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Jakob Koschel <jakobkoschel@gmail.com>
+Cc: Miaoqian Lin <linmq006@gmail.com>
+Acked-by: Vladimir Zapolskiy <vz@mleia.com>
+Link: https://lore.kernel.org/r/20230202153235.2412790-10-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/lpc32xx_udc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
+index cea10cdb83ae5..fe62db32dd0eb 100644
+--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
++++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
+@@ -532,7 +532,7 @@ static void create_debug_file(struct lpc32xx_udc *udc)
+
+ static void remove_debug_file(struct lpc32xx_udc *udc)
+ {
+- debugfs_remove(debugfs_lookup(debug_filename, NULL));
++ debugfs_lookup_and_remove(debug_filename, NULL);
+ }
+
+ #else
+--
+2.39.2
+
--- /dev/null
+From 324227769976d012aab7a761fb43ceb13b6db811 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:33 +0100
+Subject: USB: gadget: pxa25x_udc: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 7a038a681b7df78362d9fc7013e5395a694a9d3a ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Daniel Mack <daniel@zonque.org>
+Cc: Haojian Zhuang <haojian.zhuang@gmail.com>
+Cc: Robert Jarzmik <robert.jarzmik@free.fr>
+Link: https://lore.kernel.org/r/20230202153235.2412790-11-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/pxa25x_udc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c
+index c593fc383481e..9e01ddf2b4170 100644
+--- a/drivers/usb/gadget/udc/pxa25x_udc.c
++++ b/drivers/usb/gadget/udc/pxa25x_udc.c
+@@ -1340,7 +1340,7 @@ DEFINE_SHOW_ATTRIBUTE(udc_debug);
+ debugfs_create_file(dev->gadget.name, \
+ S_IRUGO, NULL, dev, &udc_debug_fops); \
+ } while (0)
+-#define remove_debug_files(dev) debugfs_remove(debugfs_lookup(dev->gadget.name, NULL))
++#define remove_debug_files(dev) debugfs_lookup_and_remove(dev->gadget.name, NULL)
+
+ #else /* !CONFIG_USB_GADGET_DEBUG_FILES */
+
+--
+2.39.2
+
--- /dev/null
+From 101835cd386eeb2af7c717cbac29d97ede92acac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:34 +0100
+Subject: USB: gadget: pxa27x_udc: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 7a6952fa0366d4408eb8695af1a0578c39ec718a ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Daniel Mack <daniel@zonque.org>
+Cc: Haojian Zhuang <haojian.zhuang@gmail.com>
+Cc: Robert Jarzmik <robert.jarzmik@free.fr>
+Link: https://lore.kernel.org/r/20230202153235.2412790-12-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/pxa27x_udc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c
+index ac980d6a47406..0ecdfd2ba9e9b 100644
+--- a/drivers/usb/gadget/udc/pxa27x_udc.c
++++ b/drivers/usb/gadget/udc/pxa27x_udc.c
+@@ -215,7 +215,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc)
+
+ static void pxa_cleanup_debugfs(struct pxa_udc *udc)
+ {
+- debugfs_remove(debugfs_lookup(udc->gadget.name, usb_debug_root));
++ debugfs_lookup_and_remove(udc->gadget.name, usb_debug_root);
+ }
+
+ #else
+--
+2.39.2
+
--- /dev/null
+From eea1dbe23164bface8972a6ee96105f000602696 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Feb 2023 16:17:52 +0000
+Subject: usb: gadget: uvc: Make bSourceID read/write
+
+From: Daniel Scally <dan.scally@ideasonboard.com>
+
+[ Upstream commit b3c839bd8a07d303bc59a900d55dd35c7826562c ]
+
+At the moment, the UVC function graph is hardcoded IT -> PU -> OT.
+To add XU support we need the ability to insert the XU descriptors
+into the chain. To facilitate that, make the output terminal's
+bSourceID attribute writeable so that we can configure its source.
+
+Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
+Link: https://lore.kernel.org/r/20230206161802.892954-2-dan.scally@ideasonboard.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ABI/testing/configfs-usb-gadget-uvc | 2 +-
+ drivers/usb/gadget/function/uvc_configfs.c | 59 ++++++++++++++++++-
+ 2 files changed, 59 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc
+index 611b23e6488d9..feb3f2cc0c167 100644
+--- a/Documentation/ABI/testing/configfs-usb-gadget-uvc
++++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc
+@@ -52,7 +52,7 @@ Date: Dec 2014
+ KernelVersion: 4.0
+ Description: Default output terminal descriptors
+
+- All attributes read only:
++ All attributes read only except bSourceID:
+
+ ============== =============================================
+ iTerminal index of string descriptor
+diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
+index 4303a3283ba0a..832565730d224 100644
+--- a/drivers/usb/gadget/function/uvc_configfs.c
++++ b/drivers/usb/gadget/function/uvc_configfs.c
+@@ -483,11 +483,68 @@ UVC_ATTR_RO(uvcg_default_output_, cname, aname)
+ UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, 8);
+ UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, 16);
+ UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, 8);
+-UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, 8);
+ UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, 8);
+
+ #undef UVCG_DEFAULT_OUTPUT_ATTR
+
++static ssize_t uvcg_default_output_b_source_id_show(struct config_item *item,
++ char *page)
++{
++ struct config_group *group = to_config_group(item);
++ struct f_uvc_opts *opts;
++ struct config_item *opts_item;
++ struct mutex *su_mutex = &group->cg_subsys->su_mutex;
++ struct uvc_output_terminal_descriptor *cd;
++ int result;
++
++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */
++
++ opts_item = group->cg_item.ci_parent->ci_parent->
++ ci_parent->ci_parent;
++ opts = to_f_uvc_opts(opts_item);
++ cd = &opts->uvc_output_terminal;
++
++ mutex_lock(&opts->lock);
++ result = sprintf(page, "%u\n", le8_to_cpu(cd->bSourceID));
++ mutex_unlock(&opts->lock);
++
++ mutex_unlock(su_mutex);
++
++ return result;
++}
++
++static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item,
++ const char *page, size_t len)
++{
++ struct config_group *group = to_config_group(item);
++ struct f_uvc_opts *opts;
++ struct config_item *opts_item;
++ struct mutex *su_mutex = &group->cg_subsys->su_mutex;
++ struct uvc_output_terminal_descriptor *cd;
++ int result;
++ u8 num;
++
++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */
++
++ opts_item = group->cg_item.ci_parent->ci_parent->
++ ci_parent->ci_parent;
++ opts = to_f_uvc_opts(opts_item);
++ cd = &opts->uvc_output_terminal;
++
++ result = kstrtou8(page, 0, &num);
++ if (result)
++ return result;
++
++ mutex_lock(&opts->lock);
++ cd->bSourceID = num;
++ mutex_unlock(&opts->lock);
++
++ mutex_unlock(su_mutex);
++
++ return len;
++}
++UVC_ATTR(uvcg_default_output_, b_source_id, bSourceID);
++
+ static struct configfs_attribute *uvcg_default_output_attrs[] = {
+ &uvcg_default_output_attr_b_terminal_id,
+ &uvcg_default_output_attr_w_terminal_type,
+--
+2.39.2
+
--- /dev/null
+From ccc3a398d00764c52f45b672ee5fe3df905cfd6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Feb 2023 10:36:52 -0800
+Subject: usb: host: xhci: mvebu: Iterate over array indexes instead of using
+ pointer math
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 0fbd2cda92cdb00f72080665554a586f88bca821 ]
+
+Walking the dram->cs array was seen as accesses beyond the first array
+item by the compiler. Instead, use the array index directly. This allows
+for run-time bounds checking under CONFIG_UBSAN_BOUNDS as well. Seen
+with GCC 13 with -fstrict-flex-arrays:
+
+In function 'xhci_mvebu_mbus_config',
+ inlined from 'xhci_mvebu_mbus_init_quirk' at ../drivers/usb/host/xhci-mvebu.c:66:2:
+../drivers/usb/host/xhci-mvebu.c:37:28: warning: array subscript 0 is outside array bounds of 'const struct mbus_dram_window[0]' [-Warray-bounds=]
+ 37 | writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
+ | ~~^~~~~~
+
+Cc: Mathias Nyman <mathias.nyman@intel.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20230204183651.never.663-kees@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-mvebu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
+index 60651a50770f9..87f1597a0e5ab 100644
+--- a/drivers/usb/host/xhci-mvebu.c
++++ b/drivers/usb/host/xhci-mvebu.c
+@@ -32,7 +32,7 @@ static void xhci_mvebu_mbus_config(void __iomem *base,
+
+ /* Program each DRAM CS in a seperate window */
+ for (win = 0; win < dram->num_cs; win++) {
+- const struct mbus_dram_window *cs = dram->cs + win;
++ const struct mbus_dram_window *cs = &dram->cs[win];
+
+ writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+--
+2.39.2
+
--- /dev/null
+From be6023bdde076bdf9b81499393aa6306b1ec2964 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:28 +0100
+Subject: USB: isp116x: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit a95f62d5813facbec20ec087472eb313ee5fa8af ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Olav Kongas <ok@artecdesign.ee>
+Link: https://lore.kernel.org/r/20230202153235.2412790-6-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/isp116x-hcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
+index 4f564d71bb0bc..49ae01487af4d 100644
+--- a/drivers/usb/host/isp116x-hcd.c
++++ b/drivers/usb/host/isp116x-hcd.c
+@@ -1205,7 +1205,7 @@ static void create_debug_file(struct isp116x *isp116x)
+
+ static void remove_debug_file(struct isp116x *isp116x)
+ {
+- debugfs_remove(debugfs_lookup(hcd_name, usb_debug_root));
++ debugfs_lookup_and_remove(hcd_name, usb_debug_root);
+ }
+
+ #else
+--
+2.39.2
+
--- /dev/null
+From 6cfe17fc712c47e1b9c4b6873ad76e894675d4aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:29 +0100
+Subject: USB: isp1362: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit c26e682afc14caa87d44beed271eec8991e93c65 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Link: https://lore.kernel.org/r/20230202153235.2412790-7-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/isp1362-hcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
+index 0e14d1d07709d..b0da143ef4be9 100644
+--- a/drivers/usb/host/isp1362-hcd.c
++++ b/drivers/usb/host/isp1362-hcd.c
+@@ -2170,7 +2170,7 @@ static void create_debug_file(struct isp1362_hcd *isp1362_hcd)
+
+ static void remove_debug_file(struct isp1362_hcd *isp1362_hcd)
+ {
+- debugfs_remove(debugfs_lookup("isp1362", usb_debug_root));
++ debugfs_lookup_and_remove("isp1362", usb_debug_root);
+ }
+
+ /*-------------------------------------------------------------------------*/
+--
+2.39.2
+
--- /dev/null
+From e83790090ce89aa660984d0efb1dbfbfb53f8c7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:26 +0100
+Subject: USB: sl811: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit e1523c4dbc54e164638ff8729d511cf91e27be04 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Link: https://lore.kernel.org/r/20230202153235.2412790-4-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/sl811-hcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
+index d206bd95c7bbc..b8b90eec91078 100644
+--- a/drivers/usb/host/sl811-hcd.c
++++ b/drivers/usb/host/sl811-hcd.c
+@@ -1501,7 +1501,7 @@ static void create_debug_file(struct sl811 *sl811)
+
+ static void remove_debug_file(struct sl811 *sl811)
+ {
+- debugfs_remove(debugfs_lookup("sl811h", usb_debug_root));
++ debugfs_lookup_and_remove("sl811h", usb_debug_root);
+ }
+
+ /*-------------------------------------------------------------------------*/
+--
+2.39.2
+
--- /dev/null
+From ce4920a081620fca860de31edbb1039c9fe78336 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:25 +0100
+Subject: USB: uhci: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 0a3f82c79c86278e7f144564b1cb6cc5c3657144 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20230202153235.2412790-3-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/uhci-hcd.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
+index c22b51af83fcb..7cdc2fa7c28fb 100644
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -536,8 +536,8 @@ static void release_uhci(struct uhci_hcd *uhci)
+ uhci->is_initialized = 0;
+ spin_unlock_irq(&uhci->lock);
+
+- debugfs_remove(debugfs_lookup(uhci_to_hcd(uhci)->self.bus_name,
+- uhci_debugfs_root));
++ debugfs_lookup_and_remove(uhci_to_hcd(uhci)->self.bus_name,
++ uhci_debugfs_root);
+
+ for (i = 0; i < UHCI_NUM_SKELQH; i++)
+ uhci_free_qh(uhci, uhci->skelqh[i]);
+@@ -700,7 +700,7 @@ static int uhci_start(struct usb_hcd *hcd)
+ uhci->frame, uhci->frame_dma_handle);
+
+ err_alloc_frame:
+- debugfs_remove(debugfs_lookup(hcd->self.bus_name, uhci_debugfs_root));
++ debugfs_lookup_and_remove(hcd->self.bus_name, uhci_debugfs_root);
+
+ return retval;
+ }
+--
+2.39.2
+
--- /dev/null
+From 0aef6cae72745774983b94b4c3227090e35afda1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:32:24 +0100
+Subject: USB: ULPI: fix memory leak with using debugfs_lookup()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 8f4d25eba599c4bd4b5ea8ae8752cda480a9d563 ]
+
+When calling debugfs_lookup() the result must have dput() called on it,
+otherwise the memory will leak over time. To make things simpler, just
+call debugfs_lookup_and_remove() instead which handles all of the logic
+at once.
+
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20230202153235.2412790-2-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/common/ulpi.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
+index d7c8461976ce0..38703781ee2d1 100644
+--- a/drivers/usb/common/ulpi.c
++++ b/drivers/usb/common/ulpi.c
+@@ -271,7 +271,7 @@ static int ulpi_regs_show(struct seq_file *seq, void *data)
+ }
+ DEFINE_SHOW_ATTRIBUTE(ulpi_regs);
+
+-#define ULPI_ROOT debugfs_lookup(KBUILD_MODNAME, NULL)
++static struct dentry *ulpi_root;
+
+ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
+ {
+@@ -301,7 +301,7 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
+ return ret;
+ }
+
+- root = debugfs_create_dir(dev_name(dev), ULPI_ROOT);
++ root = debugfs_create_dir(dev_name(dev), ulpi_root);
+ debugfs_create_file("regs", 0444, root, ulpi, &ulpi_regs_fops);
+
+ dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n",
+@@ -349,8 +349,7 @@ EXPORT_SYMBOL_GPL(ulpi_register_interface);
+ */
+ void ulpi_unregister_interface(struct ulpi *ulpi)
+ {
+- debugfs_remove_recursive(debugfs_lookup(dev_name(&ulpi->dev),
+- ULPI_ROOT));
++ debugfs_lookup_and_remove(dev_name(&ulpi->dev), ulpi_root);
+ device_unregister(&ulpi->dev);
+ }
+ EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
+@@ -360,12 +359,11 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
+ static int __init ulpi_init(void)
+ {
+ int ret;
+- struct dentry *root;
+
+- root = debugfs_create_dir(KBUILD_MODNAME, NULL);
++ ulpi_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+ ret = bus_register(&ulpi_bus);
+ if (ret)
+- debugfs_remove(root);
++ debugfs_remove(ulpi_root);
+ return ret;
+ }
+ subsys_initcall(ulpi_init);
+@@ -373,7 +371,7 @@ subsys_initcall(ulpi_init);
+ static void __exit ulpi_exit(void)
+ {
+ bus_unregister(&ulpi_bus);
+- debugfs_remove_recursive(ULPI_ROOT);
++ debugfs_remove(ulpi_root);
+ }
+ module_exit(ulpi_exit);
+
+--
+2.39.2
+
--- /dev/null
+From 776daccdc871480dbcaeea01d75032d5e0e49c41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 11:41:37 +0000
+Subject: usb: uvc: Enumerate valid values for color matching
+
+From: Daniel Scally <dan.scally@ideasonboard.com>
+
+[ Upstream commit e16cab9c1596e251761d2bfb5e1467950d616963 ]
+
+The color matching descriptors defined in the UVC Specification
+contain 3 fields with discrete numeric values representing particular
+settings. Enumerate those values so that later code setting them can
+be more readable.
+
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
+Link: https://lore.kernel.org/r/20230202114142.300858-2-dan.scally@ideasonboard.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/usb/video.h | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
+index bfdae12cdacf8..c58854fb7d94a 100644
+--- a/include/uapi/linux/usb/video.h
++++ b/include/uapi/linux/usb/video.h
+@@ -179,6 +179,36 @@
+ #define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
+ #define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
+
++/* 3.9.2.6 Color Matching Descriptor Values */
++enum uvc_color_primaries_values {
++ UVC_COLOR_PRIMARIES_UNSPECIFIED,
++ UVC_COLOR_PRIMARIES_BT_709_SRGB,
++ UVC_COLOR_PRIMARIES_BT_470_2_M,
++ UVC_COLOR_PRIMARIES_BT_470_2_B_G,
++ UVC_COLOR_PRIMARIES_SMPTE_170M,
++ UVC_COLOR_PRIMARIES_SMPTE_240M,
++};
++
++enum uvc_transfer_characteristics_values {
++ UVC_TRANSFER_CHARACTERISTICS_UNSPECIFIED,
++ UVC_TRANSFER_CHARACTERISTICS_BT_709,
++ UVC_TRANSFER_CHARACTERISTICS_BT_470_2_M,
++ UVC_TRANSFER_CHARACTERISTICS_BT_470_2_B_G,
++ UVC_TRANSFER_CHARACTERISTICS_SMPTE_170M,
++ UVC_TRANSFER_CHARACTERISTICS_SMPTE_240M,
++ UVC_TRANSFER_CHARACTERISTICS_LINEAR,
++ UVC_TRANSFER_CHARACTERISTICS_SRGB,
++};
++
++enum uvc_matrix_coefficients {
++ UVC_MATRIX_COEFFICIENTS_UNSPECIFIED,
++ UVC_MATRIX_COEFFICIENTS_BT_709,
++ UVC_MATRIX_COEFFICIENTS_FCC,
++ UVC_MATRIX_COEFFICIENTS_BT_470_2_B_G,
++ UVC_MATRIX_COEFFICIENTS_SMPTE_170M,
++ UVC_MATRIX_COEFFICIENTS_SMPTE_240M,
++};
++
+ /* ------------------------------------------------------------------------
+ * UVC structures
+ */
+--
+2.39.2
+
--- /dev/null
+From a9a5fad1803034f3ce5a19741a5bfe7b2feb98bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Feb 2023 15:21:41 -0500
+Subject: vc_screen: modify vcs_size() handling in vcs_read()
+
+From: George Kennedy <george.kennedy@oracle.com>
+
+[ Upstream commit 46d733d0efc79bc8430d63b57ab88011806d5180 ]
+
+Restore the vcs_size() handling in vcs_read() to what
+it had been in previous version.
+
+Fixes: 226fae124b2d ("vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF")
+Suggested-by: Jiri Slaby <jirislaby@kernel.org>
+Signed-off-by: George Kennedy <george.kennedy@oracle.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/vt/vc_screen.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
+index 71e091f879f0e..1dc07f9214d57 100644
+--- a/drivers/tty/vt/vc_screen.c
++++ b/drivers/tty/vt/vc_screen.c
+@@ -415,10 +415,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+ */
+ size = vcs_size(vc, attr, uni_mode);
+ if (size < 0) {
+- if (read)
+- break;
+ ret = size;
+- goto unlock_out;
++ break;
+ }
+ if (pos >= size)
+ break;
+--
+2.39.2
+
--- /dev/null
+From 53999cde211bc789044fceabc4dcdae8d132ba20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 17:49:50 +0800
+Subject: watchdog: at91sam9_wdt: use devm_request_irq to avoid missing
+ free_irq() in error path
+
+From: ruanjinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit 07bec0e09c1afbab4c5674fd2341f4f52d594f30 ]
+
+free_irq() is missing in case of error in at91_wdt_init(), use
+devm_request_irq to fix that.
+
+Fixes: 5161b31dc39a ("watchdog: at91sam9_wdt: better watchdog support")
+Signed-off-by: ruanjinjie <ruanjinjie@huawei.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20221116094950.3141943-1-ruanjinjie@huawei.com
+[groeck: Adjust multi-line alignment]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/at91sam9_wdt.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
+index 292b5a1ca8318..fed7be2464420 100644
+--- a/drivers/watchdog/at91sam9_wdt.c
++++ b/drivers/watchdog/at91sam9_wdt.c
+@@ -206,10 +206,9 @@ static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt)
+ "min heartbeat and max heartbeat might be too close for the system to handle it correctly\n");
+
+ if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) {
+- err = request_irq(wdt->irq, wdt_interrupt,
+- IRQF_SHARED | IRQF_IRQPOLL |
+- IRQF_NO_SUSPEND,
+- pdev->name, wdt);
++ err = devm_request_irq(dev, wdt->irq, wdt_interrupt,
++ IRQF_SHARED | IRQF_IRQPOLL | IRQF_NO_SUSPEND,
++ pdev->name, wdt);
+ if (err)
+ return err;
+ }
+--
+2.39.2
+
--- /dev/null
+From 43084b37ef40b89a8229a6b7d9a4ce0b3489f91e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 01:27:14 +0000
+Subject: watchdog: Fix kmemleak in watchdog_cdev_register
+
+From: Chen Jun <chenjun102@huawei.com>
+
+[ Upstream commit 13721a2ac66b246f5802ba1b75ad8637e53eeecc ]
+
+kmemleak reports memory leaks in watchdog_dev_register, as follows:
+unreferenced object 0xffff888116233000 (size 2048):
+ comm ""modprobe"", pid 28147, jiffies 4353426116 (age 61.741s)
+ hex dump (first 32 bytes):
+ 80 fa b9 05 81 88 ff ff 08 30 23 16 81 88 ff ff .........0#.....
+ 08 30 23 16 81 88 ff ff 00 00 00 00 00 00 00 00 .0#.............
+ backtrace:
+ [<000000007f001ffd>] __kmem_cache_alloc_node+0x157/0x220
+ [<000000006a389304>] kmalloc_trace+0x21/0x110
+ [<000000008d640eea>] watchdog_dev_register+0x4e/0x780 [watchdog]
+ [<0000000053c9f248>] __watchdog_register_device+0x4f0/0x680 [watchdog]
+ [<00000000b2979824>] watchdog_register_device+0xd2/0x110 [watchdog]
+ [<000000001f730178>] 0xffffffffc10880ae
+ [<000000007a1a8bcc>] do_one_initcall+0xcb/0x4d0
+ [<00000000b98be325>] do_init_module+0x1ca/0x5f0
+ [<0000000046d08e7c>] load_module+0x6133/0x70f0
+ ...
+
+unreferenced object 0xffff888105b9fa80 (size 16):
+ comm ""modprobe"", pid 28147, jiffies 4353426116 (age 61.741s)
+ hex dump (first 16 bytes):
+ 77 61 74 63 68 64 6f 67 31 00 b9 05 81 88 ff ff watchdog1.......
+ backtrace:
+ [<000000007f001ffd>] __kmem_cache_alloc_node+0x157/0x220
+ [<00000000486ab89b>] __kmalloc_node_track_caller+0x44/0x1b0
+ [<000000005a39aab0>] kvasprintf+0xb5/0x140
+ [<0000000024806f85>] kvasprintf_const+0x55/0x180
+ [<000000009276cb7f>] kobject_set_name_vargs+0x56/0x150
+ [<00000000a92e820b>] dev_set_name+0xab/0xe0
+ [<00000000cec812c6>] watchdog_dev_register+0x285/0x780 [watchdog]
+ [<0000000053c9f248>] __watchdog_register_device+0x4f0/0x680 [watchdog]
+ [<00000000b2979824>] watchdog_register_device+0xd2/0x110 [watchdog]
+ [<000000001f730178>] 0xffffffffc10880ae
+ [<000000007a1a8bcc>] do_one_initcall+0xcb/0x4d0
+ [<00000000b98be325>] do_init_module+0x1ca/0x5f0
+ [<0000000046d08e7c>] load_module+0x6133/0x70f0
+ ...
+
+The reason is that put_device is not be called if cdev_device_add fails
+and wdd->id != 0.
+
+watchdog_cdev_register
+ wd_data = kzalloc [1]
+ err = dev_set_name [2]
+ ..
+ err = cdev_device_add
+ if (err) {
+ if (wdd->id == 0) { // wdd->id != 0
+ ..
+ }
+ return err; // [1],[2] would be leaked
+
+To fix it, call put_device in all wdd->id cases.
+
+Fixes: 72139dfa2464 ("watchdog: Fix the race between the release of watchdog_core_data and cdev")
+Signed-off-by: Chen Jun <chenjun102@huawei.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20221116012714.102066-1-chenjun102@huawei.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/watchdog_dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
+index 55574ed425042..fdffa6859dde3 100644
+--- a/drivers/watchdog/watchdog_dev.c
++++ b/drivers/watchdog/watchdog_dev.c
+@@ -1061,8 +1061,8 @@ static int watchdog_cdev_register(struct watchdog_device *wdd)
+ if (wdd->id == 0) {
+ misc_deregister(&watchdog_miscdev);
+ old_wd_data = NULL;
+- put_device(&wd_data->dev);
+ }
++ put_device(&wd_data->dev);
+ return err;
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 714774f60691528dbf24efb7696324b4c2c8f92d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Nov 2022 10:07:06 +0800
+Subject: watchdog: pcwd_usb: Fix attempting to access uninitialized memory
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Li Hua <hucool.lihua@huawei.com>
+
+[ Upstream commit 7d06c07c67100fd0f8e6b3ab7145ce789f788117 ]
+
+The stack variable msb and lsb may be used uninitialized in function
+usb_pcwd_get_temperature and usb_pcwd_get_timeleft when usb card no response.
+
+The build waring is:
+drivers/watchdog/pcwd_usb.c:336:22: error: ‘lsb’ is used uninitialized in this function [-Werror=uninitialized]
+ *temperature = (lsb * 9 / 5) + 32;
+ ~~~~^~~
+drivers/watchdog/pcwd_usb.c:328:21: note: ‘lsb’ was declared here
+ unsigned char msb, lsb;
+ ^~~
+cc1: all warnings being treated as errors
+scripts/Makefile.build:250: recipe for target 'drivers/watchdog/pcwd_usb.o' failed
+make[3]: *** [drivers/watchdog/pcwd_usb.o] Error 1
+
+Fixes: b7e04f8c61a4 ("mv watchdog tree under drivers")
+Signed-off-by: Li Hua <hucool.lihua@huawei.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20221116020706.70847-1-hucool.lihua@huawei.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/pcwd_usb.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
+index 1bdaf17c1d38d..8202f0a6b0935 100644
+--- a/drivers/watchdog/pcwd_usb.c
++++ b/drivers/watchdog/pcwd_usb.c
+@@ -325,7 +325,8 @@ static int usb_pcwd_set_heartbeat(struct usb_pcwd_private *usb_pcwd, int t)
+ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd,
+ int *temperature)
+ {
+- unsigned char msb, lsb;
++ unsigned char msb = 0x00;
++ unsigned char lsb = 0x00;
+
+ usb_pcwd_send_command(usb_pcwd, CMD_READ_TEMP, &msb, &lsb);
+
+@@ -341,7 +342,8 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd,
+ static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd,
+ int *time_left)
+ {
+- unsigned char msb, lsb;
++ unsigned char msb = 0x00;
++ unsigned char lsb = 0x00;
+
+ /* Read the time that's left before rebooting */
+ /* Note: if the board is not yet armed then we will read 0xFFFF */
+--
+2.39.2
+
--- /dev/null
+From 529ce0881a928985c112aa8ae6e461ac1067b231 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 11:49:07 +0000
+Subject: watchdog: rzg2l_wdt: Handle TYPE-B reset for RZ/V2M
+
+From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+
+[ Upstream commit f769f97917c1e756e12ff042a93f6e3167254b5b ]
+
+As per section 48.4 of the HW User Manual, IPs in the RZ/V2M
+SoC need either a TYPE-A reset sequence or a TYPE-B reset
+sequence. More specifically, the watchdog IP needs a TYPE-B
+reset sequence.
+
+If the proper reset sequence isn't implemented, then resetting
+IPs may lead to undesired behaviour. In the restart callback of
+the watchdog driver the reset has basically no effect on the
+desired funcionality, as the register writes following the reset
+happen before the IP manages to come out of reset.
+
+Implement the TYPE-B reset sequence in the watchdog driver to
+address the issues with the restart callback on RZ/V2M.
+
+Fixes: ec122fd94eeb ("watchdog: rzg2l_wdt: Add rzv2m support")
+Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20221117114907.138583-3-fabrizio.castro.jz@renesas.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/rzg2l_wdt.c | 37 +++++++++++++++++++++++++++++++++++-
+ 1 file changed, 36 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c
+index ceca42db08374..d404953d0e0f4 100644
+--- a/drivers/watchdog/rzg2l_wdt.c
++++ b/drivers/watchdog/rzg2l_wdt.c
+@@ -8,6 +8,7 @@
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/of_device.h>
+@@ -35,6 +36,8 @@
+
+ #define F2CYCLE_NSEC(f) (1000000000 / (f))
+
++#define RZV2M_A_NSEC 730
++
+ static bool nowayout = WATCHDOG_NOWAYOUT;
+ module_param(nowayout, bool, 0);
+ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+@@ -51,11 +54,35 @@ struct rzg2l_wdt_priv {
+ struct reset_control *rstc;
+ unsigned long osc_clk_rate;
+ unsigned long delay;
++ unsigned long minimum_assertion_period;
+ struct clk *pclk;
+ struct clk *osc_clk;
+ enum rz_wdt_type devtype;
+ };
+
++static int rzg2l_wdt_reset(struct rzg2l_wdt_priv *priv)
++{
++ int err, status;
++
++ if (priv->devtype == WDT_RZV2M) {
++ /* WDT needs TYPE-B reset control */
++ err = reset_control_assert(priv->rstc);
++ if (err)
++ return err;
++ ndelay(priv->minimum_assertion_period);
++ err = reset_control_deassert(priv->rstc);
++ if (err)
++ return err;
++ err = read_poll_timeout(reset_control_status, status,
++ status != 1, 0, 1000, false,
++ priv->rstc);
++ } else {
++ err = reset_control_reset(priv->rstc);
++ }
++
++ return err;
++}
++
+ static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv)
+ {
+ /* delay timer when change the setting register */
+@@ -115,7 +142,7 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev)
+ {
+ struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
+
+- reset_control_reset(priv->rstc);
++ rzg2l_wdt_reset(priv);
+ pm_runtime_put(wdev->parent);
+
+ return 0;
+@@ -154,6 +181,7 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
+ rzg2l_wdt_write(priv, PEEN_FORCE, PEEN);
+ } else {
+ /* RZ/V2M doesn't have parity error registers */
++ rzg2l_wdt_reset(priv);
+
+ wdev->timeout = 0;
+
+@@ -251,6 +279,13 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
+
+ priv->devtype = (uintptr_t)of_device_get_match_data(dev);
+
++ if (priv->devtype == WDT_RZV2M) {
++ priv->minimum_assertion_period = RZV2M_A_NSEC +
++ 3 * F2CYCLE_NSEC(pclk_rate) + 5 *
++ max(F2CYCLE_NSEC(priv->osc_clk_rate),
++ F2CYCLE_NSEC(pclk_rate));
++ }
++
+ pm_runtime_enable(&pdev->dev);
+
+ priv->wdev.info = &rzg2l_wdt_ident;
+--
+2.39.2
+
--- /dev/null
+From b6ad9d40acbb2cd6ae7836784083dd5cfbbffc95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 11:49:06 +0000
+Subject: watchdog: rzg2l_wdt: Issue a reset before we put the PM clocks
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit 6ba6f0f5910d5916539268c0ad55657bb8940616 ]
+
+On RZ/Five SoC it was observed that setting timeout (to say 1 sec) wouldn't
+reset the system.
+
+The procedure described in the HW manual (Procedure for Activating Modules)
+for activating the target module states we need to start supply of the
+clock module before applying the reset signal. This patch makes sure we
+follow the same procedure to clear the registers of the WDT module, fixing
+the issues seen on RZ/Five SoC.
+
+While at it re-used rzg2l_wdt_stop() in rzg2l_wdt_set_timeout() as it has
+the same function calls.
+
+Fixes: 4055ee81009e ("watchdog: rzg2l_wdt: Add set_timeout callback")
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
+Link: https://lore.kernel.org/r/20221117114907.138583-2-fabrizio.castro.jz@renesas.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/rzg2l_wdt.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c
+index 974a4194a8fd6..ceca42db08374 100644
+--- a/drivers/watchdog/rzg2l_wdt.c
++++ b/drivers/watchdog/rzg2l_wdt.c
+@@ -115,25 +115,23 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev)
+ {
+ struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
+
+- pm_runtime_put(wdev->parent);
+ reset_control_reset(priv->rstc);
++ pm_runtime_put(wdev->parent);
+
+ return 0;
+ }
+
+ static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout)
+ {
+- struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
+-
+ wdev->timeout = timeout;
+
+ /*
+ * If the watchdog is active, reset the module for updating the WDTSET
+- * register so that it is updated with new timeout values.
++ * register by calling rzg2l_wdt_stop() (which internally calls reset_control_reset()
++ * to reset the module) so that it is updated with new timeout values.
+ */
+ if (watchdog_active(wdev)) {
+- pm_runtime_put(wdev->parent);
+- reset_control_reset(priv->rstc);
++ rzg2l_wdt_stop(wdev);
+ rzg2l_wdt_start(wdev);
+ }
+
+--
+2.39.2
+
--- /dev/null
+From 11a7632d5b71e36c1ac271517fdbbb79874484de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 02:11:17 +0000
+Subject: watchdog: sbsa_wdog: Make sure the timeout programming is within the
+ limits
+
+From: George Cherian <george.cherian@marvell.com>
+
+[ Upstream commit 000987a38b53c172f435142a4026dd71378ca464 ]
+
+Make sure to honour the max_hw_heartbeat_ms while programming the timeout
+value to WOR. Clamp the timeout passed to sbsa_gwdt_set_timeout() to
+make sure the programmed value is within the permissible range.
+
+Fixes: abd3ac7902fb ("watchdog: sbsa: Support architecture version 1")
+
+Signed-off-by: George Cherian <george.cherian@marvell.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20230209021117.1512097-1-george.cherian@marvell.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/sbsa_gwdt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
+index 9791c74aebd48..63862803421f1 100644
+--- a/drivers/watchdog/sbsa_gwdt.c
++++ b/drivers/watchdog/sbsa_gwdt.c
+@@ -150,6 +150,7 @@ static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd,
+ struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
+
+ wdd->timeout = timeout;
++ timeout = clamp_t(unsigned int, timeout, 1, wdd->max_hw_heartbeat_ms / 1000);
+
+ if (action)
+ sbsa_gwdt_reg_write(gwdt->clk * timeout, gwdt);
+--
+2.39.2
+
--- /dev/null
+From a2bf65800fd6c51d757420bfb3e44f059f56d3b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Dec 2022 00:23:38 +0700
+Subject: x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list
+
+From: Ammar Faizi <ammarfaizi2@gnuweeb.org>
+
+[ Upstream commit 5541992e512de8c9133110809f767bd1b54ee10d ]
+
+The 'syscall' instruction clobbers '%rcx' and '%r11', but they are not
+listed in the inline Assembly that performs the syscall instruction.
+
+No real bug is found. It wasn't buggy by luck because '%rcx' and '%r11'
+are caller-saved registers, and not used in the functions, and the
+functions are never inlined.
+
+Add them to the clobber list for code correctness.
+
+Fixes: f1c2bb8b9964ed31de988910f8b1cfb586d30091 ("um: implement a x86_64 vDSO")
+Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/um/vdso/um_vdso.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/um/vdso/um_vdso.c b/arch/x86/um/vdso/um_vdso.c
+index 2112b8d146688..ff0f3b4b6c45e 100644
+--- a/arch/x86/um/vdso/um_vdso.c
++++ b/arch/x86/um/vdso/um_vdso.c
+@@ -17,8 +17,10 @@ int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts)
+ {
+ long ret;
+
+- asm("syscall" : "=a" (ret) :
+- "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory");
++ asm("syscall"
++ : "=a" (ret)
++ : "0" (__NR_clock_gettime), "D" (clock), "S" (ts)
++ : "rcx", "r11", "memory");
+
+ return ret;
+ }
+@@ -29,8 +31,10 @@ int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
+ {
+ long ret;
+
+- asm("syscall" : "=a" (ret) :
+- "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
++ asm("syscall"
++ : "=a" (ret)
++ : "0" (__NR_gettimeofday), "D" (tv), "S" (tz)
++ : "rcx", "r11", "memory");
+
+ return ret;
+ }
+--
+2.39.2
+