--- /dev/null
+From fff53a551db50f5edecaa0b29a64056ab8d2bbca Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Date: Wed, 22 Sep 2021 11:10:06 +0200
+Subject: memory: renesas-rpc-if: Correct QSPI data transfer in Manual mode
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+commit fff53a551db50f5edecaa0b29a64056ab8d2bbca upstream.
+
+This patch fixes 2 problems:
+[1] The output warning logs and data loss when performing
+mount/umount then remount the device with jffs2 format.
+[2] The access width of SMWDR[0:1]/SMRDR[0:1] register is wrong.
+
+This is the sample warning logs when performing mount/umount then
+remount the device with jffs2 format:
+jffs2: jffs2_scan_inode_node(): CRC failed on node at 0x031c51d4:
+Read 0x00034e00, calculated 0xadb272a7
+
+The reason for issue [1] is that the writing data seems to
+get messed up.
+Data is only completed when the number of bytes is divisible by 4.
+If you only have 3 bytes of data left to write, 1 garbage byte
+is inserted after the end of the write stream.
+If you only have 2 bytes of data left to write, 2 bytes of '00'
+are added into the write stream.
+If you only have 1 byte of data left to write, 2 bytes of '00'
+are added into the write stream. 1 garbage byte is inserted after
+the end of the write stream.
+
+To solve problem [1], data must be written continuously in serial
+and the write stream ends when data is out.
+
+Following HW manual 62.2.15, access to SMWDR0 register should be
+in the same size as the transfer size specified in the SPIDE[3:0]
+bits in the manual mode enable setting register (SMENR).
+Be sure to access from address 0.
+
+So, in 16-bit transfer (SPIDE[3:0]=b'1100), SMWDR0 should be
+accessed by 16-bit width.
+Similar to SMWDR1, SMDDR0/1 registers.
+In current code, SMWDR0 register is accessed by regmap_write()
+that only set up to do 32-bit width.
+
+To solve problem [2], data must be written 16-bit or 8-bit when
+transferring 1-byte or 2-byte.
+
+Fixes: ca7d8b980b67 ("memory: add Renesas RPC-IF driver")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Duc Nguyen <duc.nguyen.ub@renesas.com>
+[wsa: refactored to use regmap only via reg_read/reg_write]
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20210922091007.5516-1-wsa+renesas@sang-engineering.com
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/memory/renesas-rpc-if.c | 113 +++++++++++++++++++++++++++-------------
+ include/memory/renesas-rpc-if.h | 1
+ 2 files changed, 79 insertions(+), 35 deletions(-)
+
+--- a/drivers/memory/renesas-rpc-if.c
++++ b/drivers/memory/renesas-rpc-if.c
+@@ -161,10 +161,62 @@ static const struct regmap_access_table
+ .n_yes_ranges = ARRAY_SIZE(rpcif_volatile_ranges),
+ };
+
++
++/*
++ * Custom accessor functions to ensure SMRDR0 and SMWDR0 are always accessed
++ * with proper width. Requires SMENR_SPIDE to be correctly set before!
++ */
++static int rpcif_reg_read(void *context, unsigned int reg, unsigned int *val)
++{
++ struct rpcif *rpc = context;
++
++ if (reg == RPCIF_SMRDR0 || reg == RPCIF_SMWDR0) {
++ u32 spide = readl(rpc->base + RPCIF_SMENR) & RPCIF_SMENR_SPIDE(0xF);
++
++ if (spide == 0x8) {
++ *val = readb(rpc->base + reg);
++ return 0;
++ } else if (spide == 0xC) {
++ *val = readw(rpc->base + reg);
++ return 0;
++ } else if (spide != 0xF) {
++ return -EILSEQ;
++ }
++ }
++
++ *val = readl(rpc->base + reg);
++ return 0;
++
++}
++
++static int rpcif_reg_write(void *context, unsigned int reg, unsigned int val)
++{
++ struct rpcif *rpc = context;
++
++ if (reg == RPCIF_SMRDR0 || reg == RPCIF_SMWDR0) {
++ u32 spide = readl(rpc->base + RPCIF_SMENR) & RPCIF_SMENR_SPIDE(0xF);
++
++ if (spide == 0x8) {
++ writeb(val, rpc->base + reg);
++ return 0;
++ } else if (spide == 0xC) {
++ writew(val, rpc->base + reg);
++ return 0;
++ } else if (spide != 0xF) {
++ return -EILSEQ;
++ }
++ }
++
++ writel(val, rpc->base + reg);
++ return 0;
++}
++
+ static const struct regmap_config rpcif_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
++ .reg_read = rpcif_reg_read,
++ .reg_write = rpcif_reg_write,
+ .fast_io = true,
+ .max_register = RPCIF_PHYINT,
+ .volatile_table = &rpcif_volatile_table,
+@@ -174,17 +226,15 @@ int rpcif_sw_init(struct rpcif *rpc, str
+ {
+ struct platform_device *pdev = to_platform_device(dev);
+ struct resource *res;
+- void __iomem *base;
+
+ rpc->dev = dev;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+- base = devm_ioremap_resource(&pdev->dev, res);
+- if (IS_ERR(base))
+- return PTR_ERR(base);
++ rpc->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(rpc->base))
++ return PTR_ERR(rpc->base);
+
+- rpc->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+- &rpcif_regmap_config);
++ 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",
+@@ -367,20 +417,16 @@ void rpcif_prepare(struct rpcif *rpc, co
+ nbytes = op->data.nbytes;
+ rpc->xferlen = nbytes;
+
+- rpc->enable |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)) |
+- RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth));
++ rpc->enable |= RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth));
+ }
+ }
+ EXPORT_SYMBOL(rpcif_prepare);
+
+ int rpcif_manual_xfer(struct rpcif *rpc)
+ {
+- u32 smenr, smcr, pos = 0, max = 4;
++ u32 smenr, smcr, pos = 0, max = rpc->bus_size == 2 ? 8 : 4;
+ int ret = 0;
+
+- if (rpc->bus_size == 2)
+- max = 8;
+-
+ pm_runtime_get_sync(rpc->dev);
+
+ regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
+@@ -391,37 +437,36 @@ int rpcif_manual_xfer(struct rpcif *rpc)
+ regmap_write(rpc->regmap, RPCIF_SMOPR, rpc->option);
+ regmap_write(rpc->regmap, RPCIF_SMDMCR, rpc->dummy);
+ regmap_write(rpc->regmap, RPCIF_SMDRENR, rpc->ddr);
++ regmap_write(rpc->regmap, RPCIF_SMADR, rpc->smadr);
+ smenr = rpc->enable;
+
+ switch (rpc->dir) {
+ case RPCIF_DATA_OUT:
+ while (pos < rpc->xferlen) {
+- u32 nbytes = rpc->xferlen - pos;
+- u32 data[2];
++ u32 bytes_left = rpc->xferlen - pos;
++ u32 nbytes, data[2];
+
+ smcr = rpc->smcr | RPCIF_SMCR_SPIE;
+- if (nbytes > max) {
+- nbytes = max;
++
++ /* nbytes may only be 1, 2, 4, or 8 */
++ nbytes = bytes_left >= max ? max : (1 << ilog2(bytes_left));
++ if (bytes_left > nbytes)
+ smcr |= RPCIF_SMCR_SSLKP;
+- }
++
++ smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes));
++ regmap_write(rpc->regmap, RPCIF_SMENR, smenr);
+
+ memcpy(data, rpc->buffer + pos, nbytes);
+- if (nbytes > 4) {
++ if (nbytes == 8) {
+ regmap_write(rpc->regmap, RPCIF_SMWDR1,
+ data[0]);
+ regmap_write(rpc->regmap, RPCIF_SMWDR0,
+ data[1]);
+- } else if (nbytes > 2) {
++ } else {
+ regmap_write(rpc->regmap, RPCIF_SMWDR0,
+ data[0]);
+- } else {
+- regmap_write(rpc->regmap, RPCIF_SMWDR0,
+- data[0] << 16);
+ }
+
+- regmap_write(rpc->regmap, RPCIF_SMADR,
+- rpc->smadr + pos);
+- regmap_write(rpc->regmap, RPCIF_SMENR, smenr);
+ regmap_write(rpc->regmap, RPCIF_SMCR, smcr);
+ ret = wait_msg_xfer_end(rpc);
+ if (ret)
+@@ -461,14 +506,16 @@ int rpcif_manual_xfer(struct rpcif *rpc)
+ break;
+ }
+ while (pos < rpc->xferlen) {
+- u32 nbytes = rpc->xferlen - pos;
+- u32 data[2];
++ u32 bytes_left = rpc->xferlen - pos;
++ u32 nbytes, data[2];
+
+- if (nbytes > max)
+- nbytes = max;
++ /* nbytes may only be 1, 2, 4, or 8 */
++ nbytes = bytes_left >= max ? max : (1 << ilog2(bytes_left));
+
+ regmap_write(rpc->regmap, RPCIF_SMADR,
+ rpc->smadr + pos);
++ smenr &= ~RPCIF_SMENR_SPIDE(0xF);
++ smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes));
+ regmap_write(rpc->regmap, RPCIF_SMENR, smenr);
+ regmap_write(rpc->regmap, RPCIF_SMCR,
+ rpc->smcr | RPCIF_SMCR_SPIE);
+@@ -476,18 +523,14 @@ int rpcif_manual_xfer(struct rpcif *rpc)
+ if (ret)
+ goto err_out;
+
+- if (nbytes > 4) {
++ if (nbytes == 8) {
+ regmap_read(rpc->regmap, RPCIF_SMRDR1,
+ &data[0]);
+ regmap_read(rpc->regmap, RPCIF_SMRDR0,
+ &data[1]);
+- } else if (nbytes > 2) {
+- regmap_read(rpc->regmap, RPCIF_SMRDR0,
+- &data[0]);
+- } else {
++ } else {
+ regmap_read(rpc->regmap, RPCIF_SMRDR0,
+ &data[0]);
+- data[0] >>= 16;
+ }
+ memcpy(rpc->buffer + pos, data, nbytes);
+
+--- a/include/memory/renesas-rpc-if.h
++++ b/include/memory/renesas-rpc-if.h
+@@ -58,6 +58,7 @@ struct rpcif_op {
+
+ struct rpcif {
+ struct device *dev;
++ void __iomem *base;
+ void __iomem *dirmap;
+ struct regmap *regmap;
+ struct reset_control *rstc;
--- /dev/null
+From b4ebddd6540d78a7f977b3fea0261bd575c6ffe2 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+Date: Wed, 29 Sep 2021 00:22:47 +0200
+Subject: mtd: rawnand: socrates: Keep the driver compatible with on-die ECC engines
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+commit b4ebddd6540d78a7f977b3fea0261bd575c6ffe2 upstream.
+
+Following the introduction of the generic ECC engine infrastructure, it
+was necessary to reorganize the code and move the ECC configuration in
+the ->attach_chip() hook. Failing to do that properly lead to a first
+series of fixes supposed to stabilize the situation. Unfortunately, this
+only fixed the use of software ECC engines, preventing any other kind of
+engine to be used, including on-die ones.
+
+It is now time to (finally) fix the situation by ensuring that we still
+provide a default (eg. software ECC) but will still support different
+ECC engines such as on-die ECC engines if properly described in the
+device tree.
+
+There are no changes needed on the core side in order to do this, but we
+just need to leverage the logic there which allows:
+1- a subsystem default (set to Host engines in the raw NAND world)
+2- a driver specific default (here set to software ECC engines)
+3- any type of engine requested by the user (ie. described in the DT)
+
+As the raw NAND subsystem has not yet been fully converted to the ECC
+engine infrastructure, in order to provide a default ECC engine for this
+driver we need to set chip->ecc.engine_type *before* calling
+nand_scan(). During the initialization step, the core will consider this
+entry as the default engine for this driver. This value may of course
+be overloaded by the user if the usual DT properties are provided.
+
+Fixes: b36bf0a0fe5d ("mtd: rawnand: socrates: Move the ECC initialization to ->attach_chip()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-9-miquel.raynal@bootlin.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/nand/raw/socrates_nand.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/drivers/mtd/nand/raw/socrates_nand.c
++++ b/drivers/mtd/nand/raw/socrates_nand.c
+@@ -119,9 +119,8 @@ static int socrates_nand_device_ready(st
+
+ static int socrates_attach_chip(struct nand_chip *chip)
+ {
+- chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+-
+- if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
++ if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
++ chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+ chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
+
+ return 0;
+@@ -175,6 +174,13 @@ static int socrates_nand_probe(struct pl
+ /* TODO: I have no idea what real delay is. */
+ nand_chip->legacy.chip_delay = 20; /* 20us command delay time */
+
++ /*
++ * This driver assumes that the default ECC engine should be TYPE_SOFT.
++ * Set ->engine_type before registering the NAND devices in order to
++ * provide a driver specific default value.
++ */
++ nand_chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
++
+ dev_set_drvdata(&ofdev->dev, host);
+
+ res = nand_scan(nand_chip, 1);
--- /dev/null
+From f42e8a603c88f72bf047a710b9fc1d3579f31e71 Mon Sep 17 00:00:00 2001
+From: Kan Liang <kan.liang@linux.intel.com>
+Date: Thu, 26 Aug 2021 08:32:39 -0700
+Subject: perf/x86/intel/uncore: Fix Intel ICX IIO event constraints
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+commit f42e8a603c88f72bf047a710b9fc1d3579f31e71 upstream.
+
+According to the latest uncore document, both NUM_OUTSTANDING_REQ_OF_CPU
+(0x88) event and COMP_BUF_OCCUPANCY(0xd5) event also have constraints. Add
+them into the event constraints table.
+
+Fixes: 2b3b76b5ec67 ("perf/x86/intel/uncore: Add Ice Lake server uncore support")
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/1629991963-102621-4-git-send-email-kan.liang@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/events/intel/uncore_snbep.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -4898,8 +4898,10 @@ static struct event_constraint icx_uncor
+ UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x03, 0x3),
+ UNCORE_EVENT_CONSTRAINT(0x83, 0x3),
++ UNCORE_EVENT_CONSTRAINT(0x88, 0xc),
+ UNCORE_EVENT_CONSTRAINT(0xc0, 0xc),
+ UNCORE_EVENT_CONSTRAINT(0xc5, 0xc),
++ UNCORE_EVENT_CONSTRAINT(0xd5, 0xc),
+ EVENT_CONSTRAINT_END
+ };
+
--- /dev/null
+From 496a18f09374ad89b3ab4366019bc3975db90234 Mon Sep 17 00:00:00 2001
+From: Kan Liang <kan.liang@linux.intel.com>
+Date: Thu, 26 Aug 2021 08:32:37 -0700
+Subject: perf/x86/intel/uncore: Support extra IMC channel on Ice Lake server
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+commit 496a18f09374ad89b3ab4366019bc3975db90234 upstream.
+
+There are three channels on a Ice Lake server, but only two channels
+will ever be active. Current perf only enables two channels.
+
+Support the extra IMC channel, which may be activated on some Ice Lake
+machines. For a non-activated channel, the SW can still access it. The
+write will be ignored by the HW. 0 is always returned for the reading.
+
+Fixes: 2b3b76b5ec67 ("perf/x86/intel/uncore: Add Ice Lake server uncore support")
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Andi Kleen <ak@linux.intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/1629991963-102621-2-git-send-email-kan.liang@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/events/intel/uncore_snbep.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -444,7 +444,7 @@
+ #define ICX_M3UPI_PCI_PMON_BOX_CTL 0xa0
+
+ /* ICX IMC */
+-#define ICX_NUMBER_IMC_CHN 2
++#define ICX_NUMBER_IMC_CHN 3
+ #define ICX_IMC_MEM_STRIDE 0x4
+
+ DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
+@@ -5228,7 +5228,7 @@ static struct intel_uncore_ops icx_uncor
+ static struct intel_uncore_type icx_uncore_imc = {
+ .name = "imc",
+ .num_counters = 4,
+- .num_boxes = 8,
++ .num_boxes = 12,
+ .perf_ctr_bits = 48,
+ .fixed_ctr_bits = 48,
+ .fixed_ctr = SNR_IMC_MMIO_PMON_FIXED_CTR,
--- /dev/null
+From e660dbb68c6b3f7b9eb8b9775846a44f9798b719 Mon Sep 17 00:00:00 2001
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Date: Tue, 14 Sep 2021 14:18:06 +0200
+Subject: power: supply: max17042_battery: Prevent int underflow in set_soc_threshold
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+commit e660dbb68c6b3f7b9eb8b9775846a44f9798b719 upstream.
+
+max17042_set_soc_threshold gets called with offset set to 1, which means
+that minimum threshold value would underflow once SOC got down to 0,
+causing invalid alerts from the gauge.
+
+Fixes: e5f3872d2044 ("max17042: Add support for signalling change in SOC")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/power/supply/max17042_battery.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/power/supply/max17042_battery.c
++++ b/drivers/power/supply/max17042_battery.c
+@@ -851,7 +851,8 @@ static void max17042_set_soc_threshold(s
+ regmap_read(map, MAX17042_RepSOC, &soc);
+ soc >>= 8;
+ soc_tr = (soc + off) << 8;
+- soc_tr |= (soc - off);
++ if (off < soc)
++ soc_tr |= soc - off;
+ regmap_write(map, MAX17042_SALRT_Th, soc_tr);
+ }
+
--- /dev/null
+From 223a3b82834f036a62aa831f67cbf1f1d644c6e2 Mon Sep 17 00:00:00 2001
+From: Henrik Grimler <henrik@grimler.se>
+Date: Wed, 29 Sep 2021 20:14:17 +0200
+Subject: power: supply: max17042_battery: use VFSOC for capacity when no rsns
+
+From: Henrik Grimler <henrik@grimler.se>
+
+commit 223a3b82834f036a62aa831f67cbf1f1d644c6e2 upstream.
+
+On Galaxy S3 (i9300/i9305), which has the max17047 fuel gauge and no
+current sense resistor (rsns), the RepSOC register does not provide an
+accurate state of charge value. The reported value is wrong, and does
+not change over time. VFSOC however, which uses the voltage fuel gauge
+to determine the state of charge, always shows an accurate value.
+
+For devices without current sense, VFSOC is already used for the
+soc-alert (0x0003 is written to MiscCFG register), so with this change
+the source of the alert and the PROP_CAPACITY value match.
+
+Fixes: 359ab9f5b154 ("power_supply: Add MAX17042 Fuel Gauge Driver")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Suggested-by: Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
+Signed-off-by: Henrik Grimler <henrik@grimler.se>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/power/supply/max17042_battery.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/power/supply/max17042_battery.c
++++ b/drivers/power/supply/max17042_battery.c
+@@ -316,7 +316,10 @@ static int max17042_get_property(struct
+ val->intval = data * 625 / 8;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+- ret = regmap_read(map, MAX17042_RepSOC, &data);
++ if (chip->pdata->enable_current_sense)
++ ret = regmap_read(map, MAX17042_RepSOC, &data);
++ else
++ ret = regmap_read(map, MAX17042_VFSOC, &data);
+ if (ret < 0)
+ return ret;
+
--- /dev/null
+From 4f960393a0ee9a39469ceb7c8077ae8db665cc12 Mon Sep 17 00:00:00 2001
+From: Alok Prasad <palok@marvell.com>
+Date: Wed, 27 Oct 2021 18:43:29 +0000
+Subject: RDMA/qedr: Fix NULL deref for query_qp on the GSI QP
+
+From: Alok Prasad <palok@marvell.com>
+
+commit 4f960393a0ee9a39469ceb7c8077ae8db665cc12 upstream.
+
+This patch fixes a crash caused by querying the QP via netlink, and
+corrects the state of GSI qp. GSI qp's have a NULL qed_qp.
+
+The call trace is generated by:
+ $ rdma res show
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000034
+ Hardware name: Dell Inc. PowerEdge R720/0M1GCR, BIOS 1.2.6 05/10/2012
+ RIP: 0010:qed_rdma_query_qp+0x33/0x1a0 [qed]
+ RSP: 0018:ffffba560a08f580 EFLAGS: 00010206
+ RAX: 0000000200000000 RBX: ffffba560a08f5b8 RCX: 0000000000000000
+ RDX: ffffba560a08f5b8 RSI: 0000000000000000 RDI: ffff9807ee458090
+ RBP: ffffba560a08f5a0 R08: 0000000000000000 R09: ffff9807890e7048
+ R10: ffffba560a08f658 R11: 0000000000000000 R12: 0000000000000000
+ R13: ffff9807ee458090 R14: ffff9807f0afb000 R15: ffffba560a08f7ec
+ FS: 00007fbbf8bfe740(0000) GS:ffff980aafa00000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000034 CR3: 00000001720ba001 CR4: 00000000000606f0
+ Call Trace:
+ qedr_query_qp+0x82/0x360 [qedr]
+ ib_query_qp+0x34/0x40 [ib_core]
+ ? ib_query_qp+0x34/0x40 [ib_core]
+ fill_res_qp_entry_query.isra.26+0x47/0x1d0 [ib_core]
+ ? __nla_put+0x20/0x30
+ ? nla_put+0x33/0x40
+ fill_res_qp_entry+0xe3/0x120 [ib_core]
+ res_get_common_dumpit+0x3f8/0x5d0 [ib_core]
+ ? fill_res_cm_id_entry+0x1f0/0x1f0 [ib_core]
+ nldev_res_get_qp_dumpit+0x1a/0x20 [ib_core]
+ netlink_dump+0x156/0x2f0
+ __netlink_dump_start+0x1ab/0x260
+ rdma_nl_rcv+0x1de/0x330 [ib_core]
+ ? nldev_res_get_cm_id_dumpit+0x20/0x20 [ib_core]
+ netlink_unicast+0x1b8/0x270
+ netlink_sendmsg+0x33e/0x470
+ sock_sendmsg+0x63/0x70
+ __sys_sendto+0x13f/0x180
+ ? setup_sgl.isra.12+0x70/0xc0
+ __x64_sys_sendto+0x28/0x30
+ do_syscall_64+0x3a/0xb0
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Cc: stable@vger.kernel.org
+Fixes: cecbcddf6461 ("qedr: Add support for QP verbs")
+Link: https://lore.kernel.org/r/20211027184329.18454-1-palok@marvell.com
+Signed-off-by: Ariel Elior <aelior@marvell.com>
+Signed-off-by: Shai Malin <smalin@marvell.com>
+Signed-off-by: Prabhakar Kushwaha <pkushwaha@marvell.com>
+Signed-off-by: Alok Prasad <palok@marvell.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/qedr/verbs.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/infiniband/hw/qedr/verbs.c
++++ b/drivers/infiniband/hw/qedr/verbs.c
+@@ -2744,15 +2744,18 @@ int qedr_query_qp(struct ib_qp *ibqp,
+ int rc = 0;
+
+ memset(¶ms, 0, sizeof(params));
+-
+- rc = dev->ops->rdma_query_qp(dev->rdma_ctx, qp->qed_qp, ¶ms);
+- if (rc)
+- goto err;
+-
+ memset(qp_attr, 0, sizeof(*qp_attr));
+ memset(qp_init_attr, 0, sizeof(*qp_init_attr));
+
+- qp_attr->qp_state = qedr_get_ibqp_state(params.state);
++ if (qp->qp_type != IB_QPT_GSI) {
++ rc = dev->ops->rdma_query_qp(dev->rdma_ctx, qp->qed_qp, ¶ms);
++ if (rc)
++ goto err;
++ qp_attr->qp_state = qedr_get_ibqp_state(params.state);
++ } else {
++ qp_attr->qp_state = qedr_get_ibqp_state(QED_ROCE_QP_STATE_RTS);
++ }
++
+ qp_attr->cur_qp_state = qedr_get_ibqp_state(params.state);
+ qp_attr->path_mtu = ib_mtu_int_to_enum(params.mtu);
+ qp_attr->path_mig_state = IB_MIG_MIGRATED;
rsi-fix-key-enabled-check-causing-unwanted-encryption-for-vap_id-0.patch
rsi-fix-rate-mask-set-leading-to-p2p-failure.patch
rsi-fix-module-dev_oper_mode-parameter-description.patch
+perf-x86-intel-uncore-support-extra-imc-channel-on-ice-lake-server.patch
+perf-x86-intel-uncore-fix-intel-icx-iio-event-constraints.patch
+rdma-qedr-fix-null-deref-for-query_qp-on-the-gsi-qp.patch
+signal-remove-the-bogus-sigkill_pending-in-ptrace_stop.patch
+memory-renesas-rpc-if-correct-qspi-data-transfer-in-manual-mode.patch
+signal-mips-update-_save-_restore-_fp_context-to-fail-with-efault.patch
+soc-fsl-dpio-replace-smp_processor_id-with-raw_smp_processor_id.patch
+soc-fsl-dpio-use-the-combined-functions-to-protect-critical-zone.patch
+mtd-rawnand-socrates-keep-the-driver-compatible-with-on-die-ecc-engines.patch
+power-supply-max17042_battery-prevent-int-underflow-in-set_soc_threshold.patch
+power-supply-max17042_battery-use-vfsoc-for-capacity-when-no-rsns.patch
--- /dev/null
+From 95bf9d646c3c3f95cb0be7e703b371db8da5be68 Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Wed, 20 Oct 2021 12:43:51 -0500
+Subject: signal/mips: Update (_save|_restore)_fp_context to fail with -EFAULT
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+commit 95bf9d646c3c3f95cb0be7e703b371db8da5be68 upstream.
+
+When an instruction to save or restore a register from the stack fails
+in _save_fp_context or _restore_fp_context return with -EFAULT. This
+change was made to r2300_fpu.S[1] but it looks like it got lost with
+the introduction of EX2[2]. This is also what the other implementation
+of _save_fp_context and _restore_fp_context in r4k_fpu.S does, and
+what is needed for the callers to be able to handle the error.
+
+Furthermore calling do_exit(SIGSEGV) from bad_stack is wrong because
+it does not terminate the entire process it just terminates a single
+thread.
+
+As the changed code was the only caller of arch/mips/kernel/syscall.c:bad_stack
+remove the problematic and now unused helper function.
+
+Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Cc: Maciej Rozycki <macro@orcam.me.uk>
+Cc: linux-mips@vger.kernel.org
+[1] 35938a00ba86 ("MIPS: Fix ISA I FP sigcontext access violation handling")
+[2] f92722dc4545 ("MIPS: Correct MIPS I FP sigcontext layout")
+Cc: stable@vger.kernel.org
+Fixes: f92722dc4545 ("MIPS: Correct MIPS I FP sigcontext layout")
+Acked-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Link: https://lkml.kernel.org/r/20211020174406.17889-5-ebiederm@xmission.com
+Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/kernel/r2300_fpu.S | 4 ++--
+ arch/mips/kernel/syscall.c | 9 ---------
+ 2 files changed, 2 insertions(+), 11 deletions(-)
+
+--- a/arch/mips/kernel/r2300_fpu.S
++++ b/arch/mips/kernel/r2300_fpu.S
+@@ -29,8 +29,8 @@
+ #define EX2(a,b) \
+ 9: a,##b; \
+ .section __ex_table,"a"; \
+- PTR 9b,bad_stack; \
+- PTR 9b+4,bad_stack; \
++ PTR 9b,fault; \
++ PTR 9b+4,fault; \
+ .previous
+
+ .set mips1
+--- a/arch/mips/kernel/syscall.c
++++ b/arch/mips/kernel/syscall.c
+@@ -240,12 +240,3 @@ SYSCALL_DEFINE3(cachectl, char *, addr,
+ {
+ return -ENOSYS;
+ }
+-
+-/*
+- * If we ever come here the user sp is bad. Zap the process right away.
+- * Due to the bad stack signaling wouldn't work.
+- */
+-asmlinkage void bad_stack(void)
+-{
+- do_exit(SIGSEGV);
+-}
--- /dev/null
+From 7d613f9f72ec8f90ddefcae038fdae5adb8404b3 Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Wed, 1 Sep 2021 13:21:34 -0500
+Subject: signal: Remove the bogus sigkill_pending in ptrace_stop
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+commit 7d613f9f72ec8f90ddefcae038fdae5adb8404b3 upstream.
+
+The existence of sigkill_pending is a little silly as it is
+functionally a duplicate of fatal_signal_pending that is used in
+exactly one place.
+
+Checking for pending fatal signals and returning early in ptrace_stop
+is actively harmful. It casues the ptrace_stop called by
+ptrace_signal to return early before setting current->exit_code.
+Later when ptrace_signal reads the signal number from
+current->exit_code is undefined, making it unpredictable what will
+happen.
+
+Instead rely on the fact that schedule will not sleep if there is a
+pending signal that can awaken a task.
+
+Removing the explict sigkill_pending test fixes fixes ptrace_signal
+when ptrace_stop does not stop because current->exit_code is always
+set to to signr.
+
+Cc: stable@vger.kernel.org
+Fixes: 3d749b9e676b ("ptrace: simplify ptrace_stop()->sigkill_pending() path")
+Fixes: 1a669c2f16d4 ("Add arch_ptrace_stop")
+Link: https://lkml.kernel.org/r/87pmsyx29t.fsf@disp2133
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/signal.c | 18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -2097,15 +2097,6 @@ static inline bool may_ptrace_stop(void)
+ return true;
+ }
+
+-/*
+- * Return non-zero if there is a SIGKILL that should be waking us up.
+- * Called with the siglock held.
+- */
+-static bool sigkill_pending(struct task_struct *tsk)
+-{
+- return sigismember(&tsk->pending.signal, SIGKILL) ||
+- sigismember(&tsk->signal->shared_pending.signal, SIGKILL);
+-}
+
+ /*
+ * This must be called with current->sighand->siglock held.
+@@ -2132,17 +2123,16 @@ static void ptrace_stop(int exit_code, i
+ * calling arch_ptrace_stop, so we must release it now.
+ * To preserve proper semantics, we must do this before
+ * any signal bookkeeping like checking group_stop_count.
+- * Meanwhile, a SIGKILL could come in before we retake the
+- * siglock. That must prevent us from sleeping in TASK_TRACED.
+- * So after regaining the lock, we must check for SIGKILL.
+ */
+ spin_unlock_irq(¤t->sighand->siglock);
+ arch_ptrace_stop(exit_code, info);
+ spin_lock_irq(¤t->sighand->siglock);
+- if (sigkill_pending(current))
+- return;
+ }
+
++ /*
++ * schedule() will not sleep if there is a pending signal that
++ * can awaken the task.
++ */
+ set_special_state(TASK_TRACED);
+
+ /*
--- /dev/null
+From e775eb9fc2a4107f03222fa48bc95c2c82427e64 Mon Sep 17 00:00:00 2001
+From: Meng Li <Meng.Li@windriver.com>
+Date: Tue, 19 Oct 2021 10:32:41 +0800
+Subject: soc: fsl: dpio: replace smp_processor_id with raw_smp_processor_id
+
+From: Meng Li <Meng.Li@windriver.com>
+
+commit e775eb9fc2a4107f03222fa48bc95c2c82427e64 upstream.
+
+When enable debug kernel configs,there will be calltrace as below:
+
+BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
+caller is debug_smp_processor_id+0x20/0x30
+CPU: 6 PID: 1 Comm: swapper/0 Not tainted 5.10.63-yocto-standard #1
+Hardware name: NXP Layerscape LX2160ARDB (DT)
+Call trace:
+ dump_backtrace+0x0/0x1a0
+ show_stack+0x24/0x30
+ dump_stack+0xf0/0x13c
+ check_preemption_disabled+0x100/0x110
+ debug_smp_processor_id+0x20/0x30
+ dpaa2_io_query_fq_count+0xdc/0x154
+ dpaa2_eth_stop+0x144/0x314
+ __dev_close_many+0xdc/0x160
+ __dev_change_flags+0xe8/0x220
+ dev_change_flags+0x30/0x70
+ ic_close_devs+0x50/0x78
+ ip_auto_config+0xed0/0xf10
+ do_one_initcall+0xac/0x460
+ kernel_init_freeable+0x30c/0x378
+ kernel_init+0x20/0x128
+ ret_from_fork+0x10/0x38
+
+Based on comment in the context, it doesn't matter whether
+preemption is disable or not. So, replace smp_processor_id()
+with raw_smp_processor_id() to avoid above call trace.
+
+Fixes: c89105c9b390 ("staging: fsl-mc: Move DPIO from staging to drivers/soc/fsl")
+Cc: stable@vger.kernel.org
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/soc/fsl/dpio/dpio-service.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/soc/fsl/dpio/dpio-service.c
++++ b/drivers/soc/fsl/dpio/dpio-service.c
+@@ -59,7 +59,7 @@ static inline struct dpaa2_io *service_s
+ * potentially being migrated away.
+ */
+ if (cpu < 0)
+- cpu = smp_processor_id();
++ cpu = raw_smp_processor_id();
+
+ /* If a specific cpu was requested, pick it up immediately */
+ return dpio_by_cpu[cpu];
--- /dev/null
+From dc7e5940aad6641bd5ab33ea8b21c4b3904d989f Mon Sep 17 00:00:00 2001
+From: Meng Li <Meng.Li@windriver.com>
+Date: Tue, 19 Oct 2021 11:05:55 +0800
+Subject: soc: fsl: dpio: use the combined functions to protect critical zone
+
+From: Meng Li <Meng.Li@windriver.com>
+
+commit dc7e5940aad6641bd5ab33ea8b21c4b3904d989f upstream.
+
+In orininal code, use 2 function spin_lock() and local_irq_save() to
+protect the critical zone. But when enable the kernel debug config,
+there are below inconsistent lock state detected.
+================================
+WARNING: inconsistent lock state
+5.10.63-yocto-standard #1 Not tainted
+--------------------------------
+inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
+lock_torture_wr/226 [HC0[0]:SC1[5]:HE1:SE0] takes:
+ffff002005b2dd80 (&p->access_spinlock){+.?.}-{3:3}, at: qbman_swp_enqueue_multiple_mem_back+0x44/0x270
+{SOFTIRQ-ON-W} state was registered at:
+ lock_acquire.part.0+0xf8/0x250
+ lock_acquire+0x68/0x84
+ _raw_spin_lock+0x68/0x90
+ qbman_swp_enqueue_multiple_mem_back+0x44/0x270
+ ......
+ cryptomgr_test+0x38/0x60
+ kthread+0x158/0x164
+ ret_from_fork+0x10/0x38
+irq event stamp: 4498
+hardirqs last enabled at (4498): [<ffff800010fcf980>] _raw_spin_unlock_irqrestore+0x90/0xb0
+hardirqs last disabled at (4497): [<ffff800010fcffc4>] _raw_spin_lock_irqsave+0xd4/0xe0
+softirqs last enabled at (4458): [<ffff8000100108c4>] __do_softirq+0x674/0x724
+softirqs last disabled at (4465): [<ffff80001005b2a4>] __irq_exit_rcu+0x190/0x19c
+
+other info that might help us debug this:
+ Possible unsafe locking scenario:
+ CPU0
+ ----
+ lock(&p->access_spinlock);
+ <Interrupt>
+ lock(&p->access_spinlock);
+ *** DEADLOCK ***
+
+So, in order to avoid deadlock, use the combined functions
+spin_lock_irqsave/spin_unlock_irqrestore() to protect critical zone.
+
+Fixes: 3b2abda7d28c ("soc: fsl: dpio: Replace QMAN array mode with ring mode enqueue")
+Cc: stable@vger.kernel.org
+Signed-off-by: Meng Li <Meng.Li@windriver.com>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/soc/fsl/dpio/qbman-portal.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/soc/fsl/dpio/qbman-portal.c
++++ b/drivers/soc/fsl/dpio/qbman-portal.c
+@@ -732,8 +732,7 @@ int qbman_swp_enqueue_multiple_mem_back(
+ int i, num_enqueued = 0;
+ unsigned long irq_flags;
+
+- spin_lock(&s->access_spinlock);
+- local_irq_save(irq_flags);
++ spin_lock_irqsave(&s->access_spinlock, irq_flags);
+
+ half_mask = (s->eqcr.pi_ci_mask>>1);
+ full_mask = s->eqcr.pi_ci_mask;
+@@ -744,8 +743,7 @@ int qbman_swp_enqueue_multiple_mem_back(
+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
+ eqcr_ci, s->eqcr.ci);
+ if (!s->eqcr.available) {
+- local_irq_restore(irq_flags);
+- spin_unlock(&s->access_spinlock);
++ spin_unlock_irqrestore(&s->access_spinlock, irq_flags);
+ return 0;
+ }
+ }
+@@ -784,8 +782,7 @@ int qbman_swp_enqueue_multiple_mem_back(
+ dma_wmb();
+ qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI,
+ (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);
+- local_irq_restore(irq_flags);
+- spin_unlock(&s->access_spinlock);
++ spin_unlock_irqrestore(&s->access_spinlock, irq_flags);
+
+ return num_enqueued;
+ }