kernel: backport NVMEM late fixes from v6.2

They were backported to stable kernels but we backport more stuff on our
own so we have to pick up few remaining.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
Rafał Miłecki 2023-02-23 09:47:39 +01:00
parent 9837f81bae
commit b4ae914037
10 changed files with 282 additions and 16 deletions

View File

@ -20,7 +20,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
@@ -136,6 +137,8 @@ static int brcm_nvram_probe(struct platf
@@ -139,6 +140,8 @@ static int brcm_nvram_probe(struct platf
if (err)
return err;

View File

@ -20,7 +20,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
@@ -136,6 +137,8 @@ static int brcm_nvram_probe(struct platf
@@ -139,6 +140,8 @@ static int brcm_nvram_probe(struct platf
if (err)
return err;

View File

@ -0,0 +1,30 @@
From b0576ade3aaf24b376ea1a4406ae138e2a22b0c0 Mon Sep 17 00:00:00 2001
From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
Date: Fri, 27 Jan 2023 10:40:06 +0000
Subject: [PATCH] nvmem: brcm_nvram: Add check for kzalloc
Add the check for the return value of kzalloc in order to avoid
NULL pointer dereference.
Fixes: 6e977eaa8280 ("nvmem: brcm_nvram: parse NVRAM content into NVMEM cells")
Cc: stable@vger.kernel.org
Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20230127104015.23839-2-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/brcm_nvram.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/nvmem/brcm_nvram.c
+++ b/drivers/nvmem/brcm_nvram.c
@@ -97,6 +97,9 @@ static int brcm_nvram_parse(struct brcm_
len = le32_to_cpu(header.len);
data = kzalloc(len, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
memcpy_fromio(data, priv->base, len);
data[len - 1] = '\0';

View File

@ -0,0 +1,55 @@
From c151d5ed8e8fe0474bd61dce7f2076ca5916c683 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 27 Jan 2023 10:40:07 +0000
Subject: [PATCH] nvmem: sunxi_sid: Always use 32-bit MMIO reads
The SID SRAM on at least some SoCs (A64 and D1) returns different values
when read with bus cycles narrower than 32 bits. This is not immediately
obvious, because memcpy_fromio() uses word-size accesses as long as
enough data is being copied.
The vendor driver always uses 32-bit MMIO reads, so do the same here.
This is faster than the register-based method, which is currently used
as a workaround on A64. And it fixes the values returned on D1, where
the SRAM method was being used.
The special case for the last word is needed to maintain .word_size == 1
for sysfs ABI compatibility, as noted previously in commit de2a3eaea552
("nvmem: sunxi_sid: Optimize register read-out method").
Fixes: 07ae4fde9efa ("nvmem: sunxi_sid: Add support for D1 variant")
Cc: stable@vger.kernel.org
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Samuel Holland <samuel@sholland.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20230127104015.23839-3-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/sunxi_sid.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context,
void *val, size_t bytes)
{
struct sunxi_sid *sid = context;
+ u32 word;
- memcpy_fromio(val, sid->base + sid->value_offset + offset, bytes);
+ /* .stride = 4 so offset is guaranteed to be aligned */
+ __ioread32_copy(val, sid->base + sid->value_offset + offset, bytes / 4);
+
+ val += round_down(bytes, 4);
+ offset += round_down(bytes, 4);
+ bytes = bytes % 4;
+
+ if (!bytes)
+ return 0;
+
+ /* Handle any trailing bytes */
+ word = readl_relaxed(sid->base + sid->value_offset + offset);
+ memcpy(val, &word, bytes);
return 0;
}

View File

@ -0,0 +1,48 @@
From edcf2fb660526b5ed29f93bd17328a2b4835c8b2 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Fri, 27 Jan 2023 10:40:12 +0000
Subject: [PATCH] nvmem: core: fix device node refcounting
In of_nvmem_cell_get(), of_get_next_parent() is used on cell_np. This
will decrement the refcount on cell_np, but cell_np is still used later
in the code. Use of_get_parent() instead and of_node_put() in the
appropriate places.
Fixes: 69aba7948cbe ("nvmem: Add a simple NVMEM framework for consumers")
Fixes: 7ae6478b304b ("nvmem: core: rework nvmem cell instance creation")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20230127104015.23839-8-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/core.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1242,16 +1242,21 @@ struct nvmem_cell *of_nvmem_cell_get(str
if (!cell_np)
return ERR_PTR(-ENOENT);
- nvmem_np = of_get_next_parent(cell_np);
- if (!nvmem_np)
+ nvmem_np = of_get_parent(cell_np);
+ if (!nvmem_np) {
+ of_node_put(cell_np);
return ERR_PTR(-EINVAL);
+ }
nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
of_node_put(nvmem_np);
- if (IS_ERR(nvmem))
+ if (IS_ERR(nvmem)) {
+ of_node_put(cell_np);
return ERR_CAST(nvmem);
+ }
cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np);
+ of_node_put(cell_np);
if (!cell_entry) {
__nvmem_device_put(nvmem);
return ERR_PTR(-ENOENT);

View File

@ -103,9 +103,9 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ if (cell_spec.args_count)
+ cell_index = cell_spec.args[0];
nvmem_np = of_get_next_parent(cell_np);
if (!nvmem_np)
@@ -1257,7 +1272,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
nvmem_np = of_get_parent(cell_np);
if (!nvmem_np) {
@@ -1262,7 +1277,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
return ERR_PTR(-ENOENT);
}
@ -114,7 +114,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (IS_ERR(cell))
__nvmem_device_put(nvmem);
@@ -1410,8 +1425,8 @@ static void nvmem_shift_read_buffer_in_p
@@ -1415,8 +1430,8 @@ static void nvmem_shift_read_buffer_in_p
}
static int __nvmem_cell_read(struct nvmem_device *nvmem,
@ -125,7 +125,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
{
int rc;
@@ -1425,7 +1440,7 @@ static int __nvmem_cell_read(struct nvme
@@ -1430,7 +1445,7 @@ static int __nvmem_cell_read(struct nvme
nvmem_shift_read_buffer_in_place(cell, buf);
if (nvmem->cell_post_process) {
@ -134,7 +134,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cell->offset, buf, cell->bytes);
if (rc)
return rc;
@@ -1460,7 +1475,7 @@ void *nvmem_cell_read(struct nvmem_cell
@@ -1465,7 +1480,7 @@ void *nvmem_cell_read(struct nvmem_cell
if (!buf)
return ERR_PTR(-ENOMEM);
@ -143,7 +143,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (rc) {
kfree(buf);
return ERR_PTR(rc);
@@ -1773,7 +1788,7 @@ ssize_t nvmem_device_cell_read(struct nv
@@ -1778,7 +1793,7 @@ ssize_t nvmem_device_cell_read(struct nv
if (rc)
return rc;

View File

@ -0,0 +1,30 @@
From b0576ade3aaf24b376ea1a4406ae138e2a22b0c0 Mon Sep 17 00:00:00 2001
From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
Date: Fri, 27 Jan 2023 10:40:06 +0000
Subject: [PATCH] nvmem: brcm_nvram: Add check for kzalloc
Add the check for the return value of kzalloc in order to avoid
NULL pointer dereference.
Fixes: 6e977eaa8280 ("nvmem: brcm_nvram: parse NVRAM content into NVMEM cells")
Cc: stable@vger.kernel.org
Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20230127104015.23839-2-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/brcm_nvram.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/nvmem/brcm_nvram.c
+++ b/drivers/nvmem/brcm_nvram.c
@@ -97,6 +97,9 @@ static int brcm_nvram_parse(struct brcm_
len = le32_to_cpu(header.len);
data = kzalloc(len, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
memcpy_fromio(data, priv->base, len);
data[len - 1] = '\0';

View File

@ -0,0 +1,55 @@
From c151d5ed8e8fe0474bd61dce7f2076ca5916c683 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 27 Jan 2023 10:40:07 +0000
Subject: [PATCH] nvmem: sunxi_sid: Always use 32-bit MMIO reads
The SID SRAM on at least some SoCs (A64 and D1) returns different values
when read with bus cycles narrower than 32 bits. This is not immediately
obvious, because memcpy_fromio() uses word-size accesses as long as
enough data is being copied.
The vendor driver always uses 32-bit MMIO reads, so do the same here.
This is faster than the register-based method, which is currently used
as a workaround on A64. And it fixes the values returned on D1, where
the SRAM method was being used.
The special case for the last word is needed to maintain .word_size == 1
for sysfs ABI compatibility, as noted previously in commit de2a3eaea552
("nvmem: sunxi_sid: Optimize register read-out method").
Fixes: 07ae4fde9efa ("nvmem: sunxi_sid: Add support for D1 variant")
Cc: stable@vger.kernel.org
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Samuel Holland <samuel@sholland.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20230127104015.23839-3-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/sunxi_sid.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context,
void *val, size_t bytes)
{
struct sunxi_sid *sid = context;
+ u32 word;
- memcpy_fromio(val, sid->base + sid->value_offset + offset, bytes);
+ /* .stride = 4 so offset is guaranteed to be aligned */
+ __ioread32_copy(val, sid->base + sid->value_offset + offset, bytes / 4);
+
+ val += round_down(bytes, 4);
+ offset += round_down(bytes, 4);
+ bytes = bytes % 4;
+
+ if (!bytes)
+ return 0;
+
+ /* Handle any trailing bytes */
+ word = readl_relaxed(sid->base + sid->value_offset + offset);
+ memcpy(val, &word, bytes);
return 0;
}

View File

@ -0,0 +1,48 @@
From edcf2fb660526b5ed29f93bd17328a2b4835c8b2 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Fri, 27 Jan 2023 10:40:12 +0000
Subject: [PATCH] nvmem: core: fix device node refcounting
In of_nvmem_cell_get(), of_get_next_parent() is used on cell_np. This
will decrement the refcount on cell_np, but cell_np is still used later
in the code. Use of_get_parent() instead and of_node_put() in the
appropriate places.
Fixes: 69aba7948cbe ("nvmem: Add a simple NVMEM framework for consumers")
Fixes: 7ae6478b304b ("nvmem: core: rework nvmem cell instance creation")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20230127104015.23839-8-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/core.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1240,16 +1240,21 @@ struct nvmem_cell *of_nvmem_cell_get(str
if (!cell_np)
return ERR_PTR(-ENOENT);
- nvmem_np = of_get_next_parent(cell_np);
- if (!nvmem_np)
+ nvmem_np = of_get_parent(cell_np);
+ if (!nvmem_np) {
+ of_node_put(cell_np);
return ERR_PTR(-EINVAL);
+ }
nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
of_node_put(nvmem_np);
- if (IS_ERR(nvmem))
+ if (IS_ERR(nvmem)) {
+ of_node_put(cell_np);
return ERR_CAST(nvmem);
+ }
cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np);
+ of_node_put(cell_np);
if (!cell_entry) {
__nvmem_device_put(nvmem);
return ERR_PTR(-ENOENT);

View File

@ -103,9 +103,9 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ if (cell_spec.args_count)
+ cell_index = cell_spec.args[0];
nvmem_np = of_get_next_parent(cell_np);
if (!nvmem_np)
@@ -1255,7 +1270,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
nvmem_np = of_get_parent(cell_np);
if (!nvmem_np) {
@@ -1260,7 +1275,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
return ERR_PTR(-ENOENT);
}
@ -114,7 +114,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (IS_ERR(cell))
__nvmem_device_put(nvmem);
@@ -1408,8 +1423,8 @@ static void nvmem_shift_read_buffer_in_p
@@ -1413,8 +1428,8 @@ static void nvmem_shift_read_buffer_in_p
}
static int __nvmem_cell_read(struct nvmem_device *nvmem,
@ -125,7 +125,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
{
int rc;
@@ -1423,7 +1438,7 @@ static int __nvmem_cell_read(struct nvme
@@ -1428,7 +1443,7 @@ static int __nvmem_cell_read(struct nvme
nvmem_shift_read_buffer_in_place(cell, buf);
if (nvmem->cell_post_process) {
@ -134,7 +134,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cell->offset, buf, cell->bytes);
if (rc)
return rc;
@@ -1458,7 +1473,7 @@ void *nvmem_cell_read(struct nvmem_cell
@@ -1463,7 +1478,7 @@ void *nvmem_cell_read(struct nvmem_cell
if (!buf)
return ERR_PTR(-ENOMEM);
@ -143,7 +143,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (rc) {
kfree(buf);
return ERR_PTR(rc);
@@ -1771,7 +1786,7 @@ ssize_t nvmem_device_cell_read(struct nv
@@ -1776,7 +1791,7 @@ ssize_t nvmem_device_cell_read(struct nv
if (rc)
return rc;