--- /dev/null
+From adb9dd4a47466f0afa782860a0e01c6595bcd0fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 12:39:03 +0900
+Subject: 9p: Fix read/write debug statements to report server reply
+
+From: Dominique Martinet <asmadeus@codewreck.org>
+
+[ Upstream commit be3193e58ec210b2a72fb1134c2a0695088a911d ]
+
+Previous conversion to iov missed these debug statements which would now
+always print the requested size instead of the actual server reply.
+
+Write also added a loop in a much older commit but we didn't report
+these, while reads do report each iteration -- it's more coherent to
+keep reporting all requests to server so move that at the same time.
+
+Fixes: 7f02464739da ("9p: convert to advancing variant of iov_iter_get_pages_alloc()")
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Message-ID: <20240109-9p-rw-trace-v1-1-327178114257@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/client.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 84b93b04d0f06..1d9a8a1f3f107 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -1581,7 +1581,7 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
+ received = rsize;
+ }
+
+- p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
++ p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", received);
+
+ if (non_zc) {
+ int n = copy_to_iter(dataptr, received, to);
+@@ -1607,9 +1607,6 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
+ int total = 0;
+ *err = 0;
+
+- p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %zd\n",
+- fid->fid, offset, iov_iter_count(from));
+-
+ while (iov_iter_count(from)) {
+ int count = iov_iter_count(from);
+ int rsize = fid->iounit;
+@@ -1621,6 +1618,9 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
+ if (count < rsize)
+ rsize = count;
+
++ p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d (/%d)\n",
++ fid->fid, offset, rsize, count);
++
+ /* Don't bother zerocopy for small IO (< 1024) */
+ if (clnt->trans_mod->zc_request && rsize > 1024) {
+ req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, from, 0,
+@@ -1648,7 +1648,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
+ written = rsize;
+ }
+
+- p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
++ p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", written);
+
+ p9_req_put(clnt, req);
+ iov_iter_revert(from, count - written - iov_iter_count(from));
+--
+2.43.0
+
--- /dev/null
+From 2de793980265d2aa5f4f29385b6c07fc328328bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 18:01:31 -0700
+Subject: ASoC: ops: Fix wraparound for mask in snd_soc_get_volsw
+
+From: Stephen Lee <slee08177@gmail.com>
+
+[ Upstream commit fc563aa900659a850e2ada4af26b9d7a3de6c591 ]
+
+In snd_soc_info_volsw(), mask is generated by figuring out the index of
+the most significant bit set in max and converting the index to a
+bitmask through bit shift 1. Unintended wraparound occurs when max is an
+integer value with msb bit set. Since the bit shift value 1 is treated
+as an integer type, the left shift operation will wraparound and set
+mask to 0 instead of all 1's. In order to fix this, we type cast 1 as
+`1ULL` to prevent the wraparound.
+
+Fixes: 7077148fb50a ("ASoC: core: Split ops out of soc-core.c")
+Signed-off-by: Stephen Lee <slee08177@gmail.com>
+Link: https://msgid.link/r/20240326010131.6211-1-slee08177@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-ops.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
+index 2d25748ca7066..b27e89ff6a167 100644
+--- a/sound/soc/soc-ops.c
++++ b/sound/soc/soc-ops.c
+@@ -263,7 +263,7 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
+ int max = mc->max;
+ int min = mc->min;
+ int sign_bit = mc->sign_bit;
+- unsigned int mask = (1 << fls(max)) - 1;
++ unsigned int mask = (1ULL << fls(max)) - 1;
+ unsigned int invert = mc->invert;
+ int val;
+ int ret;
+--
+2.43.0
+
--- /dev/null
+From 5e0bae0ce7a9011220253d75474bba58ac5a4cd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 17:18:12 -0500
+Subject: ASoC: rt5682-sdw: fix locking sequence
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 310a5caa4e861616a27a83c3e8bda17d65026fa8 ]
+
+The disable_irq_lock protects the 'disable_irq' value, we need to lock
+before testing it.
+
+Fixes: 02fb23d72720 ("ASoC: rt5682-sdw: fix for JD event handling in ClockStop Mode0")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Chao Song <chao.song@linux.intel.com>
+Link: https://msgid.link/r/20240325221817.206465-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt5682-sdw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c
+index 868a61c8b0608..7685011a09354 100644
+--- a/sound/soc/codecs/rt5682-sdw.c
++++ b/sound/soc/codecs/rt5682-sdw.c
+@@ -787,12 +787,12 @@ static int __maybe_unused rt5682_dev_resume(struct device *dev)
+ return 0;
+
+ if (!slave->unattach_request) {
++ mutex_lock(&rt5682->disable_irq_lock);
+ if (rt5682->disable_irq == true) {
+- mutex_lock(&rt5682->disable_irq_lock);
+ sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF);
+ rt5682->disable_irq = false;
+- mutex_unlock(&rt5682->disable_irq_lock);
+ }
++ mutex_unlock(&rt5682->disable_irq_lock);
+ goto regmap_sync;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From ab96e8abb1c6e3f145a76d57b0f0a2f46985fefc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 17:18:13 -0500
+Subject: ASoC: rt711-sdca: fix locking sequence
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit ee287771644394d071e6a331951ee8079b64f9a7 ]
+
+The disable_irq_lock protects the 'disable_irq' value, we need to lock
+before testing it.
+
+Fixes: 23adeb7056ac ("ASoC: rt711-sdca: fix for JD event handling in ClockStop Mode0")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Chao Song <chao.song@linux.intel.com>
+Link: https://msgid.link/r/20240325221817.206465-3-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt711-sdca-sdw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c
+index 487d3010ddc19..931dbc68548ee 100644
+--- a/sound/soc/codecs/rt711-sdca-sdw.c
++++ b/sound/soc/codecs/rt711-sdca-sdw.c
+@@ -443,13 +443,13 @@ static int __maybe_unused rt711_sdca_dev_resume(struct device *dev)
+ return 0;
+
+ if (!slave->unattach_request) {
++ mutex_lock(&rt711->disable_irq_lock);
+ if (rt711->disable_irq == true) {
+- mutex_lock(&rt711->disable_irq_lock);
+ sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK1, SDW_SCP_SDCA_INTMASK_SDCA_0);
+ sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK2, SDW_SCP_SDCA_INTMASK_SDCA_8);
+ rt711->disable_irq = false;
+- mutex_unlock(&rt711->disable_irq_lock);
+ }
++ mutex_unlock(&rt711->disable_irq_lock);
+ goto regmap_sync;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 7cbe7babfff3e811d6e847f55300b9fc24f4ef2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 17:18:14 -0500
+Subject: ASoC: rt711-sdw: fix locking sequence
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit aae86cfd8790bcc7693a5a0894df58de5cb5128c ]
+
+The disable_irq_lock protects the 'disable_irq' value, we need to lock
+before testing it.
+
+Fixes: b69de265bd0e ("ASoC: rt711: fix for JD event handling in ClockStop Mode0")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Chao Song <chao.song@linux.intel.com>
+Link: https://msgid.link/r/20240325221817.206465-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt711-sdw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c
+index 9545b8a7eb192..af7a0ab5669f4 100644
+--- a/sound/soc/codecs/rt711-sdw.c
++++ b/sound/soc/codecs/rt711-sdw.c
+@@ -542,12 +542,12 @@ static int __maybe_unused rt711_dev_resume(struct device *dev)
+ return 0;
+
+ if (!slave->unattach_request) {
++ mutex_lock(&rt711->disable_irq_lock);
+ if (rt711->disable_irq == true) {
+- mutex_lock(&rt711->disable_irq_lock);
+ sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF);
+ rt711->disable_irq = false;
+- mutex_unlock(&rt711->disable_irq_lock);
+ }
++ mutex_unlock(&rt711->disable_irq_lock);
+ goto regmap_sync;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From fefbad93571e9ed3c39297c11fb7b7d582cc27cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 10:06:48 +0200
+Subject: ata: sata_mv: Fix PCI device ID table declaration compilation warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 3137b83a90646917c90951d66489db466b4ae106 ]
+
+Building with W=1 shows a warning for an unused variable when CONFIG_PCI
+is diabled:
+
+drivers/ata/sata_mv.c:790:35: error: unused variable 'mv_pci_tbl' [-Werror,-Wunused-const-variable]
+static const struct pci_device_id mv_pci_tbl[] = {
+
+Move the table into the same block that containsn the pci_driver
+definition.
+
+Fixes: 7bb3c5290ca0 ("sata_mv: Remove PCI dependency")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_mv.c | 63 +++++++++++++++++++++----------------------
+ 1 file changed, 31 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
+index 17f9062b0eaa5..9cf540017a5e5 100644
+--- a/drivers/ata/sata_mv.c
++++ b/drivers/ata/sata_mv.c
+@@ -787,37 +787,6 @@ static const struct ata_port_info mv_port_info[] = {
+ },
+ };
+
+-static const struct pci_device_id mv_pci_tbl[] = {
+- { PCI_VDEVICE(MARVELL, 0x5040), chip_504x },
+- { PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
+- { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
+- { PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
+- /* RocketRAID 1720/174x have different identifiers */
+- { PCI_VDEVICE(TTI, 0x1720), chip_6042 },
+- { PCI_VDEVICE(TTI, 0x1740), chip_6042 },
+- { PCI_VDEVICE(TTI, 0x1742), chip_6042 },
+-
+- { PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
+- { PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
+- { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 },
+- { PCI_VDEVICE(MARVELL, 0x6080), chip_608x },
+- { PCI_VDEVICE(MARVELL, 0x6081), chip_608x },
+-
+- { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
+-
+- /* Adaptec 1430SA */
+- { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 },
+-
+- /* Marvell 7042 support */
+- { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
+-
+- /* Highpoint RocketRAID PCIe series */
+- { PCI_VDEVICE(TTI, 0x2300), chip_7042 },
+- { PCI_VDEVICE(TTI, 0x2310), chip_7042 },
+-
+- { } /* terminate list */
+-};
+-
+ static const struct mv_hw_ops mv5xxx_ops = {
+ .phy_errata = mv5_phy_errata,
+ .enable_leds = mv5_enable_leds,
+@@ -4301,6 +4270,36 @@ static int mv_pci_init_one(struct pci_dev *pdev,
+ static int mv_pci_device_resume(struct pci_dev *pdev);
+ #endif
+
++static const struct pci_device_id mv_pci_tbl[] = {
++ { PCI_VDEVICE(MARVELL, 0x5040), chip_504x },
++ { PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
++ { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
++ { PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
++ /* RocketRAID 1720/174x have different identifiers */
++ { PCI_VDEVICE(TTI, 0x1720), chip_6042 },
++ { PCI_VDEVICE(TTI, 0x1740), chip_6042 },
++ { PCI_VDEVICE(TTI, 0x1742), chip_6042 },
++
++ { PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
++ { PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
++ { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 },
++ { PCI_VDEVICE(MARVELL, 0x6080), chip_608x },
++ { PCI_VDEVICE(MARVELL, 0x6081), chip_608x },
++
++ { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
++
++ /* Adaptec 1430SA */
++ { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 },
++
++ /* Marvell 7042 support */
++ { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
++
++ /* Highpoint RocketRAID PCIe series */
++ { PCI_VDEVICE(TTI, 0x2300), chip_7042 },
++ { PCI_VDEVICE(TTI, 0x2310), chip_7042 },
++
++ { } /* terminate list */
++};
+
+ static struct pci_driver mv_pci_driver = {
+ .name = DRV_NAME,
+@@ -4313,6 +4312,7 @@ static struct pci_driver mv_pci_driver = {
+ #endif
+
+ };
++MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
+
+ /**
+ * mv_print_info - Dump key info to kernel log for perusal.
+@@ -4485,7 +4485,6 @@ static void __exit mv_exit(void)
+ MODULE_AUTHOR("Brett Russ");
+ MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers");
+ MODULE_LICENSE("GPL v2");
+-MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
+ MODULE_VERSION(DRV_VERSION);
+ MODULE_ALIAS("platform:" DRV_NAME);
+
+--
+2.43.0
+
--- /dev/null
+From 2f891e9177d48ee19affc0e70672147e4c5e210d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 15:53:37 +0100
+Subject: ata: sata_sx4: fix pdc20621_get_from_dimm() on 64-bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 52f80bb181a9a1530ade30bc18991900bbb9697f ]
+
+gcc warns about a memcpy() with overlapping pointers because of an
+incorrect size calculation:
+
+In file included from include/linux/string.h:369,
+ from drivers/ata/sata_sx4.c:66:
+In function 'memcpy_fromio',
+ inlined from 'pdc20621_get_from_dimm.constprop' at drivers/ata/sata_sx4.c:962:2:
+include/linux/fortify-string.h:97:33: error: '__builtin_memcpy' accessing 4294934464 bytes at offsets 0 and [16, 16400] overlaps 6442385281 bytes at offset -2147450817 [-Werror=restrict]
+ 97 | #define __underlying_memcpy __builtin_memcpy
+ | ^
+include/linux/fortify-string.h:620:9: note: in expansion of macro '__underlying_memcpy'
+ 620 | __underlying_##op(p, q, __fortify_size); \
+ | ^~~~~~~~~~~~~
+include/linux/fortify-string.h:665:26: note: in expansion of macro '__fortify_memcpy_chk'
+ 665 | #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \
+ | ^~~~~~~~~~~~~~~~~~~~
+include/asm-generic/io.h:1184:9: note: in expansion of macro 'memcpy'
+ 1184 | memcpy(buffer, __io_virt(addr), size);
+ | ^~~~~~
+
+The problem here is the overflow of an unsigned 32-bit number to a
+negative that gets converted into a signed 'long', keeping a large
+positive number.
+
+Replace the complex calculation with a more readable min() variant
+that avoids the warning.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_sx4.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
+index 6ceec59cb2913..fa1966638c060 100644
+--- a/drivers/ata/sata_sx4.c
++++ b/drivers/ata/sata_sx4.c
+@@ -958,8 +958,7 @@ static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
+
+ offset -= (idx * window_size);
+ idx++;
+- dist = ((long) (window_size - (offset + size))) >= 0 ? size :
+- (long) (window_size - offset);
++ dist = min(size, window_size - offset);
+ memcpy_fromio(psource, dimm_mmio + offset / 4, dist);
+
+ psource += dist;
+@@ -1006,8 +1005,7 @@ static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
+ readl(mmio + PDC_DIMM_WINDOW_CTLR);
+ offset -= (idx * window_size);
+ idx++;
+- dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size :
+- (long) (window_size - offset);
++ dist = min(size, window_size - offset);
+ memcpy_toio(dimm_mmio + offset / 4, psource, dist);
+ writel(0x01, mmio + PDC_GENERAL_CTLR);
+ readl(mmio + PDC_GENERAL_CTLR);
+--
+2.43.0
+
--- /dev/null
+From 71f33f7378dd4656783b83ab086106f7453d104d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Apr 2024 10:11:35 +0100
+Subject: cifs: Fix caching to try to do open O_WRONLY as rdwr on server
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit e9e62243a3e2322cf639f653a0b0a88a76446ce7 ]
+
+When we're engaged in local caching of a cifs filesystem, we cannot perform
+caching of a partially written cache granule unless we can read the rest of
+the granule. This can result in unexpected access errors being reported to
+the user.
+
+Fix this by the following: if a file is opened O_WRONLY locally, but the
+mount was given the "-o fsc" flag, try first opening the remote file with
+GENERIC_READ|GENERIC_WRITE and if that returns -EACCES, try dropping the
+GENERIC_READ and doing the open again. If that last succeeds, invalidate
+the cache for that file as for O_DIRECT.
+
+Fixes: 70431bfd825d ("cifs: Support fscache indexing rewrite")
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Steve French <sfrench@samba.org>
+cc: Shyam Prasad N <nspmangalore@gmail.com>
+cc: Rohith Surabattula <rohiths.msft@gmail.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: linux-cifs@vger.kernel.org
+cc: netfs@lists.linux.dev
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/dir.c | 15 +++++++++++++
+ fs/smb/client/file.c | 48 ++++++++++++++++++++++++++++++++---------
+ fs/smb/client/fscache.h | 6 ++++++
+ 3 files changed, 59 insertions(+), 10 deletions(-)
+
+diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
+index e382b794acbed..863c7bc3db86f 100644
+--- a/fs/smb/client/dir.c
++++ b/fs/smb/client/dir.c
+@@ -180,6 +180,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
+ int disposition;
+ struct TCP_Server_Info *server = tcon->ses->server;
+ struct cifs_open_parms oparms;
++ int rdwr_for_fscache = 0;
+
+ *oplock = 0;
+ if (tcon->ses->server->oplocks)
+@@ -191,6 +192,10 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
+ return PTR_ERR(full_path);
+ }
+
++ /* If we're caching, we need to be able to fill in around partial writes. */
++ if (cifs_fscache_enabled(inode) && (oflags & O_ACCMODE) == O_WRONLY)
++ rdwr_for_fscache = 1;
++
+ #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
+ if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
+ (CIFS_UNIX_POSIX_PATH_OPS_CAP &
+@@ -267,6 +272,8 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
+ desired_access |= GENERIC_READ; /* is this too little? */
+ if (OPEN_FMODE(oflags) & FMODE_WRITE)
+ desired_access |= GENERIC_WRITE;
++ if (rdwr_for_fscache == 1)
++ desired_access |= GENERIC_READ;
+
+ disposition = FILE_OVERWRITE_IF;
+ if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+@@ -295,6 +302,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
+ if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
+ create_options |= CREATE_OPTION_READONLY;
+
++retry_open:
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
+ .cifs_sb = cifs_sb,
+@@ -308,8 +316,15 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
+ rc = server->ops->open(xid, &oparms, oplock, buf);
+ if (rc) {
+ cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc);
++ if (rc == -EACCES && rdwr_for_fscache == 1) {
++ desired_access &= ~GENERIC_READ;
++ rdwr_for_fscache = 2;
++ goto retry_open;
++ }
+ goto out;
+ }
++ if (rdwr_for_fscache == 2)
++ cifs_invalidate_cache(inode, FSCACHE_INVAL_DIO_WRITE);
+
+ #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
+ /*
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index 0f3405e0f2e48..c240cea7ca349 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -77,12 +77,12 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
+ */
+ }
+
+-static inline int cifs_convert_flags(unsigned int flags)
++static inline int cifs_convert_flags(unsigned int flags, int rdwr_for_fscache)
+ {
+ if ((flags & O_ACCMODE) == O_RDONLY)
+ return GENERIC_READ;
+ else if ((flags & O_ACCMODE) == O_WRONLY)
+- return GENERIC_WRITE;
++ return rdwr_for_fscache == 1 ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE;
+ else if ((flags & O_ACCMODE) == O_RDWR) {
+ /* GENERIC_ALL is too much permission to request
+ can cause unnecessary access denied on create */
+@@ -219,11 +219,16 @@ static int cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_
+ int create_options = CREATE_NOT_DIR;
+ struct TCP_Server_Info *server = tcon->ses->server;
+ struct cifs_open_parms oparms;
++ int rdwr_for_fscache = 0;
+
+ if (!server->ops->open)
+ return -ENOSYS;
+
+- desired_access = cifs_convert_flags(f_flags);
++ /* If we're caching, we need to be able to fill in around partial writes. */
++ if (cifs_fscache_enabled(inode) && (f_flags & O_ACCMODE) == O_WRONLY)
++ rdwr_for_fscache = 1;
++
++ desired_access = cifs_convert_flags(f_flags, rdwr_for_fscache);
+
+ /*********************************************************************
+ * open flag mapping table:
+@@ -260,6 +265,7 @@ static int cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_
+ if (f_flags & O_DIRECT)
+ create_options |= CREATE_NO_BUFFER;
+
++retry_open:
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
+ .cifs_sb = cifs_sb,
+@@ -271,8 +277,16 @@ static int cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_
+ };
+
+ rc = server->ops->open(xid, &oparms, oplock, buf);
+- if (rc)
++ if (rc) {
++ if (rc == -EACCES && rdwr_for_fscache == 1) {
++ desired_access = cifs_convert_flags(f_flags, 0);
++ rdwr_for_fscache = 2;
++ goto retry_open;
++ }
+ return rc;
++ }
++ if (rdwr_for_fscache == 2)
++ cifs_invalidate_cache(inode, FSCACHE_INVAL_DIO_WRITE);
+
+ /* TODO: Add support for calling posix query info but with passing in fid */
+ if (tcon->unix_ext)
+@@ -705,11 +719,11 @@ int cifs_open(struct inode *inode, struct file *file)
+ use_cache:
+ fscache_use_cookie(cifs_inode_cookie(file_inode(file)),
+ file->f_mode & FMODE_WRITE);
+- if (file->f_flags & O_DIRECT &&
+- (!((file->f_flags & O_ACCMODE) != O_RDONLY) ||
+- file->f_flags & O_APPEND))
+- cifs_invalidate_cache(file_inode(file),
+- FSCACHE_INVAL_DIO_WRITE);
++ if (!(file->f_flags & O_DIRECT))
++ goto out;
++ if ((file->f_flags & (O_ACCMODE | O_APPEND)) == O_RDONLY)
++ goto out;
++ cifs_invalidate_cache(file_inode(file), FSCACHE_INVAL_DIO_WRITE);
+
+ out:
+ free_dentry_path(page);
+@@ -774,6 +788,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
+ int disposition = FILE_OPEN;
+ int create_options = CREATE_NOT_DIR;
+ struct cifs_open_parms oparms;
++ int rdwr_for_fscache = 0;
+
+ xid = get_xid();
+ mutex_lock(&cfile->fh_mutex);
+@@ -837,7 +852,11 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
+ }
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+
+- desired_access = cifs_convert_flags(cfile->f_flags);
++ /* If we're caching, we need to be able to fill in around partial writes. */
++ if (cifs_fscache_enabled(inode) && (cfile->f_flags & O_ACCMODE) == O_WRONLY)
++ rdwr_for_fscache = 1;
++
++ desired_access = cifs_convert_flags(cfile->f_flags, rdwr_for_fscache);
+
+ /* O_SYNC also has bit for O_DSYNC so following check picks up either */
+ if (cfile->f_flags & O_SYNC)
+@@ -849,6 +868,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
+ if (server->ops->get_lease_key)
+ server->ops->get_lease_key(inode, &cfile->fid);
+
++retry_open:
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
+ .cifs_sb = cifs_sb,
+@@ -874,6 +894,11 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
+ /* indicate that we need to relock the file */
+ oparms.reconnect = true;
+ }
++ if (rc == -EACCES && rdwr_for_fscache == 1) {
++ desired_access = cifs_convert_flags(cfile->f_flags, 0);
++ rdwr_for_fscache = 2;
++ goto retry_open;
++ }
+
+ if (rc) {
+ mutex_unlock(&cfile->fh_mutex);
+@@ -882,6 +907,9 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
+ goto reopen_error_exit;
+ }
+
++ if (rdwr_for_fscache == 2)
++ cifs_invalidate_cache(inode, FSCACHE_INVAL_DIO_WRITE);
++
+ #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
+ reopen_success:
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+diff --git a/fs/smb/client/fscache.h b/fs/smb/client/fscache.h
+index 67b601041f0a3..c691b98b442a6 100644
+--- a/fs/smb/client/fscache.h
++++ b/fs/smb/client/fscache.h
+@@ -108,6 +108,11 @@ static inline void cifs_readpage_to_fscache(struct inode *inode,
+ __cifs_readpage_to_fscache(inode, page);
+ }
+
++static inline bool cifs_fscache_enabled(struct inode *inode)
++{
++ return fscache_cookie_enabled(cifs_inode_cookie(inode));
++}
++
+ #else /* CONFIG_CIFS_FSCACHE */
+ static inline
+ void cifs_fscache_fill_coherency(struct inode *inode,
+@@ -123,6 +128,7 @@ static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
+ static inline void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) {}
+ static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { return NULL; }
+ static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags) {}
++static inline bool cifs_fscache_enabled(struct inode *inode) { return false; }
+
+ static inline int cifs_fscache_query_occupancy(struct inode *inode,
+ pgoff_t first, unsigned int nr_pages,
+--
+2.43.0
+
--- /dev/null
+From c50f43a25698734252d4bdf3dda28709f0f1b14d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 01:20:53 +0000
+Subject: drivers/perf: riscv: Disable PERF_SAMPLE_BRANCH_* while not supported
+
+From: Pu Lehui <pulehui@huawei.com>
+
+[ Upstream commit ea6873118493019474abbf57d5a800da365734df ]
+
+RISC-V perf driver does not yet support branch sampling. Although the
+specification is in the works [0], it is best to disable such events
+until support is available, otherwise we will get unexpected results.
+Due to this reason, two riscv bpf testcases get_branch_snapshot and
+perf_branches/perf_branches_hw fail.
+
+Link: https://github.com/riscv/riscv-control-transfer-records [0]
+Fixes: f5bfa23f576f ("RISC-V: Add a perf core library for pmu drivers")
+Signed-off-by: Pu Lehui <pulehui@huawei.com>
+Reviewed-by: Atish Patra <atishp@rivosinc.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20240312012053.1178140-1-pulehui@huaweicloud.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/riscv_pmu.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/perf/riscv_pmu.c b/drivers/perf/riscv_pmu.c
+index 56897d4d4fd3e..2d5cf135e8a1d 100644
+--- a/drivers/perf/riscv_pmu.c
++++ b/drivers/perf/riscv_pmu.c
+@@ -246,6 +246,10 @@ static int riscv_pmu_event_init(struct perf_event *event)
+ u64 event_config = 0;
+ uint64_t cmask;
+
++ /* driver does not support branch stack sampling */
++ if (has_branch_stack(event))
++ return -EOPNOTSUPP;
++
+ hwc->flags = 0;
+ mapped_event = rvpmu->event_map(event, &event_config);
+ if (mapped_event < 0) {
+--
+2.43.0
+
--- /dev/null
+From 9f068bad6f390749bde939fce64095b4cda7afbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Mar 2024 16:45:25 +0000
+Subject: drm/panfrost: fix power transition timeout warnings
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit 2bd02f5a0bac4bb13e0da18652dc75ba0e4958ec ]
+
+Increase the timeout value to prevent system logs on Amlogic boards flooding
+with power transition warnings:
+
+[ 13.047638] panfrost ffe40000.gpu: shader power transition timeout
+[ 13.048674] panfrost ffe40000.gpu: l2 power transition timeout
+[ 13.937324] panfrost ffe40000.gpu: shader power transition timeout
+[ 13.938351] panfrost ffe40000.gpu: l2 power transition timeout
+...
+[39829.506904] panfrost ffe40000.gpu: shader power transition timeout
+[39829.507938] panfrost ffe40000.gpu: l2 power transition timeout
+[39949.508369] panfrost ffe40000.gpu: shader power transition timeout
+[39949.509405] panfrost ffe40000.gpu: l2 power transition timeout
+
+The 2000 value has been found through trial and error testing with devices
+using G52 and G31 GPUs.
+
+Fixes: 22aa1a209018 ("drm/panfrost: Really power off GPU cores in panfrost_gpu_power_off()")
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240322164525.2617508-1-christianshewitt@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panfrost/panfrost_gpu.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c
+index 55d2430485168..40b6314459926 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
+@@ -379,19 +379,19 @@ void panfrost_gpu_power_off(struct panfrost_device *pfdev)
+
+ gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present);
+ ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_PWRTRANS_LO,
+- val, !val, 1, 1000);
++ val, !val, 1, 2000);
+ if (ret)
+ dev_err(pfdev->dev, "shader power transition timeout");
+
+ gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present);
+ ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_PWRTRANS_LO,
+- val, !val, 1, 1000);
++ val, !val, 1, 2000);
+ if (ret)
+ dev_err(pfdev->dev, "tiler power transition timeout");
+
+ gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present);
+ ret = readl_poll_timeout(pfdev->iomem + L2_PWRTRANS_LO,
+- val, !val, 0, 1000);
++ val, !val, 0, 2000);
+ if (ret)
+ dev_err(pfdev->dev, "l2 power transition timeout");
+ }
+--
+2.43.0
+
--- /dev/null
+From 92eed0ae8baa3815d3089d22698dbaba7994f14b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Nov 2023 16:08:22 +0100
+Subject: fs/pipe: Fix lockdep false-positive in watchqueue pipe_write()
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 055ca83559912f2cfd91c9441427bac4caf3c74e ]
+
+When you try to splice between a normal pipe and a notification pipe,
+get_pipe_info(..., true) fails, so splice() falls back to treating the
+notification pipe like a normal pipe - so we end up in
+iter_file_splice_write(), which first locks the input pipe, then calls
+vfs_iter_write(), which locks the output pipe.
+
+Lockdep complains about that, because we're taking a pipe lock while
+already holding another pipe lock.
+
+I think this probably (?) can't actually lead to deadlocks, since you'd
+need another way to nest locking a normal pipe into locking a
+watch_queue pipe, but the lockdep annotations don't make that clear.
+
+Bail out earlier in pipe_write() for notification pipes, before taking
+the pipe lock.
+
+Reported-and-tested-by: <syzbot+011e4ea1da6692cf881c@syzkaller.appspotmail.com>
+Closes: https://syzkaller.appspot.com/bug?extid=011e4ea1da6692cf881c
+Fixes: c73be61cede5 ("pipe: Add general notification queue support")
+Signed-off-by: Jann Horn <jannh@google.com>
+Link: https://lore.kernel.org/r/20231124150822.2121798-1-jannh@google.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pipe.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/fs/pipe.c b/fs/pipe.c
+index 9873a6030df56..aa8e6ffe1cb58 100644
+--- a/fs/pipe.c
++++ b/fs/pipe.c
+@@ -424,6 +424,18 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
+ bool was_empty = false;
+ bool wake_next_writer = false;
+
++ /*
++ * Reject writing to watch queue pipes before the point where we lock
++ * the pipe.
++ * Otherwise, lockdep would be unhappy if the caller already has another
++ * pipe locked.
++ * If we had to support locking a normal pipe and a notification pipe at
++ * the same time, we could set up lockdep annotations for that, but
++ * since we don't actually need that, it's simpler to just bail here.
++ */
++ if (pipe_has_watch_queue(pipe))
++ return -EXDEV;
++
+ /* Null write succeeds. */
+ if (unlikely(total_len == 0))
+ return 0;
+@@ -436,11 +448,6 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
+ goto out;
+ }
+
+- if (pipe_has_watch_queue(pipe)) {
+- ret = -EXDEV;
+- goto out;
+- }
+-
+ /*
+ * If it wasn't empty we try to merge new data into
+ * the last buffer.
+--
+2.43.0
+
--- /dev/null
+From 4422008ec5d7b599e04561afda743969c3b43f05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Apr 2024 13:56:18 -0400
+Subject: nfsd: hold a lighter-weight client reference over CB_RECALL_ANY
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit 10396f4df8b75ff6ab0aa2cd74296565466f2c8d ]
+
+Currently the CB_RECALL_ANY job takes a cl_rpc_users reference to the
+client. While a callback job is technically an RPC that counter is
+really more for client-driven RPCs, and this has the effect of
+preventing the client from being unhashed until the callback completes.
+
+If nfsd decides to send a CB_RECALL_ANY just as the client reboots, we
+can end up in a situation where the callback can't complete on the (now
+dead) callback channel, but the new client can't connect because the old
+client can't be unhashed. This usually manifests as a NFS4ERR_DELAY
+return on the CREATE_SESSION operation.
+
+The job is only holding a reference to the client so it can clear a flag
+after the RPC completes. Fix this by having CB_RECALL_ANY instead hold a
+reference to the cl_nfsdfs.cl_ref. Typically we only take that sort of
+reference when dealing with the nfsdfs info files, but it should work
+appropriately here to ensure that the nfs4_client doesn't disappear.
+
+Fixes: 44df6f439a17 ("NFSD: add delegation reaper to react to low memory condition")
+Reported-by: Vladimir Benes <vbenes@redhat.com>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4state.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index e4522e86e984e..8d15959004ad2 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -2889,12 +2889,9 @@ static void
+ nfsd4_cb_recall_any_release(struct nfsd4_callback *cb)
+ {
+ struct nfs4_client *clp = cb->cb_clp;
+- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
+
+- spin_lock(&nn->client_lock);
+ clear_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags);
+- put_client_renew_locked(clp);
+- spin_unlock(&nn->client_lock);
++ drop_client(clp);
+ }
+
+ static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops = {
+@@ -6231,7 +6228,7 @@ deleg_reaper(struct nfsd_net *nn)
+ list_add(&clp->cl_ra_cblist, &cblist);
+
+ /* release in nfsd4_cb_recall_any_release */
+- atomic_inc(&clp->cl_rpc_users);
++ kref_get(&clp->cl_nfsdfs.cl_ref);
+ set_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags);
+ clp->cl_ra_time = ktime_get_boottime_seconds();
+ }
+--
+2.43.0
+
--- /dev/null
+From 87a0b1ca036b032bcf1626ca015b8d8948b1096d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Oct 2023 11:41:33 +0100
+Subject: s390/pai: cleanup event initialization
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit 4711b7b8f99583f6105a33e91f106125134beacb ]
+
+Setting event::hw.last_tag to zero is not necessary. The memory
+for each event is dynamically allocated by the kernel common code and
+initialized to zero already. Remove this unnecessary assignment.
+Move the comment to function paicrypt_start() for clarification.
+
+Suggested-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Stable-dep-of: e9f3af02f639 ("s390/pai: fix sampling event removal for PMU device driver")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_crypto.c | 11 +++++------
+ arch/s390/kernel/perf_pai_ext.c | 1 -
+ 2 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index 4b773653a951b..3758e972bb5f9 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -207,12 +207,6 @@ static int paicrypt_event_init(struct perf_event *event)
+ if (rc)
+ return rc;
+
+- /* Event initialization sets last_tag to 0. When later on the events
+- * are deleted and re-added, do not reset the event count value to zero.
+- * Events are added, deleted and re-added when 2 or more events
+- * are active at the same time.
+- */
+- event->hw.last_tag = 0;
+ event->destroy = paicrypt_event_destroy;
+
+ if (a->sample_period) {
+@@ -246,6 +240,11 @@ static void paicrypt_start(struct perf_event *event, int flags)
+ {
+ u64 sum;
+
++ /* Event initialization sets last_tag to 0. When later on the events
++ * are deleted and re-added, do not reset the event count value to zero.
++ * Events are added, deleted and re-added when 2 or more events
++ * are active at the same time.
++ */
+ if (!event->hw.last_tag) {
+ event->hw.last_tag = 1;
+ sum = paicrypt_getall(event); /* Get current value */
+diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
+index 663cd37f8b293..53915401c3f63 100644
+--- a/arch/s390/kernel/perf_pai_ext.c
++++ b/arch/s390/kernel/perf_pai_ext.c
+@@ -267,7 +267,6 @@ static int paiext_event_init(struct perf_event *event)
+ rc = paiext_alloc(a, event);
+ if (rc)
+ return rc;
+- event->hw.last_tag = 0;
+ event->destroy = paiext_event_destroy;
+
+ if (a->sample_period) {
+--
+2.43.0
+
--- /dev/null
+From b84fb561495269f13d0648b2172d33be7727a059 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 15:00:28 +0100
+Subject: s390/pai: fix sampling event removal for PMU device driver
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit e9f3af02f63909f41b43c28330434cc437639c5c ]
+
+In case of a sampling event, the PAI PMU device drivers need a
+reference to this event. Currently to PMU device driver reference
+is removed when a sampling event is destroyed. This may lead to
+situations where the reference of the PMU device driver is removed
+while being used by a different sampling event.
+Reset the event reference pointer of the PMU device driver when
+a sampling event is deleted and before the next one might be added.
+
+Fixes: 39d62336f5c1 ("s390/pai: add support for cryptography counters")
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_crypto.c | 10 +++++++---
+ arch/s390/kernel/perf_pai_ext.c | 10 +++++++---
+ 2 files changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index ba2d2e61df747..93ccb5c955530 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -53,7 +53,6 @@ static void paicrypt_event_destroy(struct perf_event *event)
+ {
+ struct paicrypt_map *cpump = per_cpu_ptr(&paicrypt_map, event->cpu);
+
+- cpump->event = NULL;
+ static_branch_dec(&pai_key);
+ mutex_lock(&pai_reserve_mutex);
+ debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d"
+@@ -275,10 +274,15 @@ static int paicrypt_add(struct perf_event *event, int flags)
+
+ static void paicrypt_stop(struct perf_event *event, int flags)
+ {
+- if (!event->attr.sample_period) /* Counting */
++ struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
++ struct paicrypt_map *cpump = mp->mapptr;
++
++ if (!event->attr.sample_period) { /* Counting */
+ paicrypt_read(event);
+- else /* Sampling */
++ } else { /* Sampling */
+ perf_sched_cb_dec(event->pmu);
++ cpump->event = NULL;
++ }
+ event->hw.state = PERF_HES_STOPPED;
+ }
+
+diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
+index 09aebfcf679df..bbaad21123d38 100644
+--- a/arch/s390/kernel/perf_pai_ext.c
++++ b/arch/s390/kernel/perf_pai_ext.c
+@@ -128,7 +128,6 @@ static void paiext_event_destroy(struct perf_event *event)
+ struct paiext_map *cpump = mp->mapptr;
+
+ mutex_lock(&paiext_reserve_mutex);
+- cpump->event = NULL;
+ if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
+ paiext_free(mp);
+ paiext_root_free();
+@@ -361,10 +360,15 @@ static int paiext_add(struct perf_event *event, int flags)
+
+ static void paiext_stop(struct perf_event *event, int flags)
+ {
+- if (!event->attr.sample_period) /* Counting */
++ struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
++ struct paiext_map *cpump = mp->mapptr;
++
++ if (!event->attr.sample_period) { /* Counting */
+ paiext_read(event);
+- else /* Sampling */
++ } else { /* Sampling */
+ perf_sched_cb_dec(event->pmu);
++ cpump->event = NULL;
++ }
+ event->hw.state = PERF_HES_STOPPED;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 55b461e5f747fc1f06b6471715d60394d34dfb78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 12:09:30 +0200
+Subject: s390/pai: initialize event count once at initialization
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit b286997e83dcf7b498329a66a8a22fc8a5bf50f0 ]
+
+Event count value is initialized and set to zero in function
+paicrypt_start(). This function is called once per CPU when an
+event is started on that CPU. This leads to event count value
+being set to zero as many times as there are online CPUs.
+This is not necessary. The event count value is bound to the event
+and it is sufficient to initialize the event counter once at
+event creation time. This is done when the event structure
+is dynamicly allocated with __GFP_ZERO flag. This sets
+member count to zero.
+
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Stable-dep-of: e9f3af02f639 ("s390/pai: fix sampling event removal for PMU device driver")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_crypto.c | 1 -
+ arch/s390/kernel/perf_pai_ext.c | 1 -
+ 2 files changed, 2 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index a7e815563f411..7eb138b07e7be 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -250,7 +250,6 @@ static void paicrypt_start(struct perf_event *event, int flags)
+ if (!event->hw.last_tag) {
+ event->hw.last_tag = 1;
+ sum = paicrypt_getall(event); /* Get current value */
+- local64_set(&event->count, 0);
+ local64_set(&event->hw.prev_count, sum);
+ }
+ }
+diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
+index d6bc919530143..663cd37f8b293 100644
+--- a/arch/s390/kernel/perf_pai_ext.c
++++ b/arch/s390/kernel/perf_pai_ext.c
+@@ -333,7 +333,6 @@ static void paiext_start(struct perf_event *event, int flags)
+ event->hw.last_tag = 1;
+ sum = paiext_getall(event); /* Get current value */
+ local64_set(&event->hw.prev_count, sum);
+- local64_set(&event->count, 0);
+ }
+
+ static int paiext_add(struct perf_event *event, int flags)
+--
+2.43.0
+
--- /dev/null
+From f0ecea58cbe224aa614e12a7d24d14cfb5e6ef10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Oct 2022 11:55:52 +0200
+Subject: s390/pai: rename structure member users to active_events
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit 58354c7d35d35dd119ada18ff84a6686ccc8743f ]
+
+Rename structure member users to active_events to make it consistent
+with PMU pai_ext. Also use the same prefix syntax for increment and
+decrement operators in both PMUs.
+
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Stable-dep-of: e9f3af02f639 ("s390/pai: fix sampling event removal for PMU device driver")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_crypto.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index 68a6132937f3e..a7e815563f411 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -35,7 +35,7 @@ struct pai_userdata {
+ struct paicrypt_map {
+ unsigned long *page; /* Page for CPU to store counters */
+ struct pai_userdata *save; /* Page to store no-zero counters */
+- unsigned int users; /* # of PAI crypto users */
++ unsigned int active_events; /* # of PAI crypto users */
+ unsigned int refcnt; /* Reference count mapped buffers */
+ enum paievt_mode mode; /* Type of event */
+ struct perf_event *event; /* Perf event for sampling */
+@@ -58,8 +58,8 @@ static void paicrypt_event_destroy(struct perf_event *event)
+ mutex_lock(&pai_reserve_mutex);
+ debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d"
+ " mode %d refcnt %d\n", __func__,
+- event->attr.config, event->cpu, cpump->users,
+- cpump->mode, cpump->refcnt);
++ event->attr.config, event->cpu,
++ cpump->active_events, cpump->mode, cpump->refcnt);
+ if (!--cpump->refcnt) {
+ debug_sprintf_event(cfm_dbg, 4, "%s page %#lx save %p\n",
+ __func__, (unsigned long)cpump->page,
+@@ -174,7 +174,7 @@ static int paicrypt_busy(struct perf_event_attr *a, struct paicrypt_map *cpump)
+ }
+ debug_sprintf_event(cfm_dbg, 5, "%s sample_period %#llx users %d"
+ " mode %d refcnt %d page %#lx save %p rc %d\n",
+- __func__, a->sample_period, cpump->users,
++ __func__, a->sample_period, cpump->active_events,
+ cpump->mode, cpump->refcnt,
+ (unsigned long)cpump->page, cpump->save, rc);
+ mutex_unlock(&pai_reserve_mutex);
+@@ -260,7 +260,7 @@ static int paicrypt_add(struct perf_event *event, int flags)
+ struct paicrypt_map *cpump = this_cpu_ptr(&paicrypt_map);
+ unsigned long ccd;
+
+- if (cpump->users++ == 0) {
++ if (++cpump->active_events == 1) {
+ ccd = virt_to_phys(cpump->page) | PAI_CRYPTO_KERNEL_OFFSET;
+ WRITE_ONCE(S390_lowcore.ccd, ccd);
+ __ctl_set_bit(0, 50);
+@@ -291,7 +291,7 @@ static void paicrypt_del(struct perf_event *event, int flags)
+ if (!event->attr.sample_period)
+ /* Only counting needs to read counter */
+ paicrypt_stop(event, PERF_EF_UPDATE);
+- if (cpump->users-- == 1) {
++ if (--cpump->active_events == 0) {
+ __ctl_clear_bit(0, 50);
+ WRITE_ONCE(S390_lowcore.ccd, 0);
+ }
+--
+2.43.0
+
--- /dev/null
+From b21fc658137f411a84e75faa091cb425e53616d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Oct 2022 11:38:05 +0200
+Subject: s390/pai: rework pai_crypto mapped buffer reference count
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit d3db4ac3c761def3d3a8e5ea6d05d1636c44c2ba ]
+
+Rework the mapped buffer reference count in PMU pai_crypto
+to match the same technique as in PMU pai_ext.
+This simplifies the logic.
+Do not count the individual number of counter and sampling
+processes. Remember the type of access and the total number of
+references to the buffer.
+
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Stable-dep-of: e9f3af02f639 ("s390/pai: fix sampling event removal for PMU device driver")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_crypto.c | 42 ++++++++++++++----------------
+ 1 file changed, 20 insertions(+), 22 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index f61a652046cfb..68a6132937f3e 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -36,8 +36,8 @@ struct paicrypt_map {
+ unsigned long *page; /* Page for CPU to store counters */
+ struct pai_userdata *save; /* Page to store no-zero counters */
+ unsigned int users; /* # of PAI crypto users */
+- unsigned int sampler; /* # of PAI crypto samplers */
+- unsigned int counter; /* # of PAI crypto counters */
++ unsigned int refcnt; /* Reference count mapped buffers */
++ enum paievt_mode mode; /* Type of event */
+ struct perf_event *event; /* Perf event for sampling */
+ };
+
+@@ -56,15 +56,11 @@ static void paicrypt_event_destroy(struct perf_event *event)
+ cpump->event = NULL;
+ static_branch_dec(&pai_key);
+ mutex_lock(&pai_reserve_mutex);
+- if (event->attr.sample_period)
+- cpump->sampler -= 1;
+- else
+- cpump->counter -= 1;
+- debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d"
+- " sampler %d counter %d\n", __func__,
+- event->attr.config, event->cpu, cpump->sampler,
+- cpump->counter);
+- if (!cpump->counter && !cpump->sampler) {
++ debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d"
++ " mode %d refcnt %d\n", __func__,
++ event->attr.config, event->cpu, cpump->users,
++ cpump->mode, cpump->refcnt);
++ if (!--cpump->refcnt) {
+ debug_sprintf_event(cfm_dbg, 4, "%s page %#lx save %p\n",
+ __func__, (unsigned long)cpump->page,
+ cpump->save);
+@@ -72,6 +68,7 @@ static void paicrypt_event_destroy(struct perf_event *event)
+ cpump->page = NULL;
+ kvfree(cpump->save);
+ cpump->save = NULL;
++ cpump->mode = PAI_MODE_NONE;
+ }
+ mutex_unlock(&pai_reserve_mutex);
+ }
+@@ -136,17 +133,14 @@ static u64 paicrypt_getall(struct perf_event *event)
+ */
+ static int paicrypt_busy(struct perf_event_attr *a, struct paicrypt_map *cpump)
+ {
+- unsigned int *use_ptr;
+ int rc = 0;
+
+ mutex_lock(&pai_reserve_mutex);
+ if (a->sample_period) { /* Sampling requested */
+- use_ptr = &cpump->sampler;
+- if (cpump->counter || cpump->sampler)
++ if (cpump->mode != PAI_MODE_NONE)
+ rc = -EBUSY; /* ... sampling/counting active */
+ } else { /* Counting requested */
+- use_ptr = &cpump->counter;
+- if (cpump->sampler)
++ if (cpump->mode == PAI_MODE_SAMPLING)
+ rc = -EBUSY; /* ... and sampling active */
+ }
+ if (rc)
+@@ -172,12 +166,16 @@ static int paicrypt_busy(struct perf_event_attr *a, struct paicrypt_map *cpump)
+ rc = 0;
+
+ unlock:
+- /* If rc is non-zero, do not increment counter/sampler. */
+- if (!rc)
+- *use_ptr += 1;
+- debug_sprintf_event(cfm_dbg, 5, "%s sample_period %#llx sampler %d"
+- " counter %d page %#lx save %p rc %d\n", __func__,
+- a->sample_period, cpump->sampler, cpump->counter,
++ /* If rc is non-zero, do not set mode and reference count */
++ if (!rc) {
++ cpump->refcnt++;
++ cpump->mode = a->sample_period ? PAI_MODE_SAMPLING
++ : PAI_MODE_COUNTING;
++ }
++ debug_sprintf_event(cfm_dbg, 5, "%s sample_period %#llx users %d"
++ " mode %d refcnt %d page %#lx save %p rc %d\n",
++ __func__, a->sample_period, cpump->users,
++ cpump->mode, cpump->refcnt,
+ (unsigned long)cpump->page, cpump->save, rc);
+ mutex_unlock(&pai_reserve_mutex);
+ return rc;
+--
+2.43.0
+
--- /dev/null
+From 35023a996c2aa5ff04d6bb194d1acd3280dc0d11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Nov 2023 11:04:25 +0100
+Subject: s390/pai: rework paiXXX_start and paiXXX_stop functions
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit cb1259b7b574bd90ef22dac2c6282327cdae31c6 ]
+
+The PAI crypto counter and PAI NNPA counters start and stop functions
+are streamlined. Move the conditions to invoke start and stop functions
+to its respective function body and call them unconditionally.
+The start and stop functions now determine how to proceed.
+No functional change.
+
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Mete Durlu <meted@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Stable-dep-of: e9f3af02f639 ("s390/pai: fix sampling event removal for PMU device driver")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_crypto.c | 29 ++++++++++++-------------
+ arch/s390/kernel/perf_pai_ext.c | 35 ++++++++++++++----------------
+ 2 files changed, 30 insertions(+), 34 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index 3758e972bb5f9..ba2d2e61df747 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -245,10 +245,14 @@ static void paicrypt_start(struct perf_event *event, int flags)
+ * Events are added, deleted and re-added when 2 or more events
+ * are active at the same time.
+ */
+- if (!event->hw.last_tag) {
+- event->hw.last_tag = 1;
+- sum = paicrypt_getall(event); /* Get current value */
+- local64_set(&event->hw.prev_count, sum);
++ if (!event->attr.sample_period) { /* Counting */
++ if (!event->hw.last_tag) {
++ event->hw.last_tag = 1;
++ sum = paicrypt_getall(event); /* Get current value */
++ local64_set(&event->hw.prev_count, sum);
++ }
++ } else { /* Sampling */
++ perf_sched_cb_inc(event->pmu);
+ }
+ }
+
+@@ -263,19 +267,18 @@ static int paicrypt_add(struct perf_event *event, int flags)
+ __ctl_set_bit(0, 50);
+ }
+ cpump->event = event;
+- if (flags & PERF_EF_START && !event->attr.sample_period) {
+- /* Only counting needs initial counter value */
++ if (flags & PERF_EF_START)
+ paicrypt_start(event, PERF_EF_RELOAD);
+- }
+ event->hw.state = 0;
+- if (event->attr.sample_period)
+- perf_sched_cb_inc(event->pmu);
+ return 0;
+ }
+
+ static void paicrypt_stop(struct perf_event *event, int flags)
+ {
+- paicrypt_read(event);
++ if (!event->attr.sample_period) /* Counting */
++ paicrypt_read(event);
++ else /* Sampling */
++ perf_sched_cb_dec(event->pmu);
+ event->hw.state = PERF_HES_STOPPED;
+ }
+
+@@ -283,11 +286,7 @@ static void paicrypt_del(struct perf_event *event, int flags)
+ {
+ struct paicrypt_map *cpump = this_cpu_ptr(&paicrypt_map);
+
+- if (event->attr.sample_period)
+- perf_sched_cb_dec(event->pmu);
+- if (!event->attr.sample_period)
+- /* Only counting needs to read counter */
+- paicrypt_stop(event, PERF_EF_UPDATE);
++ paicrypt_stop(event, PERF_EF_UPDATE);
+ if (--cpump->active_events == 0) {
+ __ctl_clear_bit(0, 50);
+ WRITE_ONCE(S390_lowcore.ccd, 0);
+diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
+index 53915401c3f63..09aebfcf679df 100644
+--- a/arch/s390/kernel/perf_pai_ext.c
++++ b/arch/s390/kernel/perf_pai_ext.c
+@@ -327,11 +327,15 @@ static void paiext_start(struct perf_event *event, int flags)
+ {
+ u64 sum;
+
+- if (event->hw.last_tag)
+- return;
+- event->hw.last_tag = 1;
+- sum = paiext_getall(event); /* Get current value */
+- local64_set(&event->hw.prev_count, sum);
++ if (!event->attr.sample_period) { /* Counting */
++ if (!event->hw.last_tag) {
++ event->hw.last_tag = 1;
++ sum = paiext_getall(event); /* Get current value */
++ local64_set(&event->hw.prev_count, sum);
++ }
++ } else { /* Sampling */
++ perf_sched_cb_inc(event->pmu);
++ }
+ }
+
+ static int paiext_add(struct perf_event *event, int flags)
+@@ -348,21 +352,19 @@ static int paiext_add(struct perf_event *event, int flags)
+ debug_sprintf_event(paiext_dbg, 4, "%s 1508 %llx acc %llx\n",
+ __func__, S390_lowcore.aicd, pcb->acc);
+ }
+- if (flags & PERF_EF_START && !event->attr.sample_period) {
+- /* Only counting needs initial counter value */
++ cpump->event = event;
++ if (flags & PERF_EF_START)
+ paiext_start(event, PERF_EF_RELOAD);
+- }
+ event->hw.state = 0;
+- if (event->attr.sample_period) {
+- cpump->event = event;
+- perf_sched_cb_inc(event->pmu);
+- }
+ return 0;
+ }
+
+ static void paiext_stop(struct perf_event *event, int flags)
+ {
+- paiext_read(event);
++ if (!event->attr.sample_period) /* Counting */
++ paiext_read(event);
++ else /* Sampling */
++ perf_sched_cb_dec(event->pmu);
+ event->hw.state = PERF_HES_STOPPED;
+ }
+
+@@ -372,12 +374,7 @@ static void paiext_del(struct perf_event *event, int flags)
+ struct paiext_map *cpump = mp->mapptr;
+ struct paiext_cb *pcb = cpump->paiext_cb;
+
+- if (event->attr.sample_period)
+- perf_sched_cb_dec(event->pmu);
+- if (!event->attr.sample_period) {
+- /* Only counting needs to read counter */
+- paiext_stop(event, PERF_EF_UPDATE);
+- }
++ paiext_stop(event, PERF_EF_UPDATE);
+ if (--cpump->active_events == 0) {
+ /* Disable CPU instruction lookup for PAIE1 control block */
+ __ctl_clear_bit(0, 49);
+--
+2.43.0
+
--- /dev/null
+From e5bbc512d2fc789681c85eb201df45b763749612 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Oct 2023 11:53:52 +0200
+Subject: s390/pai_crypto: remove per-cpu variable assignement in event
+ initialization
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit aecd5a37b5ef4de4f6402dc079672e4243cc4c13 ]
+
+Function paicrypt_event_init() initializes the PMU device driver
+specific details for an event. It is called once per event creation.
+The function paicrypt_event_init() is not necessarily executed on
+that CPU the event will be used for.
+When an event is activated, function paicrypt_start() is used to
+start the event on that CPU.
+The per CPU data structure struct paicrypt_map has a pointer to
+the event which is active for a particular CPU. This pointer is
+set in function paicrypt_start() to point to the currently installed
+event. There is no need to also set this pointer in function
+paicrypt_event_init() where is might be assigned to the wrong CPU.
+Therefore remove this assignment in paicrypt_event_init().
+
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Stable-dep-of: e9f3af02f639 ("s390/pai: fix sampling event removal for PMU device driver")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_crypto.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index 7eb138b07e7be..4b773653a951b 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -213,7 +213,6 @@ static int paicrypt_event_init(struct perf_event *event)
+ * are active at the same time.
+ */
+ event->hw.last_tag = 0;
+- cpump->event = event;
+ event->destroy = paicrypt_event_destroy;
+
+ if (a->sample_period) {
+--
+2.43.0
+
--- /dev/null
+From 117b4dfc411cc5896e800a18ff9469c9f9db7da2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Apr 2023 10:33:31 +0200
+Subject: s390/pai_ext: replace atomic_t with refcount_t
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit 1f2597cd3686955a4d64e01909dbfe625a2a35a1 ]
+
+The s390 PMU of PAI extension 1 NNPA counters uses atomic_t for
+reference counting. Replace this with the proper data type
+refcount_t.
+
+No functional change.
+
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Stable-dep-of: e9f3af02f639 ("s390/pai: fix sampling event removal for PMU device driver")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_ext.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
+index b4d89654183a2..d6bc919530143 100644
+--- a/arch/s390/kernel/perf_pai_ext.c
++++ b/arch/s390/kernel/perf_pai_ext.c
+@@ -56,7 +56,7 @@ struct paiext_map {
+ struct pai_userdata *save; /* Area to store non-zero counters */
+ enum paiext_mode mode; /* Type of event */
+ unsigned int active_events; /* # of PAI Extension users */
+- unsigned int refcnt;
++ refcount_t refcnt;
+ struct perf_event *event; /* Perf event for sampling */
+ struct paiext_cb *paiext_cb; /* PAI extension control block area */
+ };
+@@ -66,14 +66,14 @@ struct paiext_mapptr {
+ };
+
+ static struct paiext_root { /* Anchor to per CPU data */
+- int refcnt; /* Overall active events */
++ refcount_t refcnt; /* Overall active events */
+ struct paiext_mapptr __percpu *mapptr;
+ } paiext_root;
+
+ /* Free per CPU data when the last event is removed. */
+ static void paiext_root_free(void)
+ {
+- if (!--paiext_root.refcnt) {
++ if (refcount_dec_and_test(&paiext_root.refcnt)) {
+ free_percpu(paiext_root.mapptr);
+ paiext_root.mapptr = NULL;
+ }
+@@ -86,7 +86,7 @@ static void paiext_root_free(void)
+ */
+ static int paiext_root_alloc(void)
+ {
+- if (++paiext_root.refcnt == 1) {
++ if (!refcount_inc_not_zero(&paiext_root.refcnt)) {
+ /* The memory is already zeroed. */
+ paiext_root.mapptr = alloc_percpu(struct paiext_mapptr);
+ if (!paiext_root.mapptr) {
+@@ -97,6 +97,7 @@ static int paiext_root_alloc(void)
+ */
+ return -ENOMEM;
+ }
++ refcount_set(&paiext_root.refcnt, 1);
+ }
+ return 0;
+ }
+@@ -128,7 +129,7 @@ static void paiext_event_destroy(struct perf_event *event)
+
+ mutex_lock(&paiext_reserve_mutex);
+ cpump->event = NULL;
+- if (!--cpump->refcnt) /* Last reference gone */
++ if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
+ paiext_free(mp);
+ paiext_root_free();
+ mutex_unlock(&paiext_reserve_mutex);
+@@ -169,7 +170,7 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
+ rc = -ENOMEM;
+ cpump = kzalloc(sizeof(*cpump), GFP_KERNEL);
+ if (!cpump)
+- goto unlock;
++ goto undo;
+
+ /* Allocate memory for counter area and counter extraction.
+ * These are
+@@ -189,8 +190,9 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
+ GFP_KERNEL);
+ if (!cpump->save || !cpump->area || !cpump->paiext_cb) {
+ paiext_free(mp);
+- goto unlock;
++ goto undo;
+ }
++ refcount_set(&cpump->refcnt, 1);
+ cpump->mode = a->sample_period ? PAI_MODE_SAMPLING
+ : PAI_MODE_COUNTER;
+ } else {
+@@ -201,15 +203,15 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
+ if (cpump->mode == PAI_MODE_SAMPLING ||
+ (cpump->mode == PAI_MODE_COUNTER && a->sample_period)) {
+ rc = -EBUSY;
+- goto unlock;
++ goto undo;
+ }
++ refcount_inc(&cpump->refcnt);
+ }
+
+ rc = 0;
+ cpump->event = event;
+- ++cpump->refcnt;
+
+-unlock:
++undo:
+ if (rc) {
+ /* Error in allocation of event, decrement anchor. Since
+ * the event in not created, its destroy() function is never
+@@ -217,6 +219,7 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
+ */
+ paiext_root_free();
+ }
++unlock:
+ mutex_unlock(&paiext_reserve_mutex);
+ /* If rc is non-zero, no increment of counter/sampler was done. */
+ return rc;
+--
+2.43.0
+
--- /dev/null
+From 117bab149cad28399fb8dfa21284f45e92c4eb4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 23:38:06 +0100
+Subject: scsi: mylex: Fix sysfs buffer lengths
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 1197c5b2099f716b3de327437fb50900a0b936c9 ]
+
+The myrb and myrs drivers use an odd way of implementing their sysfs files,
+calling snprintf() with a fixed length of 32 bytes to print into a page
+sized buffer. One of the strings is actually longer than 32 bytes, which
+clang can warn about:
+
+drivers/scsi/myrb.c:1906:10: error: 'snprintf' will always be truncated; specified size is 32, but format string expands to at least 34 [-Werror,-Wformat-truncation]
+drivers/scsi/myrs.c:1089:10: error: 'snprintf' will always be truncated; specified size is 32, but format string expands to at least 34 [-Werror,-Wformat-truncation]
+
+These could all be plain sprintf() without a length as the buffer is always
+long enough. On the other hand, sysfs files should not be overly long
+either, so just double the length to make sure the longest strings don't
+get truncated here.
+
+Fixes: 77266186397c ("scsi: myrs: Add Mylex RAID controller (SCSI interface)")
+Fixes: 081ff398c56c ("scsi: myrb: Add Mylex RAID controller (block interface)")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20240326223825.4084412-8-arnd@kernel.org
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/myrb.c | 20 ++++++++++----------
+ drivers/scsi/myrs.c | 24 ++++++++++++------------
+ 2 files changed, 22 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c
+index e885c1dbf61f9..e2f1b186efd00 100644
+--- a/drivers/scsi/myrb.c
++++ b/drivers/scsi/myrb.c
+@@ -1775,9 +1775,9 @@ static ssize_t raid_state_show(struct device *dev,
+
+ name = myrb_devstate_name(ldev_info->state);
+ if (name)
+- ret = snprintf(buf, 32, "%s\n", name);
++ ret = snprintf(buf, 64, "%s\n", name);
+ else
+- ret = snprintf(buf, 32, "Invalid (%02X)\n",
++ ret = snprintf(buf, 64, "Invalid (%02X)\n",
+ ldev_info->state);
+ } else {
+ struct myrb_pdev_state *pdev_info = sdev->hostdata;
+@@ -1796,9 +1796,9 @@ static ssize_t raid_state_show(struct device *dev,
+ else
+ name = myrb_devstate_name(pdev_info->state);
+ if (name)
+- ret = snprintf(buf, 32, "%s\n", name);
++ ret = snprintf(buf, 64, "%s\n", name);
+ else
+- ret = snprintf(buf, 32, "Invalid (%02X)\n",
++ ret = snprintf(buf, 64, "Invalid (%02X)\n",
+ pdev_info->state);
+ }
+ return ret;
+@@ -1886,11 +1886,11 @@ static ssize_t raid_level_show(struct device *dev,
+
+ name = myrb_raidlevel_name(ldev_info->raid_level);
+ if (!name)
+- return snprintf(buf, 32, "Invalid (%02X)\n",
++ return snprintf(buf, 64, "Invalid (%02X)\n",
+ ldev_info->state);
+- return snprintf(buf, 32, "%s\n", name);
++ return snprintf(buf, 64, "%s\n", name);
+ }
+- return snprintf(buf, 32, "Physical Drive\n");
++ return snprintf(buf, 64, "Physical Drive\n");
+ }
+ static DEVICE_ATTR_RO(raid_level);
+
+@@ -1903,15 +1903,15 @@ static ssize_t rebuild_show(struct device *dev,
+ unsigned char status;
+
+ if (sdev->channel < myrb_logical_channel(sdev->host))
+- return snprintf(buf, 32, "physical device - not rebuilding\n");
++ return snprintf(buf, 64, "physical device - not rebuilding\n");
+
+ status = myrb_get_rbld_progress(cb, &rbld_buf);
+
+ if (rbld_buf.ldev_num != sdev->id ||
+ status != MYRB_STATUS_SUCCESS)
+- return snprintf(buf, 32, "not rebuilding\n");
++ return snprintf(buf, 64, "not rebuilding\n");
+
+- return snprintf(buf, 32, "rebuilding block %u of %u\n",
++ return snprintf(buf, 64, "rebuilding block %u of %u\n",
+ rbld_buf.ldev_size - rbld_buf.blocks_left,
+ rbld_buf.ldev_size);
+ }
+diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c
+index 7eb8c39da3663..95e7c00cb7e54 100644
+--- a/drivers/scsi/myrs.c
++++ b/drivers/scsi/myrs.c
+@@ -947,9 +947,9 @@ static ssize_t raid_state_show(struct device *dev,
+
+ name = myrs_devstate_name(ldev_info->dev_state);
+ if (name)
+- ret = snprintf(buf, 32, "%s\n", name);
++ ret = snprintf(buf, 64, "%s\n", name);
+ else
+- ret = snprintf(buf, 32, "Invalid (%02X)\n",
++ ret = snprintf(buf, 64, "Invalid (%02X)\n",
+ ldev_info->dev_state);
+ } else {
+ struct myrs_pdev_info *pdev_info;
+@@ -958,9 +958,9 @@ static ssize_t raid_state_show(struct device *dev,
+ pdev_info = sdev->hostdata;
+ name = myrs_devstate_name(pdev_info->dev_state);
+ if (name)
+- ret = snprintf(buf, 32, "%s\n", name);
++ ret = snprintf(buf, 64, "%s\n", name);
+ else
+- ret = snprintf(buf, 32, "Invalid (%02X)\n",
++ ret = snprintf(buf, 64, "Invalid (%02X)\n",
+ pdev_info->dev_state);
+ }
+ return ret;
+@@ -1066,13 +1066,13 @@ static ssize_t raid_level_show(struct device *dev,
+ ldev_info = sdev->hostdata;
+ name = myrs_raid_level_name(ldev_info->raid_level);
+ if (!name)
+- return snprintf(buf, 32, "Invalid (%02X)\n",
++ return snprintf(buf, 64, "Invalid (%02X)\n",
+ ldev_info->dev_state);
+
+ } else
+ name = myrs_raid_level_name(MYRS_RAID_PHYSICAL);
+
+- return snprintf(buf, 32, "%s\n", name);
++ return snprintf(buf, 64, "%s\n", name);
+ }
+ static DEVICE_ATTR_RO(raid_level);
+
+@@ -1086,7 +1086,7 @@ static ssize_t rebuild_show(struct device *dev,
+ unsigned char status;
+
+ if (sdev->channel < cs->ctlr_info->physchan_present)
+- return snprintf(buf, 32, "physical device - not rebuilding\n");
++ return snprintf(buf, 64, "physical device - not rebuilding\n");
+
+ ldev_info = sdev->hostdata;
+ ldev_num = ldev_info->ldev_num;
+@@ -1098,11 +1098,11 @@ static ssize_t rebuild_show(struct device *dev,
+ return -EIO;
+ }
+ if (ldev_info->rbld_active) {
+- return snprintf(buf, 32, "rebuilding block %zu of %zu\n",
++ return snprintf(buf, 64, "rebuilding block %zu of %zu\n",
+ (size_t)ldev_info->rbld_lba,
+ (size_t)ldev_info->cfg_devsize);
+ } else
+- return snprintf(buf, 32, "not rebuilding\n");
++ return snprintf(buf, 64, "not rebuilding\n");
+ }
+
+ static ssize_t rebuild_store(struct device *dev,
+@@ -1190,7 +1190,7 @@ static ssize_t consistency_check_show(struct device *dev,
+ unsigned short ldev_num;
+
+ if (sdev->channel < cs->ctlr_info->physchan_present)
+- return snprintf(buf, 32, "physical device - not checking\n");
++ return snprintf(buf, 64, "physical device - not checking\n");
+
+ ldev_info = sdev->hostdata;
+ if (!ldev_info)
+@@ -1198,11 +1198,11 @@ static ssize_t consistency_check_show(struct device *dev,
+ ldev_num = ldev_info->ldev_num;
+ myrs_get_ldev_info(cs, ldev_num, ldev_info);
+ if (ldev_info->cc_active)
+- return snprintf(buf, 32, "checking block %zu of %zu\n",
++ return snprintf(buf, 64, "checking block %zu of %zu\n",
+ (size_t)ldev_info->cc_lba,
+ (size_t)ldev_info->cfg_devsize);
+ else
+- return snprintf(buf, 32, "not checking\n");
++ return snprintf(buf, 64, "not checking\n");
+ }
+
+ static ssize_t consistency_check_store(struct device *dev,
+--
+2.43.0
+
--- /dev/null
+From 705a3733323098c83e5d8e83d73e11c0d03ab583 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Dec 2023 16:23:35 +0800
+Subject: scsi: sd: Unregister device if device_add_disk() failed in sd_probe()
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 0296bea01cfa6526be6bd2d16dc83b4e7f1af91f ]
+
+"if device_add() succeeds, you should call device_del() when you want to
+get rid of it."
+
+In sd_probe(), device_add_disk() fails when device_add() has already
+succeeded, so change put_device() to device_unregister() to ensure device
+resources are released.
+
+Fixes: 2a7a891f4c40 ("scsi: sd: Add error handling support for add_disk()")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Link: https://lore.kernel.org/r/20231208082335.1754205-1-linan666@huaweicloud.com
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/sd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index c793bca882236..f32236c3f81c6 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -3636,7 +3636,7 @@ static int sd_probe(struct device *dev)
+
+ error = device_add_disk(dev, gd, NULL);
+ if (error) {
+- put_device(&sdkp->disk_dev);
++ device_unregister(&sdkp->disk_dev);
+ put_disk(gd);
+ goto out;
+ }
+--
+2.43.0
+
kvm-svm-warn-but-continue-if-misc_cg_set_capacity-fa.patch
kvm-svm-use-unsigned-integers-when-dealing-with-asid.patch
kvm-svm-add-support-for-allowing-zero-sev-asids.patch
+fs-pipe-fix-lockdep-false-positive-in-watchqueue-pip.patch
+9p-fix-read-write-debug-statements-to-report-server-.patch
+drivers-perf-riscv-disable-perf_sample_branch_-while.patch
+drm-panfrost-fix-power-transition-timeout-warnings.patch
+asoc-rt5682-sdw-fix-locking-sequence.patch
+asoc-rt711-sdca-fix-locking-sequence.patch
+asoc-rt711-sdw-fix-locking-sequence.patch
+asoc-ops-fix-wraparound-for-mask-in-snd_soc_get_vols.patch
+ata-sata_sx4-fix-pdc20621_get_from_dimm-on-64-bit.patch
+scsi-mylex-fix-sysfs-buffer-lengths.patch
+scsi-sd-unregister-device-if-device_add_disk-failed-.patch
+cifs-fix-caching-to-try-to-do-open-o_wronly-as-rdwr-.patch
+s390-pai-rework-pai_crypto-mapped-buffer-reference-c.patch
+s390-pai-rename-structure-member-users-to-active_eve.patch
+s390-pai_ext-replace-atomic_t-with-refcount_t.patch
+s390-pai-initialize-event-count-once-at-initializati.patch
+s390-pai_crypto-remove-per-cpu-variable-assignement-.patch
+s390-pai-cleanup-event-initialization.patch
+s390-pai-rework-paixxx_start-and-paixxx_stop-functio.patch
+s390-pai-fix-sampling-event-removal-for-pmu-device-d.patch
+ata-sata_mv-fix-pci-device-id-table-declaration-comp.patch
+nfsd-hold-a-lighter-weight-client-reference-over-cb_.patch