]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.12
authorSasha Levin <sashal@kernel.org>
Sun, 22 Dec 2024 04:32:14 +0000 (23:32 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 22 Dec 2024 04:32:14 +0000 (23:32 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.12/block-avoid-to-reuse-hctx-not-removed-from-cpuhp-cal.patch [new file with mode: 0644]
queue-6.12/block-revert-block-fix-potential-deadlock-while-free.patch [new file with mode: 0644]
queue-6.12/hwmon-tmp513-fix-current-register-value-interpretati.patch [new file with mode: 0644]
queue-6.12/hwmon-tmp513-fix-interpretation-of-values-of-shunt-v.patch [new file with mode: 0644]
queue-6.12/hwmon-tmp513-fix-interpretation-of-values-of-tempera.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/block-avoid-to-reuse-hctx-not-removed-from-cpuhp-cal.patch b/queue-6.12/block-avoid-to-reuse-hctx-not-removed-from-cpuhp-cal.patch
new file mode 100644 (file)
index 0000000..87e6658
--- /dev/null
@@ -0,0 +1,56 @@
+From 229fcf16283310043a235f4553dc3c3e26759b4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Dec 2024 18:16:15 +0800
+Subject: block: avoid to reuse `hctx` not removed from cpuhp callback list
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 85672ca9ceeaa1dcf2777a7048af5f4aee3fd02b ]
+
+If the 'hctx' isn't removed from cpuhp callback list, we can't reuse it,
+otherwise use-after-free may be triggered.
+
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202412172217.b906db7c-lkp@intel.com
+Tested-by: kernel test robot <oliver.sang@intel.com>
+Fixes: 22465bbac53c ("blk-mq: move cpuhp callback registering out of q->sysfs_lock")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20241218101617.3275704-3-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 1030875a3e95..d5995021815d 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -4421,6 +4421,15 @@ struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
+ }
+ EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue);
++/*
++ * Only hctx removed from cpuhp list can be reused
++ */
++static bool blk_mq_hctx_is_reusable(struct blk_mq_hw_ctx *hctx)
++{
++      return hlist_unhashed(&hctx->cpuhp_online) &&
++              hlist_unhashed(&hctx->cpuhp_dead);
++}
++
+ static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
+               struct blk_mq_tag_set *set, struct request_queue *q,
+               int hctx_idx, int node)
+@@ -4430,7 +4439,7 @@ static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
+       /* reuse dead hctx first */
+       spin_lock(&q->unused_hctx_lock);
+       list_for_each_entry(tmp, &q->unused_hctx_list, hctx_list) {
+-              if (tmp->numa_node == node) {
++              if (tmp->numa_node == node && blk_mq_hctx_is_reusable(tmp)) {
+                       hctx = tmp;
+                       break;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.12/block-revert-block-fix-potential-deadlock-while-free.patch b/queue-6.12/block-revert-block-fix-potential-deadlock-while-free.patch
new file mode 100644 (file)
index 0000000..72b30e7
--- /dev/null
@@ -0,0 +1,206 @@
+From 4f081c633e99e0f6dc7fee60fe37d7788b74e1e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Dec 2024 18:16:14 +0800
+Subject: block: Revert "block: Fix potential deadlock while freezing queue and
+ acquiring sysfs_lock"
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 224749be6c23efe7fb8a030854f4fc5d1dd813b3 ]
+
+This reverts commit be26ba96421ab0a8fa2055ccf7db7832a13c44d2.
+
+Commit be26ba96421a ("block: Fix potential deadlock while freezing queue and
+acquiring sysfs_loc") actually reverts commit 22465bbac53c ("blk-mq: move cpuhp
+callback registering out of q->sysfs_lock"), and causes the original resctrl
+lockdep warning.
+
+So revert it and we need to fix the issue in another way.
+
+Cc: Nilay Shroff <nilay@linux.ibm.com>
+Fixes: be26ba96421a ("block: Fix potential deadlock while freezing queue and acquiring sysfs_loc")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20241218101617.3275704-2-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-sysfs.c | 16 ++++++++++------
+ block/blk-mq.c       | 29 +++++++++++------------------
+ block/blk-sysfs.c    |  4 ++--
+ 3 files changed, 23 insertions(+), 26 deletions(-)
+
+diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
+index cd5ea6eaa76b..156e9bb07abf 100644
+--- a/block/blk-mq-sysfs.c
++++ b/block/blk-mq-sysfs.c
+@@ -275,13 +275,15 @@ void blk_mq_sysfs_unregister_hctxs(struct request_queue *q)
+       struct blk_mq_hw_ctx *hctx;
+       unsigned long i;
+-      lockdep_assert_held(&q->sysfs_dir_lock);
+-
++      mutex_lock(&q->sysfs_dir_lock);
+       if (!q->mq_sysfs_init_done)
+-              return;
++              goto unlock;
+       queue_for_each_hw_ctx(q, hctx, i)
+               blk_mq_unregister_hctx(hctx);
++
++unlock:
++      mutex_unlock(&q->sysfs_dir_lock);
+ }
+ int blk_mq_sysfs_register_hctxs(struct request_queue *q)
+@@ -290,10 +292,9 @@ int blk_mq_sysfs_register_hctxs(struct request_queue *q)
+       unsigned long i;
+       int ret = 0;
+-      lockdep_assert_held(&q->sysfs_dir_lock);
+-
++      mutex_lock(&q->sysfs_dir_lock);
+       if (!q->mq_sysfs_init_done)
+-              return ret;
++              goto unlock;
+       queue_for_each_hw_ctx(q, hctx, i) {
+               ret = blk_mq_register_hctx(hctx);
+@@ -301,5 +302,8 @@ int blk_mq_sysfs_register_hctxs(struct request_queue *q)
+                       break;
+       }
++unlock:
++      mutex_unlock(&q->sysfs_dir_lock);
++
+       return ret;
+ }
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index cc1b32023838..1030875a3e95 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -4462,8 +4462,7 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
+       unsigned long i, j;
+       /* protect against switching io scheduler  */
+-      lockdep_assert_held(&q->sysfs_lock);
+-
++      mutex_lock(&q->sysfs_lock);
+       for (i = 0; i < set->nr_hw_queues; i++) {
+               int old_node;
+               int node = blk_mq_get_hctx_node(set, i);
+@@ -4496,6 +4495,7 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
+       xa_for_each_start(&q->hctx_table, j, hctx, j)
+               blk_mq_exit_hctx(q, set, hctx, j);
++      mutex_unlock(&q->sysfs_lock);
+       /* unregister cpuhp callbacks for exited hctxs */
+       blk_mq_remove_hw_queues_cpuhp(q);
+@@ -4527,14 +4527,10 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
+       xa_init(&q->hctx_table);
+-      mutex_lock(&q->sysfs_lock);
+-
+       blk_mq_realloc_hw_ctxs(set, q);
+       if (!q->nr_hw_queues)
+               goto err_hctxs;
+-      mutex_unlock(&q->sysfs_lock);
+-
+       INIT_WORK(&q->timeout_work, blk_mq_timeout_work);
+       blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);
+@@ -4553,7 +4549,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
+       return 0;
+ err_hctxs:
+-      mutex_unlock(&q->sysfs_lock);
+       blk_mq_release(q);
+ err_exit:
+       q->mq_ops = NULL;
+@@ -4934,12 +4929,12 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
+               return false;
+       /* q->elevator needs protection from ->sysfs_lock */
+-      lockdep_assert_held(&q->sysfs_lock);
++      mutex_lock(&q->sysfs_lock);
+       /* the check has to be done with holding sysfs_lock */
+       if (!q->elevator) {
+               kfree(qe);
+-              goto out;
++              goto unlock;
+       }
+       INIT_LIST_HEAD(&qe->node);
+@@ -4949,7 +4944,9 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
+       __elevator_get(qe->type);
+       list_add(&qe->node, head);
+       elevator_disable(q);
+-out:
++unlock:
++      mutex_unlock(&q->sysfs_lock);
++
+       return true;
+ }
+@@ -4978,9 +4975,11 @@ static void blk_mq_elv_switch_back(struct list_head *head,
+       list_del(&qe->node);
+       kfree(qe);
++      mutex_lock(&q->sysfs_lock);
+       elevator_switch(q, t);
+       /* drop the reference acquired in blk_mq_elv_switch_none */
+       elevator_put(t);
++      mutex_unlock(&q->sysfs_lock);
+ }
+ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
+@@ -5000,11 +4999,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
+       if (set->nr_maps == 1 && nr_hw_queues == set->nr_hw_queues)
+               return;
+-      list_for_each_entry(q, &set->tag_list, tag_set_list) {
+-              mutex_lock(&q->sysfs_dir_lock);
+-              mutex_lock(&q->sysfs_lock);
++      list_for_each_entry(q, &set->tag_list, tag_set_list)
+               blk_mq_freeze_queue(q);
+-      }
+       /*
+        * Switch IO scheduler to 'none', cleaning up the data associated
+        * with the previous scheduler. We will switch back once we are done
+@@ -5060,11 +5056,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
+       list_for_each_entry(q, &set->tag_list, tag_set_list)
+               blk_mq_elv_switch_back(&head, q);
+-      list_for_each_entry(q, &set->tag_list, tag_set_list) {
++      list_for_each_entry(q, &set->tag_list, tag_set_list)
+               blk_mq_unfreeze_queue(q);
+-              mutex_unlock(&q->sysfs_lock);
+-              mutex_unlock(&q->sysfs_dir_lock);
+-      }
+       /* Free the excess tags when nr_hw_queues shrink. */
+       for (i = set->nr_hw_queues; i < prev_nr_hw_queues; i++)
+diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
+index 42c2cb97d778..207577145c54 100644
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -690,11 +690,11 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
+                       return res;
+       }
+-      mutex_lock(&q->sysfs_lock);
+       blk_mq_freeze_queue(q);
++      mutex_lock(&q->sysfs_lock);
+       res = entry->store(disk, page, length);
+-      blk_mq_unfreeze_queue(q);
+       mutex_unlock(&q->sysfs_lock);
++      blk_mq_unfreeze_queue(q);
+       return res;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.12/hwmon-tmp513-fix-current-register-value-interpretati.patch b/queue-6.12/hwmon-tmp513-fix-current-register-value-interpretati.patch
new file mode 100644 (file)
index 0000000..645b303
--- /dev/null
@@ -0,0 +1,53 @@
+From 962d8f57b7e49510ff36249d4f89ee42f18c8b7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 20:36:47 +0300
+Subject: hwmon: (tmp513) Fix Current Register value interpretation
+
+From: Murad Masimov <m.masimov@maxima.ru>
+
+[ Upstream commit da1d0e6ba211baf6747db74c07700caddfd8a179 ]
+
+The value returned by the driver after processing the contents of the
+Current Register does not correspond to the TMP512/TMP513 specifications.
+A raw register value is converted to a signed integer value by a sign
+extension in accordance with the algorithm provided in the specification,
+but due to the off-by-one error in the sign bit index, the result is
+incorrect. Moreover, negative values will be reported as large positive
+due to missing sign extension from u32 to long.
+
+According to the TMP512 and TMP513 datasheets, the Current Register (07h)
+is a 16-bit two's complement integer value. E.g., if regval = 1000 0011
+0000 0000, then the value must be (-32000 * lsb), but the driver will
+return (33536 * lsb).
+
+Fix off-by-one bug, and also cast data->curr_lsb_ua (which is of type u32)
+to long to prevent incorrect cast for negative values.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 59dfa75e5d82 ("hwmon: Add driver for Texas Instruments TMP512/513 sensor chips.")
+Signed-off-by: Murad Masimov <m.masimov@maxima.ru>
+Link: https://lore.kernel.org/r/20241216173648.526-3-m.masimov@maxima.ru
+[groeck: Fixed description line length]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/tmp513.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/tmp513.c b/drivers/hwmon/tmp513.c
+index d87fcea3ef24..2846b1cc515d 100644
+--- a/drivers/hwmon/tmp513.c
++++ b/drivers/hwmon/tmp513.c
+@@ -222,7 +222,7 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
+               break;
+       case TMP51X_BUS_CURRENT_RESULT:
+               // Current = (ShuntVoltage * CalibrationRegister) / 4096
+-              *val = sign_extend32(regval, 16) * data->curr_lsb_ua;
++              *val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua;
+               *val = DIV_ROUND_CLOSEST(*val, MILLI);
+               break;
+       case TMP51X_LOCAL_TEMP_RESULT:
+-- 
+2.39.5
+
diff --git a/queue-6.12/hwmon-tmp513-fix-interpretation-of-values-of-shunt-v.patch b/queue-6.12/hwmon-tmp513-fix-interpretation-of-values-of-shunt-v.patch
new file mode 100644 (file)
index 0000000..314162c
--- /dev/null
@@ -0,0 +1,74 @@
+From 3912edafe677b43cc391138a3de14875455fc980 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 20:36:46 +0300
+Subject: hwmon: (tmp513) Fix interpretation of values of Shunt Voltage and
+ Limit Registers
+
+From: Murad Masimov <m.masimov@maxima.ru>
+
+[ Upstream commit 74d7e038fd072635d21e4734e3223378e09168d3 ]
+
+The values returned by the driver after processing the contents of the
+Shunt Voltage Register and the Shunt Limit Registers do not correspond to
+the TMP512/TMP513 specifications. A raw register value is converted to a
+signed integer value by a sign extension in accordance with the algorithm
+provided in the specification, but due to the off-by-one error in the sign
+bit index, the result is incorrect. Moreover, the PGA shift calculated with
+the tmp51x_get_pga_shift function is relevant only to the Shunt Voltage
+Register, but is also applied to the Shunt Limit Registers.
+
+According to the TMP512 and TMP513 datasheets, the Shunt Voltage Register
+(04h) is 13 to 16 bit two's complement integer value, depending on the PGA
+setting.  The Shunt Positive (0Ch) and Negative (0Dh) Limit Registers are
+16-bit two's complement integer values. Below are some examples:
+
+* Shunt Voltage Register
+If PGA = 8, and regval = 1000 0011 0000 0000, then the decimal value must
+be -32000, but the value calculated by the driver will be 33536.
+
+* Shunt Limit Register
+If regval = 1000 0011 0000 0000, then the decimal value must be -32000, but
+the value calculated by the driver will be 768, if PGA = 1.
+
+Fix sign bit index, and also correct misleading comment describing the
+tmp51x_get_pga_shift function.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 59dfa75e5d82 ("hwmon: Add driver for Texas Instruments TMP512/513 sensor chips.")
+Signed-off-by: Murad Masimov <m.masimov@maxima.ru>
+Link: https://lore.kernel.org/r/20241216173648.526-2-m.masimov@maxima.ru
+[groeck: Fixed description and multi-line alignments]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/tmp513.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwmon/tmp513.c b/drivers/hwmon/tmp513.c
+index 926d28cd3fab..d87fcea3ef24 100644
+--- a/drivers/hwmon/tmp513.c
++++ b/drivers/hwmon/tmp513.c
+@@ -182,7 +182,7 @@ struct tmp51x_data {
+       struct regmap *regmap;
+ };
+-// Set the shift based on the gain 8=4, 4=3, 2=2, 1=1
++// Set the shift based on the gain: 8 -> 1, 4 -> 2, 2 -> 3, 1 -> 4
+ static inline u8 tmp51x_get_pga_shift(struct tmp51x_data *data)
+ {
+       return 5 - ffs(data->pga_gain);
+@@ -204,7 +204,9 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
+                * 2's complement number shifted by one to four depending
+                * on the pga gain setting. 1lsb = 10uV
+                */
+-              *val = sign_extend32(regval, 17 - tmp51x_get_pga_shift(data));
++              *val = sign_extend32(regval,
++                                   reg == TMP51X_SHUNT_CURRENT_RESULT ?
++                                   16 - tmp51x_get_pga_shift(data) : 15);
+               *val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms);
+               break;
+       case TMP51X_BUS_VOLTAGE_RESULT:
+-- 
+2.39.5
+
diff --git a/queue-6.12/hwmon-tmp513-fix-interpretation-of-values-of-tempera.patch b/queue-6.12/hwmon-tmp513-fix-interpretation-of-values-of-tempera.patch
new file mode 100644 (file)
index 0000000..3280a77
--- /dev/null
@@ -0,0 +1,51 @@
+From 604d09b6f1c99c9973b6acb61b56b8c452987154 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 20:36:48 +0300
+Subject: hwmon: (tmp513) Fix interpretation of values of Temperature Result
+ and Limit Registers
+
+From: Murad Masimov <m.masimov@maxima.ru>
+
+[ Upstream commit dd471e25770e7e632f736b90db1e2080b2171668 ]
+
+The values returned by the driver after processing the contents of the
+Temperature Result and the Temperature Limit Registers do not correspond to
+the TMP512/TMP513 specifications. A raw register value is converted to a
+signed integer value by a sign extension in accordance with the algorithm
+provided in the specification, but due to the off-by-one error in the sign
+bit index, the result is incorrect.
+
+According to the TMP512 and TMP513 datasheets, the Temperature Result (08h
+to 0Bh) and Limit (11h to 14h) Registers are 13-bit two's complement
+integer values, shifted left by 3 bits. The value is scaled by 0.0625
+degrees Celsius per bit.  E.g., if regval = 1 1110 0111 0000 000, the
+output should be -25 degrees, but the driver will return +487 degrees.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 59dfa75e5d82 ("hwmon: Add driver for Texas Instruments TMP512/513 sensor chips.")
+Signed-off-by: Murad Masimov <m.masimov@maxima.ru>
+Link: https://lore.kernel.org/r/20241216173648.526-4-m.masimov@maxima.ru
+[groeck: fixed description line length]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/tmp513.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/tmp513.c b/drivers/hwmon/tmp513.c
+index 2846b1cc515d..1c2cb12071b8 100644
+--- a/drivers/hwmon/tmp513.c
++++ b/drivers/hwmon/tmp513.c
+@@ -234,7 +234,7 @@ static int tmp51x_get_value(struct tmp51x_data *data, u8 reg, u8 pos,
+       case TMP51X_REMOTE_TEMP_LIMIT_2:
+       case TMP513_REMOTE_TEMP_LIMIT_3:
+               // 1lsb = 0.0625 degrees centigrade
+-              *val = sign_extend32(regval, 16) >> TMP51X_TEMP_SHIFT;
++              *val = sign_extend32(regval, 15) >> TMP51X_TEMP_SHIFT;
+               *val = DIV_ROUND_CLOSEST(*val * 625, 10);
+               break;
+       case TMP51X_N_FACTOR_AND_HYST_1:
+-- 
+2.39.5
+
index fd4702eec64f63d3032f5301e7381457a19f9394..f4a74d716fbee7f60616401bb099c3acdf439aee 100644 (file)
@@ -71,3 +71,8 @@ i915-guc-reset-engine-utilization-buffer-before-regi.patch
 i915-guc-ensure-busyness-counter-increases-motonical.patch
 i915-guc-accumulate-active-runtime-on-gt-reset.patch
 drm-amdgpu-don-t-access-invalid-sched.patch
+hwmon-tmp513-fix-interpretation-of-values-of-shunt-v.patch
+hwmon-tmp513-fix-current-register-value-interpretati.patch
+hwmon-tmp513-fix-interpretation-of-values-of-tempera.patch
+block-revert-block-fix-potential-deadlock-while-free.patch
+block-avoid-to-reuse-hctx-not-removed-from-cpuhp-cal.patch