]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Tue, 18 Apr 2023 01:24:53 +0000 (21:24 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 18 Apr 2023 01:24:53 +0000 (21:24 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.4/i2c-ocores-generate-stop-condition-after-timeout-in-.patch [new file with mode: 0644]
queue-5.4/mtd-ubi-wl-fix-a-couple-of-kernel-doc-issues.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/ubi-fix-deadlock-caused-by-recursively-holding-work_.patch [new file with mode: 0644]
queue-5.4/ubi-fix-failure-attaching-when-vid_hdr-offset-equals.patch [new file with mode: 0644]

diff --git a/queue-5.4/i2c-ocores-generate-stop-condition-after-timeout-in-.patch b/queue-5.4/i2c-ocores-generate-stop-condition-after-timeout-in-.patch
new file mode 100644 (file)
index 0000000..c3b25a1
--- /dev/null
@@ -0,0 +1,106 @@
+From 16cd8aa76c3ca1874f848f19b91edbac878dd628 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 11:37:37 +0200
+Subject: i2c: ocores: generate stop condition after timeout in polling mode
+
+From: Gregor Herburger <gregor.herburger@tq-group.com>
+
+[ Upstream commit f8160d3b35fc94491bb0cb974dbda310ef96c0e2 ]
+
+In polling mode, no stop condition is generated after a timeout. This
+causes SCL to remain low and thereby block the bus. If this happens
+during a transfer it can cause slaves to misinterpret the subsequent
+transfer and return wrong values.
+
+To solve this, pass the ETIMEDOUT error up from ocores_process_polling()
+instead of setting STATE_ERROR directly. The caller is adjusted to call
+ocores_process_timeout() on error both in polling and in IRQ mode, which
+will set STATE_ERROR and generate a stop condition.
+
+Fixes: 69c8c0c0efa8 ("i2c: ocores: add polling interface")
+Signed-off-by: Gregor Herburger <gregor.herburger@tq-group.com>
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Acked-by: Peter Korsgaard <peter@korsgaard.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Federico Vaga <federico.vaga@cern.ch>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-ocores.c | 35 ++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
+index ca8b3ecfa93d1..1c3595c8a761a 100644
+--- a/drivers/i2c/busses/i2c-ocores.c
++++ b/drivers/i2c/busses/i2c-ocores.c
+@@ -343,18 +343,18 @@ static int ocores_poll_wait(struct ocores_i2c *i2c)
+  * ocores_isr(), we just add our polling code around it.
+  *
+  * It can run in atomic context
++ *
++ * Return: 0 on success, -ETIMEDOUT on timeout
+  */
+-static void ocores_process_polling(struct ocores_i2c *i2c)
++static int ocores_process_polling(struct ocores_i2c *i2c)
+ {
+-      while (1) {
+-              irqreturn_t ret;
+-              int err;
++      irqreturn_t ret;
++      int err = 0;
++      while (1) {
+               err = ocores_poll_wait(i2c);
+-              if (err) {
+-                      i2c->state = STATE_ERROR;
++              if (err)
+                       break; /* timeout */
+-              }
+               ret = ocores_isr(-1, i2c);
+               if (ret == IRQ_NONE)
+@@ -365,13 +365,15 @@ static void ocores_process_polling(struct ocores_i2c *i2c)
+                                       break;
+               }
+       }
++
++      return err;
+ }
+ static int ocores_xfer_core(struct ocores_i2c *i2c,
+                           struct i2c_msg *msgs, int num,
+                           bool polling)
+ {
+-      int ret;
++      int ret = 0;
+       u8 ctrl;
+       ctrl = oc_getreg(i2c, OCI2C_CONTROL);
+@@ -389,15 +391,16 @@ static int ocores_xfer_core(struct ocores_i2c *i2c,
+       oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
+       if (polling) {
+-              ocores_process_polling(i2c);
++              ret = ocores_process_polling(i2c);
+       } else {
+-              ret = wait_event_timeout(i2c->wait,
+-                                       (i2c->state == STATE_ERROR) ||
+-                                       (i2c->state == STATE_DONE), HZ);
+-              if (ret == 0) {
+-                      ocores_process_timeout(i2c);
+-                      return -ETIMEDOUT;
+-              }
++              if (wait_event_timeout(i2c->wait,
++                                     (i2c->state == STATE_ERROR) ||
++                                     (i2c->state == STATE_DONE), HZ) == 0)
++                      ret = -ETIMEDOUT;
++      }
++      if (ret) {
++              ocores_process_timeout(i2c);
++              return ret;
+       }
+       return (i2c->state == STATE_DONE) ? num : -EIO;
+-- 
+2.39.2
+
diff --git a/queue-5.4/mtd-ubi-wl-fix-a-couple-of-kernel-doc-issues.patch b/queue-5.4/mtd-ubi-wl-fix-a-couple-of-kernel-doc-issues.patch
new file mode 100644 (file)
index 0000000..65c0c81
--- /dev/null
@@ -0,0 +1,51 @@
+From 0440fd5e35d98780a2fcec0f2858cc05779427d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Nov 2020 18:21:55 +0000
+Subject: mtd: ubi: wl: Fix a couple of kernel-doc issues
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit ab4e4de9fd8b469823a645f05f2c142e9270b012 ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ drivers/mtd/ubi/wl.c:584: warning: Function parameter or member 'nested' not described in 'schedule_erase'
+ drivers/mtd/ubi/wl.c:1075: warning: Excess function parameter 'shutdown' description in '__erase_worker'
+
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Miquel Raynal <miquel.raynal@bootlin.com>
+Cc: Vignesh Raghavendra <vigneshr@ti.com>
+Cc: linux-mtd@lists.infradead.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20201109182206.3037326-13-lee.jones@linaro.org
+Stable-dep-of: f773f0a331d6 ("ubi: Fix deadlock caused by recursively holding work_sem")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/wl.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index 4f88433d4adc7..28110cd4400b5 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -576,6 +576,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
+  * @vol_id: the volume ID that last used this PEB
+  * @lnum: the last used logical eraseblock number for the PEB
+  * @torture: if the physical eraseblock has to be tortured
++ * @nested: denotes whether the work_sem is already held in read mode
+  *
+  * This function returns zero in case of success and a %-ENOMEM in case of
+  * failure.
+@@ -1060,8 +1061,6 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
+  * __erase_worker - physical eraseblock erase worker function.
+  * @ubi: UBI device description object
+  * @wl_wrk: the work object
+- * @shutdown: non-zero if the worker has to free memory and exit
+- * because the WL sub-system is shutting down
+  *
+  * This function erases a physical eraseblock and perform torture testing if
+  * needed. It also takes care about marking the physical eraseblock bad if
+-- 
+2.39.2
+
index 6a27e6fbcde5ee8f42577fcbcfa07b42746462a0..5d203e1804498284948b3bf68841c2749a3243d9 100644 (file)
@@ -67,3 +67,7 @@ efi-sysfb_efi-add-quirk-for-lenovo-yoga-book-x91f-l.patch
 drm-panel-orientation-quirks-add-quirk-for-lenovo-yo.patch
 verify_pefile-relax-wrapper-length-check.patch
 asymmetric_keys-log-on-fatal-failures-in-pe-pkcs7.patch
+mtd-ubi-wl-fix-a-couple-of-kernel-doc-issues.patch
+ubi-fix-deadlock-caused-by-recursively-holding-work_.patch
+ubi-fix-failure-attaching-when-vid_hdr-offset-equals.patch
+i2c-ocores-generate-stop-condition-after-timeout-in-.patch
diff --git a/queue-5.4/ubi-fix-deadlock-caused-by-recursively-holding-work_.patch b/queue-5.4/ubi-fix-deadlock-caused-by-recursively-holding-work_.patch
new file mode 100644 (file)
index 0000000..5403da8
--- /dev/null
@@ -0,0 +1,66 @@
+From e825d740a2b8c68aeb5b39ab04b500733c3a4a3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Mar 2023 09:41:41 +0800
+Subject: ubi: Fix deadlock caused by recursively holding work_sem
+
+From: ZhaoLong Wang <wangzhaolong1@huawei.com>
+
+[ Upstream commit f773f0a331d6c41733b17bebbc1b6cae12e016f5 ]
+
+During the processing of the bgt, if the sync_erase() return -EBUSY
+or some other error code in __erase_worker(),schedule_erase() called
+again lead to the down_read(ubi->work_sem) hold twice and may get
+block by down_write(ubi->work_sem) in ubi_update_fastmap(),
+which cause deadlock.
+
+          ubi bgt                        other task
+ do_work
+  down_read(&ubi->work_sem)          ubi_update_fastmap
+  erase_worker                         # Blocked by down_read
+   __erase_worker                      down_write(&ubi->work_sem)
+    schedule_erase
+     schedule_ubi_work
+      down_read(&ubi->work_sem)
+
+Fix this by changing input parameter @nested of the schedule_erase() to
+'true' to avoid recursively acquiring the down_read(&ubi->work_sem).
+
+Also, fix the incorrect comment about @nested parameter of the
+schedule_erase() because when down_write(ubi->work_sem) is held, the
+@nested is also need be true.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217093
+Fixes: 2e8f08deabbc ("ubi: Fix races around ubi_refill_pools()")
+Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/wl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index 28110cd4400b5..fd0e8f948c3da 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -576,7 +576,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
+  * @vol_id: the volume ID that last used this PEB
+  * @lnum: the last used logical eraseblock number for the PEB
+  * @torture: if the physical eraseblock has to be tortured
+- * @nested: denotes whether the work_sem is already held in read mode
++ * @nested: denotes whether the work_sem is already held
+  *
+  * This function returns zero in case of success and a %-ENOMEM in case of
+  * failure.
+@@ -1110,7 +1110,7 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
+               int err1;
+               /* Re-schedule the LEB for erasure */
+-              err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false);
++              err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true);
+               if (err1) {
+                       spin_lock(&ubi->wl_lock);
+                       wl_entry_destroy(ubi, e);
+-- 
+2.39.2
+
diff --git a/queue-5.4/ubi-fix-failure-attaching-when-vid_hdr-offset-equals.patch b/queue-5.4/ubi-fix-failure-attaching-when-vid_hdr-offset-equals.patch
new file mode 100644 (file)
index 0000000..88153a1
--- /dev/null
@@ -0,0 +1,79 @@
+From 78295f107d5e71840da8aa65da48df40fb5d3bea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Mar 2023 09:33:08 +0800
+Subject: ubi: Fix failure attaching when vid_hdr offset equals to (sub)page
+ size
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 1e020e1b96afdecd20680b5b5be2a6ffc3d27628 ]
+
+Following process will make ubi attaching failed since commit
+1b42b1a36fc946 ("ubi: ensure that VID header offset ... size"):
+
+ID="0xec,0xa1,0x00,0x15" # 128M 128KB 2KB
+modprobe nandsim id_bytes=$ID
+flash_eraseall /dev/mtd0
+modprobe ubi mtd="0,2048"  # set vid_hdr offset as 2048 (one page)
+(dmesg):
+  ubi0 error: ubi_attach_mtd_dev [ubi]: VID header offset 2048 too large.
+  UBI error: cannot attach mtd0
+  UBI error: cannot initialize UBI, error -22
+
+Rework original solution, the key point is making sure
+'vid_hdr_shift + UBI_VID_HDR_SIZE < ubi->vid_hdr_alsize',
+so we should check vid_hdr_shift rather not vid_hdr_offset.
+Then, ubi still support (sub)page aligined VID header offset.
+
+Fixes: 1b42b1a36fc946 ("ubi: ensure that VID header offset ... size")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Tested-by: Nicolas Schichan <nschichan@freebox.fr>
+Tested-by: Miquel Raynal <miquel.raynal@bootlin.com> # v5.10, v4.19
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/build.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
+index 13f8292ceea52..f29ed9102ce91 100644
+--- a/drivers/mtd/ubi/build.c
++++ b/drivers/mtd/ubi/build.c
+@@ -644,12 +644,6 @@ 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);
+@@ -667,6 +661,21 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
+                                               ubi->vid_hdr_aloffset;
+       }
++      /*
++       * Memory allocation for VID header is ubi->vid_hdr_alsize
++       * which is described in comments in io.c.
++       * Make sure VID header shift + UBI_VID_HDR_SIZE not exceeds
++       * ubi->vid_hdr_alsize, so that all vid header operations
++       * won't access memory out of bounds.
++       */
++      if ((ubi->vid_hdr_shift + UBI_VID_HDR_SIZE) > ubi->vid_hdr_alsize) {
++              ubi_err(ubi, "Invalid VID header offset %d, VID header shift(%d)"
++                      " + VID header size(%zu) > VID header aligned size(%d).",
++                      ubi->vid_hdr_offset, ubi->vid_hdr_shift,
++                      UBI_VID_HDR_SIZE, ubi->vid_hdr_alsize);
++              return -EINVAL;
++      }
++
+       /* Similar for the data offset */
+       ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
+       ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);
+-- 
+2.39.2
+