From: Sasha Levin Date: Fri, 10 Mar 2023 10:31:48 +0000 (-0500) Subject: Fixes for 6.2 X-Git-Tag: v6.1.17~46^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6d94e7e95a57c0470d7e41be3994136df645bd4f;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.2 Signed-off-by: Sasha Levin --- diff --git a/queue-6.2/9p-rdma-unmap-receive-dma-buffer-in-rdma_request-pos.patch b/queue-6.2/9p-rdma-unmap-receive-dma-buffer-in-rdma_request-pos.patch new file mode 100644 index 00000000000..a2fa3f78b66 --- /dev/null +++ b/queue-6.2/9p-rdma-unmap-receive-dma-buffer-in-rdma_request-pos.patch @@ -0,0 +1,79 @@ +From 09cbff7b627a1fefa35763930b8b0f77c1fb6c10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Jan 2023 10:04:24 +0800 +Subject: 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv() + +From: Zhengchao Shao + +[ 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 +Reviewed-by: Leon Romanovsky +Signed-off-by: Dominique Martinet +Signed-off-by: Eric Van Hensbergen +Signed-off-by: Sasha Levin +--- + 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 83f9100d46bff..b84748baf9cbe 100644 +--- a/net/9p/trans_rdma.c ++++ b/net/9p/trans_rdma.c +@@ -385,6 +385,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, +@@ -402,7 +403,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"); +@@ -499,7 +505,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, +@@ -509,11 +515,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 + diff --git a/queue-6.2/9p-xen-fix-connection-sequence.patch b/queue-6.2/9p-xen-fix-connection-sequence.patch new file mode 100644 index 00000000000..01d5bd7d297 --- /dev/null +++ b/queue-6.2/9p-xen-fix-connection-sequence.patch @@ -0,0 +1,117 @@ +From 88ec6c4b32bea1084096be840ab6bf642704182a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Jan 2023 12:30:36 +0100 +Subject: 9p/xen: fix connection sequence + +From: Juergen Gross + +[ 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 +Reviewed-by: Simon Horman +Signed-off-by: Dominique Martinet +Signed-off-by: Eric Van Hensbergen +Signed-off-by: Sasha Levin +--- + 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 ad2947a3b3760..c64050e839ac6 100644 +--- a/net/9p/trans_xen.c ++++ b/net/9p/trans_xen.c +@@ -372,12 +372,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; + +@@ -405,11 +404,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); +@@ -468,23 +462,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"); +@@ -503,6 +509,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 + diff --git a/queue-6.2/9p-xen-fix-version-parsing.patch b/queue-6.2/9p-xen-fix-version-parsing.patch new file mode 100644 index 00000000000..c66aa207046 --- /dev/null +++ b/queue-6.2/9p-xen-fix-version-parsing.patch @@ -0,0 +1,63 @@ +From 3cca9343904c9ef132d9af77acf32883ea618e37 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Jan 2023 12:30:35 +0100 +Subject: 9p/xen: fix version parsing + +From: Juergen Gross + +[ 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 +Reviewed-by: Simon Horman +Signed-off-by: Dominique Martinet +Signed-off-by: Eric Van Hensbergen +Signed-off-by: Sasha Levin +--- + 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 82c7005ede656..ad2947a3b3760 100644 +--- a/net/9p/trans_xen.c ++++ b/net/9p/trans_xen.c +@@ -378,13 +378,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 + diff --git a/queue-6.2/arm-dts-aspeed-p10bmc-update-battery-node-name.patch b/queue-6.2/arm-dts-aspeed-p10bmc-update-battery-node-name.patch new file mode 100644 index 00000000000..d4f0d091a8c --- /dev/null +++ b/queue-6.2/arm-dts-aspeed-p10bmc-update-battery-node-name.patch @@ -0,0 +1,67 @@ +From 0439559387590c6a48d994b9edc411973471885a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Feb 2023 11:03:52 +1030 +Subject: ARM: dts: aspeed: p10bmc: Update battery node name + +From: Eddie James + +[ Upstream commit a8cef541dd5ef9445130660008c029205c4c5aa5 ] + +The ADC sensor for the battery needs to be named "iio-hwmon" for +compatibility with user space applications. + +Signed-off-by: Eddie James +Link: https://lore.kernel.org/r/20230202152759.67069-1-eajames@linux.ibm.com +Fixes: bf1914e2cfed ("ARM: dts: aspeed: p10bmc: Fix ADC iio-hwmon battery node name") +Signed-off-by: Joel Stanley +Link: https://lore.kernel.org/r/20230221003352.1218797-1-joel@jms.id.au +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts | 2 +- + arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts | 2 +- + arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts +index 7f755e5a4624d..d9b684ccb0956 100644 +--- a/arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts ++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts +@@ -124,7 +124,7 @@ + }; + }; + +- iio-hwmon-battery { ++ iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc1 7>; + }; +diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts +index 1448ea895be43..8ad5fe9c29900 100644 +--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts ++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts +@@ -244,7 +244,7 @@ + }; + }; + +- iio-hwmon-battery { ++ iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc1 7>; + }; +diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +index 20ef958698ec7..a3c55a0cc833e 100644 +--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts ++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +@@ -220,7 +220,7 @@ + }; + }; + +- iio-hwmon-battery { ++ iio-hwmon { + compatible = "iio-hwmon"; + io-channels = <&adc1 7>; + }; +-- +2.39.2 + diff --git a/queue-6.2/arm-dts-spear320-hmi-correct-stmpe-gpio-compatible.patch b/queue-6.2/arm-dts-spear320-hmi-correct-stmpe-gpio-compatible.patch new file mode 100644 index 00000000000..51cfad57a52 --- /dev/null +++ b/queue-6.2/arm-dts-spear320-hmi-correct-stmpe-gpio-compatible.patch @@ -0,0 +1,37 @@ +From 8f02169a558ce41ef7291da0e7d10a2a752feb7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Feb 2023 17:22:37 +0100 +Subject: ARM: dts: spear320-hmi: correct STMPE GPIO compatible + +From: Krzysztof Kozlowski + +[ 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 +Acked-by: Viresh Kumar +Link: https://lore.kernel.org/r/20230225162237.40242-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/asoc-adau7118-don-t-disable-regulators-on-device-unb.patch b/queue-6.2/asoc-adau7118-don-t-disable-regulators-on-device-unb.patch new file mode 100644 index 00000000000..f159498d1cf --- /dev/null +++ b/queue-6.2/asoc-adau7118-don-t-disable-regulators-on-device-unb.patch @@ -0,0 +1,66 @@ +From cfb93f9f4c935991d24de066ffabded3e98b7372 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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á + +[ 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á +Link: https://lore.kernel.org/r/20230224104551.1139981-1-nuno.sa@analog.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/asoc-apple-mca-fix-final-status-read-on-serdes-reset.patch b/queue-6.2/asoc-apple-mca-fix-final-status-read-on-serdes-reset.patch new file mode 100644 index 00000000000..1af84d09688 --- /dev/null +++ b/queue-6.2/asoc-apple-mca-fix-final-status-read-on-serdes-reset.patch @@ -0,0 +1,41 @@ +From 66ff8cfeed95770d4413153d313178fc5c4fe9ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230224153302.45365-1-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/asoc-apple-mca-fix-serdes-reset-sequence.patch b/queue-6.2/asoc-apple-mca-fix-serdes-reset-sequence.patch new file mode 100644 index 00000000000..38958ac9130 --- /dev/null +++ b/queue-6.2/asoc-apple-mca-fix-serdes-reset-sequence.patch @@ -0,0 +1,79 @@ +From 806da3689f886d320ca42cd45fe6b736a4de82b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230224153302.45365-2-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/asoc-apple-mca-improve-handling-of-unavailable-dma-c.patch b/queue-6.2/asoc-apple-mca-improve-handling-of-unavailable-dma-c.patch new file mode 100644 index 00000000000..c8389e74cb8 --- /dev/null +++ b/queue-6.2/asoc-apple-mca-improve-handling-of-unavailable-dma-c.patch @@ -0,0 +1,53 @@ +From 5ce1b7da58735d653366ba0560431f3802654435 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230224153302.45365-3-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/asoc-mediatek-mt8195-add-missing-initialization.patch b/queue-6.2/asoc-mediatek-mt8195-add-missing-initialization.patch new file mode 100644 index 00000000000..f2c6d0a4147 --- /dev/null +++ b/queue-6.2/asoc-mediatek-mt8195-add-missing-initialization.patch @@ -0,0 +1,45 @@ +From 4fc2aefa77dbc5d877764c8700c98f8d1586a555 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Mar 2023 19:02:00 +0800 +Subject: ASoC: mediatek: mt8195: add missing initialization + +From: Trevor Wu + +[ 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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230301110200.26177-3-trevor.wu@mediatek.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/asoc-zl38060-add-gpiolib-dependency.patch b/queue-6.2/asoc-zl38060-add-gpiolib-dependency.patch new file mode 100644 index 00000000000..488e543a155 --- /dev/null +++ b/queue-6.2/asoc-zl38060-add-gpiolib-dependency.patch @@ -0,0 +1,44 @@ +From 58bc5ee2d73b158b1de0fe9c0ce7b69bdc458711 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Feb 2023 09:58:26 +0100 +Subject: ASoC: zl38060 add gpiolib dependency + +From: Arnd Bergmann + +[ 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 +Link: https://lore.kernel.org/r/20230227085850.2503725-1-arnd@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 0f9d71490075f..ac2a2bfdaf37a 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -2045,6 +2045,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 + diff --git a/queue-6.2/auxdisplay-hd44780-fix-potential-memory-leak-in-hd44.patch b/queue-6.2/auxdisplay-hd44780-fix-potential-memory-leak-in-hd44.patch new file mode 100644 index 00000000000..665341dc166 --- /dev/null +++ b/queue-6.2/auxdisplay-hd44780-fix-potential-memory-leak-in-hd44.patch @@ -0,0 +1,45 @@ +From ab57d1ced2d0badc5a0abf20a692373d67663e4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Nov 2022 16:15:42 +0800 +Subject: auxdisplay: hd44780: Fix potential memory leak in hd44780_remove() + +From: Jianglei Nie + +[ 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 +Reported-by: kernel test robot +Signed-off-by: Jianglei Nie +Signed-off-by: Miguel Ojeda +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/bootconfig-increase-max-nodes-of-bootconfig-from-102.patch b/queue-6.2/bootconfig-increase-max-nodes-of-bootconfig-from-102.patch new file mode 100644 index 00000000000..b5f56bab100 --- /dev/null +++ b/queue-6.2/bootconfig-increase-max-nodes-of-bootconfig-from-102.patch @@ -0,0 +1,41 @@ +From 143e0d885f4a062f2ff8b749e8ffb09b3a348a2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Masami Hiramatsu (Google) +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/bus-mhi-ep-fix-the-debug-message-for-mhi_pkt_type_re.patch b/queue-6.2/bus-mhi-ep-fix-the-debug-message-for-mhi_pkt_type_re.patch new file mode 100644 index 00000000000..88eaf0313f5 --- /dev/null +++ b/queue-6.2/bus-mhi-ep-fix-the-debug-message-for-mhi_pkt_type_re.patch @@ -0,0 +1,38 @@ +From bc35f9c93c019f797a3e4a1a1d38345891e3f27a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit 8e697fcfdb9809634e268058ca743369c216b7ac ] + +The debug log incorrectly mentions that STOP command is received instead of +RESET command. Fix that. + +Signed-off-by: Manivannan Sadhasivam +Reviewed-by: Jeffrey Hugo +Link: https://lore.kernel.org/r/20221228161704.255268-5-manivannan.sadhasivam@linaro.org +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/cacheinfo-fix-shared_cpu_map-to-handle-shared-caches.patch b/queue-6.2/cacheinfo-fix-shared_cpu_map-to-handle-shared-caches.patch new file mode 100644 index 00000000000..73a35456685 --- /dev/null +++ b/queue-6.2/cacheinfo-fix-shared_cpu_map-to-handle-shared-caches.patch @@ -0,0 +1,95 @@ +From d3d69cb54a7db4055e487e1357891a01745ceafb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Yong-Xuan Wang +Link: https://lore.kernel.org/r/20230117105133.4445-2-yongxuan.wang@sifive.com +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + 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 950b22cdb5f7c..f05acf3c16c6b 100644 +--- a/drivers/base/cacheinfo.c ++++ b/drivers/base/cacheinfo.c +@@ -256,7 +256,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) +@@ -284,11 +284,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 */ +@@ -302,7 +304,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); +@@ -313,9 +315,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; ++ } ++ } + } + } + } +-- +2.39.2 + diff --git a/queue-6.2/cpufreq-apple-soc-fix-an-is_err-vs-null-check.patch b/queue-6.2/cpufreq-apple-soc-fix-an-is_err-vs-null-check.patch new file mode 100644 index 00000000000..003fc6b58e9 --- /dev/null +++ b/queue-6.2/cpufreq-apple-soc-fix-an-is_err-vs-null-check.patch @@ -0,0 +1,39 @@ +From 10e275be074b58d581454f3cfd1deb0ee569750c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Feb 2023 13:07:09 +0300 +Subject: cpufreq: apple-soc: Fix an IS_ERR() vs NULL check + +From: Dan Carpenter + +[ Upstream commit f43523620f646c89ffd8ada840a0068290e51266 ] + +The of_iomap() function returns NULL if it fails. It never returns +error pointers. Fix the check accordingly. + +Fixes: 6286bbb40576 ("cpufreq: apple-soc: Add new driver to control Apple SoC CPU P-states") +Signed-off-by: Dan Carpenter +Reviewed-by: Eric Curtin +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/apple-soc-cpufreq.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c +index c11d22fd84c37..021f423705e1b 100644 +--- a/drivers/cpufreq/apple-soc-cpufreq.c ++++ b/drivers/cpufreq/apple-soc-cpufreq.c +@@ -189,8 +189,8 @@ static int apple_soc_cpufreq_find_cluster(struct cpufreq_policy *policy, + *info = match->data; + + *reg_base = of_iomap(args.np, 0); +- if (IS_ERR(*reg_base)) +- return PTR_ERR(*reg_base); ++ if (!*reg_base) ++ return -ENOMEM; + + return 0; + } +-- +2.39.2 + diff --git a/queue-6.2/driver-soc-xilinx-fix-memory-leak-in-xlnx_add_cb_for.patch b/queue-6.2/driver-soc-xilinx-fix-memory-leak-in-xlnx_add_cb_for.patch new file mode 100644 index 00000000000..cdd8bc3d86f --- /dev/null +++ b/queue-6.2/driver-soc-xilinx-fix-memory-leak-in-xlnx_add_cb_for.patch @@ -0,0 +1,43 @@ +From 11e31c67f4b99c5e70dcff16c2005b5009fe42c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Michal Simek +Link: https://lore.kernel.org/r/20221129010146.1026685-1-cuigaosheng1@huawei.com +Signed-off-by: Michal Simek +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/drivers-base-component-fix-memory-leak-with-using-de.patch b/queue-6.2/drivers-base-component-fix-memory-leak-with-using-de.patch new file mode 100644 index 00000000000..62d975d039a --- /dev/null +++ b/queue-6.2/drivers-base-component-fix-memory-leak-with-using-de.patch @@ -0,0 +1,38 @@ +From 573f96de2ec7ca8b770d4b28ba5807646aa48883 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 15:16:20 +0100 +Subject: drivers: base: component: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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" +Link: https://lore.kernel.org/r/20230202141621.2296458-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/drivers-base-dd-fix-memory-leak-with-using-debugfs_l.patch b/queue-6.2/drivers-base-dd-fix-memory-leak-with-using-debugfs_l.patch new file mode 100644 index 00000000000..78fb7a48452 --- /dev/null +++ b/queue-6.2/drivers-base-dd-fix-memory-leak-with-using-debugfs_l.patch @@ -0,0 +1,38 @@ +From 30f35e559a52f29e721d4592c1cb79c1a5b298d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 15:16:21 +0100 +Subject: drivers: base: dd: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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" +Link: https://lore.kernel.org/r/20230202141621.2296458-2-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 e9b2f9c25efe4..959fe018d0dd7 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 + diff --git a/queue-6.2/drm-i915-move-a-kconfig-symbol-to-unbreak-the-menu-p.patch b/queue-6.2/drm-i915-move-a-kconfig-symbol-to-unbreak-the-menu-p.patch new file mode 100644 index 00000000000..151edbef373 --- /dev/null +++ b/queue-6.2/drm-i915-move-a-kconfig-symbol-to-unbreak-the-menu-p.patch @@ -0,0 +1,61 @@ +From 0460a54de8cb4497041aaf35c29b23aed159166e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Feb 2023 20:45:33 -0800 +Subject: drm/i915: move a Kconfig symbol to unbreak the menu presentation + +From: Randy Dunlap + +[ 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 +Cc: Christoph Hellwig +Cc: Zhi Wang +Cc: Jani Nikula +Cc: Joonas Lahtinen +Cc: Rodrigo Vivi +Cc: Tvrtko Ursulin +Cc: Zhenyu Wang +Cc: intel-gfx@lists.freedesktop.org +Cc: intel-gvt-dev@lists.freedesktop.org +Cc: dri-devel@lists.freedesktop.org +Reviewed-by: Christoph Hellwig +Acked-by: Zhenyu Wang +Signed-off-by: Zhenyu Wang +Link: http://patchwork.freedesktop.org/patch/msgid/20230215044533.4847-1-rdunlap@infradead.org +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/drm-i915-xelpmp-consider-gsi-offset-when-doing-mcr-l.patch b/queue-6.2/drm-i915-xelpmp-consider-gsi-offset-when-doing-mcr-l.patch new file mode 100644 index 00000000000..f37b534809f --- /dev/null +++ b/queue-6.2/drm-i915-xelpmp-consider-gsi-offset-when-doing-mcr-l.patch @@ -0,0 +1,49 @@ +From 819bb412c9eb27fcf2dd69d9d1f94d7c19785d07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Feb 2023 16:19:06 -0800 +Subject: drm/i915/xelpmp: Consider GSI offset when doing MCR lookups + +From: Matt Roper + +[ Upstream commit 33c25354939099b76ecb6c82d1c7c50400fbcca6 ] + +MCR range tables use the final MMIO offset of a register (including the +0x380000 GSI offset when applicable). Since the i915_mcr_reg_t passed +as a parameter during steering lookup does not include the GSI offset, +we need to add it back in for GSI registers before searching the tables. + +Fixes: a7ec65fc7e83 ("drm/i915/xelpmp: Add multicast steering for media GT") +Signed-off-by: Matt Roper +Reviewed-by: Radhakrishna Sripada +Link: https://patchwork.freedesktop.org/patch/msgid/20230214001906.1477370-1-matthew.d.roper@intel.com +(cherry picked from commit d6683bbe70d4cdbf3da6acecf7d569cc6f0b4382) +Signed-off-by: Jani Nikula +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c +index 58ea3325bbdaa..fa2b9c48f39b2 100644 +--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c ++++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c +@@ -464,12 +464,15 @@ static bool reg_needs_read_steering(struct intel_gt *gt, + i915_mcr_reg_t reg, + enum intel_steering_type type) + { +- const u32 offset = i915_mmio_reg_offset(reg); ++ u32 offset = i915_mmio_reg_offset(reg); + const struct intel_mmio_range *entry; + + if (likely(!gt->steering_table[type])) + return false; + ++ if (IS_GSI_REG(offset)) ++ offset += gt->uncore->gsi_offset; ++ + for (entry = gt->steering_table[type]; entry->end; entry++) { + if (offset >= entry->start && offset <= entry->end) + return true; +-- +2.39.2 + diff --git a/queue-6.2/dt-bindings-usb-add-device-id-for-genesys-logic-hub-.patch b/queue-6.2/dt-bindings-usb-add-device-id-for-genesys-logic-hub-.patch new file mode 100644 index 00000000000..69bf06f3327 --- /dev/null +++ b/queue-6.2/dt-bindings-usb-add-device-id-for-genesys-logic-hub-.patch @@ -0,0 +1,36 @@ +From 8e7fef874788852433fcd80a496a90bfa18c8767 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Jan 2023 04:44:09 +0000 +Subject: dt-bindings: usb: Add device id for Genesys Logic hub controller + +From: Anand Moon + +[ Upstream commit b72654148e34c181f532275d03ef6f37de288f24 ] + +Add usb hub device id for Genesys Logic, Inc. GL852G Hub USB 2.0 +root hub. + +Signed-off-by: Anand Moon +Acked-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20230118044418.875-2-linux.amoon@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/usb/genesys,gl850g.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml +index a9f831448ccae..cc4cf92b70d18 100644 +--- a/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml ++++ b/Documentation/devicetree/bindings/usb/genesys,gl850g.yaml +@@ -16,6 +16,7 @@ properties: + compatible: + enum: + - usb5e3,608 ++ - usb5e3,610 + + reg: true + +-- +2.39.2 + diff --git a/queue-6.2/ext4-don-t-show-commit-interval-if-it-is-zero.patch b/queue-6.2/ext4-don-t-show-commit-interval-if-it-is-zero.patch new file mode 100644 index 00000000000..dae97e5abb7 --- /dev/null +++ b/queue-6.2/ext4-don-t-show-commit-interval-if-it-is-zero.patch @@ -0,0 +1,36 @@ +From d6e3853d89cdea50db06817977c2f4485f194e69 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Dec 2022 09:51:28 +0800 +Subject: ext4: don't show commit interval if it is zero + +From: Wang Jianjian + +[ 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 +Link: https://lore.kernel.org/r/20221219015128.876717-1-wangjianjian3@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + 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 260c1b3e3ef2c..3b9e30e1afd91 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 + diff --git a/queue-6.2/ext4-fix-incorrect-options-show-of-original-mount_op.patch b/queue-6.2/ext4-fix-incorrect-options-show-of-original-mount_op.patch new file mode 100644 index 00000000000..c3ed2a79d7b --- /dev/null +++ b/queue-6.2/ext4-fix-incorrect-options-show-of-original-mount_op.patch @@ -0,0 +1,116 @@ +From 0c53de384dd2a085c939f48031d339fa2af884a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20230129034939.3702550-1-yi.zhang@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + 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 140e1eb300d17..6479146140d20 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 3b9e30e1afd91..c81fa0fa9901a 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) +@@ -5086,6 +5099,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 + diff --git a/queue-6.2/ext4-use-ext4_fc_tl_mem-in-fast-commit-replay-path.patch b/queue-6.2/ext4-use-ext4_fc_tl_mem-in-fast-commit-replay-path.patch new file mode 100644 index 00000000000..002823cfdbe --- /dev/null +++ b/queue-6.2/ext4-use-ext4_fc_tl_mem-in-fast-commit-replay-path.patch @@ -0,0 +1,143 @@ +From d42e161ef0380896948f1525e5480ed41a8912f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Dec 2022 21:02:12 -0800 +Subject: ext4: use ext4_fc_tl_mem in fast-commit replay path + +From: Eric Biggers + +[ 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 +Signed-off-by: Eric Biggers +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20221217050212.150665-1-ebiggers@kernel.org +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + 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 4594b62f147bb..b06de728b3b6c 100644 +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -1332,8 +1332,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; + +@@ -1345,16 +1351,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; +@@ -1451,8 +1459,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; +@@ -1506,8 +1514,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; +@@ -1609,8 +1617,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; +@@ -1708,7 +1716,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; +@@ -1828,8 +1836,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; +@@ -2025,7 +2033,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; +@@ -2144,7 +2152,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 + diff --git a/queue-6.2/f2fs-allow-set-compression-option-of-files-without-b.patch b/queue-6.2/f2fs-allow-set-compression-option-of-files-without-b.patch new file mode 100644 index 00000000000..a54659c2b41 --- /dev/null +++ b/queue-6.2/f2fs-allow-set-compression-option-of-files-without-b.patch @@ -0,0 +1,37 @@ +From 94a9617d6ac92cfc6e76a7d603b316f1113ed8b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Jan 2023 17:46:01 +0800 +Subject: f2fs: allow set compression option of files without blocks + +From: Yangtao Li + +[ 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 +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 2498e5c70fd83..78e6015ce3a6f 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -3945,7 +3945,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 + diff --git a/queue-6.2/f2fs-clear-atomic_write_task-in-f2fs_abort_atomic_wr.patch b/queue-6.2/f2fs-clear-atomic_write_task-in-f2fs_abort_atomic_wr.patch new file mode 100644 index 00000000000..6918d655729 --- /dev/null +++ b/queue-6.2/f2fs-clear-atomic_write_task-in-f2fs_abort_atomic_wr.patch @@ -0,0 +1,41 @@ +From ef10de2acd726647b958fc49780897a632824d8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 11:44:50 +0800 +Subject: f2fs: clear atomic_write_task in f2fs_abort_atomic_write() + +From: Chao Yu + +[ 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 +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index af3059236f542..cf430f34d1968 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -201,9 +201,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 + diff --git a/queue-6.2/f2fs-don-t-rely-on-f2fs_map_-in-f2fs_iomap_begin.patch b/queue-6.2/f2fs-don-t-rely-on-f2fs_map_-in-f2fs_iomap_begin.patch new file mode 100644 index 00000000000..be8a52bcc90 --- /dev/null +++ b/queue-6.2/f2fs-don-t-rely-on-f2fs_map_-in-f2fs_iomap_begin.patch @@ -0,0 +1,73 @@ +From 66da1a43123d4fa856b2a21c2b5dc4bd3ccc094b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Nov 2022 10:15:09 +0100 +Subject: f2fs: don't rely on F2FS_MAP_* in f2fs_iomap_begin + +From: Christoph Hellwig + +[ 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 +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 8cca566baf3ab..5263d97bef1dd 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -4155,20 +4155,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 + diff --git a/queue-6.2/f2fs-fix-to-abort-atomic-write-only-during-do_exist.patch b/queue-6.2/f2fs-fix-to-abort-atomic-write-only-during-do_exist.patch new file mode 100644 index 00000000000..33b01ec4f8a --- /dev/null +++ b/queue-6.2/f2fs-fix-to-abort-atomic-write-only-during-do_exist.patch @@ -0,0 +1,51 @@ +From 5627a015071580c7296acfe5ee6ee4905f2e043e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 11:44:51 +0800 +Subject: f2fs: fix to abort atomic write only during do_exist() + +From: Chao Yu + +[ 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 +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 78e6015ce3a6f..1aa21160a0614 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1880,7 +1880,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 + diff --git a/queue-6.2/f2fs-fix-to-avoid-potential-deadlock.patch b/queue-6.2/f2fs-fix-to-avoid-potential-deadlock.patch new file mode 100644 index 00000000000..7b3ad9cc184 --- /dev/null +++ b/queue-6.2/f2fs-fix-to-avoid-potential-deadlock.patch @@ -0,0 +1,87 @@ +From d2b83e905c2dbae895d5563fa19f55fba10d8ed7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Dec 2022 23:50:00 +0800 +Subject: f2fs: fix to avoid potential deadlock + +From: Chao Yu + +[ 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 +Reviewed-by: Eric Biggers +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 ecbc8c135b494..2498e5c70fd83 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -2338,6 +2338,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)) +@@ -2362,12 +2363,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 + diff --git a/queue-6.2/f2fs-fix-to-avoid-potential-memory-corruption-in-__u.patch b/queue-6.2/f2fs-fix-to-avoid-potential-memory-corruption-in-__u.patch new file mode 100644 index 00000000000..87dcc4b9a59 --- /dev/null +++ b/queue-6.2/f2fs-fix-to-avoid-potential-memory-corruption-in-__u.patch @@ -0,0 +1,76 @@ +From 2328dda31d97678e5b1aac919ffb2a149ffb3d09 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 21 Jan 2023 00:16:55 +0800 +Subject: f2fs: fix to avoid potential memory corruption in + __update_iostat_latency() + +From: Yangtao Li + +[ 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 +Reported-by: Dan Carpenter +Suggested-by: Chao Yu +Suggested-by: Jaegeuk Kim +Signed-off-by: Yangtao Li +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/f2fs-fix-to-do-sanity-check-on-extent-cache-correctl.patch b/queue-6.2/f2fs-fix-to-do-sanity-check-on-extent-cache-correctl.patch new file mode 100644 index 00000000000..c7b844c9f61 --- /dev/null +++ b/queue-6.2/f2fs-fix-to-do-sanity-check-on-extent-cache-correctl.patch @@ -0,0 +1,53 @@ +From e0f6dc4d9a047f8e92f9e71596cbc908d6d5bd21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 11:49:20 +0800 +Subject: f2fs: fix to do sanity check on extent cache correctly + +From: Chao Yu + +[ Upstream commit d48a7b3a72f121655d95b5157c32c7d555e44c05 ] + +In do_read_inode(), sanity_check_inode() should be called after +f2fs_init_read_extent_tree(), fix it. + +Fixes: 72840cccc0a1 ("f2fs: allocate the extent_cache by default") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/inode.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c +index fb489f55fef3a..622eb7963afac 100644 +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -413,12 +413,6 @@ static int do_read_inode(struct inode *inode) + fi->i_inline_xattr_size = 0; + } + +- if (!sanity_check_inode(inode, node_page)) { +- f2fs_put_page(node_page, 1); +- f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); +- return -EFSCORRUPTED; +- } +- + /* check data exist */ + if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) + __recover_inline_status(inode, node_page); +@@ -482,6 +476,12 @@ static int do_read_inode(struct inode *inode) + f2fs_init_read_extent_tree(inode, node_page); + f2fs_init_age_extent_tree(inode); + ++ if (!sanity_check_inode(inode, node_page)) { ++ f2fs_put_page(node_page, 1); ++ f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); ++ return -EFSCORRUPTED; ++ } ++ + f2fs_put_page(node_page, 1); + + stat_inc_inline_xattr(inode); +-- +2.39.2 + diff --git a/queue-6.2/f2fs-fix-to-handle-f2fs_ioc_start_atomic_replace-in-.patch b/queue-6.2/f2fs-fix-to-handle-f2fs_ioc_start_atomic_replace-in-.patch new file mode 100644 index 00000000000..70d2190ffee --- /dev/null +++ b/queue-6.2/f2fs-fix-to-handle-f2fs_ioc_start_atomic_replace-in-.patch @@ -0,0 +1,36 @@ +From caff1cf803d19064729e1df1fe104a6f351941cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 28 Jan 2023 18:32:26 +0800 +Subject: f2fs: fix to handle F2FS_IOC_START_ATOMIC_REPLACE in + f2fs_compat_ioctl() + +From: Chao Yu + +[ Upstream commit 933141e4eb49d8b48721e2377835063a1e8fb823 ] + +Otherwise, 32-bits binary call ioctl(F2FS_IOC_START_ATOMIC_REPLACE) will +fail in 64-bits kernel. + +Fixes: 41e8f85a75fc ("f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/file.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 1aa21160a0614..63d468b1a9b82 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -4827,6 +4827,7 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + case F2FS_IOC32_MOVE_RANGE: + return f2fs_compat_ioc_move_range(file, arg); + case F2FS_IOC_START_ATOMIC_WRITE: ++ case F2FS_IOC_START_ATOMIC_REPLACE: + case F2FS_IOC_COMMIT_ATOMIC_WRITE: + case F2FS_IOC_START_VOLATILE_WRITE: + case F2FS_IOC_RELEASE_VOLATILE_WRITE: +-- +2.39.2 + diff --git a/queue-6.2/f2fs-fix-to-set-ipu-policy.patch b/queue-6.2/f2fs-fix-to-set-ipu-policy.patch new file mode 100644 index 00000000000..f3d2b15a6de --- /dev/null +++ b/queue-6.2/f2fs-fix-to-set-ipu-policy.patch @@ -0,0 +1,125 @@ +From 34c1efe332e81df503a319ea801861ee3131da7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Feb 2023 22:43:08 +0800 +Subject: f2fs: fix to set ipu policy + +From: Yangtao Li + +[ Upstream commit c5bf83483382600988d7db5ffe9fcd1936b491fd ] + +For LFS mode, it should update outplace and no need inplace update. +When using LFS mode for small-volume devices, IPU will not be used, +and the OPU writing method is actually used, but F2FS_IPU_FORCE can +be read from the ipu_policy node, which is different from the actual +situation. And remount to lfs mode should be disallowed when +f2fs ipu is enabled, let's fix it. + +Fixes: 84b89e5d943d ("f2fs: add auto tuning for small devices") +Signed-off-by: Yangtao Li +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.h | 10 +++++++++- + fs/f2fs/super.c | 15 +++++++++++---- + fs/f2fs/sysfs.c | 9 +++++++++ + 3 files changed, 29 insertions(+), 5 deletions(-) + +diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h +index e77518c49f388..6eb5922a25361 100644 +--- a/fs/f2fs/segment.h ++++ b/fs/f2fs/segment.h +@@ -670,6 +670,8 @@ static inline int utilization(struct f2fs_sb_info *sbi) + + #define SMALL_VOLUME_SEGMENTS (16 * 512) /* 16GB */ + ++#define F2FS_IPU_DISABLE 0 ++ + enum { + F2FS_IPU_FORCE, + F2FS_IPU_SSR, +@@ -679,10 +681,16 @@ enum { + F2FS_IPU_ASYNC, + F2FS_IPU_NOCACHE, + F2FS_IPU_HONOR_OPU_WRITE, ++ F2FS_IPU_MAX, + }; + ++static inline bool IS_F2FS_IPU_DISABLE(struct f2fs_sb_info *sbi) ++{ ++ return SM_I(sbi)->ipu_policy == F2FS_IPU_DISABLE; ++} ++ + #define F2FS_IPU_POLICY(name) \ +-static inline int IS_##name(struct f2fs_sb_info *sbi) \ ++static inline bool IS_##name(struct f2fs_sb_info *sbi) \ + { \ + return SM_I(sbi)->ipu_policy & BIT(name); \ + } +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index 87d56a9883e65..53878feb69d33 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1347,12 +1347,12 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) + } + + if (test_opt(sbi, DISABLE_CHECKPOINT) && f2fs_lfs_mode(sbi)) { +- f2fs_err(sbi, "LFS not compatible with checkpoint=disable"); ++ f2fs_err(sbi, "LFS is not compatible with checkpoint=disable"); + return -EINVAL; + } + + if (test_opt(sbi, ATGC) && f2fs_lfs_mode(sbi)) { +- f2fs_err(sbi, "LFS not compatible with ATGC"); ++ f2fs_err(sbi, "LFS is not compatible with ATGC"); + return -EINVAL; + } + +@@ -2306,6 +2306,12 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) + } + } + #endif ++ if (f2fs_lfs_mode(sbi) && !IS_F2FS_IPU_DISABLE(sbi)) { ++ err = -EINVAL; ++ f2fs_warn(sbi, "LFS is not compatible with IPU"); ++ goto restore_opts; ++ } ++ + /* disallow enable atgc dynamically */ + if (no_atgc == !!test_opt(sbi, ATGC)) { + err = -EINVAL; +@@ -4089,8 +4095,9 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi) + if (f2fs_block_unit_discard(sbi)) + SM_I(sbi)->dcc_info->discard_granularity = + MIN_DISCARD_GRANULARITY; +- SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) | +- BIT(F2FS_IPU_HONOR_OPU_WRITE); ++ if (!f2fs_lfs_mode(sbi)) ++ SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) | ++ BIT(F2FS_IPU_HONOR_OPU_WRITE); + } + + sbi->readdir_ra = true; +diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c +index 83a366f3ee80e..088b816127ecb 100644 +--- a/fs/f2fs/sysfs.c ++++ b/fs/f2fs/sysfs.c +@@ -686,6 +686,15 @@ static ssize_t __sbi_store(struct f2fs_attr *a, + return count; + } + ++ if (!strcmp(a->attr.name, "ipu_policy")) { ++ if (t >= BIT(F2FS_IPU_MAX)) ++ return -EINVAL; ++ if (t && f2fs_lfs_mode(sbi)) ++ return -EINVAL; ++ SM_I(sbi)->ipu_policy = (unsigned int)t; ++ return count; ++ } ++ + *ui = (unsigned int)t; + + return count; +-- +2.39.2 + diff --git a/queue-6.2/f2fs-fix-to-update-age-extent-correctly-during-trunc.patch b/queue-6.2/f2fs-fix-to-update-age-extent-correctly-during-trunc.patch new file mode 100644 index 00000000000..6c985345264 --- /dev/null +++ b/queue-6.2/f2fs-fix-to-update-age-extent-correctly-during-trunc.patch @@ -0,0 +1,36 @@ +From 189327de7132f9552739eb0148b51a1a393cbe8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Jan 2023 22:47:00 +0800 +Subject: f2fs: fix to update age extent correctly during truncation + +From: Chao Yu + +[ Upstream commit 8c0ed062ce27f6b7f0a568cb241e2b4dd2d9e6a6 ] + +nr_free may be less than len, we should update age extent cache +w/ range [fofs, len] rather than [fofs, nr_free]. + +Fixes: 71644dff4811 ("f2fs: add block_age-based extent cache") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 63d468b1a9b82..cd1c6ed89d5ef 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -619,7 +619,7 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) + fofs = f2fs_start_bidx_of_node(ofs_of_node(dn->node_page), + dn->inode) + ofs; + f2fs_update_read_extent_cache_range(dn, fofs, 0, len); +- f2fs_update_age_extent_cache_range(dn, fofs, nr_free); ++ f2fs_update_age_extent_cache_range(dn, fofs, len); + dec_valid_block_count(sbi, dn->inode, nr_free); + } + dn->ofs_in_node = ofs; +-- +2.39.2 + diff --git a/queue-6.2/f2fs-fix-to-update-age-extent-in-f2fs_do_zero_range.patch b/queue-6.2/f2fs-fix-to-update-age-extent-in-f2fs_do_zero_range.patch new file mode 100644 index 00000000000..1265bc55ec8 --- /dev/null +++ b/queue-6.2/f2fs-fix-to-update-age-extent-in-f2fs_do_zero_range.patch @@ -0,0 +1,35 @@ +From 65688da4dfe28f57f2f7699edde4cb00653b13a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Jan 2023 22:47:01 +0800 +Subject: f2fs: fix to update age extent in f2fs_do_zero_range() + +From: Chao Yu + +[ Upstream commit a84153f939808102dfa10904aa0f743e734a3e1d ] + +We should update age extent in f2fs_do_zero_range() like we +did in f2fs_truncate_data_blocks_range(). + +Fixes: 71644dff4811 ("f2fs: add block_age-based extent cache") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/file.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index cd1c6ed89d5ef..8583c098bc985 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1498,6 +1498,7 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start, + } + + f2fs_update_read_extent_cache_range(dn, start, 0, index - start); ++ f2fs_update_age_extent_cache_range(dn, start, index - start); + + return ret; + } +-- +2.39.2 + diff --git a/queue-6.2/f2fs-introduce-is_f2fs_ipu_-macro.patch b/queue-6.2/f2fs-introduce-is_f2fs_ipu_-macro.patch new file mode 100644 index 00000000000..d36df20bc19 --- /dev/null +++ b/queue-6.2/f2fs-introduce-is_f2fs_ipu_-macro.patch @@ -0,0 +1,140 @@ +From 57c2ba77b62be3b7f879e4f8ec1d89e6a64d82f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 19 Nov 2022 03:18:39 +0800 +Subject: f2fs: introduce IS_F2FS_IPU_* macro + +From: Yangtao Li + +[ Upstream commit fdb7ccc3f9cb316c399b072c7a75a106678eb421 ] + +IS_F2FS_IPU_* macro can be used to identify whether +f2fs ipu related policies are enabled. + +BTW, convert to use BIT() instead of open code. + +Signed-off-by: Yangtao Li +Signed-off-by: Jaegeuk Kim +Stable-dep-of: c5bf83483382 ("f2fs: fix to set ipu policy") +Signed-off-by: Sasha Levin +--- + fs/f2fs/data.c | 25 ++++++++++--------------- + fs/f2fs/segment.c | 4 ++-- + fs/f2fs/segment.h | 15 +++++++++++++++ + fs/f2fs/super.c | 4 ++-- + 4 files changed, 29 insertions(+), 19 deletions(-) + +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index 5263d97bef1dd..a28d05895f5c7 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -2535,34 +2535,29 @@ static inline bool check_inplace_update_policy(struct inode *inode, + struct f2fs_io_info *fio) + { + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); +- unsigned int policy = SM_I(sbi)->ipu_policy; + +- if (policy & (0x1 << F2FS_IPU_HONOR_OPU_WRITE) && +- is_inode_flag_set(inode, FI_OPU_WRITE)) ++ if (IS_F2FS_IPU_HONOR_OPU_WRITE(sbi) && ++ is_inode_flag_set(inode, FI_OPU_WRITE)) + return false; +- if (policy & (0x1 << F2FS_IPU_FORCE)) ++ if (IS_F2FS_IPU_FORCE(sbi)) + return true; +- if (policy & (0x1 << F2FS_IPU_SSR) && f2fs_need_SSR(sbi)) ++ if (IS_F2FS_IPU_SSR(sbi) && f2fs_need_SSR(sbi)) + return true; +- if (policy & (0x1 << F2FS_IPU_UTIL) && +- utilization(sbi) > SM_I(sbi)->min_ipu_util) ++ if (IS_F2FS_IPU_UTIL(sbi) && utilization(sbi) > SM_I(sbi)->min_ipu_util) + return true; +- if (policy & (0x1 << F2FS_IPU_SSR_UTIL) && f2fs_need_SSR(sbi) && +- utilization(sbi) > SM_I(sbi)->min_ipu_util) ++ if (IS_F2FS_IPU_SSR_UTIL(sbi) && f2fs_need_SSR(sbi) && ++ utilization(sbi) > SM_I(sbi)->min_ipu_util) + return true; + + /* + * IPU for rewrite async pages + */ +- if (policy & (0x1 << F2FS_IPU_ASYNC) && +- fio && fio->op == REQ_OP_WRITE && +- !(fio->op_flags & REQ_SYNC) && +- !IS_ENCRYPTED(inode)) ++ if (IS_F2FS_IPU_ASYNC(sbi) && fio && fio->op == REQ_OP_WRITE && ++ !(fio->op_flags & REQ_SYNC) && !IS_ENCRYPTED(inode)) + return true; + + /* this is only set during fdatasync */ +- if (policy & (0x1 << F2FS_IPU_FSYNC) && +- is_inode_flag_set(inode, FI_NEED_IPU)) ++ if (IS_F2FS_IPU_FSYNC(sbi) && is_inode_flag_set(inode, FI_NEED_IPU)) + return true; + + if (unlikely(fio && is_sbi_flag_set(sbi, SBI_CP_DISABLED) && +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index cf430f34d1968..06cae55265841 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -3498,7 +3498,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio) + + stat_inc_inplace_blocks(fio->sbi); + +- if (fio->bio && !(SM_I(sbi)->ipu_policy & (1 << F2FS_IPU_NOCACHE))) ++ if (fio->bio && !IS_F2FS_IPU_NOCACHE(sbi)) + err = f2fs_merge_page_bio(fio); + else + err = f2fs_submit_page_bio(fio); +@@ -5137,7 +5137,7 @@ int f2fs_build_segment_manager(struct f2fs_sb_info *sbi) + sm_info->rec_prefree_segments = DEF_MAX_RECLAIM_PREFREE_SEGMENTS; + + if (!f2fs_lfs_mode(sbi)) +- sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC; ++ sm_info->ipu_policy = BIT(F2FS_IPU_FSYNC); + sm_info->min_ipu_util = DEF_MIN_IPU_UTIL; + sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS; + sm_info->min_seq_blocks = sbi->blocks_per_seg; +diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h +index 3ad1b7b6fa946..e77518c49f388 100644 +--- a/fs/f2fs/segment.h ++++ b/fs/f2fs/segment.h +@@ -681,6 +681,21 @@ enum { + F2FS_IPU_HONOR_OPU_WRITE, + }; + ++#define F2FS_IPU_POLICY(name) \ ++static inline int IS_##name(struct f2fs_sb_info *sbi) \ ++{ \ ++ return SM_I(sbi)->ipu_policy & BIT(name); \ ++} ++ ++F2FS_IPU_POLICY(F2FS_IPU_FORCE); ++F2FS_IPU_POLICY(F2FS_IPU_SSR); ++F2FS_IPU_POLICY(F2FS_IPU_UTIL); ++F2FS_IPU_POLICY(F2FS_IPU_SSR_UTIL); ++F2FS_IPU_POLICY(F2FS_IPU_FSYNC); ++F2FS_IPU_POLICY(F2FS_IPU_ASYNC); ++F2FS_IPU_POLICY(F2FS_IPU_NOCACHE); ++F2FS_IPU_POLICY(F2FS_IPU_HONOR_OPU_WRITE); ++ + static inline unsigned int curseg_segno(struct f2fs_sb_info *sbi, + int type) + { +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index 1f812b9ce985b..87d56a9883e65 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -4089,8 +4089,8 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi) + if (f2fs_block_unit_discard(sbi)) + SM_I(sbi)->dcc_info->discard_granularity = + MIN_DISCARD_GRANULARITY; +- SM_I(sbi)->ipu_policy = 1 << F2FS_IPU_FORCE | +- 1 << F2FS_IPU_HONOR_OPU_WRITE; ++ SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) | ++ BIT(F2FS_IPU_HONOR_OPU_WRITE); + } + + sbi->readdir_ra = true; +-- +2.39.2 + diff --git a/queue-6.2/f2fs-introduce-trace_f2fs_replace_atomic_write_block.patch b/queue-6.2/f2fs-introduce-trace_f2fs_replace_atomic_write_block.patch new file mode 100644 index 00000000000..b7f56e8fc4b --- /dev/null +++ b/queue-6.2/f2fs-introduce-trace_f2fs_replace_atomic_write_block.patch @@ -0,0 +1,88 @@ +From 5a57da406bbc619a2965960cc8da4e7fb2271cf2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 11:44:49 +0800 +Subject: f2fs: introduce trace_f2fs_replace_atomic_write_block + +From: Chao Yu + +[ 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 +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 b019f63fd5403..af3059236f542 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -255,6 +255,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 31d994e6b4ca9..35ecb3118c7d5 100644 +--- a/include/trace/events/f2fs.h ++++ b/include/trace/events/f2fs.h +@@ -1293,6 +1293,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 + diff --git a/queue-6.2/f2fs-synchronize-atomic-write-aborts.patch b/queue-6.2/f2fs-synchronize-atomic-write-aborts.patch new file mode 100644 index 00000000000..7e6500451b8 --- /dev/null +++ b/queue-6.2/f2fs-synchronize-atomic-write-aborts.patch @@ -0,0 +1,168 @@ +From a6f56df2386398c13efdc2b55cc6deb2c24f99fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Feb 2023 10:18:19 -0800 +Subject: f2fs: synchronize atomic write aborts + +From: Daeho Jeong + +[ 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 +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 8583c098bc985..05297427552ac 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1867,7 +1867,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; + } + +@@ -1882,8 +1885,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; + } + +@@ -2089,19 +2096,28 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate) + 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); +@@ -2109,8 +2125,6 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate) + 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); + + isize = i_size_read(inode); + fi->original_i_size = isize; +diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c +index 622eb7963afac..f438f39ae3f3e 100644 +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -767,11 +767,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); + +@@ -858,7 +865,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 06cae55265841..269f89d202c61 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_REPLACE); +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index 53878feb69d33..551468dad3275 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1430,8 +1430,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 + diff --git a/queue-6.2/firmware-efi-sysfb_efi-add-quirk-for-lenovo-ideapad-.patch b/queue-6.2/firmware-efi-sysfb_efi-add-quirk-for-lenovo-ideapad-.patch new file mode 100644 index 00000000000..aea1999fd32 --- /dev/null +++ b/queue-6.2/firmware-efi-sysfb_efi-add-quirk-for-lenovo-ideapad-.patch @@ -0,0 +1,43 @@ +From 9e3240f7205ecf6c5d6757876e5a5f884801ef6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Feb 2023 11:50:45 +0000 +Subject: firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3 + +From: Darrell Kavanagh + +[ 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 +Reviewed-by: Hans de Goede +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/fs-f2fs-initialize-fsdata-in-pagecache_write.patch b/queue-6.2/fs-f2fs-initialize-fsdata-in-pagecache_write.patch new file mode 100644 index 00000000000..b5541deaf17 --- /dev/null +++ b/queue-6.2/fs-f2fs-initialize-fsdata-in-pagecache_write.patch @@ -0,0 +1,40 @@ +From 0218135bed11ab5b9233576fd8e02b9e557ee856 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Nov 2022 12:21:32 +0100 +Subject: fs: f2fs: initialize fsdata in pagecache_write() + +From: Alexander Potapenko + +[ 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 +Fixes: 95ae251fe828 ("f2fs: add fs-verity support") +Signed-off-by: Alexander Potapenko +Reviewed-by: Eric Biggers +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/fs-jfs-fix-shift-exponent-db_agl2size-negative.patch b/queue-6.2/fs-jfs-fix-shift-exponent-db_agl2size-negative.patch new file mode 100644 index 00000000000..dda8a1ac5e1 --- /dev/null +++ b/queue-6.2/fs-jfs-fix-shift-exponent-db_agl2size-negative.patch @@ -0,0 +1,41 @@ +From 39c5298eccf11518661e453220b1c690948ef581 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Nov 2022 11:01:59 +0800 +Subject: fs/jfs: fix shift exponent db_agl2size negative + +From: Liu Shixin via Jfs-discussion + +[ 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 +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/genirq-ipi-fix-null-pointer-deref-in-irq_data_get_af.patch b/queue-6.2/genirq-ipi-fix-null-pointer-deref-in-irq_data_get_af.patch new file mode 100644 index 00000000000..346ef9c28b0 --- /dev/null +++ b/queue-6.2/genirq-ipi-fix-null-pointer-deref-in-irq_data_get_af.patch @@ -0,0 +1,59 @@ +From 62bbbf9d3ddaaf22a38d243e3178ded087e87a93 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/b541232d-c2b6-1fe9-79b4-a7129459e4d0@omp.ru +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ib-hfi1-update-rmt-size-calculation.patch b/queue-6.2/ib-hfi1-update-rmt-size-calculation.patch new file mode 100644 index 00000000000..90f186585f1 --- /dev/null +++ b/queue-6.2/ib-hfi1-update-rmt-size-calculation.patch @@ -0,0 +1,136 @@ +From 1788c7f710390fe6477ac2e0cd3221c6bc91bd52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Jan 2023 14:04:29 -0500 +Subject: IB/hfi1: Update RMT size calculation + +From: Dean Luick + +[ 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 +Signed-off-by: Dennis Dalessandro +Link: https://lore.kernel.org/r/167329106946.1472990.18385495251650939054.stgit@awfm-02.cornelisnetworks.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/iio-accel-mma9551_core-prevent-uninitialized-variabl.patch b/queue-6.2/iio-accel-mma9551_core-prevent-uninitialized-variabl.patch new file mode 100644 index 00000000000..3484766f986 --- /dev/null +++ b/queue-6.2/iio-accel-mma9551_core-prevent-uninitialized-variabl.patch @@ -0,0 +1,48 @@ +From 1e03d1dee22adafa3958531295b801f7af6a3a4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230126152147.3585874-1-harshit.m.mogalapalli@oracle.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/iio-accel-mma9551_core-prevent-uninitialized-variabl.patch-28624 b/queue-6.2/iio-accel-mma9551_core-prevent-uninitialized-variabl.patch-28624 new file mode 100644 index 00000000000..5ab639597cb --- /dev/null +++ b/queue-6.2/iio-accel-mma9551_core-prevent-uninitialized-variabl.patch-28624 @@ -0,0 +1,49 @@ +From 0480c3fddae306c899b6802c0f64d0f09e541017 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230126153610.3586243-1-harshit.m.mogalapalli@oracle.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/io_uring-fix-size-calculation-when-registering-buf-r.patch b/queue-6.2/io_uring-fix-size-calculation-when-registering-buf-r.patch new file mode 100644 index 00000000000..9460bb08e83 --- /dev/null +++ b/queue-6.2/io_uring-fix-size-calculation-when-registering-buf-r.patch @@ -0,0 +1,49 @@ +From 23b1a6e0e36ae4dcad83d9f061ce6cfc5358e46b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Feb 2023 18:41:41 +0000 +Subject: io_uring: fix size calculation when registering buf ring + +From: Wojciech Lukowicz + +[ 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 +Reviewed-by: Gabriel Krisman Bertazi +Link: https://lore.kernel.org/r/20230218184141.70891-1-wlukowicz01@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 4a6401080c1f8..3002dc8271959 100644 +--- a/io_uring/kbuf.c ++++ b/io_uring/kbuf.c +@@ -505,7 +505,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 + diff --git a/queue-6.2/iommu-remove-deferred-attach-check-from-__iommu_deta.patch b/queue-6.2/iommu-remove-deferred-attach-check-from-__iommu_deta.patch new file mode 100644 index 00000000000..b8fe6e4f25d --- /dev/null +++ b/queue-6.2/iommu-remove-deferred-attach-check-from-__iommu_deta.patch @@ -0,0 +1,197 @@ +From 373e9b71cce625328538e9c097cc126df3cb344b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jan 2023 10:54:07 +0800 +Subject: iommu: Remove deferred attach check from __iommu_detach_device() + +From: Jason Gunthorpe + +[ Upstream commit dd8a25c557e109f868430bd2e3e8f394cb40eaa7 ] + +At the current moment, __iommu_detach_device() is only called via call +chains that are after the device driver is attached - eg via explicit +attach APIs called by the device driver. + +Commit bd421264ed30 ("iommu: Fix deferred domain attachment") has removed +deferred domain attachment check from __iommu_attach_device() path, so it +should just unconditionally work in the __iommu_detach_device() path. + +It actually looks like a bug that we were blocking detach on these paths +since the attach was unconditional and the caller is going to free the +(probably) UNAMANGED domain once this returns. + +The only place we should be testing for deferred attach is during the +initial point the dma device is linked to the group, and then again +during the dma api calls. + +Signed-off-by: Jason Gunthorpe +Signed-off-by: Lu Baolu +Link: https://lore.kernel.org/r/20230110025408.667767-5-baolu.lu@linux.intel.com +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/iommu.c | 70 ++++++++++++++++++++++--------------------- + include/linux/iommu.h | 2 ++ + 2 files changed, 38 insertions(+), 34 deletions(-) + +diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c +index 50d858f36a81b..f8100067502fb 100644 +--- a/drivers/iommu/iommu.c ++++ b/drivers/iommu/iommu.c +@@ -371,6 +371,30 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list + return ret; + } + ++static bool iommu_is_attach_deferred(struct device *dev) ++{ ++ const struct iommu_ops *ops = dev_iommu_ops(dev); ++ ++ if (ops->is_attach_deferred) ++ return ops->is_attach_deferred(dev); ++ ++ return false; ++} ++ ++static int iommu_group_do_dma_first_attach(struct device *dev, void *data) ++{ ++ struct iommu_domain *domain = data; ++ ++ lockdep_assert_held(&dev->iommu_group->mutex); ++ ++ if (iommu_is_attach_deferred(dev)) { ++ dev->iommu->attach_deferred = 1; ++ return 0; ++ } ++ ++ return __iommu_attach_device(domain, dev); ++} ++ + int iommu_probe_device(struct device *dev) + { + const struct iommu_ops *ops; +@@ -401,7 +425,7 @@ int iommu_probe_device(struct device *dev) + * attach the default domain. + */ + if (group->default_domain && !group->owner) { +- ret = __iommu_attach_device(group->default_domain, dev); ++ ret = iommu_group_do_dma_first_attach(dev, group->default_domain); + if (ret) { + mutex_unlock(&group->mutex); + iommu_group_put(group); +@@ -951,16 +975,6 @@ static int iommu_create_device_direct_mappings(struct iommu_group *group, + return ret; + } + +-static bool iommu_is_attach_deferred(struct device *dev) +-{ +- const struct iommu_ops *ops = dev_iommu_ops(dev); +- +- if (ops->is_attach_deferred) +- return ops->is_attach_deferred(dev); +- +- return false; +-} +- + /** + * iommu_group_add_device - add a device to an iommu group + * @group: the group into which to add the device (reference should be held) +@@ -1013,8 +1027,8 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev) + + mutex_lock(&group->mutex); + list_add_tail(&device->list, &group->devices); +- if (group->domain && !iommu_is_attach_deferred(dev)) +- ret = __iommu_attach_device(group->domain, dev); ++ if (group->domain) ++ ret = iommu_group_do_dma_first_attach(dev, group->domain); + mutex_unlock(&group->mutex); + if (ret) + goto err_put_group; +@@ -1780,21 +1794,10 @@ static void probe_alloc_default_domain(struct bus_type *bus, + + } + +-static int iommu_group_do_dma_attach(struct device *dev, void *data) +-{ +- struct iommu_domain *domain = data; +- int ret = 0; +- +- if (!iommu_is_attach_deferred(dev)) +- ret = __iommu_attach_device(domain, dev); +- +- return ret; +-} +- +-static int __iommu_group_dma_attach(struct iommu_group *group) ++static int __iommu_group_dma_first_attach(struct iommu_group *group) + { + return __iommu_group_for_each_dev(group, group->default_domain, +- iommu_group_do_dma_attach); ++ iommu_group_do_dma_first_attach); + } + + static int iommu_group_do_probe_finalize(struct device *dev, void *data) +@@ -1859,7 +1862,7 @@ int bus_iommu_probe(struct bus_type *bus) + + iommu_group_create_direct_mappings(group); + +- ret = __iommu_group_dma_attach(group); ++ ret = __iommu_group_dma_first_attach(group); + + mutex_unlock(&group->mutex); + +@@ -1991,9 +1994,11 @@ static int __iommu_attach_device(struct iommu_domain *domain, + return -ENODEV; + + ret = domain->ops->attach_dev(domain, dev); +- if (!ret) +- trace_attach_device_to_domain(dev); +- return ret; ++ if (ret) ++ return ret; ++ dev->iommu->attach_deferred = 0; ++ trace_attach_device_to_domain(dev); ++ return 0; + } + + /** +@@ -2038,7 +2043,7 @@ EXPORT_SYMBOL_GPL(iommu_attach_device); + + int iommu_deferred_attach(struct device *dev, struct iommu_domain *domain) + { +- if (iommu_is_attach_deferred(dev)) ++ if (dev->iommu && dev->iommu->attach_deferred) + return __iommu_attach_device(domain, dev); + + return 0; +@@ -2047,9 +2052,6 @@ int iommu_deferred_attach(struct device *dev, struct iommu_domain *domain) + static void __iommu_detach_device(struct iommu_domain *domain, + struct device *dev) + { +- if (iommu_is_attach_deferred(dev)) +- return; +- + domain->ops->detach_dev(domain, dev); + trace_detach_device_from_domain(dev); + } +diff --git a/include/linux/iommu.h b/include/linux/iommu.h +index 46e1347bfa228..7695d9e14277f 100644 +--- a/include/linux/iommu.h ++++ b/include/linux/iommu.h +@@ -401,6 +401,7 @@ struct iommu_fault_param { + * @iommu_dev: IOMMU device this device is linked to + * @priv: IOMMU Driver private data + * @max_pasids: number of PASIDs this device can consume ++ * @attach_deferred: the dma domain attachment is deferred + * + * TODO: migrate other per device data pointers under iommu_dev_data, e.g. + * struct iommu_group *iommu_group; +@@ -413,6 +414,7 @@ struct dev_iommu { + struct iommu_device *iommu_dev; + void *priv; + u32 max_pasids; ++ u32 attach_deferred:1; + }; + + int iommu_device_register(struct iommu_device *iommu, +-- +2.39.2 + diff --git a/queue-6.2/ipv6-add-lwtunnel-encap-size-of-all-siblings-in-next.patch b/queue-6.2/ipv6-add-lwtunnel-encap-size-of-all-siblings-in-next.patch new file mode 100644 index 00000000000..6030110241c --- /dev/null +++ b/queue-6.2/ipv6-add-lwtunnel-encap-size-of-all-siblings-in-next.patch @@ -0,0 +1,96 @@ +From 62417abc95a0035ab86c164e06778c865444c630 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Feb 2023 16:36:28 +0800 +Subject: ipv6: Add lwtunnel encap size of all siblings in nexthop calculation + +From: Lu Wei + +[ 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: + + 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 +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20230222083629.335683-2-luwei32@huawei.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + 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 e74e0361fd921..a6983a13dd205 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 + diff --git a/queue-6.2/kernel-fail_function-fix-memory-leak-with-using-debu.patch b/queue-6.2/kernel-fail_function-fix-memory-leak-with-using-debu.patch new file mode 100644 index 00000000000..1b476525672 --- /dev/null +++ b/queue-6.2/kernel-fail_function-fix-memory-leak-with-using-debu.patch @@ -0,0 +1,42 @@ +From 8656162ba4fa02ad87ad6452b5fe1e381a1b5754 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:16:33 +0100 +Subject: kernel/fail_function: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Reviewed-by: Yang Yingliang +Link: https://lore.kernel.org/r/20230202151633.2310897-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/kernel-printk-index.c-fix-memory-leak-with-using-deb.patch b/queue-6.2/kernel-printk-index.c-fix-memory-leak-with-using-deb.patch new file mode 100644 index 00000000000..2522142ecc5 --- /dev/null +++ b/queue-6.2/kernel-printk-index.c-fix-memory-leak-with-using-deb.patch @@ -0,0 +1,47 @@ +From 047e502cec43f5cde763dc7850d79f34c9773d66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Petr Mladek +Cc: Sergey Senozhatsky +Cc: Steven Rostedt +Cc: John Ogness +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +Reviewed-by: Sergey Senozhatsky +Reviewed-by: John Ogness +Reviewed-by: Petr Mladek +Signed-off-by: Petr Mladek +Link: https://lore.kernel.org/r/20230202151411.2308576-1-gregkh@linuxfoundation.org +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/loop-loop_set_status_from_info-check-before-assignme.patch b/queue-6.2/loop-loop_set_status_from_info-check-before-assignme.patch new file mode 100644 index 00000000000..95519e296a3 --- /dev/null +++ b/queue-6.2/loop-loop_set_status_from_info-check-before-assignme.patch @@ -0,0 +1,59 @@ +From 37c04256f03ebbdc175a107659aa5e5c84f683ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Feb 2023 17:50:27 +0800 +Subject: loop: loop_set_status_from_info() check before assignment + +From: Zhong Jinghua + +[ 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 +Reviewed-by: Chaitanya Kulkarni +Link: https://lore.kernel.org/r/20230221095027.3656193-1-zhongjinghua@huaweicloud.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 1518a6423279b..1b35cbd029c7c 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 + diff --git a/queue-6.2/media-uvcvideo-add-guid-for-bgra-x-8-8-8-8.patch b/queue-6.2/media-uvcvideo-add-guid-for-bgra-x-8-8-8-8.patch new file mode 100644 index 00000000000..2285c36b26e --- /dev/null +++ b/queue-6.2/media-uvcvideo-add-guid-for-bgra-x-8-8-8-8.patch @@ -0,0 +1,71 @@ +From 5b6ff7bc542ccafe398edda805352f2aa631ffc2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Jan 2023 00:14:52 +0100 +Subject: media: uvcvideo: Add GUID for BGRA/X 8:8:8:8 + +From: Marek Vasut + +[ 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 +Reviewed-by: Laurent Pinchart +Reviewed-by: Ricardo Ribalda +Signed-off-by: Michael Grzeschik +Link: https://lore.kernel.org/r/20230126231456.3402323-2-m.grzeschik@pengutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/media-uvcvideo-handle-cameras-with-invalid-descripto.patch b/queue-6.2/media-uvcvideo-handle-cameras-with-invalid-descripto.patch new file mode 100644 index 00000000000..98b63186a4e --- /dev/null +++ b/queue-6.2/media-uvcvideo-handle-cameras-with-invalid-descripto.patch @@ -0,0 +1,36 @@ +From 28ac804ca9eadd30e1e453924dc861279da67a24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Sep 2022 16:04:55 +0200 +Subject: media: uvcvideo: Handle cameras with invalid descriptors + +From: Ricardo Ribalda + +[ Upstream commit 41ddb251c68ac75c101d3a50a68c4629c9055e4c ] + +If the source entity does not contain any pads, do not create a link. + +Reported-by: syzbot +Signed-off-by: Ricardo Ribalda +Reviewed-by: Laurent Pinchart +Signed-off-by: Laurent Pinchart +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/media-uvcvideo-handle-errors-from-calls-to-usb_strin.patch b/queue-6.2/media-uvcvideo-handle-errors-from-calls-to-usb_strin.patch new file mode 100644 index 00000000000..5ce90f69dc2 --- /dev/null +++ b/queue-6.2/media-uvcvideo-handle-errors-from-calls-to-usb_strin.patch @@ -0,0 +1,138 @@ +From 236bff7551bcf2e4ce365c259fa61a2daf212335 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Oct 2022 16:41:01 +0200 +Subject: media: uvcvideo: Handle errors from calls to usb_string + +From: Guenter Roeck + +[ 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 +Reviewed-by: Laurent Pinchart +Signed-off-by: Laurent Pinchart +Signed-off-by: Sasha Levin +--- + 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 d30f77d89598c..943ae2559448c 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 + diff --git a/queue-6.2/media-uvcvideo-quirk-for-autosuspend-in-logitech-b91.patch b/queue-6.2/media-uvcvideo-quirk-for-autosuspend-in-logitech-b91.patch new file mode 100644 index 00000000000..baeb094745c --- /dev/null +++ b/queue-6.2/media-uvcvideo-quirk-for-autosuspend-in-logitech-b91.patch @@ -0,0 +1,138 @@ +From 0f41dfab954d730fba1ad9b4b1310d593decdd63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Jan 2023 11:45:23 +0100 +Subject: media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910 + +From: Ricardo Ribalda + +[ 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 +Reviewed-by: Laurent Pinchart +Signed-off-by: Laurent Pinchart +Signed-off-by: Sasha Levin +--- + 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 943ae2559448c..362df9dd31525 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2450,6 +2450,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 + diff --git a/queue-6.2/media-uvcvideo-remove-format-descriptions.patch b/queue-6.2/media-uvcvideo-remove-format-descriptions.patch new file mode 100644 index 00000000000..f7f976623d1 --- /dev/null +++ b/queue-6.2/media-uvcvideo-remove-format-descriptions.patch @@ -0,0 +1,136 @@ +From fd80292132ab205cfdac5c9043149ffa8c70bd16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2016 18:44:29 +0200 +Subject: media: uvcvideo: Remove format descriptions + +From: Laurent Pinchart + +[ 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 +Reviewed-by: Ricardo Ribalda +Reviewed-by: Michael Grzeschik +Signed-off-by: Sasha Levin +--- + 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 d5ff8df20f18a..d30f77d89598c 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 + diff --git a/queue-6.2/media-uvcvideo-silence-memcpy-run-time-false-positiv.patch b/queue-6.2/media-uvcvideo-silence-memcpy-run-time-false-positiv.patch new file mode 100644 index 00000000000..72ce3a725d9 --- /dev/null +++ b/queue-6.2/media-uvcvideo-silence-memcpy-run-time-false-positiv.patch @@ -0,0 +1,60 @@ +From 14a31729c9719bdf5384d110dcd49143fd9675c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jan 2023 22:17:04 -0800 +Subject: media: uvcvideo: Silence memcpy() run-time false positive warnings + +From: Kees Cook + +[ 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 +Reviewed-by: Laurent Pinchart +Signed-off-by: Laurent Pinchart +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/mei-bus-fixup-upon-error-print-return-values-of-send.patch b/queue-6.2/mei-bus-fixup-upon-error-print-return-values-of-send.patch new file mode 100644 index 00000000000..130f6549268 --- /dev/null +++ b/queue-6.2/mei-bus-fixup-upon-error-print-return-values-of-send.patch @@ -0,0 +1,64 @@ +From 06a8e29de7702d23ea6ec1a7650fb48b4bc311e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Tomas Winkler +Link: https://lore.kernel.org/r/20221212214933.275434-1-tomas.winkler@intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 6df7679d97391..92c0930cc742c 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; + } + +@@ -380,7 +380,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; + } + +@@ -395,7 +395,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 + diff --git a/queue-6.2/memory-renesas-rpc-if-move-resource-acquisition-to-..patch b/queue-6.2/memory-renesas-rpc-if-move-resource-acquisition-to-..patch new file mode 100644 index 00000000000..138be7d03ad --- /dev/null +++ b/queue-6.2/memory-renesas-rpc-if-move-resource-acquisition-to-..patch @@ -0,0 +1,116 @@ +From 635546c4f23e21251508c25ba4560f0316109a78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 15:41:18 +0100 +Subject: memory: renesas-rpc-if: Move resource acquisition to .probe() + +From: Geert Uytterhoeven + +[ 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 +Acked-by: Wolfram Sang +Link: https://lore.kernel.org/r/c1012ef1de799e08a70817ab7313794e2d8d7bfb.1669213027.git.geert+renesas@glider.be +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + 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 ded80caec1678..5be3b46cd55f1 100644 +--- a/drivers/memory/renesas-rpc-if.c ++++ b/drivers/memory/renesas-rpc-if.c +@@ -277,32 +277,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; +@@ -705,9 +680,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; + +@@ -732,6 +709,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 + diff --git a/queue-6.2/memory-renesas-rpc-if-split-off-private-data-from-st.patch b/queue-6.2/memory-renesas-rpc-if-split-off-private-data-from-st.patch new file mode 100644 index 00000000000..cfff59a06dd --- /dev/null +++ b/queue-6.2/memory-renesas-rpc-if-split-off-private-data-from-st.patch @@ -0,0 +1,266 @@ +From 57c2572d70958d72b0fc2b5307a54b5d0cc65589 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 15:41:17 +0100 +Subject: memory: renesas-rpc-if: Split-off private data from struct rpcif + +From: Geert Uytterhoeven + +[ 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 +Acked-by: Wolfram Sang +Link: https://lore.kernel.org/r/09fbb6fa67d5a8cd48a08808c9afa2f6a499aa42.1669213027.git.geert+renesas@glider.be +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + 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 09cd4318a83d8..ded80caec1678 100644 +--- a/drivers/memory/renesas-rpc-if.c ++++ b/drivers/memory/renesas-rpc-if.c +@@ -163,14 +163,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: +@@ -206,7 +228,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: +@@ -253,13 +275,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); +@@ -280,12 +301,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); +@@ -299,8 +325,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); +@@ -364,7 +391,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; + +@@ -373,7 +400,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; +@@ -386,9 +413,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; +@@ -472,8 +501,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; + +@@ -593,7 +623,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); +@@ -640,8 +670,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; + +@@ -676,6 +707,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; + +@@ -696,11 +728,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) { +@@ -713,9 +752,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 862eff613dc79..2dcb82df0d176 100644 +--- a/include/memory/renesas-rpc-if.h ++++ b/include/memory/renesas-rpc-if.h +@@ -65,24 +65,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 + diff --git a/queue-6.2/mfd-arizona-use-pm_runtime_resume_and_get-to-prevent.patch b/queue-6.2/mfd-arizona-use-pm_runtime_resume_and_get-to-prevent.patch new file mode 100644 index 00000000000..4dc1618dc2c --- /dev/null +++ b/queue-6.2/mfd-arizona-use-pm_runtime_resume_and_get-to-prevent.patch @@ -0,0 +1,38 @@ +From 31a31bc655d2c3064fb48d3db9cf7dc4f1900925 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Charles Keepax +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230105061055.1509261-1-windhl@126.com +Signed-off-by: Sasha Levin +--- + 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 bd7ee3260d53f..c166fcd331f11 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 + diff --git a/queue-6.2/misc-vmw_balloon-fix-memory-leak-with-using-debugfs_.patch b/queue-6.2/misc-vmw_balloon-fix-memory-leak-with-using-debugfs_.patch new file mode 100644 index 00000000000..6ca29ef2718 --- /dev/null +++ b/queue-6.2/misc-vmw_balloon-fix-memory-leak-with-using-debugfs_.patch @@ -0,0 +1,40 @@ +From fbacd12641a792ff8daf926254e160e1a66783e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 15:11:00 +0100 +Subject: misc: vmw_balloon: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Cc: VMware PV-Drivers Reviewers +Cc: Arnd Bergmann +Link: https://lore.kernel.org/r/20230202141100.2291188-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/mlx5-fix-possible-ptp-queue-fifo-use-after-free.patch b/queue-6.2/mlx5-fix-possible-ptp-queue-fifo-use-after-free.patch new file mode 100644 index 00000000000..3c2846194cd --- /dev/null +++ b/queue-6.2/mlx5-fix-possible-ptp-queue-fifo-use-after-free.patch @@ -0,0 +1,108 @@ +From 19512b2ccbf4ca4b540ab08f120db44742cc1864 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 09:13:55 -0800 +Subject: mlx5: fix possible ptp queue fifo use-after-free + +From: Vadim Fedorenko + +[ 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 +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + .../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 6687b8136e441..4478223c17209 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +@@ -2138,6 +2138,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 375752d6546d5..b77100b60b505 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +@@ -461,6 +461,7 @@ struct mlx5e_ptp_cq_stats { + u64 abort_abs_diff_ns; + u64 resync_cqe; + u64 resync_event; ++ u64 ooo_cqe_drop; + }; + + struct mlx5e_rep_stats { +-- +2.39.2 + diff --git a/queue-6.2/mlx5-fix-skb-leak-while-fifo-resync-and-push.patch b/queue-6.2/mlx5-fix-skb-leak-while-fifo-resync-and-push.patch new file mode 100644 index 00000000000..14eaf9cb4fe --- /dev/null +++ b/queue-6.2/mlx5-fix-skb-leak-while-fifo-resync-and-push.patch @@ -0,0 +1,78 @@ +From fca4095a8c41a80f94a7c81d16ac54a6d88f7f67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 09:13:54 -0800 +Subject: mlx5: fix skb leak while fifo resync and push + +From: Vadim Fedorenko + +[ 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 +Reviewed-by: Tariq Toukan +Signed-off-by: Vadim Fedorenko +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/net-dsa-felix-fix-internal-mdio-controller-resource-.patch b/queue-6.2/net-dsa-felix-fix-internal-mdio-controller-resource-.patch new file mode 100644 index 00000000000..0b1cc10516d --- /dev/null +++ b/queue-6.2/net-dsa-felix-fix-internal-mdio-controller-resource-.patch @@ -0,0 +1,56 @@ +From d86ec82152c026dd3ddb768f49201bb6d680bb2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Feb 2023 17:52:34 +0200 +Subject: net: dsa: felix: fix internal MDIO controller resource length + +From: Vladimir Oltean + +[ 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 +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 01ac70fd7ddf1..4b6e4e5b47283 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 + diff --git a/queue-6.2/net-dsa-seville-ignore-mscc-miim-read-errors-from-ly.patch b/queue-6.2/net-dsa-seville-ignore-mscc-miim-read-errors-from-ly.patch new file mode 100644 index 00000000000..898b4b0e78b --- /dev/null +++ b/queue-6.2/net-dsa-seville-ignore-mscc-miim-read-errors-from-ly.patch @@ -0,0 +1,153 @@ +From 30d70f4cc527390baa9683f77b6abde4987b5b59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Feb 2023 17:52:33 +0200 +Subject: net: dsa: seville: ignore mscc-miim read errors from Lynx PCS + +From: Vladimir Oltean + +[ 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 +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 88ed3a2e487a4..fa03254adcefd 100644 +--- a/drivers/net/dsa/ocelot/seville_vsc9953.c ++++ b/drivers/net/dsa/ocelot/seville_vsc9953.c +@@ -893,8 +893,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 + diff --git a/queue-6.2/net-fix-__dev_kfree_skb_any-vs-drop-monitor.patch b/queue-6.2/net-fix-__dev_kfree_skb_any-vs-drop-monitor.patch new file mode 100644 index 00000000000..cacaab0b07c --- /dev/null +++ b/queue-6.2/net-fix-__dev_kfree_skb_any-vs-drop-monitor.patch @@ -0,0 +1,49 @@ +From 43bb144c648fc7af4721a1ef41954f5fc58232d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Feb 2023 08:38:45 +0000 +Subject: net: fix __dev_kfree_skb_any() vs drop monitor + +From: Eric Dumazet + +[ 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 +Cc: Yunsheng Lin +Reviewed-by: Yunsheng Lin +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 f23e287602b7e..fce980d531bdc 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3131,8 +3131,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 + diff --git a/queue-6.2/net-mlx5-ecpf-wait-for-vf-pages-only-after-disabling.patch b/queue-6.2/net-mlx5-ecpf-wait-for-vf-pages-only-after-disabling.patch new file mode 100644 index 00000000000..7a122dd3f6e --- /dev/null +++ b/queue-6.2/net-mlx5-ecpf-wait-for-vf-pages-only-after-disabling.patch @@ -0,0 +1,64 @@ +From 6df8884e09bde7bb4a62b754504cda4dc15760b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/net-mlx5-geneve-fix-handling-of-geneve-object-id-as-.patch b/queue-6.2/net-mlx5-geneve-fix-handling-of-geneve-object-id-as-.patch new file mode 100644 index 00000000000..1b43400c797 --- /dev/null +++ b/queue-6.2/net-mlx5-geneve-fix-handling-of-geneve-object-id-as-.patch @@ -0,0 +1,41 @@ +From cee2d862d415356342082c16682118778d0bde89 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Raed Salem +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/net-mlx5e-verify-flow_source-cap-before-using-it.patch b/queue-6.2/net-mlx5e-verify-flow_source-cap-before-using-it.patch new file mode 100644 index 00000000000..8d19cf0ba31 --- /dev/null +++ b/queue-6.2/net-mlx5e-verify-flow_source-cap-before-using-it.patch @@ -0,0 +1,38 @@ +From 90e265bb5c66e76e0c351bd47cc170e993916202 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Jan 2023 12:04:30 +0200 +Subject: net/mlx5e: Verify flow_source cap before using it + +From: Roi Dayan + +[ 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 +Reviewed-by: Maor Dickman +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 c981fa77f4398..f3b74cb67b71c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -1070,7 +1070,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(mlx5_eswitch_get_slow_fdb(on_esw), +-- +2.39.2 + diff --git a/queue-6.2/net-sched-act_mpls-fix-action-bind-logic.patch b/queue-6.2/net-sched-act_mpls-fix-action-bind-logic.patch new file mode 100644 index 00000000000..ac930919769 --- /dev/null +++ b/queue-6.2/net-sched-act_mpls-fix-action-bind-logic.patch @@ -0,0 +1,203 @@ +From bc9f27cc71b9d1035689fc224efa3f8b5cf5a51b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Feb 2023 12:00:57 -0300 +Subject: net/sched: act_mpls: fix action bind logic + +From: Pedro Tammela + +[ 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 +Signed-off-by: Pedro Tammela +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 6b26bdb999d77..809f7928a1be6 100644 +--- a/net/sched/act_mpls.c ++++ b/net/sched/act_mpls.c +@@ -190,40 +190,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]) { +@@ -238,33 +265,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 + diff --git a/queue-6.2/net-sched-act_pedit-fix-action-bind-logic.patch b/queue-6.2/net-sched-act_pedit-fix-action-bind-logic.patch new file mode 100644 index 00000000000..b35b582d88c --- /dev/null +++ b/queue-6.2/net-sched-act_pedit-fix-action-bind-logic.patch @@ -0,0 +1,205 @@ +From 8afae85c47ae6f338637704e05ffee3951fd2e40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Feb 2023 12:00:56 -0300 +Subject: net/sched: act_pedit: fix action bind logic + +From: Pedro Tammela + +[ 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 +Signed-off-by: Pedro Tammela +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 9915410942786..7532773283ea7 100644 +--- a/net/sched/act_pedit.c ++++ b/net/sched/act_pedit.c +@@ -181,26 +181,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); +@@ -209,25 +189,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; +@@ -278,12 +282,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 + diff --git a/queue-6.2/net-sched-act_sample-fix-action-bind-logic.patch b/queue-6.2/net-sched-act_sample-fix-action-bind-logic.patch new file mode 100644 index 00000000000..ab059432fa7 --- /dev/null +++ b/queue-6.2/net-sched-act_sample-fix-action-bind-logic.patch @@ -0,0 +1,92 @@ +From 5b788972348b08f8b681e8724b633ab33a0fec94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Feb 2023 12:00:58 -0300 +Subject: net/sched: act_sample: fix action bind logic + +From: Pedro Tammela + +[ 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 +Signed-off-by: Pedro Tammela +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 f7416b5598e04..4c670e7568dc6 100644 +--- a/net/sched/act_sample.c ++++ b/net/sched/act_sample.c +@@ -55,8 +55,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]); +@@ -80,6 +80,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 + diff --git a/queue-6.2/net-sched-transition-act_pedit-to-rcu-and-percpu-sta.patch b/queue-6.2/net-sched-transition-act_pedit-to-rcu-and-percpu-sta.patch new file mode 100644 index 00000000000..fc9de647df7 --- /dev/null +++ b/queue-6.2/net-sched-transition-act_pedit-to-rcu-and-percpu-sta.patch @@ -0,0 +1,437 @@ +From b53ed452eeb63593850f4b6b80fb5f2c7bf88322 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Jan 2023 16:05:11 -0300 +Subject: net/sched: transition act_pedit to rcu and percpu stats + +From: Pedro Tammela + +[ 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 +Signed-off-by: Pedro Tammela +Reviewed-by: Simon Horman +Signed-off-by: Paolo Abeni +Stable-dep-of: e9e42292ea76 ("net/sched: act_pedit: fix action bind logic") +Signed-off-by: Sasha Levin +--- + 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 + #include ++#include + + 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 a0378e9f01213..9915410942786 100644 +--- a/net/sched/act_pedit.c ++++ b/net/sched/act_pedit.c +@@ -134,6 +134,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, +@@ -141,10 +152,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; +@@ -181,18 +191,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) { +@@ -204,7 +221,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); +@@ -212,48 +229,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: +@@ -261,19 +280,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) +@@ -325,28 +347,30 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, + 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; +@@ -422,11 +446,10 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb, + } + + 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; + } + +@@ -445,30 +468,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 + diff --git a/queue-6.2/net-sunhme-fix-region-request.patch b/queue-6.2/net-sunhme-fix-region-request.patch new file mode 100644 index 00000000000..1d50e9b08e6 --- /dev/null +++ b/queue-6.2/net-sunhme-fix-region-request.patch @@ -0,0 +1,44 @@ +From 66131fc94ad83da08e61f4fc9101f696f1b94c0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Feb 2023 15:42:41 -0500 +Subject: net: sunhme: Fix region request + +From: Sean Anderson + +[ 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 +Reviewed-by: Pavan Chebbi +Link: https://lore.kernel.org/r/20230222204242.2658247-1-seanga2@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/netfilter-conntrack-fix-rmmod-double-free-race.patch b/queue-6.2/netfilter-conntrack-fix-rmmod-double-free-race.patch new file mode 100644 index 00000000000..997dfc1c415 --- /dev/null +++ b/queue-6.2/netfilter-conntrack-fix-rmmod-double-free-race.patch @@ -0,0 +1,125 @@ +From d5757439015324c677b9f554dfdad7d70f69b049 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Feb 2023 17:23:59 +0100 +Subject: netfilter: conntrack: fix rmmod double-free race + +From: Florian Westphal + +[ 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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 24002bc61e07e..e1af14e3b63c5 100644 +--- a/net/netfilter/nf_conntrack_bpf.c ++++ b/net/netfilter/nf_conntrack_bpf.c +@@ -381,7 +381,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 496c4920505b3..ead11a9c261f3 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -886,10 +886,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 { +@@ -924,6 +922,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); +@@ -932,12 +943,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 + diff --git a/queue-6.2/netfilter-ctnetlink-fix-possible-refcount-leak-in-ct.patch b/queue-6.2/netfilter-ctnetlink-fix-possible-refcount-leak-in-ct.patch new file mode 100644 index 00000000000..8bb62d55f4e --- /dev/null +++ b/queue-6.2/netfilter-ctnetlink-fix-possible-refcount-leak-in-ct.patch @@ -0,0 +1,47 @@ +From 46b6faf35f6060ad27556385cc64b50c45f6283f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Feb 2023 15:17:30 +0800 +Subject: netfilter: ctnetlink: fix possible refcount leak in + ctnetlink_create_conntrack() + +From: Hangyu Hua + +[ 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 +Acked-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/netfilter-ctnetlink-make-event-listener-tracking-glo.patch b/queue-6.2/netfilter-ctnetlink-make-event-listener-tracking-glo.patch new file mode 100644 index 00000000000..3de10aae2f8 --- /dev/null +++ b/queue-6.2/netfilter-ctnetlink-make-event-listener-tracking-glo.patch @@ -0,0 +1,143 @@ +From 26dbfa61c0c679d79e62ba96c818a25493f7a32c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Feb 2023 17:24:00 +0100 +Subject: netfilter: ctnetlink: make event listener tracking global + +From: Florian Westphal + +[ 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 +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + #include ++#include + #include + + 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 + diff --git a/queue-6.2/netfilter-ebtables-fix-table-blob-use-after-free.patch b/queue-6.2/netfilter-ebtables-fix-table-blob-use-after-free.patch new file mode 100644 index 00000000000..9fce5436da5 --- /dev/null +++ b/queue-6.2/netfilter-ebtables-fix-table-blob-use-after-free.patch @@ -0,0 +1,105 @@ +From 0bfa096f4f07ae233dc34fd5ca2006aa57475e5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Feb 2023 23:20:06 +0100 +Subject: netfilter: ebtables: fix table blob use-after-free + +From: Florian Westphal + +[ 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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/netfilter-ip6t_rpfilter-fix-regression-with-vrf-inte.patch b/queue-6.2/netfilter-ip6t_rpfilter-fix-regression-with-vrf-inte.patch new file mode 100644 index 00000000000..2be47485cb1 --- /dev/null +++ b/queue-6.2/netfilter-ip6t_rpfilter-fix-regression-with-vrf-inte.patch @@ -0,0 +1,121 @@ +From 9a6f43198175232c2afe8e6e4b746d59094704cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Feb 2023 17:05:36 +0100 +Subject: netfilter: ip6t_rpfilter: Fix regression with VRF interfaces + +From: Phil Sutter + +[ 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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 - </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 + diff --git a/queue-6.2/netfilter-nf_tables-allow-to-fetch-set-elements-when.patch b/queue-6.2/netfilter-nf_tables-allow-to-fetch-set-elements-when.patch new file mode 100644 index 00000000000..1be9dc6cba6 --- /dev/null +++ b/queue-6.2/netfilter-nf_tables-allow-to-fetch-set-elements-when.patch @@ -0,0 +1,37 @@ +From e05fbb09384e62bfed7b753e77e6ccd75d225869 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 fc8256b00b320..6023c9f72cdca 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -5487,7 +5487,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 + diff --git a/queue-6.2/netfilter-x_tables-fix-percpu-counter-block-leak-on-.patch b/queue-6.2/netfilter-x_tables-fix-percpu-counter-block-leak-on-.patch new file mode 100644 index 00000000000..f4a1281c1f8 --- /dev/null +++ b/queue-6.2/netfilter-x_tables-fix-percpu-counter-block-leak-on-.patch @@ -0,0 +1,91 @@ +From 9cc19dcab40dbbb7a0dc9934d9a3b2ad9c14e6c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/netfilter-xt_length-use-skb-len-to-match-in-length_m.patch b/queue-6.2/netfilter-xt_length-use-skb-len-to-match-in-length_m.patch new file mode 100644 index 00000000000..eef81f9d569 --- /dev/null +++ b/queue-6.2/netfilter-xt_length-use-skb-len-to-match-in-length_m.patch @@ -0,0 +1,53 @@ +From da5d79fb186795dd5e86176fbc2948378ebb6c4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Feb 2023 18:22:57 -0500 +Subject: netfilter: xt_length: use skb len to match in length_mt6 + +From: Xin Long + +[ 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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/nfc-fix-memory-leak-of-se_io-context-in-nfc_genl_se_.patch b/queue-6.2/nfc-fix-memory-leak-of-se_io-context-in-nfc_genl_se_.patch new file mode 100644 index 00000000000..58cd9ee1fc4 --- /dev/null +++ b/queue-6.2/nfc-fix-memory-leak-of-se_io-context-in-nfc_genl_se_.patch @@ -0,0 +1,85 @@ +From 8ded6a96fdbf700aecb17f30ddb6f79ae49bd248 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Alexey Khoroshilov +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/nvme-bring-back-auto-removal-of-deleted-namespaces-d.patch b/queue-6.2/nvme-bring-back-auto-removal-of-deleted-namespaces-d.patch new file mode 100644 index 00000000000..a516543d616 --- /dev/null +++ b/queue-6.2/nvme-bring-back-auto-removal-of-deleted-namespaces-d.patch @@ -0,0 +1,110 @@ +From e2829e2110dac8021de33076e3bbc469c4c58279 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Feb 2023 14:02:25 -0800 +Subject: nvme: bring back auto-removal of deleted namespaces during sequential + scan + +From: Christoph Hellwig + +[ 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 +Signed-off-by: Christoph Hellwig +Reviewed-by: Keith Busch +Reviewed-by: Sagi Grimberg +Tested-by: Nils Hanke +Signed-off-by: Sasha Levin +--- + 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 8b64211411626..fbed8d1a02ef4 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; +@@ -1445,16 +1446,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; + } + +@@ -1468,6 +1461,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; +@@ -4418,6 +4418,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; +@@ -4434,19 +4435,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 + diff --git a/queue-6.2/nvme-fabrics-show-well-known-discovery-name.patch b/queue-6.2/nvme-fabrics-show-well-known-discovery-name.patch new file mode 100644 index 00000000000..bca9f010890 --- /dev/null +++ b/queue-6.2/nvme-fabrics-show-well-known-discovery-name.patch @@ -0,0 +1,59 @@ +From 32895b2933d31b41ae5cb2411f03b34c61cddf82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Feb 2023 17:51:06 +0100 +Subject: nvme-fabrics: show well known discovery name + +From: Daniel Wagner + +[ 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 +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/nvme-tcp-don-t-access-released-socket-during-error-r.patch b/queue-6.2/nvme-tcp-don-t-access-released-socket-during-error-r.patch new file mode 100644 index 00000000000..7a56c4ee510 --- /dev/null +++ b/queue-6.2/nvme-tcp-don-t-access-released-socket-during-error-r.patch @@ -0,0 +1,53 @@ +From 5597b1b0d533229afffb3c69f527626afb7889b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 26 Feb 2023 21:42:54 +0900 +Subject: nvme-tcp: don't access released socket during error recovery + +From: Akinobu Mita + +[ 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 +Fixes: 02c57a82c008 ("nvme-tcp: print actual source IP address through sysfs "address" attr") +Reviewed-by: Martin Belanger +Reviewed-by: Hannes Reinecke +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 8cedc1ef496c7..1ca52ac163c2f 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -2486,6 +2486,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) +@@ -2493,6 +2497,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 + diff --git a/queue-6.2/objtool-fix-memory-leak-in-create_static_call_sectio.patch b/queue-6.2/objtool-fix-memory-leak-in-create_static_call_sectio.patch new file mode 100644 index 00000000000..419462dde16 --- /dev/null +++ b/queue-6.2/objtool-fix-memory-leak-in-create_static_call_sectio.patch @@ -0,0 +1,46 @@ +From b029bcc61e581893a3fc436ec0d43c1176c5bab8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Dec 2022 12:06:42 +0400 +Subject: objtool: Fix memory leak in create_static_call_sections() + +From: Miaoqian Lin + +[ 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 +Signed-off-by: Ingo Molnar +Link: https://lore.kernel.org/r/20221205080642.558583-1-linmq006@gmail.com +Cc: Josh Poimboeuf +Cc: Peter Zijlstra +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index b1a5f658673f0..ea1e7cdeb1b34 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -688,6 +688,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; +@@ -697,6 +698,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 + diff --git a/queue-6.2/octeontx2-pf-recalculate-udp-checksum-for-ptp-1-step.patch b/queue-6.2/octeontx2-pf-recalculate-udp-checksum-for-ptp-1-step.patch new file mode 100644 index 00000000000..1bd466a5087 --- /dev/null +++ b/queue-6.2/octeontx2-pf-recalculate-udp-checksum-for-ptp-1-step.patch @@ -0,0 +1,173 @@ +From 0e2f48475fa23fe2ffc3bd89bd0ff05f5ac97bc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Feb 2023 17:06:00 +0530 +Subject: octeontx2-pf: Recalculate UDP checksum for ptp 1-step sync packet + +From: Geetha sowjanya + +[ 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 +Signed-off-by: Hariprasad Kelam +Signed-off-by: Sunil Kovvuri Goutham +Signed-off-by: Sai Krishna +Link: https://lore.kernel.org/r/20230222113600.1965116-1-saikrishnag@marvell.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../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 + #include + #include ++#include + + #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 + diff --git a/queue-6.2/octeontx2-pf-use-correct-struct-reference-in-test-co.patch b/queue-6.2/octeontx2-pf-use-correct-struct-reference-in-test-co.patch new file mode 100644 index 00000000000..806ca796526 --- /dev/null +++ b/queue-6.2/octeontx2-pf-use-correct-struct-reference-in-test-co.patch @@ -0,0 +1,39 @@ +From 273348aec9dff80f7b9090a003e4df38cf891455 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Feb 2023 18:58:48 +0530 +Subject: octeontx2-pf: Use correct struct reference in test condition + +From: Deepak R Varma + +[ 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 +Link: https://lore.kernel.org/r/Y/YYkKddeHOt80cO@ubun2204.myguest.virtualbox.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 684cb8ec9f21b..10e11262d48a0 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +@@ -793,7 +793,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 + diff --git a/queue-6.2/parport_pc-set-up-mode-and-ecr-masks-for-oxford-semi.patch b/queue-6.2/parport_pc-set-up-mode-and-ecr-masks-for-oxford-semi.patch new file mode 100644 index 00000000000..91addf3b62d --- /dev/null +++ b/queue-6.2/parport_pc-set-up-mode-and-ecr-masks-for-oxford-semi.patch @@ -0,0 +1,140 @@ +From 1ab7708c372d812a850d02c53db5fdc06c3dd6d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 + + * 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 +Signed-off-by: Sudip Mukherjee +Link: https://lore.kernel.org/r/20230108215656.6433-6-sudipm.mukherjee@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/pci-acpi-account-for-_s0w-of-the-target-bridge-in-ac.patch b/queue-6.2/pci-acpi-account-for-_s0w-of-the-target-bridge-in-ac.patch new file mode 100644 index 00000000000..7a06be527f9 --- /dev/null +++ b/queue-6.2/pci-acpi-account-for-_s0w-of-the-target-bridge-in-ac.patch @@ -0,0 +1,167 @@ +From a3c0378b9c84776b3927dd356be952942146b7f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 068d6745bf98c..052a611081ecd 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 e44be31115a67..0584e9f6e3397 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 + diff --git a/queue-6.2/pci-add-acs-quirk-for-wangxun-nics.patch b/queue-6.2/pci-add-acs-quirk-for-wangxun-nics.patch new file mode 100644 index 00000000000..7b9fe5565d6 --- /dev/null +++ b/queue-6.2/pci-add-acs-quirk-for-wangxun-nics.patch @@ -0,0 +1,81 @@ +From b7aa2ea756f960eb9b4b9832caf6e7fe96fbbe37 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Feb 2023 18:24:19 +0800 +Subject: PCI: Add ACS quirk for Wangxun NICs + +From: Mengyuan Lou + +[ 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 +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/pci-align-extra-resources-for-hotplug-bridges-proper.patch b/queue-6.2/pci-align-extra-resources-for-hotplug-bridges-proper.patch new file mode 100644 index 00000000000..c2594dae157 --- /dev/null +++ b/queue-6.2/pci-align-extra-resources-for-hotplug-bridges-proper.patch @@ -0,0 +1,71 @@ +From d274381fc286b0148433039a861d19d7947d5027 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Jan 2023 11:24:03 +0200 +Subject: PCI: Align extra resources for hotplug bridges properly + +From: Mika Westerberg + +[ 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 +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/pci-distribute-available-resources-for-root-buses-to.patch b/queue-6.2/pci-distribute-available-resources-for-root-buses-to.patch new file mode 100644 index 00000000000..aeb331f2a73 --- /dev/null +++ b/queue-6.2/pci-distribute-available-resources-for-root-buses-to.patch @@ -0,0 +1,132 @@ +From 889d14665e20473267937292a842ac551df61d81 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Jan 2023 11:24:05 +0200 +Subject: PCI: Distribute available resources for root buses, too + +From: Mika Westerberg + +[ 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 +Signed-off-by: Mika Westerberg +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/pci-loongson-add-more-devices-that-need-mrrs-quirk.patch b/queue-6.2/pci-loongson-add-more-devices-that-need-mrrs-quirk.patch new file mode 100644 index 00000000000..1b380841502 --- /dev/null +++ b/queue-6.2/pci-loongson-add-more-devices-that-need-mrrs-quirk.patch @@ -0,0 +1,85 @@ +From 24beabf5269b92480ecfd09f93d530e162b4b66f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 11 Feb 2023 10:33:21 +0800 +Subject: PCI: loongson: Add more devices that need MRRS quirk + +From: Huacai Chen + +[ 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 +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/pci-loongson-prevent-ls7a-mrrs-increases.patch b/queue-6.2/pci-loongson-prevent-ls7a-mrrs-increases.patch new file mode 100644 index 00000000000..843d5bf813f --- /dev/null +++ b/queue-6.2/pci-loongson-prevent-ls7a-mrrs-increases.patch @@ -0,0 +1,141 @@ +From 801f87901eef7627c03bc14f6eb0bdcfd301faba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Feb 2023 12:30:18 +0800 +Subject: PCI: loongson: Prevent LS7A MRRS increases + +From: Huacai Chen + +[ 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 +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 da748247061d2..7a67611dc5f48 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 254c8a4126a89..50042ea8e0083 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -572,6 +572,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 + diff --git a/queue-6.2/pci-pciehp-add-qualcomm-quirk-for-command-completed-.patch b/queue-6.2/pci-pciehp-add-qualcomm-quirk-for-command-completed-.patch new file mode 100644 index 00000000000..35721b728f5 --- /dev/null +++ b/queue-6.2/pci-pciehp-add-qualcomm-quirk-for-command-completed-.patch @@ -0,0 +1,46 @@ +From 488601844e919ffa5107b17f52fce49bf3c39a04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Feb 2023 20:19:22 +0530 +Subject: PCI: pciehp: Add Qualcomm quirk for Command Completed erratum + +From: Manivannan Sadhasivam + +[ 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 +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 10e9670eea0b0..f8c70115b6917 100644 +--- a/drivers/pci/hotplug/pciehp_hpc.c ++++ b/drivers/pci/hotplug/pciehp_hpc.c +@@ -1088,6 +1088,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 + diff --git a/queue-6.2/pci-portdrv-prevent-ls7a-bus-master-clearing-on-shut.patch b/queue-6.2/pci-portdrv-prevent-ls7a-bus-master-clearing-on-shut.patch new file mode 100644 index 00000000000..c4d818b8031 --- /dev/null +++ b/queue-6.2/pci-portdrv-prevent-ls7a-bus-master-clearing-on-shut.patch @@ -0,0 +1,91 @@ +From 648e2444f9a7a6957529b1378f3a5a41039f1f2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Feb 2023 12:30:17 +0800 +Subject: PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown + +From: Huacai Chen + +[ Upstream commit 62b6dee1b44aa23b3935543aff7df80399ec726b ] + +After cc27b735ad3a ("PCI/portdrv: Turn off PCIe services during shutdown") +we observe hangs during poweroff/reboot on systems with LS7A chipset. + +This happens because the portdrv .shutdown() method (pcie_portdrv_remove()) +clears PCI_COMMAND_MASTER via pci_disable_device(), which prevents bridges +from forwarding memory or I/O Requests in the upstream direction (PCIe +r6.0, sec 7.5.1.1.3). + +LS7A Root Ports have a hardware defect: clearing PCI_COMMAND_MASTER *also* +prevents the bridge from forwarding CPU MMIO requests in the downstream +direction, and these MMIO accesses to devices below the bridge happen even +after .shutdown(), e.g., to print console messages. LS7A neither forwards +the requests nor sends an unsuccessful completion to the CPU, so the CPU +waits forever, resulting in the hang. + +The purpose of .shutdown() is to disable interrupts and DMA from the +device. PCIe ports may generate interrupts (either MSI/MSI-X or INTx) for +AER, DPC, PME, hotplug, etc., but they never perform DMA except MSI/MSI-X. +Clearing PCI_COMMAND_MASTER effectively disables MSI/MSI-X, but not INTx. + +The port service driver .remove() methods clear the interrupt enables in +PCI_ERR_ROOT_COMMAND, PCI_EXP_DPC_CTL, PCI_EXP_SLTCTL, and PCI_EXP_RTCTL, +etc., which disables interrupts regardless of whether they are MSI/MSI-X or +INTx. + +Add a pcie_portdrv_shutdown() method that calls all the port service driver +.remove() methods to clear the interrupt enables for each service but does +not clear Bus Mastering on the port itself. + +[bhelgaas: commit log] +Link: https://lore.kernel.org/r/20230201043018.778499-2-chenhuacai@loongson.cn +Signed-off-by: Huacai Chen +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/pci/pcie/portdrv.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c +index 2cc2e60bcb396..46fad0d813b2b 100644 +--- a/drivers/pci/pcie/portdrv.c ++++ b/drivers/pci/pcie/portdrv.c +@@ -501,7 +501,6 @@ static void pcie_port_device_remove(struct pci_dev *dev) + { + device_for_each_child(&dev->dev, NULL, remove_iter); + pci_free_irq_vectors(dev); +- pci_disable_device(dev); + } + + /** +@@ -727,6 +726,19 @@ static void pcie_portdrv_remove(struct pci_dev *dev) + } + + pcie_port_device_remove(dev); ++ ++ pci_disable_device(dev); ++} ++ ++static void pcie_portdrv_shutdown(struct pci_dev *dev) ++{ ++ if (pci_bridge_d3_possible(dev)) { ++ pm_runtime_forbid(&dev->dev); ++ pm_runtime_get_noresume(&dev->dev); ++ pm_runtime_dont_use_autosuspend(&dev->dev); ++ } ++ ++ pcie_port_device_remove(dev); + } + + static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, +@@ -777,7 +789,7 @@ static struct pci_driver pcie_portdriver = { + + .probe = pcie_portdrv_probe, + .remove = pcie_portdrv_remove, +- .shutdown = pcie_portdrv_remove, ++ .shutdown = pcie_portdrv_shutdown, + + .err_handler = &pcie_portdrv_err_handler, + +-- +2.39.2 + diff --git a/queue-6.2/pci-take-other-bus-devices-into-account-when-distrib.patch b/queue-6.2/pci-take-other-bus-devices-into-account-when-distrib.patch new file mode 100644 index 00000000000..f52bc100bb0 --- /dev/null +++ b/queue-6.2/pci-take-other-bus-devices-into-account-when-distrib.patch @@ -0,0 +1,281 @@ +From 8a3bb03b48a13dedc5b20e86be8aa5f87edbd030 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Jan 2023 11:24:04 +0200 +Subject: PCI: Take other bus devices into account when distributing resources + +From: Mika Westerberg + +[ 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 +Reported-by: Alexander Motin +Signed-off-by: Mika Westerberg +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/phy-rockchip-typec-fix-unsigned-comparison-with-less.patch b/queue-6.2/phy-rockchip-typec-fix-unsigned-comparison-with-less.patch new file mode 100644 index 00000000000..3560a7a4b15 --- /dev/null +++ b/queue-6.2/phy-rockchip-typec-fix-unsigned-comparison-with-less.patch @@ -0,0 +1,43 @@ +From 5511f33edb3652b51f184adc2521501b0b85fdd3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Feb 2023 11:57:09 +0800 +Subject: phy: rockchip-typec: Fix unsigned comparison with less than zero + +From: Jiapeng Chong + +[ 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 +Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3962 +Signed-off-by: Jiapeng Chong +Link: https://lore.kernel.org/r/20230213035709.99027-1-jiapeng.chong@linux.alibaba.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ptp-vclock-use-mutex-to-fix-sleep-on-atomic-bug.patch b/queue-6.2/ptp-vclock-use-mutex-to-fix-sleep-on-atomic-bug.patch new file mode 100644 index 00000000000..f1b20938079 --- /dev/null +++ b/queue-6.2/ptp-vclock-use-mutex-to-fix-sleep-on-atomic-bug.patch @@ -0,0 +1,208 @@ +From 725bc298f797c73a07ea480f3185dad761580b8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Suggested-by: Richard Cochran +Tested-by: Miroslav Lichvar +Signed-off-by: Íñigo Huguet +Acked-by: Richard Cochran +Link: https://lore.kernel.org/r/20230221130616.21837-1-ihuguet@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/pwm-sifive-always-let-the-first-pwm_apply_state-succ.patch b/queue-6.2/pwm-sifive-always-let-the-first-pwm_apply_state-succ.patch new file mode 100644 index 00000000000..7f1b95e4195 --- /dev/null +++ b/queue-6.2/pwm-sifive-always-let-the-first-pwm_apply_state-succ.patch @@ -0,0 +1,69 @@ +From e7acb7289a497397ecf91c32e2c3e879ec1ad55c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Nov 2022 12:37:24 +0100 +Subject: pwm: sifive: Always let the first pwm_apply_state succeed + +From: Emil Renner Berthing + +[ 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 +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + 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 62b6acc6373db..393a4b97fc19e 100644 +--- a/drivers/pwm/pwm-sifive.c ++++ b/drivers/pwm/pwm-sifive.c +@@ -161,7 +161,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 + diff --git a/queue-6.2/pwm-stm32-lp-fix-the-check-on-arr-and-cmp-registers-.patch b/queue-6.2/pwm-stm32-lp-fix-the-check-on-arr-and-cmp-registers-.patch new file mode 100644 index 00000000000..6dc50a09a24 --- /dev/null +++ b/queue-6.2/pwm-stm32-lp-fix-the-check-on-arr-and-cmp-registers-.patch @@ -0,0 +1,44 @@ +From 359f1927f742e9d01debecb236935d87c5376979 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Uwe Kleine-König +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + 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 514ff58a4471d..f315fa106be87 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 + diff --git a/queue-6.2/rdma-cma-distinguish-between-sockaddr_in-and-sockadd.patch b/queue-6.2/rdma-cma-distinguish-between-sockaddr_in-and-sockadd.patch new file mode 100644 index 00000000000..9eb324a3c71 --- /dev/null +++ b/queue-6.2/rdma-cma-distinguish-between-sockaddr_in-and-sockadd.patch @@ -0,0 +1,75 @@ +From 9ad442cc0efad03af97e77320c48410bdb22bff0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Feb 2023 15:25:53 -0800 +Subject: RDMA/cma: Distinguish between sockaddr_in and sockaddr_in6 by size + +From: Kees Cook + +[ 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 +Tested-by: Nathan Chancellor # build +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + 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 68721ff10255e..7e508b15e7761 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 + diff --git a/queue-6.2/rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch b/queue-6.2/rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch new file mode 100644 index 00000000000..c6f178c76ea --- /dev/null +++ b/queue-6.2/rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch @@ -0,0 +1,40 @@ +From f773f0722f9c73e18e24115892629a095ae71848 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Feb 2023 23:27:53 +0100 +Subject: rtc: allow rtc_read_alarm without read_alarm callback + +From: Alexandre Belloni + +[ 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 +Reported-by: Marcel Ziswiler +Fixes: 7ae41220ef58 ("rtc: introduce features bitfield") +Tested-by: Philippe Schenker +Link: https://lore.kernel.org/r/20230214222754.582582-1-alexandre.belloni@bootlin.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + 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 7c30cb3c764d8..499d89150afc9 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 + diff --git a/queue-6.2/rtc-sun6i-always-export-the-internal-oscillator.patch b/queue-6.2/rtc-sun6i-always-export-the-internal-oscillator.patch new file mode 100644 index 00000000000..a59dacc8e31 --- /dev/null +++ b/queue-6.2/rtc-sun6i-always-export-the-internal-oscillator.patch @@ -0,0 +1,83 @@ +From c517009b80e252f9b8143ac8c6834f438a5f49d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Dec 2022 15:53:19 -0600 +Subject: rtc: sun6i: Always export the internal oscillator + +From: Samuel Holland + +[ 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 +Acked-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20221229215319.14145-1-samuel@sholland.org +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/scsi-ipr-work-around-fortify-string-warning.patch b/queue-6.2/scsi-ipr-work-around-fortify-string-warning.patch new file mode 100644 index 00000000000..580813898a3 --- /dev/null +++ b/queue-6.2/scsi-ipr-work-around-fortify-string-warning.patch @@ -0,0 +1,114 @@ +From bcb6b3b5c84eaf74f9a3c2604052ee2068294167 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Feb 2023 14:28:08 +0100 +Subject: scsi: ipr: Work around fortify-string warning + +From: Arnd Bergmann + +[ 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 +Fixes: 8cf093e275d0 ("[SCSI] ipr: Improved dual adapter errors") +Signed-off-by: Arnd Bergmann +Reviewed-by: Damien Le Moal +Reviewed-by: Kees Cook +Acked-by: Brian King +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/scsi-mpi3mr-fix-an-issue-found-by-kasan.patch b/queue-6.2/scsi-mpi3mr-fix-an-issue-found-by-kasan.patch new file mode 100644 index 00000000000..d1bfc00a810 --- /dev/null +++ b/queue-6.2/scsi-mpi3mr-fix-an-issue-found-by-kasan.patch @@ -0,0 +1,37 @@ +From 56f5202f909b2d5d41a92aab1940cc2f55f5bf47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Feb 2023 20:37:52 +0100 +Subject: scsi: mpi3mr: Fix an issue found by KASAN + +From: Tomas Henzl + +[ 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 +Acked-by: Sathya Prakash Veerichetty +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/scsi-mpi3mr-use-number-of-bits-to-manage-bitmap-size.patch b/queue-6.2/scsi-mpi3mr-use-number-of-bits-to-manage-bitmap-size.patch new file mode 100644 index 00000000000..6d7efe3c3d3 --- /dev/null +++ b/queue-6.2/scsi-mpi3mr-use-number-of-bits-to-manage-bitmap-size.patch @@ -0,0 +1,238 @@ +From 80f30dd10598d1db66b084464d78cd11a99d4ff4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Feb 2023 09:50:18 +0900 +Subject: scsi: mpi3mr: Use number of bits to manage bitmap sizes + +From: Shin'ichiro Kawasaki + +[ 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 +Acked-by: Sathya Prakash Veerichetty +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 286a44506578b..758f7ca9e0ee8 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; +@@ -4189,10 +4174,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++) { +@@ -4318,16 +4304,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); +@@ -4886,9 +4872,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 + diff --git a/queue-6.2/sctp-add-a-refcnt-in-sctp_stream_priorities-to-avoid.patch b/queue-6.2/sctp-add-a-refcnt-in-sctp_stream_priorities-to-avoid.patch new file mode 100644 index 00000000000..19d1b80c5dc --- /dev/null +++ b/queue-6.2/sctp-add-a-refcnt-in-sctp_stream_priorities-to-avoid.patch @@ -0,0 +1,166 @@ +From 554a7606ad33d4a43d7999db179477a302406af9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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: + + 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 +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: Xin Long +Link: https://lore.kernel.org/r/825eb0c905cb864991eba335f4a2b780e543f06b.1677085641.git.lucien.xin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 afa3781e3ca21..e1f6e7fc2b11e 100644 +--- a/include/net/sctp/structs.h ++++ b/include/net/sctp/structs.h +@@ -1412,6 +1412,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 42d4800f263dd..4d4d9da331f4c 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_enqueue(struct sctp_outq *q, +-- +2.39.2 + diff --git a/queue-6.2/serial-sc16is7xx-setup-gpio-controller-later-in-prob.patch b/queue-6.2/serial-sc16is7xx-setup-gpio-controller-later-in-prob.patch new file mode 100644 index 00000000000..9c24c22d129 --- /dev/null +++ b/queue-6.2/serial-sc16is7xx-setup-gpio-controller-later-in-prob.patch @@ -0,0 +1,142 @@ +From 6510e6b6a12bb15cf26767c8474e2e3e65281813 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Nov 2022 11:55:30 +0100 +Subject: serial: sc16is7xx: setup GPIO controller later in probe + +From: Isaac True + +[ 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 +Signed-off-by: Wen-chien Jesse Sung +Signed-off-by: Isaac True +Link: https://lore.kernel.org/r/20221130105529.698385-1-isaac.true@canonical.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 39f92eb1e6989..29c94be091596 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -1423,25 +1423,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); +@@ -1518,6 +1499,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. +@@ -1537,18 +1537,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 + diff --git a/queue-6.2/series b/queue-6.2/series index e0e5729ed47..8f80c257f7b 100644 --- a/queue-6.2/series +++ b/queue-6.2/series @@ -1 +1,188 @@ 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 +soc-qcom-socinfo-fix-soc_id-order.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-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 +f2fs-fix-to-do-sanity-check-on-extent-cache-correctl.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-handle-f2fs_ioc_start_atomic_replace-in-.patch +f2fs-fix-to-avoid-potential-memory-corruption-in-__u.patch +f2fs-fix-to-update-age-extent-correctly-during-trunc.patch +f2fs-fix-to-update-age-extent-in-f2fs_do_zero_range.patch +soc-qcom-stats-populate-all-subsystem-debugfs-files.patch +f2fs-introduce-is_f2fs_ipu_-macro.patch +f2fs-fix-to-set-ipu-policy.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 +swiotlb-mark-swiotlb_memblock_alloc-as-__init.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 +drm-i915-xelpmp-consider-gsi-offset-when-doing-mcr-l.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-aspeed-p10bmc-update-battery-node-name.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 +cpufreq-apple-soc-fix-an-is_err-vs-null-check.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-remove-deferred-attach-check-from-__iommu_deta.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 +usb-fotg210-list-different-variants.patch +dt-bindings-usb-add-device-id-for-genesys-logic-hub-.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-28624 +media-uvcvideo-add-guid-for-bgra-x-8-8-8-8.patch +soundwire-bus_type-avoid-lockdep-assert-in-sdw_drv_p.patch +pci-portdrv-prevent-ls7a-bus-master-clearing-on-shut.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 +soundwire-cadence-remove-wasted-space-in-response_bu.patch +soundwire-cadence-drain-the-rx-fifo-after-an-io-time.patch diff --git a/queue-6.2/soc-mediatek-mtk-pm-domains-allow-mt8186-adsp-defaul.patch b/queue-6.2/soc-mediatek-mtk-pm-domains-allow-mt8186-adsp-defaul.patch new file mode 100644 index 00000000000..b39c370c2f7 --- /dev/null +++ b/queue-6.2/soc-mediatek-mtk-pm-domains-allow-mt8186-adsp-defaul.patch @@ -0,0 +1,55 @@ +From c7a46f021fb95fc04fab38dc22020285b64490c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Oct 2022 15:54:34 +0800 +Subject: soc: mediatek: mtk-pm-domains: Allow mt8186 ADSP default power on + +From: Tinghan Shen + +[ 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 +Fixes: 88590cbc1703 ("soc: mediatek: pm-domains: Add support for mt8186") +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221012075434.30009-1-tinghan.shen@mediatek.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/soc-mediatek-mtk-svs-enable-the-irq-later.patch b/queue-6.2/soc-mediatek-mtk-svs-enable-the-irq-later.patch new file mode 100644 index 00000000000..f0c40dc7ba4 --- /dev/null +++ b/queue-6.2/soc-mediatek-mtk-svs-enable-the-irq-later.patch @@ -0,0 +1,64 @@ +From ccb6309af8e1d69935842b3e4590eb85fb96a4b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Dec 2022 22:35:59 +0100 +Subject: soc: mediatek: mtk-svs: Enable the IRQ later + +From: Ricardo Ribalda + +[ 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 +Link: https://lore.kernel.org/r/20221127-mtk-svs-v2-0-145b07663ea8@chromium.org +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/soc-mediatek-mtk-svs-reset-svs-when-svs_resume-fail.patch b/queue-6.2/soc-mediatek-mtk-svs-reset-svs-when-svs_resume-fail.patch new file mode 100644 index 00000000000..77d19b429d2 --- /dev/null +++ b/queue-6.2/soc-mediatek-mtk-svs-reset-svs-when-svs_resume-fail.patch @@ -0,0 +1,45 @@ +From 7f7f39cc37d1c1e831952bde8c242e58db7478b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jan 2023 15:45:16 +0800 +Subject: soc: mediatek: mtk-svs: reset svs when svs_resume() fail + +From: Roger Lu + +[ 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 +Link: https://lore.kernel.org/r/20230111074528.29354-3-roger.lu@mediatek.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/soc-mediatek-mtk-svs-restore-default-voltages-when-s.patch b/queue-6.2/soc-mediatek-mtk-svs-restore-default-voltages-when-s.patch new file mode 100644 index 00000000000..980eb31a334 --- /dev/null +++ b/queue-6.2/soc-mediatek-mtk-svs-restore-default-voltages-when-s.patch @@ -0,0 +1,81 @@ +From 2a0d8eeeecb6ef6124cd8503530c231602c18ba1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jan 2023 15:45:15 +0800 +Subject: soc: mediatek: mtk-svs: restore default voltages when svs_init02() + fail + +From: Roger Lu + +[ 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 +Link: https://lore.kernel.org/r/20230111074528.29354-2-roger.lu@mediatek.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/soc-mediatek-mtk-svs-use-pm_runtime_resume_and_get-i.patch b/queue-6.2/soc-mediatek-mtk-svs-use-pm_runtime_resume_and_get-i.patch new file mode 100644 index 00000000000..4a65fac0511 --- /dev/null +++ b/queue-6.2/soc-mediatek-mtk-svs-use-pm_runtime_resume_and_get-i.patch @@ -0,0 +1,42 @@ +From 192ef4e7e09ba8379ff01f1562fc55137d01e71e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Roger Lu +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230111074528.29354-5-roger.lu@mediatek.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/soc-qcom-socinfo-fix-soc_id-order.patch b/queue-6.2/soc-qcom-socinfo-fix-soc_id-order.patch new file mode 100644 index 00000000000..d2cc313ba90 --- /dev/null +++ b/queue-6.2/soc-qcom-socinfo-fix-soc_id-order.patch @@ -0,0 +1,67 @@ +From 77d8e0f0441385046efc7579f59ec97ee5bba215 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Jan 2023 12:53:45 +0100 +Subject: soc: qcom: socinfo: Fix soc_id order + +From: Stephan Gerhold + +[ Upstream commit 017a7c11a8a29e266aa40c6d1bf2ba83f880f719 ] + +The soc_id array is mostly ordered by the numeric "msm-id" defined in +qcom,ids.h but some recent entries were added at the wrong place. + +While it does not make a functional difference it does make it harder +to regenerate the entire array after adding a bunch of new IDs. + +Fixes: de320c07da3d ("soc: qcom: socinfo: Add MSM8956/76 SoC IDs to the soc_id table") +Fixes: 147f6534b8ff ("soc: qcom: socinfo: Add SM8550 ID") +Signed-off-by: Stephan Gerhold +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230104115348.25046-2-stephan@gerhold.net +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/socinfo.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c +index ebcbf9b9c18bc..7ce28be9f435e 100644 +--- a/drivers/soc/qcom/socinfo.c ++++ b/drivers/soc/qcom/socinfo.c +@@ -250,8 +250,6 @@ static const struct soc_id soc_id[] = { + { qcom_board_id(MSM8926) }, + { qcom_board_id(MSM8326) }, + { qcom_board_id(MSM8916) }, +- { qcom_board_id(MSM8956) }, +- { qcom_board_id(MSM8976) }, + { qcom_board_id(MSM8994) }, + { qcom_board_id_named(APQ8074PRO_AA, "APQ8074PRO-AA") }, + { qcom_board_id_named(APQ8074PRO_AB, "APQ8074PRO-AB") }, +@@ -283,6 +281,8 @@ static const struct soc_id soc_id[] = { + { qcom_board_id(MSM8616) }, + { qcom_board_id(MSM8992) }, + { qcom_board_id(APQ8094) }, ++ { qcom_board_id(MSM8956) }, ++ { qcom_board_id(MSM8976) }, + { qcom_board_id(MDM9607) }, + { qcom_board_id(APQ8096) }, + { qcom_board_id(MSM8998) }, +@@ -341,7 +341,6 @@ static const struct soc_id soc_id[] = { + { qcom_board_id(IPQ6005) }, + { qcom_board_id(QRB5165) }, + { qcom_board_id(SM8450) }, +- { qcom_board_id(SM8550) }, + { qcom_board_id(SM7225) }, + { qcom_board_id(SA8295P) }, + { qcom_board_id(SA8540P) }, +@@ -352,6 +351,7 @@ static const struct soc_id soc_id[] = { + { qcom_board_id(SC7280) }, + { qcom_board_id(SC7180P) }, + { qcom_board_id(SM6375) }, ++ { qcom_board_id(SM8550) }, + { qcom_board_id(QRU1000) }, + { qcom_board_id(QDU1000) }, + { qcom_board_id(QDU1010) }, +-- +2.39.2 + diff --git a/queue-6.2/soc-qcom-stats-populate-all-subsystem-debugfs-files.patch b/queue-6.2/soc-qcom-stats-populate-all-subsystem-debugfs-files.patch new file mode 100644 index 00000000000..415099427f1 --- /dev/null +++ b/queue-6.2/soc-qcom-stats-populate-all-subsystem-debugfs-files.patch @@ -0,0 +1,74 @@ +From da62cc632acdebd2d1cb3c83c77d6f0f20214c77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Jan 2023 19:23:29 -0800 +Subject: soc: qcom: stats: Populate all subsystem debugfs files + +From: Stephen Boyd + +[ 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 +Signed-off-by: Stephen Boyd +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230119032329.2909383-1-swboyd@chromium.org +Signed-off-by: Sasha Levin +--- + 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 6228af057120b..c207bb96c523a 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 + diff --git a/queue-6.2/soundwire-bus_type-avoid-lockdep-assert-in-sdw_drv_p.patch b/queue-6.2/soundwire-bus_type-avoid-lockdep-assert-in-sdw_drv_p.patch new file mode 100644 index 00000000000..ff9dd8ed99e --- /dev/null +++ b/queue-6.2/soundwire-bus_type-avoid-lockdep-assert-in-sdw_drv_p.patch @@ -0,0 +1,277 @@ +From 40b5748b77731cf0eca2abd442c7017c95b87cad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Jan 2023 17:25:20 +0000 +Subject: soundwire: bus_type: Avoid lockdep assert in sdw_drv_probe() + +From: Richard Fitzgerald + +[ 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] +[ 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] + +Signed-off-by: Richard Fitzgerald +Reviewed-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20230123172520.339367-1-rf@opensource.cirrus.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/soundwire-cadence-drain-the-rx-fifo-after-an-io-time.patch b/queue-6.2/soundwire-cadence-drain-the-rx-fifo-after-an-io-time.patch new file mode 100644 index 00000000000..19ef565ec57 --- /dev/null +++ b/queue-6.2/soundwire-cadence-drain-the-rx-fifo-after-an-io-time.patch @@ -0,0 +1,112 @@ +From d5aa1e40cfa08f2171db218702ef04f65abd59f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Dec 2022 16:18:12 +0000 +Subject: soundwire: cadence: Drain the RX FIFO after an IO timeout + +From: Richard Fitzgerald + +[ 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 +Reviewed-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20221202161812.4186897-4-rf@opensource.cirrus.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + 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 a6635f7f350ef..5213873221458 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 + diff --git a/queue-6.2/soundwire-cadence-remove-wasted-space-in-response_bu.patch b/queue-6.2/soundwire-cadence-remove-wasted-space-in-response_bu.patch new file mode 100644 index 00000000000..c792b5ba204 --- /dev/null +++ b/queue-6.2/soundwire-cadence-remove-wasted-space-in-response_bu.patch @@ -0,0 +1,82 @@ +From da93c55b18d371cc4a24f4faf3503bf55356159b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Dec 2022 16:18:11 +0000 +Subject: soundwire: cadence: Remove wasted space in response_buf + +From: Richard Fitzgerald + +[ 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 +Reviewed-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20221202161812.4186897-3-rf@opensource.cirrus.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + 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 27699f341f2c5..a6635f7f350ef 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 0434d70d4b1f5..e0a64b28c6b9c 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 + * +@@ -117,7 +123,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 + diff --git a/queue-6.2/spi-tegra210-quad-fix-iterator-outside-loop.patch b/queue-6.2/spi-tegra210-quad-fix-iterator-outside-loop.patch new file mode 100644 index 00000000000..ecc27f61d95 --- /dev/null +++ b/queue-6.2/spi-tegra210-quad-fix-iterator-outside-loop.patch @@ -0,0 +1,62 @@ +From b1b54fabd783348504be20fa047ce98caa48acdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Feb 2023 01:34:28 +0530 +Subject: spi: tegra210-quad: Fix iterator outside loop + +From: Krishna Yarlagadda + +[ 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 +Link:https://lore.kernel.org/all/202210191211.46FkzKmv-lkp@intel.com/ +Fixes: 8777dd9dff40 ("spi: tegra210-quad: Fix combined sequence") + +Signed-off-by: Krishna Yarlagadda +Link: https://lore.kernel.org/r/20230227200428.45832-1-kyarlagadda@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/spi-tegra210-quad-fix-validate-combined-sequence.patch b/queue-6.2/spi-tegra210-quad-fix-validate-combined-sequence.patch new file mode 100644 index 00000000000..c79e31bb0ab --- /dev/null +++ b/queue-6.2/spi-tegra210-quad-fix-validate-combined-sequence.patch @@ -0,0 +1,38 @@ +From 6d7ad009ea5dd01808f006505731d225488660ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Feb 2023 22:10:34 +0530 +Subject: spi: tegra210-quad: Fix validate combined sequence + +From: Krishna Yarlagadda + +[ 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 +Link: https://lore.kernel.org/r/20230224164034.56933-1-kyarlagadda@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/staging-emxx_udc-add-checks-for-dma_alloc_coherent.patch b/queue-6.2/staging-emxx_udc-add-checks-for-dma_alloc_coherent.patch new file mode 100644 index 00000000000..f20e6a8f29e --- /dev/null +++ b/queue-6.2/staging-emxx_udc-add-checks-for-dma_alloc_coherent.patch @@ -0,0 +1,45 @@ +From b208c889ae2fbe5cf0b9207d5f862606b80c7a7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Jan 2023 08:31:19 +0000 +Subject: staging: emxx_udc: Add checks for dma_alloc_coherent() + +From: Yuan Can + +[ 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 +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20230119083119.16956-1-yuancan@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 b4e19174bef2e..f9765841c4aa3 100644 +--- a/drivers/staging/emxx_udc/emxx_udc.c ++++ b/drivers/staging/emxx_udc/emxx_udc.c +@@ -2587,10 +2587,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 + diff --git a/queue-6.2/staging-pi433-fix-memory-leak-with-using-debugfs_loo.patch b/queue-6.2/staging-pi433-fix-memory-leak-with-using-debugfs_loo.patch new file mode 100644 index 00000000000..84c5875f58a --- /dev/null +++ b/queue-6.2/staging-pi433-fix-memory-leak-with-using-debugfs_loo.patch @@ -0,0 +1,84 @@ +From 8ff6c7759a9a678395470221ad3535ed9824857f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Dan Carpenter +Cc: Sidong Yang +Cc: Liu Shixin +Cc: "Uwe Kleine-König" +Link: https://lore.kernel.org/r/20230202141138.2291946-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/swiotlb-mark-swiotlb_memblock_alloc-as-__init.patch b/queue-6.2/swiotlb-mark-swiotlb_memblock_alloc-as-__init.patch new file mode 100644 index 00000000000..e11ee41ddf6 --- /dev/null +++ b/queue-6.2/swiotlb-mark-swiotlb_memblock_alloc-as-__init.patch @@ -0,0 +1,51 @@ +From dd7cff6757d2df49f0115934bd41ae613288f7b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Feb 2023 23:04:11 -0800 +Subject: swiotlb: mark swiotlb_memblock_alloc() as __init + +From: Randy Dunlap + +[ Upstream commit 9b07d27d0fbb7f7441aa986859a0f53ec93a0335 ] + +swiotlb_memblock_alloc() calls memblock_alloc(), which calls +(__init) memblock_alloc_try_nid(). However, swiotlb_membloc_alloc() +can be marked as __init since it is only called by swiotlb_init_remap(), +which is already marked as __init. This prevents a modpost build +warning/error: + +WARNING: modpost: vmlinux.o: section mismatch in reference: swiotlb_memblock_alloc (section: .text) -> memblock_alloc_try_nid (section: .init.text) +WARNING: modpost: vmlinux.o: section mismatch in reference: swiotlb_memblock_alloc (section: .text) -> memblock_alloc_try_nid (section: .init.text) + +This fixes the build warning/error seen on ARM64, PPC64, S390, i386, +and x86_64. + +Fixes: 8d58aa484920 ("swiotlb: reduce the swiotlb buffer size on allocation failure") +Signed-off-by: Randy Dunlap +Cc: Alexey Kardashevskiy +Cc: Christoph Hellwig +Cc: iommu@lists.linux.dev +Cc: Mike Rapoport +Cc: linux-mm@kvack.org +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + kernel/dma/swiotlb.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c +index a34c38bbe28f1..ef3bc3a5bbed3 100644 +--- a/kernel/dma/swiotlb.c ++++ b/kernel/dma/swiotlb.c +@@ -300,7 +300,8 @@ static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start, + return; + } + +-static void *swiotlb_memblock_alloc(unsigned long nslabs, unsigned int flags, ++static void __init *swiotlb_memblock_alloc(unsigned long nslabs, ++ unsigned int flags, + int (*remap)(void *tlb, unsigned long nslabs)) + { + size_t bytes = PAGE_ALIGN(nslabs << IO_TLB_SHIFT); +-- +2.39.2 + diff --git a/queue-6.2/tcp-tcp_check_req-can-be-called-from-process-context.patch b/queue-6.2/tcp-tcp_check_req-can-be-called-from-process-context.patch new file mode 100644 index 00000000000..815ed342f79 --- /dev/null +++ b/queue-6.2/tcp-tcp_check_req-can-be-called-from-process-context.patch @@ -0,0 +1,68 @@ +From 004981a582214911c3084176e370fd093d024c92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Feb 2023 08:33:36 +0000 +Subject: tcp: tcp_check_req() can be called from process context + +From: Eric Dumazet + +[ 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 +Reported-by: Frederick Lawler +Tested-by: Frederick Lawler +Link: https://lore.kernel.org/r/20230227083336.4153089-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 e002f2e1d4f2d..9a7ef7732c24c 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -597,6 +597,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, +@@ -748,7 +751,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; + } + +@@ -767,7 +770,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 + diff --git a/queue-6.2/thermal-intel-bxt_pmic-select-regmap-instead-of-depe.patch b/queue-6.2/thermal-intel-bxt_pmic-select-regmap-instead-of-depe.patch new file mode 100644 index 00000000000..1933f3441d6 --- /dev/null +++ b/queue-6.2/thermal-intel-bxt_pmic-select-regmap-instead-of-depe.patch @@ -0,0 +1,43 @@ +From 9b87be2622762e992cb9d8cd64f9cd75eaf25142 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Feb 2023 21:39:52 -0800 +Subject: thermal: intel: BXT_PMIC: select REGMAP instead of depending on it + +From: Randy Dunlap + +[ 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 +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/thermal-intel-quark_dts-fix-error-pointer-dereferenc.patch b/queue-6.2/thermal-intel-quark_dts-fix-error-pointer-dereferenc.patch new file mode 100644 index 00000000000..05a22651db0 --- /dev/null +++ b/queue-6.2/thermal-intel-quark_dts-fix-error-pointer-dereferenc.patch @@ -0,0 +1,52 @@ +From c5d796bc42153470555452877b55ce5d200195bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Feb 2023 13:06:50 +0300 +Subject: thermal: intel: quark_dts: fix error pointer dereference + +From: Dan Carpenter + +[ 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 +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/tools-iio-iio_utils-fix-memory-leak.patch b/queue-6.2/tools-iio-iio_utils-fix-memory-leak.patch new file mode 100644 index 00000000000..94c5eba9eb8 --- /dev/null +++ b/queue-6.2/tools-iio-iio_utils-fix-memory-leak.patch @@ -0,0 +1,154 @@ +From 6843b0c9e9eaea37de621239c27250f763f372ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jan 2023 10:51:47 +0800 +Subject: tools/iio/iio_utils:fix memory leak + +From: Yulong Zhang + +[ 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 +Link: https://lore.kernel.org/r/20230117025147.69890-1-yulong.zhang@metoak.net +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/tracing-add-null-checks-for-buffer-in-ring_buffer_fr.patch b/queue-6.2/tracing-add-null-checks-for-buffer-in-ring_buffer_fr.patch new file mode 100644 index 00000000000..f74f570e4fe --- /dev/null +++ b/queue-6.2/tracing-add-null-checks-for-buffer-in-ring_buffer_fr.patch @@ -0,0 +1,62 @@ +From 7b4431df60138265f19c9c323c1e05384fd7fb61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Jia-Ju Bai +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +--- + 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 b641cab2745e9..20cd8c9d245e2 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -5604,11 +5604,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 + diff --git a/queue-6.2/tty-fix-out-of-bounds-access-in-tty_driver_lookup_tt.patch b/queue-6.2/tty-fix-out-of-bounds-access-in-tty_driver_lookup_tt.patch new file mode 100644 index 00000000000..ae8bac6f803 --- /dev/null +++ b/queue-6.2/tty-fix-out-of-bounds-access-in-tty_driver_lookup_tt.patch @@ -0,0 +1,75 @@ +From 27d1f0492fd78d676094f1ac0862a3f32ae6c054 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Dec 2022 12:27:36 +0100 +Subject: tty: fix out-of-bounds access in tty_driver_lookup_tty() + +From: Sven Schnelle + +[ 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 +Reviewed-by: Jiri Slaby +Link: https://lore.kernel.org/r/20221209112737.3222509-2-svens@linux.ibm.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 3149114bf130e..36fb945fdad48 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 + diff --git a/queue-6.2/tty-pcn_uart-fix-memory-leak-with-using-debugfs_look.patch b/queue-6.2/tty-pcn_uart-fix-memory-leak-with-using-debugfs_look.patch new file mode 100644 index 00000000000..75f6596cc2f --- /dev/null +++ b/queue-6.2/tty-pcn_uart-fix-memory-leak-with-using-debugfs_look.patch @@ -0,0 +1,38 @@ +From d554aff9825aa45a6074afc20d5d7a68272e59e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 15:12:21 +0100 +Subject: tty: pcn_uart: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Link: https://lore.kernel.org/r/20230202141221.2293012-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 9576ba8bbc40e..cc83b772b7ca9 100644 +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -1775,7 +1775,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 + diff --git a/queue-6.2/tty-serial-fsl_lpuart-disable-the-cts-when-send-brea.patch b/queue-6.2/tty-serial-fsl_lpuart-disable-the-cts-when-send-brea.patch new file mode 100644 index 00000000000..1f12dee6633 --- /dev/null +++ b/queue-6.2/tty-serial-fsl_lpuart-disable-the-cts-when-send-brea.patch @@ -0,0 +1,76 @@ +From f83d49d40926e02c782f8152e01811d61d75ea65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Dec 2022 11:11:35 +0800 +Subject: tty: serial: fsl_lpuart: disable the CTS when send break signal + +From: Sherry Sun + +[ 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 +Link: https://lore.kernel.org/r/20221214031137.28815-2-sherry.sun@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 23910ac724b11..b136c596fe6ae 100644 +--- a/drivers/tty/serial/fsl_lpuart.c ++++ b/drivers/tty/serial/fsl_lpuart.c +@@ -1462,12 +1462,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 + diff --git a/queue-6.2/ubi-ensure-that-vid-header-offset-vid-header-size-al.patch b/queue-6.2/ubi-ensure-that-vid-header-offset-vid-header-size-al.patch new file mode 100644 index 00000000000..6b834c7364c --- /dev/null +++ b/queue-6.2/ubi-ensure-that-vid-header-offset-vid-header-size-al.patch @@ -0,0 +1,131 @@ +From 9b906afacc37e3def0705598185149764d0ac5d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 10:14:44 -0500 +Subject: ubi: ensure that VID header offset + VID header size <= alloc, size + +From: George Kennedy + +[ 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: + + __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 + + +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 +Signed-off-by: George Kennedy +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubi-fastmap-fix-missed-fm_anchor-peb-in-wear-levelin.patch b/queue-6.2/ubi-fastmap-fix-missed-fm_anchor-peb-in-wear-levelin.patch new file mode 100644 index 00000000000..77a70099fce --- /dev/null +++ b/queue-6.2/ubi-fastmap-fix-missed-fm_anchor-peb-in-wear-levelin.patch @@ -0,0 +1,64 @@ +From 2778766ee10d4fa090f6f45960792fcec4673f09 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubi-fix-possible-null-ptr-deref-in-ubi_free_volume.patch b/queue-6.2/ubi-fix-possible-null-ptr-deref-in-ubi_free_volume.patch new file mode 100644 index 00000000000..e866188edb9 --- /dev/null +++ b/queue-6.2/ubi-fix-possible-null-ptr-deref-in-ubi_free_volume.patch @@ -0,0 +1,89 @@ +From c0c3238d9378f9500cf802492f095f547ec4db5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Nov 2022 18:26:24 +0800 +Subject: ubi: Fix possible null-ptr-deref in ubi_free_volume() + +From: Yang Yingliang + +[ 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 +Signed-off-by: Yang Yingliang +Reviewed-by: Zhihao Cheng +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubi-fix-uaf-wear-leveling-entry-in-eraseblk_count_se.patch b/queue-6.2/ubi-fix-uaf-wear-leveling-entry-in-eraseblk_count_se.patch new file mode 100644 index 00000000000..b1ace5aac10 --- /dev/null +++ b/queue-6.2/ubi-fix-uaf-wear-leveling-entry-in-eraseblk_count_se.patch @@ -0,0 +1,76 @@ +From 6723b7a53f99b74d3ddaf1bb7c1cdb161f317788 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Jul 2022 19:28:37 +0800 +Subject: ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show() + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubi-fix-unreferenced-object-reported-by-kmemleak-in-.patch b/queue-6.2/ubi-fix-unreferenced-object-reported-by-kmemleak-in-.patch new file mode 100644 index 00000000000..7e968bd79f6 --- /dev/null +++ b/queue-6.2/ubi-fix-unreferenced-object-reported-by-kmemleak-in-.patch @@ -0,0 +1,59 @@ +From 7358622f7b9379eb586c418d3fac523a500706dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 18:21:57 +0800 +Subject: ubi: Fix unreferenced object reported by kmemleak in + ubi_resize_volume() + +From: Li Zetao + +[ 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: +[] __kmalloc+0x4d/0x150 +[] ubi_eba_create_table+0x76/0x170 [ubi] +[] ubi_resize_volume+0x1be/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 + +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 +Reviewed-by: Zhihao Cheng +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubi-fix-use-after-free-when-volume-resizing-failed.patch b/queue-6.2/ubi-fix-use-after-free-when-volume-resizing-failed.patch new file mode 100644 index 00000000000..6ec4274131c --- /dev/null +++ b/queue-6.2/ubi-fix-use-after-free-when-volume-resizing-failed.patch @@ -0,0 +1,74 @@ +From dada4c8ecc54a3087d0244a0528ecdd4bec282d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 18:21:56 +0800 +Subject: ubi: Fix use-after-free when volume resizing failed + +From: Li Zetao + +[ 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: + + 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 + + +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 +Reviewed-by: Zhihao Cheng +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubi-ubi_wl_put_peb-fix-infinite-loop-when-wear-level.patch b/queue-6.2/ubi-ubi_wl_put_peb-fix-infinite-loop-when-wear-level.patch new file mode 100644 index 00000000000..35b32fa0770 --- /dev/null +++ b/queue-6.2/ubi-ubi_wl_put_peb-fix-infinite-loop-when-wear-level.patch @@ -0,0 +1,90 @@ +From c16aab1b3be6b453793591d18a9a4de9ce7f2d79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-dirty_cow_znode-fix-memleak-in-error-handling-.patch b/queue-6.2/ubifs-dirty_cow_znode-fix-memleak-in-error-handling-.patch new file mode 100644 index 00000000000..fcaffc20504 --- /dev/null +++ b/queue-6.2/ubifs-dirty_cow_znode-fix-memleak-in-error-handling-.patch @@ -0,0 +1,58 @@ +From c3107c18105ec51d5e492e88f3073045d24b3291 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Nov 2022 17:02:36 +0800 +Subject: ubifs: dirty_cow_znode: Fix memleak in error handling path + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-do_rename-fix-wrong-space-budget-when-target-i.patch b/queue-6.2/ubifs-do_rename-fix-wrong-space-budget-when-target-i.patch new file mode 100644 index 00000000000..07797f3ec90 --- /dev/null +++ b/queue-6.2/ubifs-do_rename-fix-wrong-space-budget-when-target-i.patch @@ -0,0 +1,43 @@ +From c3695f3b6db20c81e95656634c1da4b0d7285701 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-fix-build-errors-as-symbol-undefined.patch b/queue-6.2/ubifs-fix-build-errors-as-symbol-undefined.patch new file mode 100644 index 00000000000..a91575d3296 --- /dev/null +++ b/queue-6.2/ubifs-fix-build-errors-as-symbol-undefined.patch @@ -0,0 +1,49 @@ +From 02818eb7d26d23084e27bb40e33361167f8fe47f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Nov 2022 19:18:47 +0800 +Subject: ubifs: Fix build errors as symbol undefined + +From: Li Hua + +[ 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 +Reviewed-by: Sascha Hauer +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-fix-memory-leak-in-alloc_wbufs.patch b/queue-6.2/ubifs-fix-memory-leak-in-alloc_wbufs.patch new file mode 100644 index 00000000000..c3fc026ab46 --- /dev/null +++ b/queue-6.2/ubifs-fix-memory-leak-in-alloc_wbufs.patch @@ -0,0 +1,104 @@ +From 45f0911b10cff8a312f06b7e31d8be321ff16f52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Oct 2022 19:52:11 +0800 +Subject: ubifs: Fix memory leak in alloc_wbufs() + +From: Li Zetao + +[ 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: + [] __kmalloc+0x4d/0x150 + [] ubifs_mount+0x307b/0x7170 [ubifs] + [] legacy_get_tree+0xed/0x1d0 + [] vfs_get_tree+0x7d/0x230 + [] path_mount+0xdd4/0x17b0 + [] __x64_sys_mount+0x1fa/0x270 + [] do_syscall_64+0x35/0x80 + [] 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: + [] __kmalloc+0x4d/0x150 + [] ubifs_wbuf_init+0x52/0x480 [ubifs] + [] ubifs_mount+0x31f5/0x7170 [ubifs] + [] legacy_get_tree+0xed/0x1d0 + [] vfs_get_tree+0x7d/0x230 + [] path_mount+0xdd4/0x17b0 + [] __x64_sys_mount+0x1fa/0x270 + [] do_syscall_64+0x35/0x80 + [] 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 +Reviewed-by: Zhihao Cheng +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-fix-memory-leak-in-ubifs_sysfs_init.patch b/queue-6.2/ubifs-fix-memory-leak-in-ubifs_sysfs_init.patch new file mode 100644 index 00000000000..b7a69770059 --- /dev/null +++ b/queue-6.2/ubifs-fix-memory-leak-in-ubifs_sysfs_init.patch @@ -0,0 +1,57 @@ +From 306892591ff52a0deb2d9ce0883b627fa9973a19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Oct 2022 12:30:31 +0800 +Subject: ubifs: Fix memory leak in ubifs_sysfs_init() + +From: Liu Shixin + +[ 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: + [] slab_post_alloc_hook+0x9c/0x3c0 + [] __kmalloc_track_caller+0x183/0x410 + [] kstrdup+0x3a/0x80 + [] kstrdup_const+0x66/0x80 + [] kvasprintf_const+0x155/0x190 + [] kobject_set_name_vargs+0x5b/0x150 + [] kobject_set_name+0xbb/0xf0 + [] do_one_initcall+0x14c/0x5a0 + [] do_init_module+0x1f0/0x660 + [] load_module+0x6d7e/0x7590 + [] __do_sys_finit_module+0x19f/0x230 + [] __x64_sys_finit_module+0x73/0xb0 + [] do_syscall_64+0x35/0x80 + [] 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-fix-wrong-dirty-space-budget-for-dirty-inode.patch b/queue-6.2/ubifs-fix-wrong-dirty-space-budget-for-dirty-inode.patch new file mode 100644 index 00000000000..22a3902b846 --- /dev/null +++ b/queue-6.2/ubifs-fix-wrong-dirty-space-budget-for-dirty-inode.patch @@ -0,0 +1,37 @@ +From 1130ae7888214cf9b5d47c88db4b16f40fb83246 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Oct 2022 11:47:30 +0800 +Subject: ubifs: Fix wrong dirty space budget for dirty inode + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-re-statistic-cleaned-znode-count-if-commit-fai.patch b/queue-6.2/ubifs-re-statistic-cleaned-znode-count-if-commit-fai.patch new file mode 100644 index 00000000000..11812cd40cb --- /dev/null +++ b/queue-6.2/ubifs-re-statistic-cleaned-znode-count-if-commit-fai.patch @@ -0,0 +1,86 @@ +From 15e023bba7f421576dfce969ddf2fbf4d8686646 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Nov 2022 17:02:35 +0800 +Subject: ubifs: Re-statistic cleaned znode count if commit failed + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-rectify-space-budget-for-ubifs_symlink-if-syml.patch b/queue-6.2/ubifs-rectify-space-budget-for-ubifs_symlink-if-syml.patch new file mode 100644 index 00000000000..e2f4d11ae41 --- /dev/null +++ b/queue-6.2/ubifs-rectify-space-budget-for-ubifs_symlink-if-syml.patch @@ -0,0 +1,48 @@ +From 0dade300a4261210c261eed5ed2b01645246e4e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Oct 2022 11:47:27 +0800 +Subject: ubifs: Rectify space budget for ubifs_symlink() if symlink is + encrypted + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-rectify-space-budget-for-ubifs_xrename.patch b/queue-6.2/ubifs-rectify-space-budget-for-ubifs_xrename.patch new file mode 100644 index 00000000000..f9a673bd5b6 --- /dev/null +++ b/queue-6.2/ubifs-rectify-space-budget-for-ubifs_xrename.patch @@ -0,0 +1,51 @@ +From 3e77591582372dceb7452e4ed2b7682997167e8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Oct 2022 11:47:28 +0800 +Subject: ubifs: Rectify space budget for ubifs_xrename() + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-reserve-one-leb-for-each-journal-head-while-do.patch b/queue-6.2/ubifs-reserve-one-leb-for-each-journal-head-while-do.patch new file mode 100644 index 00000000000..27bad676a4f --- /dev/null +++ b/queue-6.2/ubifs-reserve-one-leb-for-each-journal-head-while-do.patch @@ -0,0 +1,65 @@ +From 928bd4bc5c55ea22fdb4347e2869f30a4419c799 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Oct 2022 11:47:32 +0800 +Subject: ubifs: Reserve one leb for each journal head while doing budget + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-ubifs_releasepage-remove-ubifs_assert-0-to-val.patch b/queue-6.2/ubifs-ubifs_releasepage-remove-ubifs_assert-0-to-val.patch new file mode 100644 index 00000000000..06850482815 --- /dev/null +++ b/queue-6.2/ubifs-ubifs_releasepage-remove-ubifs_assert-0-to-val.patch @@ -0,0 +1,116 @@ +From ccdc6c9496c2f0845fadd7899393d522b27588f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Jun 2022 11:00:00 +0800 +Subject: ubifs: ubifs_releasepage: Remove ubifs_assert(0) to valid this + process + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/ubifs-ubifs_writepage-mark-page-dirty-after-writing-.patch b/queue-6.2/ubifs-ubifs_writepage-mark-page-dirty-after-writing-.patch new file mode 100644 index 00000000000..994f22ca41c --- /dev/null +++ b/queue-6.2/ubifs-ubifs_writepage-mark-page-dirty-after-writing-.patch @@ -0,0 +1,114 @@ +From 365c2a856b61bb6bfed48d4dceb7cda4af94563d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Jun 2022 10:59:59 +0800 +Subject: ubifs: ubifs_writepage: Mark page dirty after writing inode failed + +From: Zhihao Cheng + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/um-vector-fix-memory-leak-in-vector_config.patch b/queue-6.2/um-vector-fix-memory-leak-in-vector_config.patch new file mode 100644 index 00000000000..7e71ed8b069 --- /dev/null +++ b/queue-6.2/um-vector-fix-memory-leak-in-vector_config.patch @@ -0,0 +1,36 @@ +From 7ff9393c39f383ca2aaa4d663f23d8bad9c5d07a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Nov 2022 15:32:25 +0800 +Subject: um: vector: Fix memory leak in vector_config + +From: Xiang Yang + +[ 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 +Acked-By: Anton Ivanov +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/um-virt-pci-properly-remove-pci-device-from-bus.patch b/queue-6.2/um-virt-pci-properly-remove-pci-device-from-bus.patch new file mode 100644 index 00000000000..d4717cb865b --- /dev/null +++ b/queue-6.2/um-virt-pci-properly-remove-pci-device-from-bus.patch @@ -0,0 +1,66 @@ +From df45daf9bc8c84614b2457aca8b17634b2a9b058 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Feb 2023 10:00:05 +0100 +Subject: um: virt-pci: properly remove PCI device from bus + +From: Benjamin Berg + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/um-virtio_uml-free-command-if-adding-to-virtqueue-fa.patch b/queue-6.2/um-virtio_uml-free-command-if-adding-to-virtqueue-fa.patch new file mode 100644 index 00000000000..f056ce7210d --- /dev/null +++ b/queue-6.2/um-virtio_uml-free-command-if-adding-to-virtqueue-fa.patch @@ -0,0 +1,40 @@ +From 7c37793035ccf052be212b9bc7e192d585c3ac59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Feb 2023 10:00:02 +0100 +Subject: um: virtio_uml: free command if adding to virtqueue failed + +From: Benjamin Berg + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/um-virtio_uml-mark-device-as-unregistered-when-break.patch b/queue-6.2/um-virtio_uml-mark-device-as-unregistered-when-break.patch new file mode 100644 index 00000000000..a5f93b33abb --- /dev/null +++ b/queue-6.2/um-virtio_uml-mark-device-as-unregistered-when-break.patch @@ -0,0 +1,37 @@ +From 0d672bbf4a022a5daa45ba97609131df3d69a907 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Feb 2023 10:00:03 +0100 +Subject: um: virtio_uml: mark device as unregistered when breaking it + +From: Benjamin Berg + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/um-virtio_uml-move-device-breaking-into-workqueue.patch b/queue-6.2/um-virtio_uml-move-device-breaking-into-workqueue.patch new file mode 100644 index 00000000000..c8d3710f62c --- /dev/null +++ b/queue-6.2/um-virtio_uml-move-device-breaking-into-workqueue.patch @@ -0,0 +1,67 @@ +From c81390064c12f1e06f4cb6410e29ef53ab5f1c28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Feb 2023 10:00:04 +0100 +Subject: um: virtio_uml: move device breaking into workqueue + +From: Benjamin Berg + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-chipidea-fix-memory-leak-with-using-debugfs_look.patch b/queue-6.2/usb-chipidea-fix-memory-leak-with-using-debugfs_look.patch new file mode 100644 index 00000000000..2135f367111 --- /dev/null +++ b/queue-6.2/usb-chipidea-fix-memory-leak-with-using-debugfs_look.patch @@ -0,0 +1,36 @@ +From de598e420e4fe5c818ba35e1d506cd04c996bc45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:32:23 +0100 +Subject: USB: chipidea: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-dwc3-fix-memory-leak-with-using-debugfs_lookup.patch b/queue-6.2/usb-dwc3-fix-memory-leak-with-using-debugfs_lookup.patch new file mode 100644 index 00000000000..ed2cdfd8b08 --- /dev/null +++ b/queue-6.2/usb-dwc3-fix-memory-leak-with-using-debugfs_lookup.patch @@ -0,0 +1,143 @@ +From 1bc3168d6bd316c1898fa7d54cea9af0c737d1cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:28:20 +0100 +Subject: USB: dwc3: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Reported-by: Cixi Geng +Tested-by: Cixi Geng +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20230202152820.2409908-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 89dcfac01235f..3c63fa97a6800 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -3194,9 +3194,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 + diff --git a/queue-6.2/usb-ene_usb6250-allocate-enough-memory-for-full-obje.patch b/queue-6.2/usb-ene_usb6250-allocate-enough-memory-for-full-obje.patch new file mode 100644 index 00000000000..ef6bd68a18b --- /dev/null +++ b/queue-6.2/usb-ene_usb6250-allocate-enough-memory-for-full-obje.patch @@ -0,0 +1,61 @@ +From 68a6743e84947eaf66a3b463bbbf6b6436eb045c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Feb 2023 10:35:46 -0800 +Subject: USB: ene_usb6250: Allocate enough memory for full object + +From: Kees Cook + +[ 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 +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20230204183546.never.849-kees@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-fix-memory-leak-with-using-debugfs_lookup.patch b/queue-6.2/usb-fix-memory-leak-with-using-debugfs_lookup.patch new file mode 100644 index 00000000000..11c3c2af73d --- /dev/null +++ b/queue-6.2/usb-fix-memory-leak-with-using-debugfs_lookup.patch @@ -0,0 +1,39 @@ +From b33855175cce91cfa23ca83cc240203d134a7834 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jan 2023 16:28:28 +0100 +Subject: USB: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Cc: Jilin Yuan +Link: https://lore.kernel.org/r/20230106152828.3790902-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-fotg210-fix-memory-leak-with-using-debugfs_looku.patch b/queue-6.2/usb-fotg210-fix-memory-leak-with-using-debugfs_looku.patch new file mode 100644 index 00000000000..359e138d2b3 --- /dev/null +++ b/queue-6.2/usb-fotg210-fix-memory-leak-with-using-debugfs_looku.patch @@ -0,0 +1,38 @@ +From 9688be3e4a2b5fe68e98f6a7c476e84c3242a4fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:32:27 +0100 +Subject: USB: fotg210: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-5-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/fotg210/fotg210-hcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/fotg210/fotg210-hcd.c b/drivers/usb/fotg210/fotg210-hcd.c +index 51ac93a2eb98e..1c5eb8f8c19c6 100644 +--- a/drivers/usb/fotg210/fotg210-hcd.c ++++ b/drivers/usb/fotg210/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 + diff --git a/queue-6.2/usb-fotg210-list-different-variants.patch b/queue-6.2/usb-fotg210-list-different-variants.patch new file mode 100644 index 00000000000..579c876d447 --- /dev/null +++ b/queue-6.2/usb-fotg210-list-different-variants.patch @@ -0,0 +1,38 @@ +From bb1f9ec94ed401eb3a45fefc3dcef44e9cbfd67b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Jan 2023 08:09:16 +0100 +Subject: usb: fotg210: List different variants + +From: Linus Walleij + +[ Upstream commit 170da81aab077c9e85fc2b786413ca07942774a0 ] + +There are at least two variants of the FOTG: FOTG200 and +FOTG210. Handle them in this driver and let's add +more quirks as we go along. + +Signed-off-by: Linus Walleij +Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-2-100388af9810@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/fotg210/fotg210-core.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/usb/fotg210/fotg210-core.c b/drivers/usb/fotg210/fotg210-core.c +index ee740a6da463f..da9ea5957ccff 100644 +--- a/drivers/usb/fotg210/fotg210-core.c ++++ b/drivers/usb/fotg210/fotg210-core.c +@@ -127,7 +127,9 @@ static int fotg210_remove(struct platform_device *pdev) + + #ifdef CONFIG_OF + static const struct of_device_id fotg210_of_match[] = { ++ { .compatible = "faraday,fotg200" }, + { .compatible = "faraday,fotg210" }, ++ /* TODO: can we also handle FUSB220? */ + {}, + }; + MODULE_DEVICE_TABLE(of, fotg210_of_match); +-- +2.39.2 + diff --git a/queue-6.2/usb-gadget-bcm63xx_udc-fix-memory-leak-with-using-de.patch b/queue-6.2/usb-gadget-bcm63xx_udc-fix-memory-leak-with-using-de.patch new file mode 100644 index 00000000000..045b09796ce --- /dev/null +++ b/queue-6.2/usb-gadget-bcm63xx_udc-fix-memory-leak-with-using-de.patch @@ -0,0 +1,38 @@ +From 2c95ebdeb76f22eabd2bfdab375da4349b331604 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-9-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-gadget-gr_udc-fix-memory-leak-with-using-debugfs.patch b/queue-6.2/usb-gadget-gr_udc-fix-memory-leak-with-using-debugfs.patch new file mode 100644 index 00000000000..ee5fec9a621 --- /dev/null +++ b/queue-6.2/usb-gadget-gr_udc-fix-memory-leak-with-using-debugfs.patch @@ -0,0 +1,38 @@ +From 8b893c3ae7fd6aeecbde9c434116cb0c624cd465 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-8-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-gadget-lpc32xx_udc-fix-memory-leak-with-using-de.patch b/queue-6.2/usb-gadget-lpc32xx_udc-fix-memory-leak-with-using-de.patch new file mode 100644 index 00000000000..4da09946e52 --- /dev/null +++ b/queue-6.2/usb-gadget-lpc32xx_udc-fix-memory-leak-with-using-de.patch @@ -0,0 +1,40 @@ +From dd76a2cb76ba8b9aaded71a3b40b53b5a53af571 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Miaoqian Lin +Acked-by: Vladimir Zapolskiy +Link: https://lore.kernel.org/r/20230202153235.2412790-10-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-gadget-pxa25x_udc-fix-memory-leak-with-using-deb.patch b/queue-6.2/usb-gadget-pxa25x_udc-fix-memory-leak-with-using-deb.patch new file mode 100644 index 00000000000..74569309c96 --- /dev/null +++ b/queue-6.2/usb-gadget-pxa25x_udc-fix-memory-leak-with-using-deb.patch @@ -0,0 +1,40 @@ +From 37376c888592559b46eaf6b4e007a99b731f342f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Haojian Zhuang +Cc: Robert Jarzmik +Link: https://lore.kernel.org/r/20230202153235.2412790-11-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-gadget-pxa27x_udc-fix-memory-leak-with-using-deb.patch b/queue-6.2/usb-gadget-pxa27x_udc-fix-memory-leak-with-using-deb.patch new file mode 100644 index 00000000000..801f8150060 --- /dev/null +++ b/queue-6.2/usb-gadget-pxa27x_udc-fix-memory-leak-with-using-deb.patch @@ -0,0 +1,40 @@ +From 0d3b56047a37310ca11fde86cbbb63e873f555e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Haojian Zhuang +Cc: Robert Jarzmik +Link: https://lore.kernel.org/r/20230202153235.2412790-12-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-gadget-uvc-make-bsourceid-read-write.patch b/queue-6.2/usb-gadget-uvc-make-bsourceid-read-write.patch new file mode 100644 index 00000000000..6d01787d1be --- /dev/null +++ b/queue-6.2/usb-gadget-uvc-make-bsourceid-read-write.patch @@ -0,0 +1,113 @@ +From b9ee796e2503d07d03ad2dd39a6f5c4cf8e44d46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Feb 2023 16:17:52 +0000 +Subject: usb: gadget: uvc: Make bSourceID read/write + +From: Daniel Scally + +[ 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 +Link: https://lore.kernel.org/r/20230206161802.892954-2-dan.scally@ideasonboard.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + .../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 f00cff6d8c5cb..c25cc2823fc8f 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 76cb60d13049f..0a3095c0450bb 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 + diff --git a/queue-6.2/usb-host-xhci-mvebu-iterate-over-array-indexes-inste.patch b/queue-6.2/usb-host-xhci-mvebu-iterate-over-array-indexes-inste.patch new file mode 100644 index 00000000000..9b662cea4be --- /dev/null +++ b/queue-6.2/usb-host-xhci-mvebu-iterate-over-array-indexes-inste.patch @@ -0,0 +1,46 @@ +From 95e1fab51ba0c2d4ac79d100e095bf07453c02fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20230204183651.never.663-kees@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-isp116x-fix-memory-leak-with-using-debugfs_looku.patch b/queue-6.2/usb-isp116x-fix-memory-leak-with-using-debugfs_looku.patch new file mode 100644 index 00000000000..9850ed878ef --- /dev/null +++ b/queue-6.2/usb-isp116x-fix-memory-leak-with-using-debugfs_looku.patch @@ -0,0 +1,38 @@ +From 1c712be56f9044df1a46cc072fd5b40a2aefc989 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:32:28 +0100 +Subject: USB: isp116x: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-6-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-isp1362-fix-memory-leak-with-using-debugfs_looku.patch b/queue-6.2/usb-isp1362-fix-memory-leak-with-using-debugfs_looku.patch new file mode 100644 index 00000000000..0183c4b051d --- /dev/null +++ b/queue-6.2/usb-isp1362-fix-memory-leak-with-using-debugfs_looku.patch @@ -0,0 +1,38 @@ +From 86cc4f8deab3c6814f12e304c64a6a2b81142c4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:32:29 +0100 +Subject: USB: isp1362: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-7-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-sl811-fix-memory-leak-with-using-debugfs_lookup.patch b/queue-6.2/usb-sl811-fix-memory-leak-with-using-debugfs_lookup.patch new file mode 100644 index 00000000000..3185d713468 --- /dev/null +++ b/queue-6.2/usb-sl811-fix-memory-leak-with-using-debugfs_lookup.patch @@ -0,0 +1,38 @@ +From 3d306aaa9356f5ab183ae578f2c93016c2ce3f00 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:32:26 +0100 +Subject: USB: sl811: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-4-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-uhci-fix-memory-leak-with-using-debugfs_lookup.patch b/queue-6.2/usb-uhci-fix-memory-leak-with-using-debugfs_lookup.patch new file mode 100644 index 00000000000..28c40471523 --- /dev/null +++ b/queue-6.2/usb-uhci-fix-memory-leak-with-using-debugfs_lookup.patch @@ -0,0 +1,49 @@ +From b371e0274028c32dbc6718386f66ddb1e4017481 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:32:25 +0100 +Subject: USB: uhci: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-3-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-ulpi-fix-memory-leak-with-using-debugfs_lookup.patch b/queue-6.2/usb-ulpi-fix-memory-leak-with-using-debugfs_lookup.patch new file mode 100644 index 00000000000..5c4d4b424d1 --- /dev/null +++ b/queue-6.2/usb-ulpi-fix-memory-leak-with-using-debugfs_lookup.patch @@ -0,0 +1,81 @@ +From 01717e06defefff95e50955eabfb2e6ced216edb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 16:32:24 +0100 +Subject: USB: ULPI: fix memory leak with using debugfs_lookup() + +From: Greg Kroah-Hartman + +[ 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 +Link: https://lore.kernel.org/r/20230202153235.2412790-2-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/usb-uvc-enumerate-valid-values-for-color-matching.patch b/queue-6.2/usb-uvc-enumerate-valid-values-for-color-matching.patch new file mode 100644 index 00000000000..5f8e595795a --- /dev/null +++ b/queue-6.2/usb-uvc-enumerate-valid-values-for-color-matching.patch @@ -0,0 +1,67 @@ +From 518a13894d138f90ae8a11ed4295659346f5bcf0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Feb 2023 11:41:37 +0000 +Subject: usb: uvc: Enumerate valid values for color matching + +From: Daniel Scally + +[ 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 +Signed-off-by: Daniel Scally +Link: https://lore.kernel.org/r/20230202114142.300858-2-dan.scally@ideasonboard.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 6e8e572c2980a..2ff0e8a3a683d 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 + diff --git a/queue-6.2/vc_screen-modify-vcs_size-handling-in-vcs_read.patch b/queue-6.2/vc_screen-modify-vcs_size-handling-in-vcs_read.patch new file mode 100644 index 00000000000..fd24f17a86e --- /dev/null +++ b/queue-6.2/vc_screen-modify-vcs_size-handling-in-vcs_read.patch @@ -0,0 +1,40 @@ +From db3b3f3dd4c8436d903ba51c63cd80ba9ed05424 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Feb 2023 15:21:41 -0500 +Subject: vc_screen: modify vcs_size() handling in vcs_read() + +From: George Kennedy + +[ 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 +Signed-off-by: George Kennedy +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/watchdog-at91sam9_wdt-use-devm_request_irq-to-avoid-.patch b/queue-6.2/watchdog-at91sam9_wdt-use-devm_request_irq-to-avoid-.patch new file mode 100644 index 00000000000..f1f02b713eb --- /dev/null +++ b/queue-6.2/watchdog-at91sam9_wdt-use-devm_request_irq-to-avoid-.patch @@ -0,0 +1,46 @@ +From a07986a289625b53713a0ba4e1ac039b268be5ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20221116094950.3141943-1-ruanjinjie@huawei.com +[groeck: Adjust multi-line alignment] +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/watchdog-fix-kmemleak-in-watchdog_cdev_register.patch b/queue-6.2/watchdog-fix-kmemleak-in-watchdog_cdev_register.patch new file mode 100644 index 00000000000..965f955ad9e --- /dev/null +++ b/queue-6.2/watchdog-fix-kmemleak-in-watchdog_cdev_register.patch @@ -0,0 +1,91 @@ +From bf852cde5ea84e173678fc805f0f3f466ad36fbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Nov 2022 01:27:14 +0000 +Subject: watchdog: Fix kmemleak in watchdog_cdev_register + +From: Chen Jun + +[ 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 +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20221116012714.102066-1-chenjun102@huawei.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/watchdog-pcwd_usb-fix-attempting-to-access-uninitial.patch b/queue-6.2/watchdog-pcwd_usb-fix-attempting-to-access-uninitial.patch new file mode 100644 index 00000000000..532d563609f --- /dev/null +++ b/queue-6.2/watchdog-pcwd_usb-fix-attempting-to-access-uninitial.patch @@ -0,0 +1,64 @@ +From e10caecbd1ab0acc2a14cb5b3fce2b55940d8183 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20221116020706.70847-1-hucool.lihua@huawei.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/watchdog-rzg2l_wdt-handle-type-b-reset-for-rz-v2m.patch b/queue-6.2/watchdog-rzg2l_wdt-handle-type-b-reset-for-rz-v2m.patch new file mode 100644 index 00000000000..6f2c0f7a83a --- /dev/null +++ b/queue-6.2/watchdog-rzg2l_wdt-handle-type-b-reset-for-rz-v2m.patch @@ -0,0 +1,126 @@ +From 7929ec46970ac1c3ddb6d5df8be66ea2262af507 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 11:49:07 +0000 +Subject: watchdog: rzg2l_wdt: Handle TYPE-B reset for RZ/V2M + +From: Fabrizio Castro + +[ 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 +Reviewed-by: Guenter Roeck +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20221117114907.138583-3-fabrizio.castro.jz@renesas.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + #include + #include +@@ -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 + diff --git a/queue-6.2/watchdog-rzg2l_wdt-issue-a-reset-before-we-put-the-p.patch b/queue-6.2/watchdog-rzg2l_wdt-issue-a-reset-before-we-put-the-p.patch new file mode 100644 index 00000000000..6a5a2388f8c --- /dev/null +++ b/queue-6.2/watchdog-rzg2l_wdt-issue-a-reset-before-we-put-the-p.patch @@ -0,0 +1,71 @@ +From 82c456241622b921f657091720a671b1f176b189 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Guenter Roeck +Reviewed-by: Geert Uytterhoeven +Reviewed-by: Biju Das +Link: https://lore.kernel.org/r/20221117114907.138583-2-fabrizio.castro.jz@renesas.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/watchdog-sbsa_wdog-make-sure-the-timeout-programming.patch b/queue-6.2/watchdog-sbsa_wdog-make-sure-the-timeout-programming.patch new file mode 100644 index 00000000000..70a00b62b4a --- /dev/null +++ b/queue-6.2/watchdog-sbsa_wdog-make-sure-the-timeout-programming.patch @@ -0,0 +1,41 @@ +From 7cb74d63ac65a90a3e368b8d1d5e2659eb7707c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20230209021117.1512097-1-george.cherian@marvell.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.2/x86-um-vdso-add-rcx-and-r11-to-the-syscall-clobber-l.patch b/queue-6.2/x86-um-vdso-add-rcx-and-r11-to-the-syscall-clobber-l.patch new file mode 100644 index 00000000000..d5d2212ab92 --- /dev/null +++ b/queue-6.2/x86-um-vdso-add-rcx-and-r11-to-the-syscall-clobber-l.patch @@ -0,0 +1,59 @@ +From 19d2c03d8d120a653ca8005f4eaa9ef39fa5f2cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Richard Weinberger +Signed-off-by: Sasha Levin +--- + 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 +