--- /dev/null
+From 0a0c848ac09baecd396937d501460ce7f7a08b2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 22:46:50 +0100
+Subject: ahci: asm1064: asm1166: don't limit reported ports
+
+From: Conrad Kostecki <conikost@gentoo.org>
+
+[ Upstream commit 6cd8adc3e18960f6e59d797285ed34ef473cc896 ]
+
+Previously, patches have been added to limit the reported count of SATA
+ports for asm1064 and asm1166 SATA controllers, as those controllers do
+report more ports than physically having.
+
+While it is allowed to report more ports than physically having in CAP.NP,
+it is not allowed to report more ports than physically having in the PI
+(Ports Implemented) register, which is what these HBAs do.
+(This is a AHCI spec violation.)
+
+Unfortunately, it seems that the PMP implementation in these ASMedia HBAs
+is also violating the AHCI and SATA-IO PMP specification.
+
+What these HBAs do is that they do not report that they support PMP
+(CAP.SPM (Supports Port Multiplier) is not set).
+
+Instead, they have decided to add extra "virtual" ports in the PI register
+that is used if a port multiplier is connected to any of the physical
+ports of the HBA.
+
+Enumerating the devices behind the PMP as specified in the AHCI and
+SATA-IO specifications, by using PMP READ and PMP WRITE commands to the
+physical ports of the HBA is not possible, you have to use the "virtual"
+ports.
+
+This is of course bad, because this gives us no way to detect the device
+and vendor ID of the PMP actually connected to the HBA, which means that
+we can not apply the proper PMP quirks for the PMP that is connected to
+the HBA.
+
+Limiting the port map will thus stop these controllers from working with
+SATA Port Multipliers.
+
+This patch reverts both patches for asm1064 and asm1166, so old behavior
+is restored and SATA PMP will work again, but it will also reintroduce the
+(minutes long) extra boot time for the ASMedia controllers that do not
+have a PMP connected (either on the PCIe card itself, or an external PMP).
+
+However, a longer boot time for some, is the lesser evil compared to some
+other users not being able to detect their drives at all.
+
+Fixes: 0077a504e1a4 ("ahci: asm1166: correct count of reported ports")
+Fixes: 9815e3961754 ("ahci: asm1064: correct count of reported ports")
+Cc: stable@vger.kernel.org
+Reported-by: Matt <cryptearth@googlemail.com>
+Signed-off-by: Conrad Kostecki <conikost@gentoo.org>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+[cassel: rewrote commit message]
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/ahci.c | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 5df344e26c110..55a07dbe1d8a6 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -662,19 +662,6 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
+ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+ struct ahci_host_priv *hpriv)
+ {
+- if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA) {
+- switch (pdev->device) {
+- case 0x1166:
+- dev_info(&pdev->dev, "ASM1166 has only six ports\n");
+- hpriv->saved_port_map = 0x3f;
+- break;
+- case 0x1064:
+- dev_info(&pdev->dev, "ASM1064 has only four ports\n");
+- hpriv->saved_port_map = 0xf;
+- break;
+- }
+- }
+-
+ if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
+ dev_info(&pdev->dev, "JMB361 has only one port\n");
+ hpriv->force_port_map = 1;
+--
+2.43.0
+
--- /dev/null
+From 4ba9c518eb3440fa70ff5e2ee5001db47a439238 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 17:57:57 +0100
+Subject: ahci: asm1064: correct count of reported ports
+
+From: Andrey Jr. Melnikov <temnota.am@gmail.com>
+
+[ Upstream commit 9815e39617541ef52d0dfac4be274ad378c6dc09 ]
+
+The ASM1064 SATA host controller always reports wrongly,
+that it has 24 ports. But in reality, it only has four ports.
+
+before:
+ahci 0000:04:00.0: SSS flag set, parallel bus scan disabled
+ahci 0000:04:00.0: AHCI 0001.0301 32 slots 24 ports 6 Gbps 0xffff0f impl SATA mode
+ahci 0000:04:00.0: flags: 64bit ncq sntf stag pm led only pio sxs deso sadm sds apst
+
+after:
+ahci 0000:04:00.0: ASM1064 has only four ports
+ahci 0000:04:00.0: forcing port_map 0xffff0f -> 0xf
+ahci 0000:04:00.0: SSS flag set, parallel bus scan disabled
+ahci 0000:04:00.0: AHCI 0001.0301 32 slots 24 ports 6 Gbps 0xf impl SATA mode
+ahci 0000:04:00.0: flags: 64bit ncq sntf stag pm led only pio sxs deso sadm sds apst
+
+Signed-off-by: "Andrey Jr. Melnikov" <temnota.am@gmail.com>
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Stable-dep-of: 6cd8adc3e189 ("ahci: asm1064: asm1166: don't limit reported ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/ahci.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 6f7f8e41404dc..5df344e26c110 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -662,9 +662,17 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
+ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+ struct ahci_host_priv *hpriv)
+ {
+- if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1166) {
+- dev_info(&pdev->dev, "ASM1166 has only six ports\n");
+- hpriv->saved_port_map = 0x3f;
++ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA) {
++ switch (pdev->device) {
++ case 0x1166:
++ dev_info(&pdev->dev, "ASM1166 has only six ports\n");
++ hpriv->saved_port_map = 0x3f;
++ break;
++ case 0x1064:
++ dev_info(&pdev->dev, "ASM1064 has only four ports\n");
++ hpriv->saved_port_map = 0xf;
++ break;
++ }
+ }
+
+ if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
+--
+2.43.0
+
--- /dev/null
+From 3a5391ae4217794673ff76d4ae3bbad263678b51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 19:39:32 +0100
+Subject: arm: dts: marvell: Fix maxium->maxim typo in brownstone dts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Duje Mihanović <duje.mihanovic@skole.hr>
+
+[ Upstream commit 831e0cd4f9ee15a4f02ae10b67e7fdc10eb2b4fc ]
+
+Fix an obvious spelling error in the PMIC compatible in the MMP2
+Brownstone DTS file.
+
+Fixes: 58f1193e6210 ("mfd: max8925: Add dts")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Duje Mihanović <duje.mihanovic@skole.hr>
+Reported-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Closes: https://lore.kernel.org/linux-devicetree/1410884282-18041-1-git-send-email-k.kozlowski@samsung.com/
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/20240125-brownstone-typo-fix-v2-1-45bc48a0c81c@skole.hr
+[krzysztof: Just 10 years to take a patch, not bad! Rephrased commit
+ msg]
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/mmp2-brownstone.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts
+index 04f1ae1382e7a..bc64348b82185 100644
+--- a/arch/arm/boot/dts/mmp2-brownstone.dts
++++ b/arch/arm/boot/dts/mmp2-brownstone.dts
+@@ -28,7 +28,7 @@ &uart3 {
+ &twsi1 {
+ status = "okay";
+ pmic: max8925@3c {
+- compatible = "maxium,max8925";
++ compatible = "maxim,max8925";
+ reg = <0x3c>;
+ interrupts = <1>;
+ interrupt-parent = <&intcmux4>;
+--
+2.43.0
+
--- /dev/null
+From 6c9133e43d3ef643925b0e7ef7e9ab37658a008d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Feb 2024 22:17:23 +0900
+Subject: block: Clear zone limits for a non-zoned stacked queue
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+[ Upstream commit c8f6f88d25929ad2f290b428efcae3b526f3eab0 ]
+
+Device mapper may create a non-zoned mapped device out of a zoned device
+(e.g., the dm-zoned target). In such case, some queue limit such as the
+max_zone_append_sectors and zone_write_granularity endup being non zero
+values for a block device that is not zoned. Avoid this by clearing
+these limits in blk_stack_limits() when the stacked zoned limit is
+false.
+
+Fixes: 3093a479727b ("block: inherit the zoned characteristics in blk_stack_limits")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Link: https://lore.kernel.org/r/20240222131724.1803520-1-dlemoal@kernel.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-settings.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index ab39169aa2b28..ebd373469c807 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -656,6 +656,10 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ t->zone_write_granularity = max(t->zone_write_granularity,
+ b->zone_write_granularity);
+ t->zoned = max(t->zoned, b->zoned);
++ if (!t->zoned) {
++ t->zone_write_granularity = 0;
++ t->max_zone_append_sectors = 0;
++ }
+ return ret;
+ }
+ EXPORT_SYMBOL(blk_stack_limits);
+--
+2.43.0
+
--- /dev/null
+From 98d50011356df4ddbee57f0c3bf86a04b398d97f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Jan 2021 13:47:30 +0900
+Subject: block: introduce zone_write_granularity limit
+
+From: Damien Le Moal <damien.lemoal@wdc.com>
+
+[ Upstream commit a805a4fa4fa376bbc145762bb8b09caa2fa8af48 ]
+
+Per ZBC and ZAC specifications, host-managed SMR hard-disks mandate that
+all writes into sequential write required zones be aligned to the device
+physical block size. However, NVMe ZNS does not have this constraint and
+allows write operations into sequential zones to be aligned to the
+device logical block size. This inconsistency does not help with
+software portability across device types.
+
+To solve this, introduce the zone_write_granularity queue limit to
+indicate the alignment constraint, in bytes, of write operations into
+zones of a zoned block device. This new limit is exported as a
+read-only sysfs queue attribute and the helper
+blk_queue_zone_write_granularity() introduced for drivers to set this
+limit.
+
+The function blk_queue_set_zoned() is modified to set this new limit to
+the device logical block size by default. NVMe ZNS devices as well as
+zoned nullb devices use this default value as is. The scsi disk driver
+is modified to execute the blk_queue_zone_write_granularity() helper to
+set the zone write granularity of host-managed SMR disks to the disk
+physical block size.
+
+The accessor functions queue_zone_write_granularity() and
+bdev_zone_write_granularity() are also introduced.
+
+Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@edc.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: c8f6f88d2592 ("block: Clear zone limits for a non-zoned stacked queue")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/block/queue-sysfs.rst | 7 ++++++
+ block/blk-settings.c | 37 ++++++++++++++++++++++++++++-
+ block/blk-sysfs.c | 8 +++++++
+ drivers/scsi/sd_zbc.c | 8 +++++++
+ include/linux/blkdev.h | 15 ++++++++++++
+ 5 files changed, 74 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/block/queue-sysfs.rst b/Documentation/block/queue-sysfs.rst
+index 2638d3446b794..c8bf8bc3c03af 100644
+--- a/Documentation/block/queue-sysfs.rst
++++ b/Documentation/block/queue-sysfs.rst
+@@ -273,4 +273,11 @@ devices are described in the ZBC (Zoned Block Commands) and ZAC
+ do not support zone commands, they will be treated as regular block devices
+ and zoned will report "none".
+
++zone_write_granularity (RO)
++---------------------------
++This indicates the alignment constraint, in bytes, for write operations in
++sequential zones of zoned block devices (devices with a zoned attributed
++that reports "host-managed" or "host-aware"). This value is always 0 for
++regular block devices.
++
+ Jens Axboe <jens.axboe@oracle.com>, February 2009
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index c3aa7f8ee3883..ab39169aa2b28 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -60,6 +60,7 @@ void blk_set_default_limits(struct queue_limits *lim)
+ lim->io_opt = 0;
+ lim->misaligned = 0;
+ lim->zoned = BLK_ZONED_NONE;
++ lim->zone_write_granularity = 0;
+ }
+ EXPORT_SYMBOL(blk_set_default_limits);
+
+@@ -353,6 +354,28 @@ void blk_queue_physical_block_size(struct request_queue *q, unsigned int size)
+ }
+ EXPORT_SYMBOL(blk_queue_physical_block_size);
+
++/**
++ * blk_queue_zone_write_granularity - set zone write granularity for the queue
++ * @q: the request queue for the zoned device
++ * @size: the zone write granularity size, in bytes
++ *
++ * Description:
++ * This should be set to the lowest possible size allowing to write in
++ * sequential zones of a zoned block device.
++ */
++void blk_queue_zone_write_granularity(struct request_queue *q,
++ unsigned int size)
++{
++ if (WARN_ON_ONCE(!blk_queue_is_zoned(q)))
++ return;
++
++ q->limits.zone_write_granularity = size;
++
++ if (q->limits.zone_write_granularity < q->limits.logical_block_size)
++ q->limits.zone_write_granularity = q->limits.logical_block_size;
++}
++EXPORT_SYMBOL_GPL(blk_queue_zone_write_granularity);
++
+ /**
+ * blk_queue_alignment_offset - set physical block alignment offset
+ * @q: the request queue for the device
+@@ -630,6 +653,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ t->discard_granularity;
+ }
+
++ t->zone_write_granularity = max(t->zone_write_granularity,
++ b->zone_write_granularity);
+ t->zoned = max(t->zoned, b->zoned);
+ return ret;
+ }
+@@ -846,6 +871,8 @@ EXPORT_SYMBOL_GPL(blk_queue_can_use_dma_map_merging);
+ */
+ void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model)
+ {
++ struct request_queue *q = disk->queue;
++
+ switch (model) {
+ case BLK_ZONED_HM:
+ /*
+@@ -874,7 +901,15 @@ void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model)
+ break;
+ }
+
+- disk->queue->limits.zoned = model;
++ q->limits.zoned = model;
++ if (model != BLK_ZONED_NONE) {
++ /*
++ * Set the zone write granularity to the device logical block
++ * size by default. The driver can change this value if needed.
++ */
++ blk_queue_zone_write_granularity(q,
++ queue_logical_block_size(q));
++ }
+ }
+ EXPORT_SYMBOL_GPL(blk_queue_set_zoned);
+
+diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
+index 9174137a913c4..ddf23bf3e0f1d 100644
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -219,6 +219,12 @@ static ssize_t queue_write_zeroes_max_show(struct request_queue *q, char *page)
+ (unsigned long long)q->limits.max_write_zeroes_sectors << 9);
+ }
+
++static ssize_t queue_zone_write_granularity_show(struct request_queue *q,
++ char *page)
++{
++ return queue_var_show(queue_zone_write_granularity(q), page);
++}
++
+ static ssize_t queue_zone_append_max_show(struct request_queue *q, char *page)
+ {
+ unsigned long long max_sectors = q->limits.max_zone_append_sectors;
+@@ -585,6 +591,7 @@ QUEUE_RO_ENTRY(queue_discard_zeroes_data, "discard_zeroes_data");
+ QUEUE_RO_ENTRY(queue_write_same_max, "write_same_max_bytes");
+ QUEUE_RO_ENTRY(queue_write_zeroes_max, "write_zeroes_max_bytes");
+ QUEUE_RO_ENTRY(queue_zone_append_max, "zone_append_max_bytes");
++QUEUE_RO_ENTRY(queue_zone_write_granularity, "zone_write_granularity");
+
+ QUEUE_RO_ENTRY(queue_zoned, "zoned");
+ QUEUE_RO_ENTRY(queue_nr_zones, "nr_zones");
+@@ -639,6 +646,7 @@ static struct attribute *queue_attrs[] = {
+ &queue_write_same_max_entry.attr,
+ &queue_write_zeroes_max_entry.attr,
+ &queue_zone_append_max_entry.attr,
++ &queue_zone_write_granularity_entry.attr,
+ &queue_nonrot_entry.attr,
+ &queue_zoned_entry.attr,
+ &queue_nr_zones_entry.attr,
+diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
+index 01088f333dbc4..f9cd41703d99b 100644
+--- a/drivers/scsi/sd_zbc.c
++++ b/drivers/scsi/sd_zbc.c
+@@ -793,6 +793,14 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)
+ blk_queue_max_active_zones(q, 0);
+ nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks);
+
++ /*
++ * Per ZBC and ZAC specifications, writes in sequential write required
++ * zones of host-managed devices must be aligned to the device physical
++ * block size.
++ */
++ if (blk_queue_zoned_model(q) == BLK_ZONED_HM)
++ blk_queue_zone_write_granularity(q, sdkp->physical_block_size);
++
+ /* READ16/WRITE16 is mandatory for ZBC disks */
+ sdkp->device->use_16_for_rw = 1;
+ sdkp->device->use_10_for_rw = 0;
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 583824f111079..a47e1aebaff24 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -345,6 +345,7 @@ struct queue_limits {
+ unsigned int max_zone_append_sectors;
+ unsigned int discard_granularity;
+ unsigned int discard_alignment;
++ unsigned int zone_write_granularity;
+
+ unsigned short max_segments;
+ unsigned short max_integrity_segments;
+@@ -1169,6 +1170,8 @@ extern void blk_queue_logical_block_size(struct request_queue *, unsigned int);
+ extern void blk_queue_max_zone_append_sectors(struct request_queue *q,
+ unsigned int max_zone_append_sectors);
+ extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);
++void blk_queue_zone_write_granularity(struct request_queue *q,
++ unsigned int size);
+ extern void blk_queue_alignment_offset(struct request_queue *q,
+ unsigned int alignment);
+ void blk_queue_update_readahead(struct request_queue *q);
+@@ -1480,6 +1483,18 @@ static inline int bdev_io_opt(struct block_device *bdev)
+ return queue_io_opt(bdev_get_queue(bdev));
+ }
+
++static inline unsigned int
++queue_zone_write_granularity(const struct request_queue *q)
++{
++ return q->limits.zone_write_granularity;
++}
++
++static inline unsigned int
++bdev_zone_write_granularity(struct block_device *bdev)
++{
++ return queue_zone_write_granularity(bdev_get_queue(bdev));
++}
++
+ static inline int queue_alignment_offset(const struct request_queue *q)
+ {
+ if (q->limits.misaligned)
+--
+2.43.0
+
--- /dev/null
+From 37f3ef3a6bf5531bd0417f358891bb1c23104fb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Oct 2023 15:55:49 +0100
+Subject: bounds: support non-power-of-two CONFIG_NR_CPUS
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit f2d5dcb48f7ba9e3ff249d58fc1fa963d374e66a ]
+
+ilog2() rounds down, so for example when PowerPC 85xx sets CONFIG_NR_CPUS
+to 24, we will only allocate 4 bits to store the number of CPUs instead of
+5. Use bits_per() instead, which rounds up. Found by code inspection.
+The effect of this would probably be a misaccounting when doing NUMA
+balancing, so to a user, it would only be a performance penalty. The
+effects may be more wide-spread; it's hard to tell.
+
+Link: https://lkml.kernel.org/r/20231010145549.1244748-1-willy@infradead.org
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Fixes: 90572890d202 ("mm: numa: Change page last {nid,pid} into {cpu,pid}")
+Reviewed-by: Rik van Riel <riel@surriel.com>
+Acked-by: Mel Gorman <mgorman@techsingularity.net>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bounds.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/bounds.c b/kernel/bounds.c
+index 9795d75b09b23..a94e3769347ee 100644
+--- a/kernel/bounds.c
++++ b/kernel/bounds.c
+@@ -19,7 +19,7 @@ int main(void)
+ DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS);
+ DEFINE(MAX_NR_ZONES, __MAX_NR_ZONES);
+ #ifdef CONFIG_SMP
+- DEFINE(NR_CPUS_BITS, ilog2(CONFIG_NR_CPUS));
++ DEFINE(NR_CPUS_BITS, bits_per(CONFIG_NR_CPUS));
+ #endif
+ DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
+ /* End of constants */
+--
+2.43.0
+
--- /dev/null
+From 3c08ded511b2a7ef5b450c2ea47545c74490f48b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 10:37:04 +0000
+Subject: btrfs: fix off-by-one chunk length calculation at
+ contains_pending_extent()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ae6bd7f9b46a29af52ebfac25d395757e2031d0d ]
+
+At contains_pending_extent() the value of the end offset of a chunk we
+found in the device's allocation state io tree is inclusive, so when
+we calculate the length we pass to the in_range() macro, we must sum
+1 to the expression "physical_end - physical_offset".
+
+In practice the wrong calculation should be harmless as chunks sizes
+are never 1 byte and we should never have 1 byte ranges of unallocated
+space. Nevertheless fix the wrong calculation.
+
+Reported-by: Alex Lyakas <alex.lyakas@zadara.com>
+Link: https://lore.kernel.org/linux-btrfs/CAOcd+r30e-f4R-5x-S7sV22RJPe7+pgwherA6xqN2_qe7o4XTg@mail.gmail.com/
+Fixes: 1c11b63eff2a ("btrfs: replace pending/pinned chunks lists with io tree")
+CC: stable@vger.kernel.org # 6.1+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/volumes.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index eaf5cd043dace..9a05313c69f33 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -1471,7 +1471,7 @@ static bool contains_pending_extent(struct btrfs_device *device, u64 *start,
+
+ if (in_range(physical_start, *start, len) ||
+ in_range(*start, physical_start,
+- physical_end - physical_start)) {
++ physical_end + 1 - physical_start)) {
+ *start = physical_end + 1;
+ return true;
+ }
+--
+2.43.0
+
--- /dev/null
+From f09680f70096d522edabea536ae1b363bfdd86f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 19:07:47 +0100
+Subject: clk: qcom: gcc-ipq6018: fix terminating of frequency table arrays
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit cdbc6e2d8108bc47895e5a901cfcaf799b00ca8d ]
+
+The frequency table arrays are supposed to be terminated with an
+empty element. Add such entry to the end of the arrays where it
+is missing in order to avoid possible out-of-bound access when
+the table is traversed by functions like qcom_find_freq() or
+qcom_find_freq_floor().
+
+Only compile tested.
+
+Fixes: d9db07f088af ("clk: qcom: Add ipq6018 Global Clock Controller support")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240229-freq-table-terminator-v1-2-074334f0905c@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq6018.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c
+index 4c5c7a8f41d08..b9844e41cf99d 100644
+--- a/drivers/clk/qcom/gcc-ipq6018.c
++++ b/drivers/clk/qcom/gcc-ipq6018.c
+@@ -1557,6 +1557,7 @@ static struct clk_regmap_div nss_ubi0_div_clk_src = {
+
+ static const struct freq_tbl ftbl_pcie_aux_clk_src[] = {
+ F(24000000, P_XO, 1, 0, 0),
++ { }
+ };
+
+ static const struct clk_parent_data gcc_xo_gpll0_core_pi_sleep_clk[] = {
+@@ -1737,6 +1738,7 @@ static const struct freq_tbl ftbl_sdcc_ice_core_clk_src[] = {
+ F(160000000, P_GPLL0, 5, 0, 0),
+ F(216000000, P_GPLL6, 5, 0, 0),
+ F(308570000, P_GPLL6, 3.5, 0, 0),
++ { }
+ };
+
+ static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = {
+--
+2.43.0
+
--- /dev/null
+From 2588b1b88f601f2814082fc60d5d6739971bf5b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 19:07:48 +0100
+Subject: clk: qcom: gcc-ipq8074: fix terminating of frequency table arrays
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit 1040ef5ed95d6fd2628bad387d78a61633e09429 ]
+
+The frequency table arrays are supposed to be terminated with an
+empty element. Add such entry to the end of the arrays where it
+is missing in order to avoid possible out-of-bound access when
+the table is traversed by functions like qcom_find_freq() or
+qcom_find_freq_floor().
+
+Only compile tested.
+
+Fixes: 9607f6224b39 ("clk: qcom: ipq8074: add PCIE, USB and SDCC clocks")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240229-freq-table-terminator-v1-3-074334f0905c@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index 0393154fea2f9..649e75a41f7af 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -972,6 +972,7 @@ static struct clk_rcg2 pcie0_axi_clk_src = {
+
+ static const struct freq_tbl ftbl_pcie_aux_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 pcie0_aux_clk_src = {
+@@ -1077,6 +1078,7 @@ static const struct freq_tbl ftbl_sdcc_ice_core_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(160000000, P_GPLL0, 5, 0, 0),
+ F(308570000, P_GPLL6, 3.5, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+--
+2.43.0
+
--- /dev/null
+From 652ef2740a0c1ba7645831728099033dc518f18c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jan 2024 11:58:14 +0530
+Subject: clk: qcom: gcc-sdm845: Add soft dependency on rpmhpd
+
+From: Amit Pundir <amit.pundir@linaro.org>
+
+[ Upstream commit 1d9054e3a4fd36e2949e616f7360bdb81bcc1921 ]
+
+With the addition of RPMh power domain to the GCC node in
+device tree, we noticed a significant delay in getting the
+UFS driver probed on AOSP which futher led to mount failures
+because Android do not support rootwait. So adding a soft
+dependency on RPMh power domain which informs modprobe to
+load rpmhpd module before gcc-sdm845.
+
+Cc: stable@vger.kernel.org # v5.4+
+Fixes: 4b6ea15c0a11 ("arm64: dts: qcom: sdm845: Add missing RPMh power domain to GCC")
+Suggested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240123062814.2555649-1-amit.pundir@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sdm845.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
+index 90f7febaf5288..a6b07aa8eb650 100644
+--- a/drivers/clk/qcom/gcc-sdm845.c
++++ b/drivers/clk/qcom/gcc-sdm845.c
+@@ -3646,3 +3646,4 @@ module_exit(gcc_sdm845_exit);
+ MODULE_DESCRIPTION("QTI GCC SDM845 Driver");
+ MODULE_LICENSE("GPL v2");
+ MODULE_ALIAS("platform:gcc-sdm845");
++MODULE_SOFTDEP("pre: rpmhpd");
+--
+2.43.0
+
--- /dev/null
+From 0ad60175653fdea0bee0174748d5098d4cbea9be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 19:07:51 +0100
+Subject: clk: qcom: mmcc-apq8084: fix terminating of frequency table arrays
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit a903cfd38d8dee7e754fb89fd1bebed99e28003d ]
+
+The frequency table arrays are supposed to be terminated with an
+empty element. Add such entry to the end of the arrays where it
+is missing in order to avoid possible out-of-bound access when
+the table is traversed by functions like qcom_find_freq() or
+qcom_find_freq_floor().
+
+Only compile tested.
+
+Fixes: 2b46cd23a5a2 ("clk: qcom: Add APQ8084 Multimedia Clock Controller (MMCC) support")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240229-freq-table-terminator-v1-6-074334f0905c@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/mmcc-apq8084.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c
+index fbfcf00067394..c2fd0e8f4bc09 100644
+--- a/drivers/clk/qcom/mmcc-apq8084.c
++++ b/drivers/clk/qcom/mmcc-apq8084.c
+@@ -333,6 +333,7 @@ static struct freq_tbl ftbl_mmss_axi_clk[] = {
+ F(333430000, P_MMPLL1, 3.5, 0, 0),
+ F(400000000, P_MMPLL0, 2, 0, 0),
+ F(466800000, P_MMPLL1, 2.5, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 mmss_axi_clk_src = {
+@@ -357,6 +358,7 @@ static struct freq_tbl ftbl_ocmemnoc_clk[] = {
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(228570000, P_MMPLL0, 3.5, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 ocmemnoc_clk_src = {
+--
+2.43.0
+
--- /dev/null
+From 8bb7199015fc7c0a40ab514cca31161d96eb01a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 19:07:52 +0100
+Subject: clk: qcom: mmcc-msm8974: fix terminating of frequency table arrays
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit e2c02a85bf53ae86d79b5fccf0a75ac0b78e0c96 ]
+
+The frequency table arrays are supposed to be terminated with an
+empty element. Add such entry to the end of the arrays where it
+is missing in order to avoid possible out-of-bound access when
+the table is traversed by functions like qcom_find_freq() or
+qcom_find_freq_floor().
+
+Only compile tested.
+
+Fixes: d8b212014e69 ("clk: qcom: Add support for MSM8974's multimedia clock controller (MMCC)")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240229-freq-table-terminator-v1-7-074334f0905c@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/mmcc-msm8974.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c
+index 015426262d080..dfc377463a7af 100644
+--- a/drivers/clk/qcom/mmcc-msm8974.c
++++ b/drivers/clk/qcom/mmcc-msm8974.c
+@@ -283,6 +283,7 @@ static struct freq_tbl ftbl_mmss_axi_clk[] = {
+ F(291750000, P_MMPLL1, 4, 0, 0),
+ F(400000000, P_MMPLL0, 2, 0, 0),
+ F(466800000, P_MMPLL1, 2.5, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 mmss_axi_clk_src = {
+@@ -307,6 +308,7 @@ static struct freq_tbl ftbl_ocmemnoc_clk[] = {
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(291750000, P_MMPLL1, 4, 0, 0),
+ F(400000000, P_MMPLL0, 2, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 ocmemnoc_clk_src = {
+--
+2.43.0
+
--- /dev/null
+From 82988c5aea66c118f5dbd66de066c6d2f81dbeaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Mar 2024 13:54:57 +0100
+Subject: cpufreq: dt: always allocate zeroed cpumask
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit d2399501c2c081eac703ca9597ceb83c7875a537 ]
+
+Commit 0499a78369ad ("ARM64: Dynamically allocate cpumasks and increase
+supported CPUs to 512") changed the handling of cpumasks on ARM 64bit,
+what resulted in the strange issues and warnings during cpufreq-dt
+initialization on some big.LITTLE platforms.
+
+This was caused by mixing OPPs between big and LITTLE cores, because
+OPP-sharing information between big and LITTLE cores is computed on
+cpumask, which in turn was not zeroed on allocation. Fix this by
+switching to zalloc_cpumask_var() call.
+
+Fixes: dc279ac6e5b4 ("cpufreq: dt: Refactor initialization to handle probe deferral properly")
+CC: stable@vger.kernel.org # v5.10+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Christoph Lameter (Ampere) <cl@linux.com>
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq-dt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
+index e363ae04aac62..44cc596ca0a5e 100644
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -251,7 +251,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
+ if (!priv)
+ return -ENOMEM;
+
+- if (!alloc_cpumask_var(&priv->cpus, GFP_KERNEL))
++ if (!zalloc_cpumask_var(&priv->cpus, GFP_KERNEL))
+ return -ENOMEM;
+
+ priv->cpu_dev = cpu_dev;
+--
+2.43.0
+
--- /dev/null
+From 12efba42e382567af2d4a1a76bbf5306599609c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Oct 2023 13:27:19 +0100
+Subject: crypto: qat - fix double free during reset
+
+From: Svyatoslav Pankratov <svyatoslav.pankratov@intel.com>
+
+[ Upstream commit 01aed663e6c421aeafc9c330bda630976b50a764 ]
+
+There is no need to free the reset_data structure if the recovery is
+unsuccessful and the reset is synchronous. The function
+adf_dev_aer_schedule_reset() handles the cleanup properly. Only
+asynchronous resets require such structure to be freed inside the reset
+worker.
+
+Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework")
+Signed-off-by: Svyatoslav Pankratov <svyatoslav.pankratov@intel.com>
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 7d42e097607c ("crypto: qat - resolve race condition during AER recovery")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/adf_aer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c
+index d2ae293d0df6a..d1a7809c51c0a 100644
+--- a/drivers/crypto/qat/qat_common/adf_aer.c
++++ b/drivers/crypto/qat/qat_common/adf_aer.c
+@@ -95,7 +95,8 @@ static void adf_device_reset_worker(struct work_struct *work)
+ if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) {
+ /* The device hanged and we can't restart it so stop here */
+ dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
+- kfree(reset_data);
++ if (reset_data->mode == ADF_DEV_RESET_ASYNC)
++ kfree(reset_data);
+ WARN(1, "QAT: device restart failed. Device is unusable\n");
+ return;
+ }
+--
+2.43.0
+
--- /dev/null
+From c1545447e28f9c773ed5a5515e5adf38d3cdbb18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Feb 2024 13:43:42 +0100
+Subject: crypto: qat - resolve race condition during AER recovery
+
+From: Damian Muszynski <damian.muszynski@intel.com>
+
+[ Upstream commit 7d42e097607c4d246d99225bf2b195b6167a210c ]
+
+During the PCI AER system's error recovery process, the kernel driver
+may encounter a race condition with freeing the reset_data structure's
+memory. If the device restart will take more than 10 seconds the function
+scheduling that restart will exit due to a timeout, and the reset_data
+structure will be freed. However, this data structure is used for
+completion notification after the restart is completed, which leads
+to a UAF bug.
+
+This results in a KFENCE bug notice.
+
+ BUG: KFENCE: use-after-free read in adf_device_reset_worker+0x38/0xa0 [intel_qat]
+ Use-after-free read at 0x00000000bc56fddf (in kfence-#142):
+ adf_device_reset_worker+0x38/0xa0 [intel_qat]
+ process_one_work+0x173/0x340
+
+To resolve this race condition, the memory associated to the container
+of the work_struct is freed on the worker if the timeout expired,
+otherwise on the function that schedules the worker.
+The timeout detection can be done by checking if the caller is
+still waiting for completion or not by using completion_done() function.
+
+Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Damian Muszynski <damian.muszynski@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/adf_aer.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c
+index d1a7809c51c0a..dc0feedf52702 100644
+--- a/drivers/crypto/qat/qat_common/adf_aer.c
++++ b/drivers/crypto/qat/qat_common/adf_aer.c
+@@ -95,7 +95,8 @@ static void adf_device_reset_worker(struct work_struct *work)
+ if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) {
+ /* The device hanged and we can't restart it so stop here */
+ dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
+- if (reset_data->mode == ADF_DEV_RESET_ASYNC)
++ if (reset_data->mode == ADF_DEV_RESET_ASYNC ||
++ completion_done(&reset_data->compl))
+ kfree(reset_data);
+ WARN(1, "QAT: device restart failed. Device is unusable\n");
+ return;
+@@ -103,11 +104,19 @@ static void adf_device_reset_worker(struct work_struct *work)
+ adf_dev_restarted_notify(accel_dev);
+ clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+
+- /* The dev is back alive. Notify the caller if in sync mode */
+- if (reset_data->mode == ADF_DEV_RESET_SYNC)
+- complete(&reset_data->compl);
+- else
++ /*
++ * The dev is back alive. Notify the caller if in sync mode
++ *
++ * If device restart will take a more time than expected,
++ * the schedule_reset() function can timeout and exit. This can be
++ * detected by calling the completion_done() function. In this case
++ * the reset_data structure needs to be freed here.
++ */
++ if (reset_data->mode == ADF_DEV_RESET_ASYNC ||
++ completion_done(&reset_data->compl))
+ kfree(reset_data);
++ else
++ complete(&reset_data->compl);
+ }
+
+ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
+@@ -140,8 +149,9 @@ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
+ dev_err(&GET_DEV(accel_dev),
+ "Reset device timeout expired\n");
+ ret = -EFAULT;
++ } else {
++ kfree(reset_data);
+ }
+- kfree(reset_data);
+ return ret;
+ }
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From dc4a65976fa0b7d9af41e525bbf2627eb88ccae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 15:23:06 +0800
+Subject: dm-raid: fix lockdep waring in "pers->hot_add_disk"
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 95009ae904b1e9dca8db6f649f2d7c18a6e42c75 ]
+
+The lockdep assert is added by commit a448af25becf ("md/raid10: remove
+rcu protection to access rdev from conf") in print_conf(). And I didn't
+notice that dm-raid is calling "pers->hot_add_disk" without holding
+'reconfig_mutex'.
+
+"pers->hot_add_disk" read and write many fields that is protected by
+'reconfig_mutex', and raid_resume() already grab the lock in other
+contex. Hence fix this problem by protecting "pers->host_add_disk"
+with the lock.
+
+Fixes: 9092c02d9435 ("DM RAID: Add ability to restore transiently failed devices on resume")
+Fixes: a448af25becf ("md/raid10: remove rcu protection to access rdev from conf")
+Cc: stable@vger.kernel.org # v6.7+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Acked-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20240305072306.2562024-10-yukuai1@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-raid.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index e523ecdf947f4..99995b1804b32 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -4019,7 +4019,9 @@ static void raid_resume(struct dm_target *ti)
+ * Take this opportunity to check whether any failed
+ * devices are reachable again.
+ */
++ mddev_lock_nointr(mddev);
+ attempt_restore_of_faulty_devices(rs);
++ mddev_unlock(mddev);
+ }
+
+ if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
+--
+2.43.0
+
--- /dev/null
+From d34dc105da100e9ea5d00a6b7a2f6d4cd1302f9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Mar 2024 18:43:11 +0100
+Subject: dm snapshot: fix lockup in dm_exception_table_exit
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 6e7132ed3c07bd8a6ce3db4bb307ef2852b322dc ]
+
+There was reported lockup when we exit a snapshot with many exceptions.
+Fix this by adding "cond_resched" to the loop that frees the exceptions.
+
+Reported-by: John Pittman <jpittman@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-snap.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index 41735a25d50aa..de73fe79640fd 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -685,8 +685,10 @@ static void dm_exception_table_exit(struct dm_exception_table *et,
+ for (i = 0; i < size; i++) {
+ slot = et->table + i;
+
+- hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list)
++ hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list) {
+ kmem_cache_free(mem, ex);
++ cond_resched();
++ }
+ }
+
+ vfree(et->table);
+--
+2.43.0
+
--- /dev/null
+From 11f683f72e70b7c1070c6b933a9d26961d2d63a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 08:35:07 -0400
+Subject: drm/amd/display: Fix noise issue on HDMI AV mute
+
+From: Leo Ma <hanghong.ma@amd.com>
+
+[ Upstream commit 69e3be6893a7e668660b05a966bead82bbddb01d ]
+
+[Why]
+When mode switching is triggered there is momentary noise visible on
+some HDMI TV or displays.
+
+[How]
+Wait for 2 frames to make sure we have enough time to send out AV mute
+and sink receives a full frame.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
+Acked-by: Wayne Lin <wayne.lin@amd.com>
+Signed-off-by: Leo Ma <hanghong.ma@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index 22c77e96f6a54..02d22f62c0031 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -641,10 +641,20 @@ void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
+ if (pipe_ctx == NULL)
+ return;
+
+- if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) && pipe_ctx->stream_res.stream_enc != NULL)
++ if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) && pipe_ctx->stream_res.stream_enc != NULL) {
+ pipe_ctx->stream_res.stream_enc->funcs->set_avmute(
+ pipe_ctx->stream_res.stream_enc,
+ enable);
++
++ /* Wait for two frame to make sure AV mute is sent out */
++ if (enable) {
++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
++ pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
++ }
++ }
+ }
+
+ void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx)
+--
+2.43.0
+
--- /dev/null
+From e4f3dd365caf01279362596040e421dd134d6888 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 13:29:51 -0700
+Subject: drm/amd/display: Return the correct HDCP error code
+
+From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+
+[ Upstream commit e64b3f55e458ce7e2087a0051f47edabf74545e7 ]
+
+[WHY & HOW]
+If the display is null when creating an HDCP session, return a proper
+error code.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Acked-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+index 972f2600f967f..05d96fa681354 100644
+--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+@@ -405,6 +405,9 @@ enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp)
+ hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.hdcp_shared_buf;
+ memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
+
++ if (!display)
++ return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
++
+ hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index;
+
+ if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0)
+--
+2.43.0
+
--- /dev/null
+From 75cae35b079e066f7396dbaa38b67d91cb3c2f81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 14:28:11 +0100
+Subject: drm/etnaviv: Restore some id values
+
+From: Christian Gmeiner <cgmeiner@igalia.com>
+
+[ Upstream commit b735ee173f84d5d0d0733c53946a83c12d770d05 ]
+
+The hwdb selection logic as a feature that allows it to mark some fields
+as 'don't care'. If we match with such a field we memcpy(..)
+the current etnaviv_chip_identity into ident.
+
+This step can overwrite some id values read from the GPU with the
+'don't care' value.
+
+Fix this issue by restoring the affected values after the memcpy(..).
+
+As this is crucial for user space to know when this feature works as
+expected increment the minor version too.
+
+Fixes: 4078a1186dd3 ("drm/etnaviv: update hwdb selection logic")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
+Reviewed-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_drv.c | 2 +-
+ drivers/gpu/drm/etnaviv/etnaviv_hwdb.c | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+index a9a3afaef9a1c..edf9387069cdc 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+@@ -511,7 +511,7 @@ static struct drm_driver etnaviv_drm_driver = {
+ .desc = "etnaviv DRM",
+ .date = "20151214",
+ .major = 1,
+- .minor = 3,
++ .minor = 4,
+ };
+
+ /*
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
+index 167971a09be79..e9b777ab3be7f 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
+@@ -73,6 +73,9 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = {
+ bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu)
+ {
+ struct etnaviv_chip_identity *ident = &gpu->identity;
++ const u32 product_id = ident->product_id;
++ const u32 customer_id = ident->customer_id;
++ const u32 eco_id = ident->eco_id;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(etnaviv_chip_identities); i++) {
+@@ -86,6 +89,12 @@ bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu)
+ etnaviv_chip_identities[i].eco_id == ~0U)) {
+ memcpy(ident, &etnaviv_chip_identities[i],
+ sizeof(*ident));
++
++ /* Restore some id values as ~0U aka 'don't care' might been used. */
++ ident->product_id = product_id;
++ ident->customer_id = customer_id;
++ ident->eco_id = eco_id;
++
+ return true;
+ }
+ }
+--
+2.43.0
+
--- /dev/null
+From 1dbf3309334fed008409c01403a47a52b11135e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 18:03:41 +0200
+Subject: drm/exynos: do not return negative values from .get_modes()
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit 13d5b040363c7ec0ac29c2de9cf661a24a8aa531 ]
+
+The .get_modes() hooks aren't supposed to return negative error
+codes. Return 0 for no modes, whatever the reason.
+
+Cc: Inki Dae <inki.dae@samsung.com>
+Cc: Seung-Woo Kim <sw0312.kim@samsung.com>
+Cc: Kyungmin Park <kyungmin.park@samsung.com>
+Cc: stable@vger.kernel.org
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/d8665f620d9c252aa7d5a4811ff6b16e773903a2.1709913674.git.jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c | 4 ++--
+ drivers/gpu/drm/exynos/exynos_hdmi.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index e96436e11a36c..e1ffe8a28b649 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -315,14 +315,14 @@ static int vidi_get_modes(struct drm_connector *connector)
+ */
+ if (!ctx->raw_edid) {
+ DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n");
+- return -EFAULT;
++ return 0;
+ }
+
+ edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
+ edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
+ if (!edid) {
+ DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n");
+- return -ENOMEM;
++ return 0;
+ }
+
+ drm_connector_update_edid_property(connector, edid);
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 981bffacda243..576fcf1807164 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -878,11 +878,11 @@ static int hdmi_get_modes(struct drm_connector *connector)
+ int ret;
+
+ if (!hdata->ddc_adpt)
+- return -ENODEV;
++ return 0;
+
+ edid = drm_get_edid(connector, hdata->ddc_adpt);
+ if (!edid)
+- return -ENODEV;
++ return 0;
+
+ hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
+ DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n",
+--
+2.43.0
+
--- /dev/null
+From a9f8da5bf7fb1c34113f427f0f11585111dad905 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 18:03:43 +0200
+Subject: drm/imx/ipuv3: do not return negative values from .get_modes()
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit c2da9ada64962fcd2e6395ed9987b9874ea032d3 ]
+
+The .get_modes() hooks aren't supposed to return negative error
+codes. Return 0 for no modes, whatever the reason.
+
+Cc: Philipp Zabel <p.zabel@pengutronix.de>
+Cc: stable@vger.kernel.org
+Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/311f6eec96d47949b16a670529f4d89fcd97aefa.1709913674.git.jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/imx/parallel-display.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
+index b61bfa84b6bbd..bcd6b9ee8eea6 100644
+--- a/drivers/gpu/drm/imx/parallel-display.c
++++ b/drivers/gpu/drm/imx/parallel-display.c
+@@ -65,14 +65,14 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
+ int ret;
+
+ if (!mode)
+- return -EINVAL;
++ return 0;
+
+ ret = of_get_drm_display_mode(np, &imxpd->mode,
+ &imxpd->bus_flags,
+ OF_USE_NATIVE_MODE);
+ if (ret) {
+ drm_mode_destroy(connector->dev, mode);
+- return ret;
++ return 0;
+ }
+
+ drm_mode_copy(mode, &imxpd->mode);
+--
+2.43.0
+
--- /dev/null
+From f00709602b156d4de3b0c25eddbc493798887e08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 18:03:40 +0200
+Subject: drm/panel: do not return negative error codes from
+ drm_panel_get_modes()
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit fc4e97726530241d96dd7db72eb65979217422c9 ]
+
+None of the callers of drm_panel_get_modes() expect it to return
+negative error codes. Either they propagate the return value in their
+struct drm_connector_helper_funcs .get_modes() hook (which is also not
+supposed to return negative codes), or add it to other counts leading to
+bogus values.
+
+On the other hand, many of the struct drm_panel_funcs .get_modes() hooks
+do return negative error codes, so handle them gracefully instead of
+propagating further.
+
+Return 0 for no modes, whatever the reason.
+
+Cc: Neil Armstrong <neil.armstrong@linaro.org>
+Cc: Jessica Zhang <quic_jesszhan@quicinc.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/79f559b72d8c493940417304e222a4b04dfa19c4.1709913674.git.jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panel.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
+index f634371c717a8..7fd3de89ed079 100644
+--- a/drivers/gpu/drm/drm_panel.c
++++ b/drivers/gpu/drm/drm_panel.c
+@@ -207,19 +207,24 @@ EXPORT_SYMBOL(drm_panel_disable);
+ * The modes probed from the panel are automatically added to the connector
+ * that the panel is attached to.
+ *
+- * Return: The number of modes available from the panel on success or a
+- * negative error code on failure.
++ * Return: The number of modes available from the panel on success, or 0 on
++ * failure (no modes).
+ */
+ int drm_panel_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+ {
+ if (!panel)
+- return -EINVAL;
++ return 0;
+
+- if (panel->funcs && panel->funcs->get_modes)
+- return panel->funcs->get_modes(panel, connector);
++ if (panel->funcs && panel->funcs->get_modes) {
++ int num;
+
+- return -EOPNOTSUPP;
++ num = panel->funcs->get_modes(panel, connector);
++ if (num > 0)
++ return num;
++ }
++
++ return 0;
+ }
+ EXPORT_SYMBOL(drm_panel_get_modes);
+
+--
+2.43.0
+
--- /dev/null
+From 251b1f3b82416912971a0b0da3ca7cd6a67076a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 18:03:44 +0200
+Subject: drm/vc4: hdmi: do not return negative values from .get_modes()
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit abf493988e380f25242c1023275c68bd3579c9ce ]
+
+The .get_modes() hooks aren't supposed to return negative error
+codes. Return 0 for no modes, whatever the reason.
+
+Cc: Maxime Ripard <mripard@kernel.org>
+Cc: stable@vger.kernel.org
+Acked-by: Maxime Ripard <mripard@kernel.org>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/dcda6d4003e2c6192987916b35c7304732800e08.1709913674.git.jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 7e8620838de9c..6d01258349faa 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -197,7 +197,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
+ edid = drm_get_edid(connector, vc4_hdmi->ddc);
+ cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid);
+ if (!edid)
+- return -ENODEV;
++ return 0;
+
+ vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
+
+--
+2.43.0
+
--- /dev/null
+From 147569de9465ff85ad568cb81a75fc536537ad16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 15:03:05 -0500
+Subject: drm/vmwgfx: Fix possible null pointer derefence with invalid contexts
+
+From: Zack Rusin <zack.rusin@broadcom.com>
+
+[ Upstream commit 517621b7060096e48e42f545fa6646fc00252eac ]
+
+vmw_context_cotable can return either an error or a null pointer and its
+usage sometimes went unchecked. Subsequent code would then try to access
+either a null pointer or an error value.
+
+The invalid dereferences were only possible with malformed userspace
+apps which never properly initialized the rendering contexts.
+
+Check the results of vmw_context_cotable to fix the invalid derefs.
+
+Thanks:
+ziming zhang(@ezrak1e) from Ant Group Light-Year Security Lab
+who was the first person to discover it.
+Niels De Graef who reported it and helped to track down the poc.
+
+Fixes: 9c079b8ce8bf ("drm/vmwgfx: Adapt execbuf to the new validation api")
+Cc: <stable@vger.kernel.org> # v4.20+
+Reported-by: Niels De Graef <ndegraef@redhat.com>
+Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
+Cc: Martin Krastev <martin.krastev@broadcom.com>
+Cc: Maaz Mombasawala <maaz.mombasawala@broadcom.com>
+Cc: Ian Forbes <ian.forbes@broadcom.com>
+Cc: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
+Cc: dri-devel@lists.freedesktop.org
+Reviewed-by: Maaz Mombasawala <maaz.mombasawala@broadcom.com>
+Reviewed-by: Martin Krastev <martin.krastev@broadcom.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240110200305.94086-1-zack.rusin@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+index 831291b5d1a03..616f6cb622783 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+@@ -467,7 +467,7 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv,
+ vmw_res_type(ctx) == vmw_res_dx_context) {
+ for (i = 0; i < cotable_max; ++i) {
+ res = vmw_context_cotable(ctx, i);
+- if (IS_ERR(res))
++ if (IS_ERR_OR_NULL(res))
+ continue;
+
+ ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
+@@ -1272,6 +1272,8 @@ static int vmw_cmd_dx_define_query(struct vmw_private *dev_priv,
+ return -EINVAL;
+
+ cotable_res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXQUERY);
++ if (IS_ERR_OR_NULL(cotable_res))
++ return cotable_res ? PTR_ERR(cotable_res) : -EINVAL;
+ ret = vmw_cotable_notify(cotable_res, cmd->body.queryId);
+
+ return ret;
+@@ -2450,6 +2452,8 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv,
+ return ret;
+
+ res = vmw_context_cotable(ctx_node->ctx, vmw_view_cotables[view_type]);
++ if (IS_ERR_OR_NULL(res))
++ return res ? PTR_ERR(res) : -EINVAL;
+ ret = vmw_cotable_notify(res, cmd->defined_id);
+ if (unlikely(ret != 0))
+ return ret;
+@@ -2535,8 +2539,8 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv,
+
+ so_type = vmw_so_cmd_to_type(header->id);
+ res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]);
+- if (IS_ERR(res))
+- return PTR_ERR(res);
++ if (IS_ERR_OR_NULL(res))
++ return res ? PTR_ERR(res) : -EINVAL;
+ cmd = container_of(header, typeof(*cmd), header);
+ ret = vmw_cotable_notify(res, cmd->defined_id);
+
+@@ -2655,6 +2659,8 @@ static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv,
+ return -EINVAL;
+
+ res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXSHADER);
++ if (IS_ERR_OR_NULL(res))
++ return res ? PTR_ERR(res) : -EINVAL;
+ ret = vmw_cotable_notify(res, cmd->body.shaderId);
+ if (ret)
+ return ret;
+@@ -2976,6 +2982,8 @@ static int vmw_cmd_dx_define_streamoutput(struct vmw_private *dev_priv,
+ }
+
+ res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT);
++ if (IS_ERR_OR_NULL(res))
++ return res ? PTR_ERR(res) : -EINVAL;
+ ret = vmw_cotable_notify(res, cmd->body.soid);
+ if (ret)
+ return ret;
+--
+2.43.0
+
--- /dev/null
+From cd29d1ade0637ba6751daa742dcdca85c4cb3d54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Jun 2021 13:23:02 -0400
+Subject: drm/vmwgfx: Fix some static checker warnings
+
+From: Zack Rusin <zackr@vmware.com>
+
+[ Upstream commit 74231041d14030f1ae6582b9233bfe782ac23e33 ]
+
+Fix some minor issues that Coverity spotted in the code. None
+of that are serious but they're all valid concerns so fixing
+them makes sense.
+
+Signed-off-by: Zack Rusin <zackr@vmware.com>
+Reviewed-by: Roland Scheidegger <sroland@vmware.com>
+Reviewed-by: Martin Krastev <krastevm@vmware.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210609172307.131929-5-zackr@vmware.com
+Stable-dep-of: 517621b70600 ("drm/vmwgfx: Fix possible null pointer derefence with invalid contexts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/ttm/ttm_memory.c | 2 ++
+ drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 20 ++++++++------------
+ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 2 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 4 +++-
+ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 ++
+ drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 4 +++-
+ drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 ++++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 8 ++++++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 3 ++-
+ drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 4 ++--
+ 10 files changed, 33 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
+index 89d50f38c0f2c..5af52012fc5c6 100644
+--- a/drivers/gpu/drm/ttm/ttm_memory.c
++++ b/drivers/gpu/drm/ttm/ttm_memory.c
+@@ -431,8 +431,10 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
+
+ si_meminfo(&si);
+
++ spin_lock(&glob->lock);
+ /* set it as 0 by default to keep original behavior of OOM */
+ glob->lower_mem_limit = 0;
++ spin_unlock(&glob->lock);
+
+ ret = ttm_mem_init_kernel_zone(glob, &si);
+ if (unlikely(ret != 0))
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
+index f41550797970b..4da4bf3b7f0b3 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
+@@ -713,7 +713,7 @@ static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind)
+ * without checking which bindings actually need to be emitted
+ *
+ * @cbs: Pointer to the context's struct vmw_ctx_binding_state
+- * @bi: Pointer to where the binding info array is stored in @cbs
++ * @biv: Pointer to where the binding info array is stored in @cbs
+ * @max_num: Maximum number of entries in the @bi array.
+ *
+ * Scans the @bi array for bindings and builds a buffer of view id data.
+@@ -723,11 +723,9 @@ static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind)
+ * contains the command data.
+ */
+ static void vmw_collect_view_ids(struct vmw_ctx_binding_state *cbs,
+- const struct vmw_ctx_bindinfo *bi,
++ const struct vmw_ctx_bindinfo_view *biv,
+ u32 max_num)
+ {
+- const struct vmw_ctx_bindinfo_view *biv =
+- container_of(bi, struct vmw_ctx_bindinfo_view, bi);
+ unsigned long i;
+
+ cbs->bind_cmd_count = 0;
+@@ -835,7 +833,7 @@ static int vmw_emit_set_sr(struct vmw_ctx_binding_state *cbs,
+ */
+ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs)
+ {
+- const struct vmw_ctx_bindinfo *loc = &cbs->render_targets[0].bi;
++ const struct vmw_ctx_bindinfo_view *loc = &cbs->render_targets[0];
+ struct {
+ SVGA3dCmdHeader header;
+ SVGA3dCmdDXSetRenderTargets body;
+@@ -871,7 +869,7 @@ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs)
+ * without checking which bindings actually need to be emitted
+ *
+ * @cbs: Pointer to the context's struct vmw_ctx_binding_state
+- * @bi: Pointer to where the binding info array is stored in @cbs
++ * @biso: Pointer to where the binding info array is stored in @cbs
+ * @max_num: Maximum number of entries in the @bi array.
+ *
+ * Scans the @bi array for bindings and builds a buffer of SVGA3dSoTarget data.
+@@ -881,11 +879,9 @@ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs)
+ * contains the command data.
+ */
+ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs,
+- const struct vmw_ctx_bindinfo *bi,
++ const struct vmw_ctx_bindinfo_so_target *biso,
+ u32 max_num)
+ {
+- const struct vmw_ctx_bindinfo_so_target *biso =
+- container_of(bi, struct vmw_ctx_bindinfo_so_target, bi);
+ unsigned long i;
+ SVGA3dSoTarget *so_buffer = (SVGA3dSoTarget *) cbs->bind_cmd_buffer;
+
+@@ -916,7 +912,7 @@ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs,
+ */
+ static int vmw_emit_set_so_target(struct vmw_ctx_binding_state *cbs)
+ {
+- const struct vmw_ctx_bindinfo *loc = &cbs->so_targets[0].bi;
++ const struct vmw_ctx_bindinfo_so_target *loc = &cbs->so_targets[0];
+ struct {
+ SVGA3dCmdHeader header;
+ SVGA3dCmdDXSetSOTargets body;
+@@ -1063,7 +1059,7 @@ static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs)
+
+ static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs)
+ {
+- const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[0].views[0].bi;
++ const struct vmw_ctx_bindinfo_view *loc = &cbs->ua_views[0].views[0];
+ struct {
+ SVGA3dCmdHeader header;
+ SVGA3dCmdDXSetUAViews body;
+@@ -1093,7 +1089,7 @@ static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs)
+
+ static int vmw_emit_set_cs_uav(struct vmw_ctx_binding_state *cbs)
+ {
+- const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[1].views[0].bi;
++ const struct vmw_ctx_bindinfo_view *loc = &cbs->ua_views[1].views[0];
+ struct {
+ SVGA3dCmdHeader header;
+ SVGA3dCmdDXSetCSUAViews body;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+index 9a9fe10d829b8..87a39721e5bc0 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+@@ -514,7 +514,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
+ struct vmw_cmdbuf_man *man =
+ container_of(work, struct vmw_cmdbuf_man, work);
+ struct vmw_cmdbuf_header *entry, *next;
+- uint32_t dummy;
++ uint32_t dummy = 0;
+ bool send_fence = false;
+ struct list_head restart_head[SVGA_CB_CONTEXT_MAX];
+ int i;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
+index 47b92d0c898a7..f212368c03129 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
+@@ -160,6 +160,7 @@ void vmw_cmdbuf_res_commit(struct list_head *list)
+ void vmw_cmdbuf_res_revert(struct list_head *list)
+ {
+ struct vmw_cmdbuf_res *entry, *next;
++ int ret;
+
+ list_for_each_entry_safe(entry, next, list, head) {
+ switch (entry->state) {
+@@ -167,7 +168,8 @@ void vmw_cmdbuf_res_revert(struct list_head *list)
+ vmw_cmdbuf_res_free(entry->man, entry);
+ break;
+ case VMW_CMDBUF_RES_DEL:
+- drm_ht_insert_item(&entry->man->resources, &entry->hash);
++ ret = drm_ht_insert_item(&entry->man->resources, &entry->hash);
++ BUG_ON(ret);
+ list_del(&entry->head);
+ list_add_tail(&entry->head, &entry->man->list);
+ entry->state = VMW_CMDBUF_RES_COMMITTED;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+index 00082c679170a..831291b5d1a03 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+@@ -2535,6 +2535,8 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv,
+
+ so_type = vmw_so_cmd_to_type(header->id);
+ res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]);
++ if (IS_ERR(res))
++ return PTR_ERR(res);
+ cmd = container_of(header, typeof(*cmd), header);
+ ret = vmw_cotable_notify(res, cmd->defined_id);
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
+index 7f95ed6aa2241..fb0797b380dd2 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
+@@ -494,11 +494,13 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob,
+ {
+ unsigned long num_pt_pages = 0;
+ struct ttm_buffer_object *bo = mob->pt_bo;
+- struct vmw_piter save_pt_iter;
++ struct vmw_piter save_pt_iter = {0};
+ struct vmw_piter pt_iter;
+ const struct vmw_sg_table *vsgt;
+ int ret;
+
++ BUG_ON(num_data_pages == 0);
++
+ ret = ttm_bo_reserve(bo, false, true, NULL);
+ BUG_ON(ret != 0);
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+index 15b5bde693242..751582f5ab0b1 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+@@ -154,6 +154,7 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
+ /* HB port can't access encrypted memory. */
+ if (hb && !mem_encrypt_active()) {
+ unsigned long bp = channel->cookie_high;
++ u32 channel_id = (channel->channel_id << 16);
+
+ si = (uintptr_t) msg;
+ di = channel->cookie_low;
+@@ -161,7 +162,7 @@ static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
+ VMW_PORT_HB_OUT(
+ (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
+ msg_len, si, di,
+- VMWARE_HYPERVISOR_HB | (channel->channel_id << 16) |
++ VMWARE_HYPERVISOR_HB | channel_id |
+ VMWARE_HYPERVISOR_OUT,
+ VMW_HYPERVISOR_MAGIC, bp,
+ eax, ebx, ecx, edx, si, di);
+@@ -209,6 +210,7 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
+ /* HB port can't access encrypted memory */
+ if (hb && !mem_encrypt_active()) {
+ unsigned long bp = channel->cookie_low;
++ u32 channel_id = (channel->channel_id << 16);
+
+ si = channel->cookie_high;
+ di = (uintptr_t) reply;
+@@ -216,7 +218,7 @@ static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
+ VMW_PORT_HB_IN(
+ (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
+ reply_len, si, di,
+- VMWARE_HYPERVISOR_HB | (channel->channel_id << 16),
++ VMWARE_HYPERVISOR_HB | channel_id,
+ VMW_HYPERVISOR_MAGIC, bp,
+ eax, ebx, ecx, edx, si, di);
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+index 5e922d9d5f2cc..26f88d64879f1 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+@@ -114,6 +114,7 @@ static void vmw_resource_release(struct kref *kref)
+ container_of(kref, struct vmw_resource, kref);
+ struct vmw_private *dev_priv = res->dev_priv;
+ int id;
++ int ret;
+ struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+
+ spin_lock(&dev_priv->resource_lock);
+@@ -122,7 +123,8 @@ static void vmw_resource_release(struct kref *kref)
+ if (res->backup) {
+ struct ttm_buffer_object *bo = &res->backup->base;
+
+- ttm_bo_reserve(bo, false, false, NULL);
++ ret = ttm_bo_reserve(bo, false, false, NULL);
++ BUG_ON(ret);
+ if (vmw_resource_mob_attached(res) &&
+ res->func->unbind != NULL) {
+ struct ttm_validate_buffer val_buf;
+@@ -1001,7 +1003,9 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible)
+ if (res->backup) {
+ vbo = res->backup;
+
+- ttm_bo_reserve(&vbo->base, interruptible, false, NULL);
++ ret = ttm_bo_reserve(&vbo->base, interruptible, false, NULL);
++ if (ret)
++ goto out_no_validate;
+ if (!vbo->base.pin_count) {
+ ret = ttm_bo_validate
+ (&vbo->base,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c
+index 3f97b61dd5d83..9330f1a0f1743 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c
+@@ -538,7 +538,8 @@ const SVGACOTableType vmw_so_cotables[] = {
+ [vmw_so_ds] = SVGA_COTABLE_DEPTHSTENCIL,
+ [vmw_so_rs] = SVGA_COTABLE_RASTERIZERSTATE,
+ [vmw_so_ss] = SVGA_COTABLE_SAMPLER,
+- [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT
++ [vmw_so_so] = SVGA_COTABLE_STREAMOUTPUT,
++ [vmw_so_max]= SVGA_COTABLE_MAX
+ };
+
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
+index f2e2bf6d1421f..cc1cfc827bb9a 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
+@@ -585,13 +585,13 @@ int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr)
+ container_of(entry->base.bo, typeof(*vbo), base);
+
+ if (entry->cpu_blit) {
+- struct ttm_operation_ctx ctx = {
++ struct ttm_operation_ctx ttm_ctx = {
+ .interruptible = intr,
+ .no_wait_gpu = false
+ };
+
+ ret = ttm_bo_validate(entry->base.bo,
+- &vmw_nonfixed_placement, &ctx);
++ &vmw_nonfixed_placement, &ttm_ctx);
+ } else {
+ ret = vmw_validation_bo_validate_single
+ (entry->base.bo, intr, entry->as_mob);
+--
+2.43.0
+
--- /dev/null
+From bee3795972f59cc139539c2bfd2e24edf6b1c6ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Sep 2020 14:14:32 +0200
+Subject: drm/vmwgfx: stop using ttm_bo_create v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+[ Upstream commit b254557cb244e2c18e59ee1cc2293128c52d2473 ]
+
+Implement in the driver instead since it is the only user of that function.
+
+v2: fix usage of ttm_bo_init_reserved
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Dave Airlie <airlied@redhat.com>
+Reviewed-by: Huang Rui <ray.huang@amd.com>
+Link: https://patchwork.freedesktop.org/patch/391614/?series=81973&rev=1
+Stable-dep-of: 517621b70600 ("drm/vmwgfx: Fix possible null pointer derefence with invalid contexts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 43 ++++++++++++++++++++++
+ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 6 +--
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 ++
+ drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 8 ++--
+ 4 files changed, 53 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+index 813f1b1480941..c8ca09f0e6274 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+@@ -487,6 +487,49 @@ static void vmw_user_bo_destroy(struct ttm_buffer_object *bo)
+ ttm_prime_object_kfree(vmw_user_bo, prime);
+ }
+
++/**
++ * vmw_bo_create_kernel - Create a pinned BO for internal kernel use.
++ *
++ * @dev_priv: Pointer to the device private struct
++ * @size: size of the BO we need
++ * @placement: where to put it
++ * @p_bo: resulting BO
++ *
++ * Creates and pin a simple BO for in kernel use.
++ */
++int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size,
++ struct ttm_placement *placement,
++ struct ttm_buffer_object **p_bo)
++{
++ unsigned npages = PAGE_ALIGN(size) >> PAGE_SHIFT;
++ struct ttm_operation_ctx ctx = { false, false };
++ struct ttm_buffer_object *bo;
++ size_t acc_size;
++ int ret;
++
++ bo = kzalloc(sizeof(*bo), GFP_KERNEL);
++ if (unlikely(!bo))
++ return -ENOMEM;
++
++ acc_size = ttm_round_pot(sizeof(*bo));
++ acc_size += ttm_round_pot(npages * sizeof(void *));
++ acc_size += ttm_round_pot(sizeof(struct ttm_tt));
++ ret = ttm_bo_init_reserved(&dev_priv->bdev, bo, size,
++ ttm_bo_type_device, placement, 0,
++ &ctx, acc_size, NULL, NULL, NULL);
++ if (unlikely(ret))
++ goto error_free;
++
++ ttm_bo_pin(bo);
++ ttm_bo_unreserve(bo);
++ *p_bo = bo;
++
++ return 0;
++
++error_free:
++ kfree(bo);
++ return ret;
++}
+
+ /**
+ * vmw_bo_init - Initialize a vmw buffer object
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+index 3b41cf63110ad..9a9fe10d829b8 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+@@ -1245,9 +1245,9 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man,
+ !dev_priv->has_mob)
+ return -ENOMEM;
+
+- ret = ttm_bo_create(&dev_priv->bdev, size, ttm_bo_type_device,
+- &vmw_mob_ne_placement, 0, false,
+- &man->cmd_space);
++ ret = vmw_bo_create_kernel(dev_priv, size,
++ &vmw_mob_placement,
++ &man->cmd_space);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+index 0a79c57c7db64..e6af950c40370 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+@@ -845,6 +845,10 @@ extern void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *buf,
+ SVGAGuestPtr *ptr);
+ extern void vmw_bo_pin_reserved(struct vmw_buffer_object *bo, bool pin);
+ extern void vmw_bo_bo_free(struct ttm_buffer_object *bo);
++extern int vmw_bo_create_kernel(struct vmw_private *dev_priv,
++ unsigned long size,
++ struct ttm_placement *placement,
++ struct ttm_buffer_object **p_bo);
+ extern int vmw_bo_init(struct vmw_private *dev_priv,
+ struct vmw_buffer_object *vmw_bo,
+ size_t size, struct ttm_placement *placement,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+index 73116ec70ba59..8abeef691ad29 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+@@ -817,11 +817,9 @@ int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
+ struct ttm_buffer_object *bo;
+ int ret;
+
+- ret = ttm_bo_create(&dev_priv->bdev, bo_size,
+- ttm_bo_type_device,
+- &vmw_sys_ne_placement,
+- 0, false, &bo);
+-
++ ret = vmw_bo_create_kernel(dev_priv, bo_size,
++ &vmw_sys_placement,
++ &bo);
+ if (unlikely(ret != 0))
+ return ret;
+
+--
+2.43.0
+
--- /dev/null
+From d43c32e37b480556e350deb013e56160ca2f41c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Sep 2020 14:37:25 +0200
+Subject: drm/vmwgfx: switch over to the new pin interface v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+[ Upstream commit fbe86ca567919b22bbba1220ce55020b1868879f ]
+
+Stop using TTM_PL_FLAG_NO_EVICT.
+
+v2: fix unconditional pinning
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Dave Airlie <airlied@redhat.com>
+Reviewed-by: Huang Rui <ray.huang@amd.com>
+Link: https://patchwork.freedesktop.org/patch/391601/?series=81973&rev=1
+Stable-dep-of: 517621b70600 ("drm/vmwgfx: Fix possible null pointer derefence with invalid contexts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_blit.c | 4 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 49 +++++++++++-----------
+ drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 4 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 7 +---
+ drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 2 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 4 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 4 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 4 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 42 -------------------
+ drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 2 +-
+ 11 files changed, 39 insertions(+), 85 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
+index e8d66182cd7b5..ea2f2f937eb30 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
+@@ -459,9 +459,9 @@ int vmw_bo_cpu_blit(struct ttm_buffer_object *dst,
+ int ret = 0;
+
+ /* Buffer objects need to be either pinned or reserved: */
+- if (!(dst->mem.placement & TTM_PL_FLAG_NO_EVICT))
++ if (!(dst->pin_count))
+ dma_resv_assert_held(dst->base.resv);
+- if (!(src->mem.placement & TTM_PL_FLAG_NO_EVICT))
++ if (!(src->pin_count))
+ dma_resv_assert_held(src->base.resv);
+
+ if (!ttm_tt_is_populated(dst->ttm)) {
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+index c8ca09f0e6274..9a66ba2543263 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+@@ -106,7 +106,7 @@ int vmw_bo_pin_in_placement(struct vmw_private *dev_priv,
+ if (unlikely(ret != 0))
+ goto err;
+
+- if (buf->pin_count > 0)
++ if (buf->base.pin_count > 0)
+ ret = ttm_bo_mem_compat(placement, &bo->mem,
+ &new_flags) == true ? 0 : -EINVAL;
+ else
+@@ -155,7 +155,7 @@ int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
+ if (unlikely(ret != 0))
+ goto err;
+
+- if (buf->pin_count > 0) {
++ if (buf->base.pin_count > 0) {
+ ret = ttm_bo_mem_compat(&vmw_vram_gmr_placement, &bo->mem,
+ &new_flags) == true ? 0 : -EINVAL;
+ goto out_unreserve;
+@@ -246,12 +246,12 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv,
+ if (bo->mem.mem_type == TTM_PL_VRAM &&
+ bo->mem.start < bo->num_pages &&
+ bo->mem.start > 0 &&
+- buf->pin_count == 0) {
++ buf->base.pin_count == 0) {
+ ctx.interruptible = false;
+ (void) ttm_bo_validate(bo, &vmw_sys_placement, &ctx);
+ }
+
+- if (buf->pin_count > 0)
++ if (buf->base.pin_count > 0)
+ ret = ttm_bo_mem_compat(&placement, &bo->mem,
+ &new_flags) == true ? 0 : -EINVAL;
+ else
+@@ -343,23 +343,13 @@ void vmw_bo_pin_reserved(struct vmw_buffer_object *vbo, bool pin)
+
+ dma_resv_assert_held(bo->base.resv);
+
+- if (pin) {
+- if (vbo->pin_count++ > 0)
+- return;
+- } else {
+- WARN_ON(vbo->pin_count <= 0);
+- if (--vbo->pin_count > 0)
+- return;
+- }
++ if (pin == !!bo->pin_count)
++ return;
+
+ pl.fpfn = 0;
+ pl.lpfn = 0;
+ pl.mem_type = bo->mem.mem_type;
+ pl.flags = bo->mem.placement;
+- if (pin)
+- pl.flags |= TTM_PL_FLAG_NO_EVICT;
+- else
+- pl.flags &= ~TTM_PL_FLAG_NO_EVICT;
+
+ memset(&placement, 0, sizeof(placement));
+ placement.num_placement = 1;
+@@ -368,8 +358,12 @@ void vmw_bo_pin_reserved(struct vmw_buffer_object *vbo, bool pin)
+ ret = ttm_bo_validate(bo, &placement, &ctx);
+
+ BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type);
+-}
+
++ if (pin)
++ ttm_bo_pin(bo);
++ else
++ ttm_bo_unpin(bo);
++}
+
+ /**
+ * vmw_bo_map_and_cache - Map a buffer object and cache the map
+@@ -539,6 +533,7 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size,
+ * @size: Buffer object size in bytes.
+ * @placement: Initial placement.
+ * @interruptible: Whether waits should be performed interruptible.
++ * @pin: If the BO should be created pinned at a fixed location.
+ * @bo_free: The buffer object destructor.
+ * Returns: Zero on success, negative error code on error.
+ *
+@@ -547,9 +542,10 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size,
+ int vmw_bo_init(struct vmw_private *dev_priv,
+ struct vmw_buffer_object *vmw_bo,
+ size_t size, struct ttm_placement *placement,
+- bool interruptible,
++ bool interruptible, bool pin,
+ void (*bo_free)(struct ttm_buffer_object *bo))
+ {
++ struct ttm_operation_ctx ctx = { interruptible, false };
+ struct ttm_bo_device *bdev = &dev_priv->bdev;
+ size_t acc_size;
+ int ret;
+@@ -563,11 +559,16 @@ int vmw_bo_init(struct vmw_private *dev_priv,
+ vmw_bo->base.priority = 3;
+ vmw_bo->res_tree = RB_ROOT;
+
+- ret = ttm_bo_init(bdev, &vmw_bo->base, size,
+- ttm_bo_type_device, placement,
+- 0, interruptible, acc_size,
+- NULL, NULL, bo_free);
+- return ret;
++ ret = ttm_bo_init_reserved(bdev, &vmw_bo->base, size,
++ ttm_bo_type_device, placement,
++ 0, &ctx, acc_size, NULL, NULL, bo_free);
++ if (unlikely(ret))
++ return ret;
++
++ if (pin)
++ ttm_bo_pin(&vmw_bo->base);
++ ttm_bo_unreserve(&vmw_bo->base);
++ return 0;
+ }
+
+
+@@ -656,7 +657,7 @@ int vmw_user_bo_alloc(struct vmw_private *dev_priv,
+ ret = vmw_bo_init(dev_priv, &user_bo->vbo, size,
+ (dev_priv->has_mob) ?
+ &vmw_sys_placement :
+- &vmw_vram_sys_placement, true,
++ &vmw_vram_sys_placement, true, false,
+ &vmw_user_bo_destroy);
+ if (unlikely(ret != 0))
+ return ret;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
+index 65e8e7a977246..984d8884357d9 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
+@@ -410,8 +410,8 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size)
+ if (!buf)
+ return -ENOMEM;
+
+- ret = vmw_bo_init(dev_priv, buf, new_size, &vmw_mob_ne_placement,
+- true, vmw_bo_bo_free);
++ ret = vmw_bo_init(dev_priv, buf, new_size, &vmw_mob_placement,
++ true, true, vmw_bo_bo_free);
+ if (ret) {
+ DRM_ERROR("Failed initializing new cotable MOB.\n");
+ return ret;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+index 31e3e5c9f3622..bdb7a5e965601 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -372,7 +372,7 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv)
+ return -ENOMEM;
+
+ ret = vmw_bo_init(dev_priv, vbo, PAGE_SIZE,
+- &vmw_sys_ne_placement, false,
++ &vmw_sys_placement, false, true,
+ &vmw_bo_bo_free);
+ if (unlikely(ret != 0))
+ return ret;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+index e6af950c40370..fa285c20d6dac 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+@@ -99,7 +99,6 @@ struct vmw_fpriv {
+ * struct vmw_buffer_object - TTM buffer object with vmwgfx additions
+ * @base: The TTM buffer object
+ * @res_tree: RB tree of resources using this buffer object as a backing MOB
+- * @pin_count: pin depth
+ * @cpu_writers: Number of synccpu write grabs. Protected by reservation when
+ * increased. May be decreased without reservation.
+ * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB
+@@ -110,7 +109,6 @@ struct vmw_fpriv {
+ struct vmw_buffer_object {
+ struct ttm_buffer_object base;
+ struct rb_root res_tree;
+- s32 pin_count;
+ atomic_t cpu_writers;
+ /* Not ref-counted. Protected by binding_mutex */
+ struct vmw_resource *dx_query_ctx;
+@@ -852,7 +850,7 @@ extern int vmw_bo_create_kernel(struct vmw_private *dev_priv,
+ extern int vmw_bo_init(struct vmw_private *dev_priv,
+ struct vmw_buffer_object *vmw_bo,
+ size_t size, struct ttm_placement *placement,
+- bool interruptible,
++ bool interruptible, bool pin,
+ void (*bo_free)(struct ttm_buffer_object *bo));
+ extern int vmw_user_bo_verify_access(struct ttm_buffer_object *bo,
+ struct ttm_object_file *tfile);
+@@ -1009,16 +1007,13 @@ extern void vmw_validation_mem_init_ttm(struct vmw_private *dev_priv,
+
+ extern const size_t vmw_tt_size;
+ extern struct ttm_placement vmw_vram_placement;
+-extern struct ttm_placement vmw_vram_ne_placement;
+ extern struct ttm_placement vmw_vram_sys_placement;
+ extern struct ttm_placement vmw_vram_gmr_placement;
+ extern struct ttm_placement vmw_vram_gmr_ne_placement;
+ extern struct ttm_placement vmw_sys_placement;
+-extern struct ttm_placement vmw_sys_ne_placement;
+ extern struct ttm_placement vmw_evictable_placement;
+ extern struct ttm_placement vmw_srf_placement;
+ extern struct ttm_placement vmw_mob_placement;
+-extern struct ttm_placement vmw_mob_ne_placement;
+ extern struct ttm_placement vmw_nonfixed_placement;
+ extern struct ttm_bo_driver vmw_bo_driver;
+ extern const struct vmw_sg_table *
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+index 97d9d2557447b..3923acc3ab1e5 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+@@ -406,7 +406,7 @@ static int vmw_fb_create_bo(struct vmw_private *vmw_priv,
+
+ ret = vmw_bo_init(vmw_priv, vmw_bo, size,
+ &vmw_sys_placement,
+- false,
++ false, false,
+ &vmw_bo_bo_free);
+ if (unlikely(ret != 0))
+ goto err_unlock; /* init frees the buffer on failure */
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+index c0f156078ddae..5e922d9d5f2cc 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+@@ -370,7 +370,7 @@ static int vmw_resource_buf_alloc(struct vmw_resource *res,
+
+ ret = vmw_bo_init(res->dev_priv, backup, res->backup_size,
+ res->func->backup_placement,
+- interruptible,
++ interruptible, false,
+ &vmw_bo_bo_free);
+ if (unlikely(ret != 0))
+ goto out_no_bo;
+@@ -1002,7 +1002,7 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible)
+ vbo = res->backup;
+
+ ttm_bo_reserve(&vbo->base, interruptible, false, NULL);
+- if (!vbo->pin_count) {
++ if (!vbo->base.pin_count) {
+ ret = ttm_bo_validate
+ (&vbo->base,
+ res->func->backup_placement,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+index 2b6590344468d..9c8109efefbd6 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+@@ -451,8 +451,8 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane,
+ */
+ vmw_overlay_pause_all(dev_priv);
+ ret = vmw_bo_init(dev_priv, vps->bo, size,
+- &vmw_vram_ne_placement,
+- false, &vmw_bo_bo_free);
++ &vmw_vram_placement,
++ false, true, &vmw_bo_bo_free);
+ vmw_overlay_resume_all(dev_priv);
+ if (ret) {
+ vps->bo = NULL; /* vmw_bo_init frees on error */
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+index e139fdfd16356..f328aa5839a22 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+@@ -978,8 +978,8 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
+ if (unlikely(!buf))
+ return -ENOMEM;
+
+- ret = vmw_bo_init(dev_priv, buf, size, &vmw_sys_ne_placement,
+- true, vmw_bo_bo_free);
++ ret = vmw_bo_init(dev_priv, buf, size, &vmw_sys_placement,
++ true, true, vmw_bo_bo_free);
+ if (unlikely(ret != 0))
+ goto out;
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+index 8abeef691ad29..89b3356ec27f0 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+@@ -37,13 +37,6 @@ static const struct ttm_place vram_placement_flags = {
+ .flags = TTM_PL_FLAG_CACHED
+ };
+
+-static const struct ttm_place vram_ne_placement_flags = {
+- .fpfn = 0,
+- .lpfn = 0,
+- .mem_type = TTM_PL_VRAM,
+- .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT
+-};
+-
+ static const struct ttm_place sys_placement_flags = {
+ .fpfn = 0,
+ .lpfn = 0,
+@@ -51,13 +44,6 @@ static const struct ttm_place sys_placement_flags = {
+ .flags = TTM_PL_FLAG_CACHED
+ };
+
+-static const struct ttm_place sys_ne_placement_flags = {
+- .fpfn = 0,
+- .lpfn = 0,
+- .mem_type = TTM_PL_SYSTEM,
+- .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT
+-};
+-
+ static const struct ttm_place gmr_placement_flags = {
+ .fpfn = 0,
+ .lpfn = 0,
+@@ -79,13 +65,6 @@ static const struct ttm_place mob_placement_flags = {
+ .flags = TTM_PL_FLAG_CACHED
+ };
+
+-static const struct ttm_place mob_ne_placement_flags = {
+- .fpfn = 0,
+- .lpfn = 0,
+- .mem_type = VMW_PL_MOB,
+- .flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT
+-};
+-
+ struct ttm_placement vmw_vram_placement = {
+ .num_placement = 1,
+ .placement = &vram_placement_flags,
+@@ -158,13 +137,6 @@ struct ttm_placement vmw_vram_sys_placement = {
+ .busy_placement = &sys_placement_flags
+ };
+
+-struct ttm_placement vmw_vram_ne_placement = {
+- .num_placement = 1,
+- .placement = &vram_ne_placement_flags,
+- .num_busy_placement = 1,
+- .busy_placement = &vram_ne_placement_flags
+-};
+-
+ struct ttm_placement vmw_sys_placement = {
+ .num_placement = 1,
+ .placement = &sys_placement_flags,
+@@ -172,13 +144,6 @@ struct ttm_placement vmw_sys_placement = {
+ .busy_placement = &sys_placement_flags
+ };
+
+-struct ttm_placement vmw_sys_ne_placement = {
+- .num_placement = 1,
+- .placement = &sys_ne_placement_flags,
+- .num_busy_placement = 1,
+- .busy_placement = &sys_ne_placement_flags
+-};
+-
+ static const struct ttm_place evictable_placement_flags[] = {
+ {
+ .fpfn = 0,
+@@ -243,13 +208,6 @@ struct ttm_placement vmw_mob_placement = {
+ .busy_placement = &mob_placement_flags
+ };
+
+-struct ttm_placement vmw_mob_ne_placement = {
+- .num_placement = 1,
+- .num_busy_placement = 1,
+- .placement = &mob_ne_placement_flags,
+- .busy_placement = &mob_ne_placement_flags
+-};
+-
+ struct ttm_placement vmw_nonfixed_placement = {
+ .num_placement = 3,
+ .placement = nonfixed_placement_flags,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
+index e69bc373ae2e5..f2e2bf6d1421f 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
+@@ -540,7 +540,7 @@ int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo,
+ if (atomic_read(&vbo->cpu_writers))
+ return -EBUSY;
+
+- if (vbo->pin_count > 0)
++ if (vbo->base.pin_count > 0)
+ return 0;
+
+ if (validate_as_mob)
+--
+2.43.0
+
--- /dev/null
+From e09932a0db5a6806780e673f1c0933d5d013f118 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jan 2021 18:13:12 +0000
+Subject: drm/vmwgfx/vmwgfx_cmdbuf_res: Remove unused variable 'ret'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit 43ebfe61c3928573a5ef8d80c2f5300aa5c904c0 ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c: In function ‘vmw_cmdbuf_res_revert’:
+ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c:162:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable]
+
+Cc: VMware Graphics <linux-graphics-maintainer@vmware.com>
+Cc: Roland Scheidegger <sroland@vmware.com>
+Cc: Zack Rusin <zackr@vmware.com>
+Cc: David Airlie <airlied@linux.ie>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: dri-devel@lists.freedesktop.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Zack Rusin <zackr@vmware.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210115181313.3431493-40-lee.jones@linaro.org
+Stable-dep-of: 517621b70600 ("drm/vmwgfx: Fix possible null pointer derefence with invalid contexts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
+index 44d858ce4ce7f..47b92d0c898a7 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
+@@ -160,7 +160,6 @@ void vmw_cmdbuf_res_commit(struct list_head *list)
+ void vmw_cmdbuf_res_revert(struct list_head *list)
+ {
+ struct vmw_cmdbuf_res *entry, *next;
+- int ret;
+
+ list_for_each_entry_safe(entry, next, list, head) {
+ switch (entry->state) {
+@@ -168,8 +167,7 @@ void vmw_cmdbuf_res_revert(struct list_head *list)
+ vmw_cmdbuf_res_free(entry->man, entry);
+ break;
+ case VMW_CMDBUF_RES_DEL:
+- ret = drm_ht_insert_item(&entry->man->resources,
+- &entry->hash);
++ drm_ht_insert_item(&entry->man->resources, &entry->hash);
+ list_del(&entry->head);
+ list_add_tail(&entry->head, &entry->man->list);
+ entry->state = VMW_CMDBUF_RES_COMMITTED;
+--
+2.43.0
+
--- /dev/null
+From 19183b5ea7e1a24f6335680fb4de16f335b4e060 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Feb 2024 22:18:45 +0800
+Subject: ext4: correct best extent lstart adjustment logic
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 4fbf8bc733d14bceb16dda46a3f5e19c6a9621c5 ]
+
+When yangerkun review commit 93cdf49f6eca ("ext4: Fix best extent lstart
+adjustment logic in ext4_mb_new_inode_pa()"), it was found that the best
+extent did not completely cover the original request after adjusting the
+best extent lstart in ext4_mb_new_inode_pa() as follows:
+
+ original request: 2/10(8)
+ normalized request: 0/64(64)
+ best extent: 0/9(9)
+
+When we check if best ex can be kept at start of goal, ac_o_ex.fe_logical
+is 2 less than the adjusted best extent logical end 9, so we think the
+adjustment is done. But obviously 0/9(9) doesn't cover 2/10(8), so we
+should determine here if the original request logical end is less than or
+equal to the adjusted best extent logical end.
+
+In addition, add a comment stating when adjusted best_ex will not cover
+the original request, and remove the duplicate assertion because adjusting
+lstart makes no change to b_ex.fe_len.
+
+Link: https://lore.kernel.org/r/3630fa7f-b432-7afd-5f79-781bc3b2c5ea@huawei.com
+Fixes: 93cdf49f6eca ("ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa()")
+Cc: <stable@kernel.org>
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240201141845.1879253-1-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 61988b7b5be77..6ce59e2ac2d47 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -4162,10 +4162,16 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ .fe_len = ac->ac_g_ex.fe_len,
+ };
+ loff_t orig_goal_end = extent_logical_end(sbi, &ex);
++ loff_t o_ex_end = extent_logical_end(sbi, &ac->ac_o_ex);
+
+- /* we can't allocate as much as normalizer wants.
+- * so, found space must get proper lstart
+- * to cover original request */
++ /*
++ * We can't allocate as much as normalizer wants, so we try
++ * to get proper lstart to cover the original request, except
++ * when the goal doesn't cover the original request as below:
++ *
++ * orig_ex:2045/2055(10), isize:8417280 -> normalized:0/2048
++ * best_ex:0/200(200) -> adjusted: 1848/2048(200)
++ */
+ BUG_ON(ac->ac_g_ex.fe_logical > ac->ac_o_ex.fe_logical);
+ BUG_ON(ac->ac_g_ex.fe_len < ac->ac_o_ex.fe_len);
+
+@@ -4177,7 +4183,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ * 1. Check if best ex can be kept at end of goal and still
+ * cover original start
+ * 2. Else, check if best ex can be kept at start of goal and
+- * still cover original start
++ * still cover original end
+ * 3. Else, keep the best ex at start of original request.
+ */
+ ex.fe_len = ac->ac_b_ex.fe_len;
+@@ -4187,7 +4193,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ goto adjust_bex;
+
+ ex.fe_logical = ac->ac_g_ex.fe_logical;
+- if (ac->ac_o_ex.fe_logical < extent_logical_end(sbi, &ex))
++ if (o_ex_end <= extent_logical_end(sbi, &ex))
+ goto adjust_bex;
+
+ ex.fe_logical = ac->ac_o_ex.fe_logical;
+@@ -4195,7 +4201,6 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ ac->ac_b_ex.fe_logical = ex.fe_logical;
+
+ BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
+- BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
+ BUG_ON(extent_logical_end(sbi, &ex) > orig_goal_end);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 51480a128f45c53876fed614c72708660dde505c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 15:50:09 +0000
+Subject: ext4: fix corruption during on-line resize
+
+From: Maximilian Heyne <mheyne@amazon.de>
+
+[ Upstream commit a6b3bfe176e8a5b05ec4447404e412c2a3fc92cc ]
+
+We observed a corruption during on-line resize of a file system that is
+larger than 16 TiB with 4k block size. With having more then 2^32 blocks
+resize_inode is turned off by default by mke2fs. The issue can be
+reproduced on a smaller file system for convenience by explicitly
+turning off resize_inode. An on-line resize across an 8 GiB boundary (the
+size of a meta block group in this setup) then leads to a corruption:
+
+ dev=/dev/<some_dev> # should be >= 16 GiB
+ mkdir -p /corruption
+ /sbin/mke2fs -t ext4 -b 4096 -O ^resize_inode $dev $((2 * 2**21 - 2**15))
+ mount -t ext4 $dev /corruption
+
+ dd if=/dev/zero bs=4096 of=/corruption/test count=$((2*2**21 - 4*2**15))
+ sha1sum /corruption/test
+ # 79d2658b39dcfd77274e435b0934028adafaab11 /corruption/test
+
+ /sbin/resize2fs $dev $((2*2**21))
+ # drop page cache to force reload the block from disk
+ echo 1 > /proc/sys/vm/drop_caches
+
+ sha1sum /corruption/test
+ # 3c2abc63cbf1a94c9e6977e0fbd72cd832c4d5c3 /corruption/test
+
+2^21 = 2^15*2^6 equals 8 GiB whereof 2^15 is the number of blocks per
+block group and 2^6 are the number of block groups that make a meta
+block group.
+
+The last checksum might be different depending on how the file is laid
+out across the physical blocks. The actual corruption occurs at physical
+block 63*2^15 = 2064384 which would be the location of the backup of the
+meta block group's block descriptor. During the on-line resize the file
+system will be converted to meta_bg starting at s_first_meta_bg which is
+2 in the example - meaning all block groups after 16 GiB. However, in
+ext4_flex_group_add we might add block groups that are not part of the
+first meta block group yet. In the reproducer we achieved this by
+substracting the size of a whole block group from the point where the
+meta block group would start. This must be considered when updating the
+backup block group descriptors to follow the non-meta_bg layout. The fix
+is to add a test whether the group to add is already part of the meta
+block group or not.
+
+Fixes: 01f795f9e0d67 ("ext4: add online resizing support for meta_bg and 64-bit file systems")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
+Tested-by: Srivathsa Dara <srivathsa.d.dara@oracle.com>
+Reviewed-by: Srivathsa Dara <srivathsa.d.dara@oracle.com>
+Link: https://lore.kernel.org/r/20240215155009.94493-1-mheyne@amazon.de
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/resize.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 06e0eaf2ea4e1..5d45ec29e61a6 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1545,7 +1545,8 @@ static int ext4_flex_group_add(struct super_block *sb,
+ int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+ int gdb_num_end = ((group + flex_gd->count - 1) /
+ EXT4_DESC_PER_BLOCK(sb));
+- int meta_bg = ext4_has_feature_meta_bg(sb);
++ int meta_bg = ext4_has_feature_meta_bg(sb) &&
++ gdb_num >= le32_to_cpu(es->s_first_meta_bg);
+ sector_t padding_blocks = meta_bg ? 0 : sbi->s_sbh->b_blocknr -
+ ext4_group_first_block_no(sb, 0);
+ sector_t old_gdb = 0;
+--
+2.43.0
+
--- /dev/null
+From 8ea651354ff60d607dc35f34975db5fd66464fc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Feb 2024 13:26:26 +0100
+Subject: fat: fix uninitialized field in nostale filehandles
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit fde2497d2bc3a063d8af88b258dbadc86bd7b57c ]
+
+When fat_encode_fh_nostale() encodes file handle without a parent it
+stores only first 10 bytes of the file handle. However the length of the
+file handle must be a multiple of 4 so the file handle is actually 12
+bytes long and the last two bytes remain uninitialized. This is not
+great at we potentially leak uninitialized information with the handle
+to userspace. Properly initialize the full handle length.
+
+Link: https://lkml.kernel.org/r/20240205122626.13701-1-jack@suse.cz
+Reported-by: syzbot+3ce5dea5b1539ff36769@syzkaller.appspotmail.com
+Fixes: ea3983ace6b7 ("fat: restructure export_operations")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Cc: Amir Goldstein <amir73il@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fat/nfs.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/fat/nfs.c b/fs/fat/nfs.c
+index af191371c3529..bab63eeaf9cbc 100644
+--- a/fs/fat/nfs.c
++++ b/fs/fat/nfs.c
+@@ -130,6 +130,12 @@ fat_encode_fh_nostale(struct inode *inode, __u32 *fh, int *lenp,
+ fid->parent_i_gen = parent->i_generation;
+ type = FILEID_FAT_WITH_PARENT;
+ *lenp = FAT_FID_SIZE_WITH_PARENT;
++ } else {
++ /*
++ * We need to initialize this field because the fh is actually
++ * 12 bytes long
++ */
++ fid->parent_i_pos_hi = 0;
+ }
+
+ return type;
+--
+2.43.0
+
--- /dev/null
+From 1d1a3dcaabf48c515ec575726aa68829983e4861 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Feb 2024 16:50:49 +0100
+Subject: fuse: don't unhash root
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+[ Upstream commit b1fe686a765e6c0d71811d825b5a1585a202b777 ]
+
+The root inode is assumed to be always hashed. Do not unhash the root
+inode even if it is marked BAD.
+
+Fixes: 5d069dbe8aaf ("fuse: fix bad inode")
+Cc: <stable@vger.kernel.org> # v5.11
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/fuse_i.h | 1 -
+ fs/fuse/inode.c | 7 +++++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index ceaa6868386e6..33eb5fefc06b4 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -873,7 +873,6 @@ static inline bool fuse_stale_inode(const struct inode *inode, int generation,
+
+ static inline void fuse_make_bad(struct inode *inode)
+ {
+- remove_inode_hash(inode);
+ set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state);
+ }
+
+diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
+index 9ea175ff9c8e6..4a7ebccd359ee 100644
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -352,8 +352,11 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
+ } else if (fuse_stale_inode(inode, generation, attr)) {
+ /* nodeid was reused, any I/O on the old inode should fail */
+ fuse_make_bad(inode);
+- iput(inode);
+- goto retry;
++ if (inode != d_inode(sb->s_root)) {
++ remove_inode_hash(inode);
++ iput(inode);
++ goto retry;
++ }
+ }
+ done:
+ fi = get_fuse_inode(inode);
+--
+2.43.0
+
--- /dev/null
+From fb8fa0a949ad56f652d8ff0d3d4b2571a9913300 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Feb 2024 16:50:49 +0100
+Subject: fuse: fix root lookup with nonzero generation
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+[ Upstream commit 68ca1b49e430f6534d0774a94147a823e3b8b26e ]
+
+The root inode has a fixed nodeid and generation (1, 0).
+
+Prior to the commit 15db16837a35 ("fuse: fix illegal access to inode with
+reused nodeid") generation number on lookup was ignored. After this commit
+lookup with the wrong generation number resulted in the inode being
+unhashed. This is correct for non-root inodes, but replacing the root
+inode is wrong and results in weird behavior.
+
+Fix by reverting to the old behavior if ignoring the generation for the
+root inode, but issuing a warning in dmesg.
+
+Reported-by: Antonio SJ Musumeci <trapexit@spawn.link>
+Closes: https://lore.kernel.org/all/CAOQ4uxhek5ytdN8Yz2tNEOg5ea4NkBb4nk0FGPjPk_9nz-VG3g@mail.gmail.com/
+Fixes: 15db16837a35 ("fuse: fix illegal access to inode with reused nodeid")
+Cc: <stable@vger.kernel.org> # v5.14
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/dir.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
+index b0c701c007c68..d131f34cd3e13 100644
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -451,6 +451,10 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name
+ goto out_put_forget;
+ if (fuse_invalid_attr(&outarg->attr))
+ goto out_put_forget;
++ if (outarg->nodeid == FUSE_ROOT_ID && outarg->generation != 0) {
++ pr_warn_once("root generation should be zero\n");
++ outarg->generation = 0;
++ }
+
+ *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
+ &outarg->attr, entry_attr_timeout(outarg),
+--
+2.43.0
+
--- /dev/null
+From e31c43a474db1421c7e947a47a2719bab01cc984 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 12:06:58 +0100
+Subject: hwmon: (amc6821) add of_match table
+
+From: Josua Mayer <josua@solid-run.com>
+
+[ Upstream commit 3f003fda98a7a8d5f399057d92e6ed56b468657c ]
+
+Add of_match table for "ti,amc6821" compatible string.
+This fixes automatic driver loading by userspace when using device-tree,
+and if built as a module like major linux distributions do.
+
+While devices probe just fine with i2c_device_id table, userspace can't
+match the "ti,amc6821" compatible string from dt with the plain
+"amc6821" device id. As a result, the kernel module can not be loaded.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+Link: https://lore.kernel.org/r/20240307-amc6821-of-match-v1-1-5f40464a3110@solid-run.com
+[groeck: Cleaned up patch description]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/amc6821.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c
+index 6b1ce2242c618..60dfdb0f55231 100644
+--- a/drivers/hwmon/amc6821.c
++++ b/drivers/hwmon/amc6821.c
+@@ -934,10 +934,21 @@ static const struct i2c_device_id amc6821_id[] = {
+
+ MODULE_DEVICE_TABLE(i2c, amc6821_id);
+
++static const struct of_device_id __maybe_unused amc6821_of_match[] = {
++ {
++ .compatible = "ti,amc6821",
++ .data = (void *)amc6821,
++ },
++ { }
++};
++
++MODULE_DEVICE_TABLE(of, amc6821_of_match);
++
+ static struct i2c_driver amc6821_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "amc6821",
++ .of_match_table = of_match_ptr(amc6821_of_match),
+ },
+ .probe_new = amc6821_probe,
+ .id_table = amc6821_id,
+--
+2.43.0
+
--- /dev/null
+From ed1a32846999c2a104178c64a59aa81bcc2c80db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 15:12:47 -0700
+Subject: kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 75b5ab134bb5f657ef7979a59106dce0657e8d87 ]
+
+Clang enables -Wenum-enum-conversion and -Wenum-compare-conditional
+under -Wenum-conversion. A recent change in Clang strengthened these
+warnings and they appear frequently in common builds, primarily due to
+several instances in common headers but there are quite a few drivers
+that have individual instances as well.
+
+ include/linux/vmstat.h:508:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
+ 508 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
+ | ~~~~~~~~~~~~~~~~~~~~~ ^
+ 509 | item];
+ | ~~~~
+
+ drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c:955:24: warning: conditional expression between different enumeration types ('enum iwl_mac_beacon_flags' and 'enum iwl_mac_beacon_flags_v1') [-Wenum-compare-conditional]
+ 955 | flags |= is_new_rate ? IWL_MAC_BEACON_CCK
+ | ^ ~~~~~~~~~~~~~~~~~~
+ 956 | : IWL_MAC_BEACON_CCK_V1;
+ | ~~~~~~~~~~~~~~~~~~~~~
+ drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c:1120:21: warning: conditional expression between different enumeration types ('enum iwl_mac_beacon_flags' and 'enum iwl_mac_beacon_flags_v1') [-Wenum-compare-conditional]
+ 1120 | 0) > 10 ?
+ | ^
+ 1121 | IWL_MAC_BEACON_FILS :
+ | ~~~~~~~~~~~~~~~~~~~
+ 1122 | IWL_MAC_BEACON_FILS_V1;
+ | ~~~~~~~~~~~~~~~~~~~~~~
+
+Doing arithmetic between or returning two different types of enums could
+be a bug, so each of the instance of the warning needs to be evaluated.
+Unfortunately, as mentioned above, there are many instances of this
+warning in many different configurations, which can break the build when
+CONFIG_WERROR is enabled.
+
+To avoid introducing new instances of the warnings while cleaning up the
+disruption for the majority of users, disable these warnings for the
+default build while leaving them on for W=1 builds.
+
+Cc: stable@vger.kernel.org
+Closes: https://github.com/ClangBuiltLinux/linux/issues/2002
+Link: https://github.com/llvm/llvm-project/commit/8c2ae42b3e1c6aa7c18f873edcebff7c0b45a37e
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/Makefile.extrawarn | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
+index fe327a4532ddb..eb01e8d07e280 100644
+--- a/scripts/Makefile.extrawarn
++++ b/scripts/Makefile.extrawarn
+@@ -53,6 +53,8 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
+ KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
+ KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
+ KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict)
++KBUILD_CFLAGS += -Wno-enum-compare-conditional
++KBUILD_CFLAGS += -Wno-enum-enum-conversion
+ endif
+
+ endif
+--
+2.43.0
+
--- /dev/null
+From 2a0bae53bf0afae406eea688415444a516f27bc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 17:15:30 -0800
+Subject: KVM: Always flush async #PF workqueue when vCPU is being destroyed
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 3d75b8aa5c29058a512db29da7cbee8052724157 ]
+
+Always flush the per-vCPU async #PF workqueue when a vCPU is clearing its
+completion queue, e.g. when a VM and all its vCPUs is being destroyed.
+KVM must ensure that none of its workqueue callbacks is running when the
+last reference to the KVM _module_ is put. Gifting a reference to the
+associated VM prevents the workqueue callback from dereferencing freed
+vCPU/VM memory, but does not prevent the KVM module from being unloaded
+before the callback completes.
+
+Drop the misguided VM refcount gifting, as calling kvm_put_kvm() from
+async_pf_execute() if kvm_put_kvm() flushes the async #PF workqueue will
+result in deadlock. async_pf_execute() can't return until kvm_put_kvm()
+finishes, and kvm_put_kvm() can't return until async_pf_execute() finishes:
+
+ WARNING: CPU: 8 PID: 251 at virt/kvm/kvm_main.c:1435 kvm_put_kvm+0x2d/0x320 [kvm]
+ Modules linked in: vhost_net vhost vhost_iotlb tap kvm_intel kvm irqbypass
+ CPU: 8 PID: 251 Comm: kworker/8:1 Tainted: G W 6.6.0-rc1-e7af8d17224a-x86/gmem-vm #119
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+ Workqueue: events async_pf_execute [kvm]
+ RIP: 0010:kvm_put_kvm+0x2d/0x320 [kvm]
+ Call Trace:
+ <TASK>
+ async_pf_execute+0x198/0x260 [kvm]
+ process_one_work+0x145/0x2d0
+ worker_thread+0x27e/0x3a0
+ kthread+0xba/0xe0
+ ret_from_fork+0x2d/0x50
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+ ---[ end trace 0000000000000000 ]---
+ INFO: task kworker/8:1:251 blocked for more than 120 seconds.
+ Tainted: G W 6.6.0-rc1-e7af8d17224a-x86/gmem-vm #119
+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ task:kworker/8:1 state:D stack:0 pid:251 ppid:2 flags:0x00004000
+ Workqueue: events async_pf_execute [kvm]
+ Call Trace:
+ <TASK>
+ __schedule+0x33f/0xa40
+ schedule+0x53/0xc0
+ schedule_timeout+0x12a/0x140
+ __wait_for_common+0x8d/0x1d0
+ __flush_work.isra.0+0x19f/0x2c0
+ kvm_clear_async_pf_completion_queue+0x129/0x190 [kvm]
+ kvm_arch_destroy_vm+0x78/0x1b0 [kvm]
+ kvm_put_kvm+0x1c1/0x320 [kvm]
+ async_pf_execute+0x198/0x260 [kvm]
+ process_one_work+0x145/0x2d0
+ worker_thread+0x27e/0x3a0
+ kthread+0xba/0xe0
+ ret_from_fork+0x2d/0x50
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+
+If kvm_clear_async_pf_completion_queue() actually flushes the workqueue,
+then there's no need to gift async_pf_execute() a reference because all
+invocations of async_pf_execute() will be forced to complete before the
+vCPU and its VM are destroyed/freed. And that in turn fixes the module
+unloading bug as __fput() won't do module_put() on the last vCPU reference
+until the vCPU has been freed, e.g. if closing the vCPU file also puts the
+last reference to the KVM module.
+
+Note that kvm_check_async_pf_completion() may also take the work item off
+the completion queue and so also needs to flush the work queue, as the
+work will not be seen by kvm_clear_async_pf_completion_queue(). Waiting
+on the workqueue could theoretically delay a vCPU due to waiting for the
+work to complete, but that's a very, very small chance, and likely a very
+small delay. kvm_arch_async_page_present_queued() unconditionally makes a
+new request, i.e. will effectively delay entering the guest, so the
+remaining work is really just:
+
+ trace_kvm_async_pf_completed(addr, cr2_or_gpa);
+
+ __kvm_vcpu_wake_up(vcpu);
+
+ mmput(mm);
+
+and mmput() can't drop the last reference to the page tables if the vCPU is
+still alive, i.e. the vCPU won't get stuck tearing down page tables.
+
+Add a helper to do the flushing, specifically to deal with "wakeup all"
+work items, as they aren't actually work items, i.e. are never placed in a
+workqueue. Trying to flush a bogus workqueue entry rightly makes
+__flush_work() complain (kudos to whoever added that sanity check).
+
+Note, commit 5f6de5cbebee ("KVM: Prevent module exit until all VMs are
+freed") *tried* to fix the module refcounting issue by having VMs grab a
+reference to the module, but that only made the bug slightly harder to hit
+as it gave async_pf_execute() a bit more time to complete before the KVM
+module could be unloaded.
+
+Fixes: af585b921e5d ("KVM: Halt vcpu if page it tries to access is swapped out")
+Cc: stable@vger.kernel.org
+Cc: David Matlack <dmatlack@google.com>
+Reviewed-by: Xu Yilun <yilun.xu@intel.com>
+Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Link: https://lore.kernel.org/r/20240110011533.503302-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ virt/kvm/async_pf.c | 31 ++++++++++++++++++++++++++-----
+ 1 file changed, 26 insertions(+), 5 deletions(-)
+
+diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c
+index dd777688d14a9..952afb1bc83b4 100644
+--- a/virt/kvm/async_pf.c
++++ b/virt/kvm/async_pf.c
+@@ -88,7 +88,27 @@ static void async_pf_execute(struct work_struct *work)
+ rcuwait_wake_up(&vcpu->wait);
+
+ mmput(mm);
+- kvm_put_kvm(vcpu->kvm);
++}
++
++static void kvm_flush_and_free_async_pf_work(struct kvm_async_pf *work)
++{
++ /*
++ * The async #PF is "done", but KVM must wait for the work item itself,
++ * i.e. async_pf_execute(), to run to completion. If KVM is a module,
++ * KVM must ensure *no* code owned by the KVM (the module) can be run
++ * after the last call to module_put(). Note, flushing the work item
++ * is always required when the item is taken off the completion queue.
++ * E.g. even if the vCPU handles the item in the "normal" path, the VM
++ * could be terminated before async_pf_execute() completes.
++ *
++ * Wake all events skip the queue and go straight done, i.e. don't
++ * need to be flushed (but sanity check that the work wasn't queued).
++ */
++ if (work->wakeup_all)
++ WARN_ON_ONCE(work->work.func);
++ else
++ flush_work(&work->work);
++ kmem_cache_free(async_pf_cache, work);
+ }
+
+ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
+@@ -115,7 +135,6 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
+ #else
+ if (cancel_work_sync(&work->work)) {
+ mmput(work->mm);
+- kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */
+ kmem_cache_free(async_pf_cache, work);
+ }
+ #endif
+@@ -127,7 +146,10 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
+ list_first_entry(&vcpu->async_pf.done,
+ typeof(*work), link);
+ list_del(&work->link);
+- kmem_cache_free(async_pf_cache, work);
++
++ spin_unlock(&vcpu->async_pf.lock);
++ kvm_flush_and_free_async_pf_work(work);
++ spin_lock(&vcpu->async_pf.lock);
+ }
+ spin_unlock(&vcpu->async_pf.lock);
+
+@@ -152,7 +174,7 @@ void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)
+
+ list_del(&work->queue);
+ vcpu->async_pf.queued--;
+- kmem_cache_free(async_pf_cache, work);
++ kvm_flush_and_free_async_pf_work(work);
+ }
+ }
+
+@@ -187,7 +209,6 @@ bool kvm_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
+ work->arch = *arch;
+ work->mm = current->mm;
+ mmget(work->mm);
+- kvm_get_kvm(work->vcpu->kvm);
+
+ INIT_WORK(&work->work, async_pf_execute);
+
+--
+2.43.0
+
--- /dev/null
+From 04a80b4287a734d61e96b8255fc3663fd4f3e14b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Feb 2024 19:38:39 +0300
+Subject: mac802154: fix llsec key resources release in mac802154_llsec_key_del
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit e8a1e58345cf40b7b272e08ac7b32328b2543e40 ]
+
+mac802154_llsec_key_del() can free resources of a key directly without
+following the RCU rules for waiting before the end of a grace period. This
+may lead to use-after-free in case llsec_lookup_key() is traversing the
+list of keys in parallel with a key deletion:
+
+refcount_t: addition on 0; use-after-free.
+WARNING: CPU: 4 PID: 16000 at lib/refcount.c:25 refcount_warn_saturate+0x162/0x2a0
+Modules linked in:
+CPU: 4 PID: 16000 Comm: wpan-ping Not tainted 6.7.0 #19
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
+RIP: 0010:refcount_warn_saturate+0x162/0x2a0
+Call Trace:
+ <TASK>
+ llsec_lookup_key.isra.0+0x890/0x9e0
+ mac802154_llsec_encrypt+0x30c/0x9c0
+ ieee802154_subif_start_xmit+0x24/0x1e0
+ dev_hard_start_xmit+0x13e/0x690
+ sch_direct_xmit+0x2ae/0xbc0
+ __dev_queue_xmit+0x11dd/0x3c20
+ dgram_sendmsg+0x90b/0xd60
+ __sys_sendto+0x466/0x4c0
+ __x64_sys_sendto+0xe0/0x1c0
+ do_syscall_64+0x45/0xf0
+ entry_SYSCALL_64_after_hwframe+0x6e/0x76
+
+Also, ieee802154_llsec_key_entry structures are not freed by
+mac802154_llsec_key_del():
+
+unreferenced object 0xffff8880613b6980 (size 64):
+ comm "iwpan", pid 2176, jiffies 4294761134 (age 60.475s)
+ hex dump (first 32 bytes):
+ 78 0d 8f 18 80 88 ff ff 22 01 00 00 00 00 ad de x.......".......
+ 00 00 00 00 00 00 00 00 03 00 cd ab 00 00 00 00 ................
+ backtrace:
+ [<ffffffff81dcfa62>] __kmem_cache_alloc_node+0x1e2/0x2d0
+ [<ffffffff81c43865>] kmalloc_trace+0x25/0xc0
+ [<ffffffff88968b09>] mac802154_llsec_key_add+0xac9/0xcf0
+ [<ffffffff8896e41a>] ieee802154_add_llsec_key+0x5a/0x80
+ [<ffffffff8892adc6>] nl802154_add_llsec_key+0x426/0x5b0
+ [<ffffffff86ff293e>] genl_family_rcv_msg_doit+0x1fe/0x2f0
+ [<ffffffff86ff46d1>] genl_rcv_msg+0x531/0x7d0
+ [<ffffffff86fee7a9>] netlink_rcv_skb+0x169/0x440
+ [<ffffffff86ff1d88>] genl_rcv+0x28/0x40
+ [<ffffffff86fec15c>] netlink_unicast+0x53c/0x820
+ [<ffffffff86fecd8b>] netlink_sendmsg+0x93b/0xe60
+ [<ffffffff86b91b35>] ____sys_sendmsg+0xac5/0xca0
+ [<ffffffff86b9c3dd>] ___sys_sendmsg+0x11d/0x1c0
+ [<ffffffff86b9c65a>] __sys_sendmsg+0xfa/0x1d0
+ [<ffffffff88eadbf5>] do_syscall_64+0x45/0xf0
+ [<ffffffff890000ea>] entry_SYSCALL_64_after_hwframe+0x6e/0x76
+
+Handle the proper resource release in the RCU callback function
+mac802154_llsec_key_del_rcu().
+
+Note that if llsec_lookup_key() finds a key, it gets a refcount via
+llsec_key_get() and locally copies key id from key_entry (which is a
+list element). So it's safe to call llsec_key_put() and free the list
+entry after the RCU grace period elapses.
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: 5d637d5aabd8 ("mac802154: add llsec structures and mutators")
+Cc: stable@vger.kernel.org
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Alexander Aring <aahringo@redhat.com>
+Message-ID: <20240228163840.6667-1-pchelkin@ispras.ru>
+Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/cfg802154.h | 1 +
+ net/mac802154/llsec.c | 18 +++++++++++++-----
+ 2 files changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
+index 6ed07844eb244..5290781abba3d 100644
+--- a/include/net/cfg802154.h
++++ b/include/net/cfg802154.h
+@@ -257,6 +257,7 @@ struct ieee802154_llsec_key {
+
+ struct ieee802154_llsec_key_entry {
+ struct list_head list;
++ struct rcu_head rcu;
+
+ struct ieee802154_llsec_key_id id;
+ struct ieee802154_llsec_key *key;
+diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
+index 55550ead2ced8..a4cc9d077c59c 100644
+--- a/net/mac802154/llsec.c
++++ b/net/mac802154/llsec.c
+@@ -265,19 +265,27 @@ int mac802154_llsec_key_add(struct mac802154_llsec *sec,
+ return -ENOMEM;
+ }
+
++static void mac802154_llsec_key_del_rcu(struct rcu_head *rcu)
++{
++ struct ieee802154_llsec_key_entry *pos;
++ struct mac802154_llsec_key *mkey;
++
++ pos = container_of(rcu, struct ieee802154_llsec_key_entry, rcu);
++ mkey = container_of(pos->key, struct mac802154_llsec_key, key);
++
++ llsec_key_put(mkey);
++ kfree_sensitive(pos);
++}
++
+ int mac802154_llsec_key_del(struct mac802154_llsec *sec,
+ const struct ieee802154_llsec_key_id *key)
+ {
+ struct ieee802154_llsec_key_entry *pos;
+
+ list_for_each_entry(pos, &sec->table.keys, list) {
+- struct mac802154_llsec_key *mkey;
+-
+- mkey = container_of(pos->key, struct mac802154_llsec_key, key);
+-
+ if (llsec_key_id_equal(&pos->id, key)) {
+ list_del_rcu(&pos->list);
+- llsec_key_put(mkey);
++ call_rcu(&pos->rcu, mac802154_llsec_key_del_rcu);
+ return 0;
+ }
+ }
+--
+2.43.0
+
--- /dev/null
+From c30cc09293e1041dde8e823db36f68020e9b9ac5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 17:09:09 +0900
+Subject: media: staging: ipu3-imgu: Set fields before media_entity_pads_init()
+
+From: Hidenori Kobayashi <hidenorik@chromium.org>
+
+[ Upstream commit 87318b7092670d4086bfec115a0280a60c51c2dd ]
+
+The imgu driver fails to probe with the following message because it
+does not set the pad's flags before calling media_entity_pads_init().
+
+[ 14.596315] ipu3-imgu 0000:00:05.0: failed initialize subdev media entity (-22)
+[ 14.596322] ipu3-imgu 0000:00:05.0: failed to register subdev0 ret (-22)
+[ 14.596327] ipu3-imgu 0000:00:05.0: failed to register pipes (-22)
+[ 14.596331] ipu3-imgu 0000:00:05.0: failed to create V4L2 devices (-22)
+
+Fix the initialization order so that the driver probe succeeds. The ops
+initialization is also moved together for readability.
+
+Fixes: a0ca1627b450 ("media: staging/intel-ipu3: Add v4l2 driver based on media framework")
+Cc: <stable@vger.kernel.org> # 6.7
+Cc: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Hidenori Kobayashi <hidenorik@chromium.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/ipu3/ipu3-v4l2.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
+index 103f84466f6fc..371117b511e21 100644
+--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
+@@ -1063,6 +1063,11 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
+ struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];
+
+ /* Initialize subdev media entity */
++ imgu_sd->subdev.entity.ops = &imgu_media_ops;
++ for (i = 0; i < IMGU_NODE_NUM; i++) {
++ imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ?
++ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
++ }
+ r = media_entity_pads_init(&imgu_sd->subdev.entity, IMGU_NODE_NUM,
+ imgu_sd->subdev_pads);
+ if (r) {
+@@ -1070,11 +1075,6 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
+ "failed initialize subdev media entity (%d)\n", r);
+ return r;
+ }
+- imgu_sd->subdev.entity.ops = &imgu_media_ops;
+- for (i = 0; i < IMGU_NODE_NUM; i++) {
+- imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ?
+- MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+- }
+
+ /* Initialize subdev */
+ v4l2_subdev_init(&imgu_sd->subdev, &imgu_subdev_ops);
+@@ -1169,15 +1169,15 @@ static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe,
+ }
+
+ /* Initialize media entities */
++ node->vdev_pad.flags = node->output ?
++ MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
++ vdev->entity.ops = NULL;
+ r = media_entity_pads_init(&vdev->entity, 1, &node->vdev_pad);
+ if (r) {
+ dev_err(dev, "failed initialize media entity (%d)\n", r);
+ mutex_destroy(&node->lock);
+ return r;
+ }
+- node->vdev_pad.flags = node->output ?
+- MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
+- vdev->entity.ops = NULL;
+
+ /* Initialize vbq */
+ vbq->type = node->vdev_fmt.type;
+--
+2.43.0
+
--- /dev/null
+From 21d97f1bb55c29eb4f3f3c24e9913cfa6e68d291 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 13:50:30 +0800
+Subject: media: xc4000: Fix atomicity violation in xc4000_get_frequency
+
+From: Gui-Dong Han <2045gemini@gmail.com>
+
+[ Upstream commit 36d503ad547d1c75758a6fcdbec2806f1b6aeb41 ]
+
+In xc4000_get_frequency():
+ *freq = priv->freq_hz + priv->freq_offset;
+The code accesses priv->freq_hz and priv->freq_offset without holding any
+lock.
+
+In xc4000_set_params():
+ // Code that updates priv->freq_hz and priv->freq_offset
+ ...
+
+xc4000_get_frequency() and xc4000_set_params() may execute concurrently,
+risking inconsistent reads of priv->freq_hz and priv->freq_offset. Since
+these related data may update during reading, it can result in incorrect
+frequency calculation, leading to atomicity violations.
+
+This possible bug is found by an experimental static analysis tool
+developed by our team, BassCheck[1]. This tool analyzes the locking APIs
+to extract function pairs that can be concurrently executed, and then
+analyzes the instructions in the paired functions to identify possible
+concurrency bugs including data races and atomicity violations. The above
+possible bug is reported when our tool analyzes the source code of
+Linux 6.2.
+
+To address this issue, it is proposed to add a mutex lock pair in
+xc4000_get_frequency() to ensure atomicity. With this patch applied, our
+tool no longer reports the possible bug, with the kernel configuration
+allyesconfig for x86_64. Due to the lack of associated hardware, we cannot
+test the patch in runtime testing, and just verify it according to the
+code logic.
+
+[1] https://sites.google.com/view/basscheck/
+
+Fixes: 4c07e32884ab ("[media] xc4000: Fix get_frequency()")
+Cc: stable@vger.kernel.org
+Reported-by: BassCheck <bass@buaa.edu.cn>
+Signed-off-by: Gui-Dong Han <2045gemini@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/tuners/xc4000.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
+index ef9af052007cb..849df4d1c573c 100644
+--- a/drivers/media/tuners/xc4000.c
++++ b/drivers/media/tuners/xc4000.c
+@@ -1517,10 +1517,10 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
+ {
+ struct xc4000_priv *priv = fe->tuner_priv;
+
++ mutex_lock(&priv->lock);
+ *freq = priv->freq_hz + priv->freq_offset;
+
+ if (debug) {
+- mutex_lock(&priv->lock);
+ if ((priv->cur_fw.type
+ & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
+ u16 snr = 0;
+@@ -1531,8 +1531,8 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
+ return 0;
+ }
+ }
+- mutex_unlock(&priv->lock);
+ }
++ mutex_unlock(&priv->lock);
+
+ dprintk(1, "%s()\n", __func__);
+
+--
+2.43.0
+
--- /dev/null
+From 15be35372524b63d964ac36f212f6b04f85977cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 16:04:23 +0800
+Subject: memtest: use {READ,WRITE}_ONCE in memory scanning
+
+From: Qiang Zhang <qiang4.zhang@intel.com>
+
+[ Upstream commit 82634d7e24271698e50a3ec811e5f50de790a65f ]
+
+memtest failed to find bad memory when compiled with clang. So use
+{WRITE,READ}_ONCE to access memory to avoid compiler over optimization.
+
+Link: https://lkml.kernel.org/r/20240312080422.691222-1-qiang4.zhang@intel.com
+Signed-off-by: Qiang Zhang <qiang4.zhang@intel.com>
+Cc: Bill Wendling <morbo@google.com>
+Cc: Justin Stitt <justinstitt@google.com>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memtest.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/memtest.c b/mm/memtest.c
+index f53ace709ccd8..d407373f225b4 100644
+--- a/mm/memtest.c
++++ b/mm/memtest.c
+@@ -46,10 +46,10 @@ static void __init memtest(u64 pattern, phys_addr_t start_phys, phys_addr_t size
+ last_bad = 0;
+
+ for (p = start; p < end; p++)
+- *p = pattern;
++ WRITE_ONCE(*p, pattern);
+
+ for (p = start; p < end; p++, start_phys_aligned += incr) {
+- if (*p == pattern)
++ if (READ_ONCE(*p) == pattern)
+ continue;
+ if (start_phys_aligned == last_bad + incr) {
+ last_bad += incr;
+--
+2.43.0
+
--- /dev/null
+From 01c918ea3e4f7778cef3a485cedc774e4cfb77fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Mar 2024 14:03:56 +0000
+Subject: mm: swap: fix race between free_swap_and_cache() and swapoff()
+
+From: Ryan Roberts <ryan.roberts@arm.com>
+
+[ Upstream commit 82b1c07a0af603e3c47b906c8e991dc96f01688e ]
+
+There was previously a theoretical window where swapoff() could run and
+teardown a swap_info_struct while a call to free_swap_and_cache() was
+running in another thread. This could cause, amongst other bad
+possibilities, swap_page_trans_huge_swapped() (called by
+free_swap_and_cache()) to access the freed memory for swap_map.
+
+This is a theoretical problem and I haven't been able to provoke it from a
+test case. But there has been agreement based on code review that this is
+possible (see link below).
+
+Fix it by using get_swap_device()/put_swap_device(), which will stall
+swapoff(). There was an extra check in _swap_info_get() to confirm that
+the swap entry was not free. This isn't present in get_swap_device()
+because it doesn't make sense in general due to the race between getting
+the reference and swapoff. So I've added an equivalent check directly in
+free_swap_and_cache().
+
+Details of how to provoke one possible issue (thanks to David Hildenbrand
+for deriving this):
+
+--8<-----
+
+__swap_entry_free() might be the last user and result in
+"count == SWAP_HAS_CACHE".
+
+swapoff->try_to_unuse() will stop as soon as soon as si->inuse_pages==0.
+
+So the question is: could someone reclaim the folio and turn
+si->inuse_pages==0, before we completed swap_page_trans_huge_swapped().
+
+Imagine the following: 2 MiB folio in the swapcache. Only 2 subpages are
+still references by swap entries.
+
+Process 1 still references subpage 0 via swap entry.
+Process 2 still references subpage 1 via swap entry.
+
+Process 1 quits. Calls free_swap_and_cache().
+-> count == SWAP_HAS_CACHE
+[then, preempted in the hypervisor etc.]
+
+Process 2 quits. Calls free_swap_and_cache().
+-> count == SWAP_HAS_CACHE
+
+Process 2 goes ahead, passes swap_page_trans_huge_swapped(), and calls
+__try_to_reclaim_swap().
+
+__try_to_reclaim_swap()->folio_free_swap()->delete_from_swap_cache()->
+put_swap_folio()->free_swap_slot()->swapcache_free_entries()->
+swap_entry_free()->swap_range_free()->
+...
+WRITE_ONCE(si->inuse_pages, si->inuse_pages - nr_entries);
+
+What stops swapoff to succeed after process 2 reclaimed the swap cache
+but before process1 finished its call to swap_page_trans_huge_swapped()?
+
+--8<-----
+
+Link: https://lkml.kernel.org/r/20240306140356.3974886-1-ryan.roberts@arm.com
+Fixes: 7c00bafee87c ("mm/swap: free swap slots in batch")
+Closes: https://lore.kernel.org/linux-mm/65a66eb9-41f8-4790-8db2-0c70ea15979f@redhat.com/
+Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: "Huang, Ying" <ying.huang@intel.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/swapfile.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/mm/swapfile.c b/mm/swapfile.c
+index 86ade667a7af6..4ca1d04d8732f 100644
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -1271,6 +1271,11 @@ static unsigned char __swap_entry_free_locked(struct swap_info_struct *p,
+ }
+
+ /*
++ * Note that when only holding the PTL, swapoff might succeed immediately
++ * after freeing a swap entry. Therefore, immediately after
++ * __swap_entry_free(), the swap info might become stale and should not
++ * be touched without a prior get_swap_device().
++ *
+ * Check whether swap entry is valid in the swap device. If so,
+ * return pointer to swap_info_struct, and keep the swap entry valid
+ * via preventing the swap device from being swapoff, until
+@@ -1797,13 +1802,19 @@ int free_swap_and_cache(swp_entry_t entry)
+ if (non_swap_entry(entry))
+ return 1;
+
+- p = _swap_info_get(entry);
++ p = get_swap_device(entry);
+ if (p) {
++ if (WARN_ON(data_race(!p->swap_map[swp_offset(entry)]))) {
++ put_swap_device(p);
++ return 0;
++ }
++
+ count = __swap_entry_free(p, entry);
+ if (count == SWAP_HAS_CACHE &&
+ !swap_page_trans_huge_swapped(p, entry))
+ __try_to_reclaim_swap(p, swp_offset(entry),
+ TTRS_UNMAPPED | TTRS_FULL);
++ put_swap_device(p);
+ }
+ return p != NULL;
+ }
+--
+2.43.0
+
--- /dev/null
+From 97952ccb21447f4a11ddb26e4a44593f2c403bbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Mar 2024 10:44:38 +0900
+Subject: mmc: core: Fix switch on gp3 partition
+
+From: Dominique Martinet <dominique.martinet@atmark-techno.com>
+
+[ Upstream commit 4af59a8df5ea930038cd3355e822f5eedf4accc1 ]
+
+Commit e7794c14fd73 ("mmc: rpmb: fixes pause retune on all RPMB
+partitions.") added a mask check for 'part_type', but the mask used was
+wrong leading to the code intended for rpmb also being executed for GP3.
+
+On some MMCs (but not all) this would make gp3 partition inaccessible:
+armadillo:~# head -c 1 < /dev/mmcblk2gp3
+head: standard input: I/O error
+armadillo:~# dmesg -c
+[ 422.976583] mmc2: running CQE recovery
+[ 423.058182] mmc2: running CQE recovery
+[ 423.137607] mmc2: running CQE recovery
+[ 423.137802] blk_update_request: I/O error, dev mmcblk2gp3, sector 0 op 0x0:(READ) flags 0x80700 phys_seg 4 prio class 0
+[ 423.237125] mmc2: running CQE recovery
+[ 423.318206] mmc2: running CQE recovery
+[ 423.397680] mmc2: running CQE recovery
+[ 423.397837] blk_update_request: I/O error, dev mmcblk2gp3, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
+[ 423.408287] Buffer I/O error on dev mmcblk2gp3, logical block 0, async page read
+
+the part_type values of interest here are defined as follow:
+main 0
+boot0 1
+boot1 2
+rpmb 3
+gp0 4
+gp1 5
+gp2 6
+gp3 7
+
+so mask with EXT_CSD_PART_CONFIG_ACC_MASK (7) to correctly identify rpmb
+
+Fixes: e7794c14fd73 ("mmc: rpmb: fixes pause retune on all RPMB partitions.")
+Cc: stable@vger.kernel.org
+Cc: Jorge Ramirez-Ortiz <jorge@foundries.io>
+Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20240306-mmc-partswitch-v1-1-bf116985d950@codewreck.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/block.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index 2058f31a1bce6..d826a1bb39f2c 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -823,10 +823,11 @@ static const struct block_device_operations mmc_bdops = {
+ static int mmc_blk_part_switch_pre(struct mmc_card *card,
+ unsigned int part_type)
+ {
+- const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
++ const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK;
++ const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB;
+ int ret = 0;
+
+- if ((part_type & mask) == mask) {
++ if ((part_type & mask) == rpmb) {
+ if (card->ext_csd.cmdq_en) {
+ ret = mmc_cmdq_disable(card);
+ if (ret)
+@@ -841,10 +842,11 @@ static int mmc_blk_part_switch_pre(struct mmc_card *card,
+ static int mmc_blk_part_switch_post(struct mmc_card *card,
+ unsigned int part_type)
+ {
+- const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
++ const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK;
++ const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB;
+ int ret = 0;
+
+- if ((part_type & mask) == mask) {
++ if ((part_type & mask) == rpmb) {
+ mmc_retune_unpause(card->host);
+ if (card->reenable_cmdq && !card->ext_csd.cmdq_en)
+ ret = mmc_cmdq_enable(card);
+--
+2.43.0
+
--- /dev/null
+From 456a9c116e1cdcf6b0bd43d81a5190c74eadaaf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 11:42:56 +0100
+Subject: mmc: tmio: avoid concurrent runs of mmc_request_done()
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit e8d1b41e69d72c62865bebe8f441163ec00b3d44 ]
+
+With the to-be-fixed commit, the reset_work handler cleared 'host->mrq'
+outside of the spinlock protected critical section. That leaves a small
+race window during execution of 'tmio_mmc_reset()' where the done_work
+handler could grab a pointer to the now invalid 'host->mrq'. Both would
+use it to call mmc_request_done() causing problems (see link below).
+
+However, 'host->mrq' cannot simply be cleared earlier inside the
+critical section. That would allow new mrqs to come in asynchronously
+while the actual reset of the controller still needs to be done. So,
+like 'tmio_mmc_set_ios()', an ERR_PTR is used to prevent new mrqs from
+coming in but still avoiding concurrency between work handlers.
+
+Reported-by: Dirk Behme <dirk.behme@de.bosch.com>
+Closes: https://lore.kernel.org/all/20240220061356.3001761-1-dirk.behme@de.bosch.com/
+Fixes: df3ef2d3c92c ("mmc: protect the tmio_mmc driver against a theoretical race")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
+Reviewed-by: Dirk Behme <dirk.behme@de.bosch.com>
+Cc: stable@vger.kernel.org # 3.0+
+Link: https://lore.kernel.org/r/20240305104423.3177-2-wsa+renesas@sang-engineering.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/tmio_mmc_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
+index abf36acb2641f..0482920a79681 100644
+--- a/drivers/mmc/host/tmio_mmc_core.c
++++ b/drivers/mmc/host/tmio_mmc_core.c
+@@ -216,6 +216,8 @@ static void tmio_mmc_reset_work(struct work_struct *work)
+ else
+ mrq->cmd->error = -ETIMEDOUT;
+
++ /* No new calls yet, but disallow concurrent tmio_mmc_done_work() */
++ host->mrq = ERR_PTR(-EBUSY);
+ host->cmd = NULL;
+ host->data = NULL;
+
+--
+2.43.0
+
--- /dev/null
+From 89194d1d6fb61dce22f5207740e0553c700e4adb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Feb 2024 00:45:51 +0300
+Subject: mtd: rawnand: meson: fix scrambling mode value in command macro
+
+From: Arseniy Krasnov <avkrasnov@salutedevices.com>
+
+[ Upstream commit ef6f463599e16924cdd02ce5056ab52879dc008c ]
+
+Scrambling mode is enabled by value (1 << 19). NFC_CMD_SCRAMBLER_ENABLE
+is already (1 << 19), so there is no need to shift it again in CMDRWGEN
+macro.
+
+Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com>
+Cc: <Stable@vger.kernel.org>
+Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20240210214551.441610-1-avkrasnov@salutedevices.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/meson_nand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
+index 6bb0fca4a91d0..9a64190f30e9b 100644
+--- a/drivers/mtd/nand/raw/meson_nand.c
++++ b/drivers/mtd/nand/raw/meson_nand.c
+@@ -59,7 +59,7 @@
+ #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \
+ ( \
+ (cmd_dir) | \
+- ((ran) << 19) | \
++ (ran) | \
+ ((bch) << 14) | \
+ ((short_mode) << 13) | \
+ (((page_size) & 0x7f) << 6) | \
+--
+2.43.0
+
--- /dev/null
+From 03009e88eb92146a0a700e09909333253492dd5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 09:34:54 -0400
+Subject: net: hns3: tracing: fix hclgevf trace event strings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 3f9952e8d80cca2da3b47ecd5ad9ec16cfd1a649 ]
+
+The __string() and __assign_str() helper macros of the TRACE_EVENT() macro
+are going through some optimizations where only the source string of
+__string() will be used and the __assign_str() source will be ignored and
+later removed.
+
+To make sure that there's no issues, a new check is added between the
+__string() src argument and the __assign_str() src argument that does a
+strcmp() to make sure they are the same string.
+
+The hclgevf trace events have:
+
+ __assign_str(devname, &hdev->nic.kinfo.netdev->name);
+
+Which triggers the warning:
+
+hclgevf_trace.h:34:39: error: passing argument 1 of ‘strcmp’ from incompatible pointer type [-Werror=incompatible-pointer-types]
+ 34 | __assign_str(devname, &hdev->nic.kinfo.netdev->name);
+ [..]
+arch/x86/include/asm/string_64.h:75:24: note: expected ‘const char *’ but argument is of type ‘char (*)[16]’
+ 75 | int strcmp(const char *cs, const char *ct);
+ | ~~~~~~~~~~~~^~
+
+Because __assign_str() now has:
+
+ WARN_ON_ONCE(__builtin_constant_p(src) ? \
+ strcmp((src), __data_offsets.dst##_ptr_) : \
+ (src) != __data_offsets.dst##_ptr_); \
+
+The problem is the '&' on hdev->nic.kinfo.netdev->name. That's because
+that name is:
+
+ char name[IFNAMSIZ]
+
+Where passing an address '&' of a char array is not compatible with strcmp().
+
+The '&' is not necessary, remove it.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240313093454.3909afe7@gandalf.local.home
+
+Cc: netdev <netdev@vger.kernel.org>
+Cc: Yisen Zhuang <yisen.zhuang@huawei.com>
+Cc: Salil Mehta <salil.mehta@huawei.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Yufeng Mo <moyufeng@huawei.com>
+Cc: Huazhong Tan <tanhuazhong@huawei.com>
+Cc: stable@vger.kernel.org
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Jijie Shao <shaojijie@huawei.com>
+Fixes: d8355240cf8fb ("net: hns3: add trace event support for PF/VF mailbox")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h | 8 ++++----
+ .../net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h | 8 ++++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h
+index 5b0b71bd61200..e8e67321e9632 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h
+@@ -24,7 +24,7 @@ TRACE_EVENT(hclge_pf_mbx_get,
+ __field(u8, code)
+ __field(u8, subcode)
+ __string(pciname, pci_name(hdev->pdev))
+- __string(devname, &hdev->vport[0].nic.kinfo.netdev->name)
++ __string(devname, hdev->vport[0].nic.kinfo.netdev->name)
+ __array(u32, mbx_data, PF_GET_MBX_LEN)
+ ),
+
+@@ -33,7 +33,7 @@ TRACE_EVENT(hclge_pf_mbx_get,
+ __entry->code = req->msg.code;
+ __entry->subcode = req->msg.subcode;
+ __assign_str(pciname, pci_name(hdev->pdev));
+- __assign_str(devname, &hdev->vport[0].nic.kinfo.netdev->name);
++ __assign_str(devname, hdev->vport[0].nic.kinfo.netdev->name);
+ memcpy(__entry->mbx_data, req,
+ sizeof(struct hclge_mbx_vf_to_pf_cmd));
+ ),
+@@ -56,7 +56,7 @@ TRACE_EVENT(hclge_pf_mbx_send,
+ __field(u8, vfid)
+ __field(u16, code)
+ __string(pciname, pci_name(hdev->pdev))
+- __string(devname, &hdev->vport[0].nic.kinfo.netdev->name)
++ __string(devname, hdev->vport[0].nic.kinfo.netdev->name)
+ __array(u32, mbx_data, PF_SEND_MBX_LEN)
+ ),
+
+@@ -64,7 +64,7 @@ TRACE_EVENT(hclge_pf_mbx_send,
+ __entry->vfid = req->dest_vfid;
+ __entry->code = req->msg.code;
+ __assign_str(pciname, pci_name(hdev->pdev));
+- __assign_str(devname, &hdev->vport[0].nic.kinfo.netdev->name);
++ __assign_str(devname, hdev->vport[0].nic.kinfo.netdev->name);
+ memcpy(__entry->mbx_data, req,
+ sizeof(struct hclge_mbx_pf_to_vf_cmd));
+ ),
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h
+index e4bfb6191fef5..a208af567909f 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h
+@@ -23,7 +23,7 @@ TRACE_EVENT(hclge_vf_mbx_get,
+ __field(u8, vfid)
+ __field(u16, code)
+ __string(pciname, pci_name(hdev->pdev))
+- __string(devname, &hdev->nic.kinfo.netdev->name)
++ __string(devname, hdev->nic.kinfo.netdev->name)
+ __array(u32, mbx_data, VF_GET_MBX_LEN)
+ ),
+
+@@ -31,7 +31,7 @@ TRACE_EVENT(hclge_vf_mbx_get,
+ __entry->vfid = req->dest_vfid;
+ __entry->code = req->msg.code;
+ __assign_str(pciname, pci_name(hdev->pdev));
+- __assign_str(devname, &hdev->nic.kinfo.netdev->name);
++ __assign_str(devname, hdev->nic.kinfo.netdev->name);
+ memcpy(__entry->mbx_data, req,
+ sizeof(struct hclge_mbx_pf_to_vf_cmd));
+ ),
+@@ -55,7 +55,7 @@ TRACE_EVENT(hclge_vf_mbx_send,
+ __field(u8, code)
+ __field(u8, subcode)
+ __string(pciname, pci_name(hdev->pdev))
+- __string(devname, &hdev->nic.kinfo.netdev->name)
++ __string(devname, hdev->nic.kinfo.netdev->name)
+ __array(u32, mbx_data, VF_SEND_MBX_LEN)
+ ),
+
+@@ -64,7 +64,7 @@ TRACE_EVENT(hclge_vf_mbx_send,
+ __entry->code = req->msg.code;
+ __entry->subcode = req->msg.subcode;
+ __assign_str(pciname, pci_name(hdev->pdev));
+- __assign_str(devname, &hdev->nic.kinfo.netdev->name);
++ __assign_str(devname, hdev->nic.kinfo.netdev->name);
+ memcpy(__entry->mbx_data, req,
+ sizeof(struct hclge_mbx_vf_to_pf_cmd));
+ ),
+--
+2.43.0
+
--- /dev/null
+From 0f235516da1ec92eef82b725e50490f8ef7a886c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 11:49:57 -0500
+Subject: nfs: fix UAF in direct writes
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 17f46b803d4f23c66cacce81db35fef3adb8f2af ]
+
+In production we have been hitting the following warning consistently
+
+------------[ cut here ]------------
+refcount_t: underflow; use-after-free.
+WARNING: CPU: 17 PID: 1800359 at lib/refcount.c:28 refcount_warn_saturate+0x9c/0xe0
+Workqueue: nfsiod nfs_direct_write_schedule_work [nfs]
+RIP: 0010:refcount_warn_saturate+0x9c/0xe0
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ ? __warn+0x9f/0x130
+ ? refcount_warn_saturate+0x9c/0xe0
+ ? report_bug+0xcc/0x150
+ ? handle_bug+0x3d/0x70
+ ? exc_invalid_op+0x16/0x40
+ ? asm_exc_invalid_op+0x16/0x20
+ ? refcount_warn_saturate+0x9c/0xe0
+ nfs_direct_write_schedule_work+0x237/0x250 [nfs]
+ process_one_work+0x12f/0x4a0
+ worker_thread+0x14e/0x3b0
+ ? ZSTD_getCParams_internal+0x220/0x220
+ kthread+0xdc/0x120
+ ? __btf_name_valid+0xa0/0xa0
+ ret_from_fork+0x1f/0x30
+
+This is because we're completing the nfs_direct_request twice in a row.
+
+The source of this is when we have our commit requests to submit, we
+process them and send them off, and then in the completion path for the
+commit requests we have
+
+if (nfs_commit_end(cinfo.mds))
+ nfs_direct_write_complete(dreq);
+
+However since we're submitting asynchronous requests we sometimes have
+one that completes before we submit the next one, so we end up calling
+complete on the nfs_direct_request twice.
+
+The only other place we use nfs_generic_commit_list() is in
+__nfs_commit_inode, which wraps this call in a
+
+nfs_commit_begin();
+nfs_commit_end();
+
+Which is a common pattern for this style of completion handling, one
+that is also repeated in the direct code with get_dreq()/put_dreq()
+calls around where we process events as well as in the completion paths.
+
+Fix this by using the same pattern for the commit requests.
+
+Before with my 200 node rocksdb stress running this warning would pop
+every 10ish minutes. With my patch the stress test has been running for
+several hours without popping.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/direct.c | 11 +++++++++--
+ fs/nfs/write.c | 2 +-
+ include/linux/nfs_fs.h | 1 +
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index 5d86ffa72ceab..499519f0f6ecd 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -678,10 +678,17 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
+ LIST_HEAD(mds_list);
+
+ nfs_init_cinfo_from_dreq(&cinfo, dreq);
++ nfs_commit_begin(cinfo.mds);
+ nfs_scan_commit(dreq->inode, &mds_list, &cinfo);
+ res = nfs_generic_commit_list(dreq->inode, &mds_list, 0, &cinfo);
+- if (res < 0) /* res == -ENOMEM */
+- nfs_direct_write_reschedule(dreq);
++ if (res < 0) { /* res == -ENOMEM */
++ spin_lock(&dreq->lock);
++ if (dreq->flags == 0)
++ dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
++ spin_unlock(&dreq->lock);
++ }
++ if (nfs_commit_end(cinfo.mds))
++ nfs_direct_write_complete(dreq);
+ }
+
+ static void nfs_direct_write_clear_reqs(struct nfs_direct_req *dreq)
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index d3cd099ffb6e1..4cf0606919794 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -1637,7 +1637,7 @@ static int wait_on_commit(struct nfs_mds_commit_info *cinfo)
+ !atomic_read(&cinfo->rpcs_out));
+ }
+
+-static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo)
++void nfs_commit_begin(struct nfs_mds_commit_info *cinfo)
+ {
+ atomic_inc(&cinfo->rpcs_out);
+ }
+diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
+index e39342945a80b..7488864589a7a 100644
+--- a/include/linux/nfs_fs.h
++++ b/include/linux/nfs_fs.h
+@@ -553,6 +553,7 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
+ extern int nfs_commit_inode(struct inode *, int);
+ extern struct nfs_commit_data *nfs_commitdata_alloc(void);
+ extern void nfs_commit_free(struct nfs_commit_data *data);
++void nfs_commit_begin(struct nfs_mds_commit_info *cinfo);
+ bool nfs_commit_end(struct nfs_mds_commit_info *cinfo);
+
+ static inline int
+--
+2.43.0
+
--- /dev/null
+From 8ebfc9053ad1cff4e1fc4292ac4109168ec7b403 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 19:58:26 +0900
+Subject: nilfs2: fix failure to detect DAT corruption in btree and direct
+ mappings
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit f2f26b4a84a0ef41791bd2d70861c8eac748f4ba ]
+
+Patch series "nilfs2: fix kernel bug at submit_bh_wbc()".
+
+This resolves a kernel BUG reported by syzbot. Since there are two
+flaws involved, I've made each one a separate patch.
+
+The first patch alone resolves the syzbot-reported bug, but I think
+both fixes should be sent to stable, so I've tagged them as such.
+
+This patch (of 2):
+
+Syzbot has reported a kernel bug in submit_bh_wbc() when writing file data
+to a nilfs2 file system whose metadata is corrupted.
+
+There are two flaws involved in this issue.
+
+The first flaw is that when nilfs_get_block() locates a data block using
+btree or direct mapping, if the disk address translation routine
+nilfs_dat_translate() fails with internal code -ENOENT due to DAT metadata
+corruption, it can be passed back to nilfs_get_block(). This causes
+nilfs_get_block() to misidentify an existing block as non-existent,
+causing both data block lookup and insertion to fail inconsistently.
+
+The second flaw is that nilfs_get_block() returns a successful status in
+this inconsistent state. This causes the caller __block_write_begin_int()
+or others to request a read even though the buffer is not mapped,
+resulting in a BUG_ON check for the BH_Mapped flag in submit_bh_wbc()
+failing.
+
+This fixes the first issue by changing the return value to code -EINVAL
+when a conversion using DAT fails with code -ENOENT, avoiding the
+conflicting condition that leads to the kernel bug described above. Here,
+code -EINVAL indicates that metadata corruption was detected during the
+block lookup, which will be properly handled as a file system error and
+converted to -EIO when passing through the nilfs2 bmap layer.
+
+Link: https://lkml.kernel.org/r/20240313105827.5296-1-konishi.ryusuke@gmail.com
+Link: https://lkml.kernel.org/r/20240313105827.5296-2-konishi.ryusuke@gmail.com
+Fixes: c3a7abf06ce7 ("nilfs2: support contiguous lookup of blocks")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+cfed5b56649bddf80d6e@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=cfed5b56649bddf80d6e
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/btree.c | 9 +++++++--
+ fs/nilfs2/direct.c | 9 +++++++--
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
+index 65cd599cb2ab6..4905b7cd7bf33 100644
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -724,7 +724,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
+ dat = nilfs_bmap_get_dat(btree);
+ ret = nilfs_dat_translate(dat, ptr, &blocknr);
+ if (ret < 0)
+- goto out;
++ goto dat_error;
+ ptr = blocknr;
+ }
+ cnt = 1;
+@@ -743,7 +743,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
+ if (dat) {
+ ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+ if (ret < 0)
+- goto out;
++ goto dat_error;
+ ptr2 = blocknr;
+ }
+ if (ptr2 != ptr + cnt || ++cnt == maxblocks)
+@@ -782,6 +782,11 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
+ out:
+ nilfs_btree_free_path(path);
+ return ret;
++
++ dat_error:
++ if (ret == -ENOENT)
++ ret = -EINVAL; /* Notify bmap layer of metadata corruption */
++ goto out;
+ }
+
+ static void nilfs_btree_promote_key(struct nilfs_bmap *btree,
+diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
+index f353101955e3b..7faf8c285d6c9 100644
+--- a/fs/nilfs2/direct.c
++++ b/fs/nilfs2/direct.c
+@@ -66,7 +66,7 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
+ dat = nilfs_bmap_get_dat(direct);
+ ret = nilfs_dat_translate(dat, ptr, &blocknr);
+ if (ret < 0)
+- return ret;
++ goto dat_error;
+ ptr = blocknr;
+ }
+
+@@ -79,7 +79,7 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
+ if (dat) {
+ ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+ if (ret < 0)
+- return ret;
++ goto dat_error;
+ ptr2 = blocknr;
+ }
+ if (ptr2 != ptr + cnt)
+@@ -87,6 +87,11 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
+ }
+ *ptrp = ptr;
+ return cnt;
++
++ dat_error:
++ if (ret == -ENOENT)
++ ret = -EINVAL; /* Notify bmap layer of metadata corruption */
++ return ret;
+ }
+
+ static __u64
+--
+2.43.0
+
--- /dev/null
+From 7d5156e7874d5e2a0c4c59d747646d97524f79ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 19:58:27 +0900
+Subject: nilfs2: prevent kernel bug at submit_bh_wbc()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit 269cdf353b5bdd15f1a079671b0f889113865f20 ]
+
+Fix a bug where nilfs_get_block() returns a successful status when
+searching and inserting the specified block both fail inconsistently. If
+this inconsistent behavior is not due to a previously fixed bug, then an
+unexpected race is occurring, so return a temporary error -EAGAIN instead.
+
+This prevents callers such as __block_write_begin_int() from requesting a
+read into a buffer that is not mapped, which would cause the BUG_ON check
+for the BH_Mapped flag in submit_bh_wbc() to fail.
+
+Link: https://lkml.kernel.org/r/20240313105827.5296-3-konishi.ryusuke@gmail.com
+Fixes: 1f5abe7e7dbc ("nilfs2: replace BUG_ON and BUG calls triggerable from ioctl")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
+index d144e08a9003a..06f4deb550c9f 100644
+--- a/fs/nilfs2/inode.c
++++ b/fs/nilfs2/inode.c
+@@ -112,7 +112,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
+ "%s (ino=%lu): a race condition while inserting a data block at offset=%llu",
+ __func__, inode->i_ino,
+ (unsigned long long)blkoff);
+- err = 0;
++ err = -EAGAIN;
+ }
+ nilfs_transaction_abort(inode->i_sb);
+ goto out;
+--
+2.43.0
+
--- /dev/null
+From 2c28f00144d93a984baea8b14809cf41e29d2115 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Feb 2024 11:40:23 +0000
+Subject: nvmem: meson-efuse: fix function pointer type mismatch
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit cbd38332c140829ab752ba4e727f98be5c257f18 ]
+
+clang-16 warns about casting functions to incompatible types, as is done
+here to call clk_disable_unprepare:
+
+drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 78 | (void(*)(void *))clk_disable_unprepare,
+
+The pattern of getting, enabling and setting a disable callback for a
+clock can be replaced with devm_clk_get_enabled(), which also fixes
+this warning.
+
+Fixes: 611fbca1c861 ("nvmem: meson-efuse: add peripheral clock")
+Cc: Stable@vger.kernel.org
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114023.85535-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvmem/meson-efuse.c | 25 +++----------------------
+ 1 file changed, 3 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
+index d6b533497ce1a..ba2714bef8d0e 100644
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -47,7 +47,6 @@ static int meson_efuse_probe(struct platform_device *pdev)
+ struct nvmem_config *econfig;
+ struct clk *clk;
+ unsigned int size;
+- int ret;
+
+ sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+ if (!sm_np) {
+@@ -60,27 +59,9 @@ static int meson_efuse_probe(struct platform_device *pdev)
+ if (!fw)
+ return -EPROBE_DEFER;
+
+- clk = devm_clk_get(dev, NULL);
+- if (IS_ERR(clk)) {
+- ret = PTR_ERR(clk);
+- if (ret != -EPROBE_DEFER)
+- dev_err(dev, "failed to get efuse gate");
+- return ret;
+- }
+-
+- ret = clk_prepare_enable(clk);
+- if (ret) {
+- dev_err(dev, "failed to enable gate");
+- return ret;
+- }
+-
+- ret = devm_add_action_or_reset(dev,
+- (void(*)(void *))clk_disable_unprepare,
+- clk);
+- if (ret) {
+- dev_err(dev, "failed to add disable callback");
+- return ret;
+- }
++ clk = devm_clk_get_enabled(dev, NULL);
++ if (IS_ERR(clk))
++ return dev_err_probe(dev, PTR_ERR(clk), "failed to get efuse gate");
+
+ if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
+ dev_err(dev, "failed to get max user");
+--
+2.43.0
+
--- /dev/null
+From 770848ac7ff0f246483483102f09bed7494924ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Feb 2024 16:40:51 +0100
+Subject: parisc: Avoid clobbering the C/B bits in the PSW with tophys and
+ tovirt macros
+
+From: John David Anglin <dave.anglin@bell.net>
+
+[ Upstream commit 4603fbaa76b5e703b38ac8cc718102834eb6e330 ]
+
+Use add,l to avoid clobbering the C/B bits in the PSW.
+
+Signed-off-by: John David Anglin <dave.anglin@bell.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/assembly.h | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h
+index a39250cb7dfcf..d3f23ed570c66 100644
+--- a/arch/parisc/include/asm/assembly.h
++++ b/arch/parisc/include/asm/assembly.h
+@@ -83,26 +83,28 @@
+ * version takes two arguments: a src and destination register.
+ * However, the source and destination registers can not be
+ * the same register.
++ *
++ * We use add,l to avoid clobbering the C/B bits in the PSW.
+ */
+
+ .macro tophys grvirt, grphys
+- ldil L%(__PAGE_OFFSET), \grphys
+- sub \grvirt, \grphys, \grphys
++ ldil L%(-__PAGE_OFFSET), \grphys
++ addl \grvirt, \grphys, \grphys
+ .endm
+-
++
+ .macro tovirt grphys, grvirt
+ ldil L%(__PAGE_OFFSET), \grvirt
+- add \grphys, \grvirt, \grvirt
++ addl \grphys, \grvirt, \grvirt
+ .endm
+
+ .macro tophys_r1 gr
+- ldil L%(__PAGE_OFFSET), %r1
+- sub \gr, %r1, \gr
++ ldil L%(-__PAGE_OFFSET), %r1
++ addl \gr, %r1, \gr
+ .endm
+-
++
+ .macro tovirt_r1 gr
+ ldil L%(__PAGE_OFFSET), %r1
+- add \gr, %r1, \gr
++ addl \gr, %r1, \gr
+ .endm
+
+ .macro delay value
+--
+2.43.0
+
--- /dev/null
+From d7be07a7c05b6c546840d1ba7baecd6933c434ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 11:15:56 -0800
+Subject: parisc: Fix csum_ipv6_magic on 32-bit systems
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 4408ba75e4ba80c91fde7e10bccccf388f5c09be ]
+
+Calculating the IPv6 checksum on 32-bit systems missed overflows when
+adding the proto+len fields into the checksum. This results in the
+following unit test failure.
+
+ # test_csum_ipv6_magic: ASSERTION FAILED at lib/checksum_kunit.c:506
+ Expected ( u64)csum_result == ( u64)expected, but
+ ( u64)csum_result == 46722 (0xb682)
+ ( u64)expected == 46721 (0xb681)
+ not ok 5 test_csum_ipv6_magic
+
+This is probably rarely seen in the real world because proto+len are
+usually small values which will rarely result in overflows when calculating
+the checksum. However, the unit test code uses large values for the length
+field, causing the test to fail.
+
+Fix the problem by adding the missing carry into the final checksum.
+
+Cc: Palmer Dabbelt <palmer@rivosinc.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Charlie Jenkins <charlie@rivosinc.com>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index f705e5dd10742..e619e67440db9 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -163,7 +163,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ " ldw,ma 4(%2), %7\n" /* 4th daddr */
+ " addc %6, %0, %0\n"
+ " addc %7, %0, %0\n"
+-" addc %3, %0, %0\n" /* fold in proto+len, catch carry */
++" addc %3, %0, %0\n" /* fold in proto+len */
++" addc 0, %0, %0\n" /* add carry */
+
+ #endif
+ : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len),
+--
+2.43.0
+
--- /dev/null
+From 3bcfd61e0f3522fa0c014f935700bbe3eaadb8d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 15:46:31 -0800
+Subject: parisc: Fix csum_ipv6_magic on 64-bit systems
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 4b75b12d70506e31fc02356bbca60f8d5ca012d0 ]
+
+hppa 64-bit systems calculates the IPv6 checksum using 64-bit add
+operations. The last add folds protocol and length fields into the 64-bit
+result. While unlikely, this operation can overflow. The overflow can be
+triggered with a code sequence such as the following.
+
+ /* try to trigger massive overflows */
+ memset(tmp_buf, 0xff, sizeof(struct in6_addr));
+ csum_result = csum_ipv6_magic((struct in6_addr *)tmp_buf,
+ (struct in6_addr *)tmp_buf,
+ 0xffff, 0xff, 0xffffffff);
+
+Fix the problem by adding any overflows from the final add operation into
+the calculated checksum. Fortunately, we can do this without additional
+cost by replacing the add operation used to fold the checksum into 32 bit
+with "add,dc" to add in the missing carry.
+
+Cc: Palmer Dabbelt <palmer@rivosinc.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index e619e67440db9..c949aa20fa162 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -137,8 +137,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ " add,dc %3, %0, %0\n" /* fold in proto+len | carry bit */
+ " extrd,u %0, 31, 32, %4\n"/* copy upper half down */
+ " depdi 0, 31, 32, %0\n"/* clear upper half */
+-" add %4, %0, %0\n" /* fold into 32-bits */
+-" addc 0, %0, %0\n" /* add carry */
++" add,dc %4, %0, %0\n" /* fold into 32-bits, plus carry */
++" addc 0, %0, %0\n" /* add final carry */
+
+ #else
+
+--
+2.43.0
+
--- /dev/null
+From 5654c95a42ec81b0eaf40129ffd2b60df3f60ea2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 09:55:26 -0800
+Subject: parisc: Fix ip_fast_csum
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit a2abae8f0b638c31bb9799d9dd847306e0d005bd ]
+
+IP checksum unit tests report the following error when run on hppa/hppa64.
+
+ # test_ip_fast_csum: ASSERTION FAILED at lib/checksum_kunit.c:463
+ Expected ( u64)csum_result == ( u64)expected, but
+ ( u64)csum_result == 33754 (0x83da)
+ ( u64)expected == 10946 (0x2ac2)
+ not ok 4 test_ip_fast_csum
+
+0x83da is the expected result if the IP header length is 20 bytes. 0x2ac2
+is the expected result if the IP header length is 24 bytes. The test fails
+with an IP header length of 24 bytes. It appears that ip_fast_csum()
+always returns the checksum for a 20-byte header, no matter how long
+the header actually is.
+
+Code analysis shows a suspicious assembler sequence in ip_fast_csum().
+
+ " addc %0, %3, %0\n"
+ "1: ldws,ma 4(%1), %3\n"
+ " addib,< 0, %2, 1b\n" <---
+
+While my understanding of HPPA assembler is limited, it does not seem
+to make much sense to subtract 0 from a register and to expect the result
+to ever be negative. Subtracting 1 from the length parameter makes more
+sense. On top of that, the operation should be repeated if and only if
+the result is still > 0, so change the suspicious instruction to
+ " addib,> -1, %2, 1b\n"
+
+The IP checksum unit test passes after this change.
+
+Cc: Palmer Dabbelt <palmer@rivosinc.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Charlie Jenkins <charlie@rivosinc.com>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index 3c43baca7b397..f705e5dd10742 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -40,7 +40,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+ " addc %0, %5, %0\n"
+ " addc %0, %3, %0\n"
+ "1: ldws,ma 4(%1), %3\n"
+-" addib,< 0, %2, 1b\n"
++" addib,> -1, %2, 1b\n"
+ " addc %0, %3, %0\n"
+ "\n"
+ " extru %0, 31, 16, %4\n"
+--
+2.43.0
+
--- /dev/null
+From be88dd6feae7d23cbd2c97ef887c702786815e25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 12:33:51 -0800
+Subject: parisc: Strip upper 32 bit of sum in csum_ipv6_magic for 64-bit
+ builds
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 0568b6f0d863643db2edcc7be31165740c89fa82 ]
+
+IPv6 checksum tests with unaligned addresses on 64-bit builds result
+in unexpected failures.
+
+Expected expected == csum_result, but
+ expected == 46591 (0xb5ff)
+ csum_result == 46381 (0xb52d)
+with alignment offset 1
+
+Oddly enough, the problem disappeared after adding test code into
+the beginning of csum_ipv6_magic().
+
+As it turns out, the 'sum' parameter of csum_ipv6_magic() is declared as
+__wsum, which is a 32-bit variable. However, it is treated as 64-bit
+variable in the 64-bit assembler code. Tests showed that the upper 32 bit
+of the register used to pass the variable are _not_ cleared when entering
+the function. This can result in checksum calculation errors.
+
+Clearing the upper 32 bit of 'sum' as first operation in the assembler
+code fixes the problem.
+
+Acked-by: Helge Deller <deller@gmx.de>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index c949aa20fa162..2aceebcd695c8 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -126,6 +126,7 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ ** Try to keep 4 registers with "live" values ahead of the ALU.
+ */
+
++" depdi 0, 31, 32, %0\n"/* clear upper half of incoming checksum */
+ " ldd,ma 8(%1), %4\n" /* get 1st saddr word */
+ " ldd,ma 8(%2), %5\n" /* get 1st daddr word */
+ " add %4, %0, %0\n"
+--
+2.43.0
+
--- /dev/null
+From fbfc6ca933c2e7b0583cb6589b0eaf00e06b8c6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Feb 2024 13:01:35 +0100
+Subject: PCI/AER: Block runtime suspend when handling errors
+
+From: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
+
+[ Upstream commit 002bf2fbc00e5c4b95fb167287e2ae7d1973281e ]
+
+PM runtime can be done simultaneously with AER error handling. Avoid that
+by using pm_runtime_get_sync() before and pm_runtime_put() after reset in
+pcie_do_recovery() for all recovering devices.
+
+pm_runtime_get_sync() will increase dev->power.usage_count counter to
+prevent any possible future request to runtime suspend a device. It will
+also resume a device, if it was previously in D3hot state.
+
+I tested with igc device by doing simultaneous aer_inject and rpm
+suspend/resume via /sys/bus/pci/devices/PCI_ID/power/control and can
+reproduce:
+
+ igc 0000:02:00.0: not ready 65535ms after bus reset; giving up
+ pcieport 0000:00:1c.2: AER: Root Port link has been reset (-25)
+ pcieport 0000:00:1c.2: AER: subordinate device reset failed
+ pcieport 0000:00:1c.2: AER: device recovery failed
+ igc 0000:02:00.0: Unable to change power state from D3hot to D0, device inaccessible
+
+The problem disappears when this patch is applied.
+
+Link: https://lore.kernel.org/r/20240212120135.146068-1-stanislaw.gruszka@linux.intel.com
+Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Acked-by: Rafael J. Wysocki <rafael@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/err.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
+index a806dfd94586c..bb4febcf45ba1 100644
+--- a/drivers/pci/pcie/err.c
++++ b/drivers/pci/pcie/err.c
+@@ -13,6 +13,7 @@
+ #define dev_fmt(fmt) "AER: " fmt
+
+ #include <linux/pci.h>
++#include <linux/pm_runtime.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+@@ -79,6 +80,18 @@ static int report_error_detected(struct pci_dev *dev,
+ return 0;
+ }
+
++static int pci_pm_runtime_get_sync(struct pci_dev *pdev, void *data)
++{
++ pm_runtime_get_sync(&pdev->dev);
++ return 0;
++}
++
++static int pci_pm_runtime_put(struct pci_dev *pdev, void *data)
++{
++ pm_runtime_put(&pdev->dev);
++ return 0;
++}
++
+ static int report_frozen_detected(struct pci_dev *dev, void *data)
+ {
+ return report_error_detected(dev, pci_channel_io_frozen, data);
+@@ -194,6 +207,8 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
+ else
+ bridge = pci_upstream_bridge(dev);
+
++ pci_walk_bridge(bridge, pci_pm_runtime_get_sync, NULL);
++
+ pci_dbg(bridge, "broadcast error_detected message\n");
+ if (state == pci_channel_io_frozen) {
+ pci_walk_bridge(bridge, report_frozen_detected, &status);
+@@ -239,10 +254,15 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
+ pcie_clear_device_status(bridge);
+ pci_aer_clear_nonfatal_status(bridge);
+ }
++
++ pci_walk_bridge(bridge, pci_pm_runtime_put, NULL);
++
+ pci_info(bridge, "device recovery successful\n");
+ return status;
+
+ failed:
++ pci_walk_bridge(bridge, pci_pm_runtime_put, NULL);
++
+ pci_uevent_ers(bridge, PCI_ERS_RESULT_DISCONNECT);
+
+ /* TODO: Should kernel panic here? */
+--
+2.43.0
+
--- /dev/null
+From 80c3347aa40d371adb0c862641de61048ac75c9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Apr 2022 12:38:10 +0300
+Subject: PCI/ASPM: Make Intel DG2 L1 acceptable latency unlimited
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 03038d84ace72678a9944524508f218a00377dc0 ]
+
+Intel DG2 discrete graphics PCIe endpoints advertise L1 acceptable exit
+latency to be < 1us even though they can actually tolerate unlimited exit
+latencies just fine. Quirk the L1 acceptable exit latency for these
+endpoints to be unlimited so ASPM L1 can be enabled.
+
+[bhelgaas: use FIELD_GET/FIELD_PREP, wordsmith comment & commit log]
+Link: https://lore.kernel.org/r/20220405093810.76613-1-mika.westerberg@linux.intel.com
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Stable-dep-of: 627c6db20703 ("PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/quirks.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index d7c4149855eb6..3f494d6653284 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -12,6 +12,7 @@
+ * file, where their drivers can use them.
+ */
+
++#include <linux/bitfield.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/export.h>
+@@ -5862,3 +5863,49 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1533, rom_bar_overlap_defect);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1536, rom_bar_overlap_defect);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1537, rom_bar_overlap_defect);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1538, rom_bar_overlap_defect);
++
++#ifdef CONFIG_PCIEASPM
++/*
++ * Several Intel DG2 graphics devices advertise that they can only tolerate
++ * 1us latency when transitioning from L1 to L0, which may prevent ASPM L1
++ * from being enabled. But in fact these devices can tolerate unlimited
++ * latency. Override their Device Capabilities value to allow ASPM L1 to
++ * be enabled.
++ */
++static void aspm_l1_acceptable_latency(struct pci_dev *dev)
++{
++ u32 l1_lat = FIELD_GET(PCI_EXP_DEVCAP_L1, dev->devcap);
++
++ if (l1_lat < 7) {
++ dev->devcap |= FIELD_PREP(PCI_EXP_DEVCAP_L1, 7);
++ pci_info(dev, "ASPM: overriding L1 acceptable latency from %#x to 0x7\n",
++ l1_lat);
++ }
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f80, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f81, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f82, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f83, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f84, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f85, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f86, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f87, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f88, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5690, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5691, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5692, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5693, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5694, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5695, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a0, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a1, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a2, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a3, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a4, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a5, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a6, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56b0, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56b1, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56c0, aspm_l1_acceptable_latency);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56c1, aspm_l1_acceptable_latency);
++#endif
+--
+2.43.0
+
--- /dev/null
+From 741d4f42d99e58e5fc957d0341ac759a599a78de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Aug 2021 23:34:52 +0530
+Subject: PCI: Cache PCIe Device Capabilities register
+
+From: Amey Narkhede <ameynarkhede03@gmail.com>
+
+[ Upstream commit 69139244806537f9d51364f37fe146bb2ee88a05 ]
+
+Add a new member called devcap in struct pci_dev for caching the PCIe
+Device Capabilities register to avoid reading PCI_EXP_DEVCAP multiple
+times.
+
+Refactor pcie_has_flr() to use cached device capabilities.
+
+Link: https://lore.kernel.org/r/20210817180500.1253-2-ameynarkhede03@gmail.com
+Signed-off-by: Amey Narkhede <ameynarkhede03@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
+Stable-dep-of: 627c6db20703 ("PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c | 6 ++----
+ drivers/pci/probe.c | 5 +++--
+ include/linux/pci.h | 1 +
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 1f8106ec70945..d1631109b1422 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -31,6 +31,7 @@
+ #include <linux/vmalloc.h>
+ #include <asm/dma.h>
+ #include <linux/aer.h>
++#include <linux/bitfield.h>
+ #include "pci.h"
+
+ DEFINE_MUTEX(pci_slot_mutex);
+@@ -4572,13 +4573,10 @@ EXPORT_SYMBOL(pci_wait_for_pending_transaction);
+ */
+ bool pcie_has_flr(struct pci_dev *dev)
+ {
+- u32 cap;
+-
+ if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
+ return false;
+
+- pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
+- return cap & PCI_EXP_DEVCAP_FLR;
++ return FIELD_GET(PCI_EXP_DEVCAP_FLR, dev->devcap) == 1;
+ }
+ EXPORT_SYMBOL_GPL(pcie_has_flr);
+
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index ab106d2a99479..02a75f3b59208 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -19,6 +19,7 @@
+ #include <linux/hypervisor.h>
+ #include <linux/irqdomain.h>
+ #include <linux/pm_runtime.h>
++#include <linux/bitfield.h>
+ #include "pci.h"
+
+ #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
+@@ -1496,8 +1497,8 @@ void set_pcie_port_type(struct pci_dev *pdev)
+ pdev->pcie_cap = pos;
+ pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16);
+ pdev->pcie_flags_reg = reg16;
+- pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16);
+- pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD;
++ pci_read_config_dword(pdev, pos + PCI_EXP_DEVCAP, &pdev->devcap);
++ pdev->pcie_mpss = FIELD_GET(PCI_EXP_DEVCAP_PAYLOAD, pdev->devcap);
+
+ parent = pci_upstream_bridge(pdev);
+ if (!parent)
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 1e3df93b39ca9..75f29838d25cf 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -333,6 +333,7 @@ struct pci_dev {
+ #ifdef CONFIG_PCIEPORTBUS
+ struct rcec_ea *rcec_ea; /* RCEC cached endpoint association */
+ #endif
++ u32 devcap; /* PCIe Device Capabilities */
+ u8 pcie_cap; /* PCIe capability offset */
+ u8 msi_cap; /* MSI capability offset */
+ u8 msix_cap; /* MSI-X capability offset */
+--
+2.43.0
+
--- /dev/null
+From 162bcd09d07c58d018bd4fc2d34797592efc4b6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Aug 2022 13:20:42 +0300
+Subject: PCI/DPC: Quirk PIO log size for certain Intel Root Ports
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 5459c0b7046752e519a646e1c2404852bb628459 ]
+
+Some Root Ports on Intel Tiger Lake and Alder Lake systems support the RP
+Extensions for DPC and the RP PIO Log registers but incorrectly advertise
+an RP PIO Log Size of zero. This means the kernel complains that:
+
+ DPC: RP PIO log size 0 is invalid
+
+and if DPC is triggered, the DPC driver will not dump the RP PIO Log
+registers when it should.
+
+This is caused by a BIOS bug and should be fixed the BIOS for future CPUs.
+
+Add a quirk to set the correct RP PIO Log size for the affected Root Ports.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=209943
+Link: https://lore.kernel.org/r/20220816102042.69125-1-mika.westerberg@linux.intel.com
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Stable-dep-of: 627c6db20703 ("PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/dpc.c | 15 ++++++++++-----
+ drivers/pci/quirks.c | 36 ++++++++++++++++++++++++++++++++++++
+ 2 files changed, 46 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
+index cf0d4ba2e157a..ab83f78f3eb1d 100644
+--- a/drivers/pci/pcie/dpc.c
++++ b/drivers/pci/pcie/dpc.c
+@@ -335,11 +335,16 @@ void pci_dpc_init(struct pci_dev *pdev)
+ return;
+
+ pdev->dpc_rp_extensions = true;
+- pdev->dpc_rp_log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
+- if (pdev->dpc_rp_log_size < 4 || pdev->dpc_rp_log_size > 9) {
+- pci_err(pdev, "RP PIO log size %u is invalid\n",
+- pdev->dpc_rp_log_size);
+- pdev->dpc_rp_log_size = 0;
++
++ /* Quirks may set dpc_rp_log_size if device or firmware is buggy */
++ if (!pdev->dpc_rp_log_size) {
++ pdev->dpc_rp_log_size =
++ (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
++ if (pdev->dpc_rp_log_size < 4 || pdev->dpc_rp_log_size > 9) {
++ pci_err(pdev, "RP PIO log size %u is invalid\n",
++ pdev->dpc_rp_log_size);
++ pdev->dpc_rp_log_size = 0;
++ }
+ }
+ }
+
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 3f494d6653284..a467e3ce6fb10 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -5909,3 +5909,39 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56b1, aspm_l1_acceptable_latency
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56c0, aspm_l1_acceptable_latency);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56c1, aspm_l1_acceptable_latency);
+ #endif
++
++#ifdef CONFIG_PCIE_DPC
++/*
++ * Intel Tiger Lake and Alder Lake BIOS has a bug that clears the DPC
++ * RP PIO Log Size of the integrated Thunderbolt PCIe Root Ports.
++ */
++static void dpc_log_size(struct pci_dev *dev)
++{
++ u16 dpc, val;
++
++ dpc = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC);
++ if (!dpc)
++ return;
++
++ pci_read_config_word(dev, dpc + PCI_EXP_DPC_CAP, &val);
++ if (!(val & PCI_EXP_DPC_CAP_RP_EXT))
++ return;
++
++ if (!((val & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8)) {
++ pci_info(dev, "Overriding RP PIO Log Size to 4\n");
++ dev->dpc_rp_log_size = 4;
++ }
++}
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x461f, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x462f, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x463f, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x466e, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a23, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a25, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a27, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a29, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2b, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size);
++#endif
+--
+2.43.0
+
--- /dev/null
+From db64fef2c39c0ae81a9e7342ebde8ffac31fcd81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 12:30:56 +0100
+Subject: PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports
+
+From: Paul Menzel <pmenzel@molgen.mpg.de>
+
+[ Upstream commit 627c6db20703b5d18d928464f411d0d4ec327508 ]
+
+Commit 5459c0b70467 ("PCI/DPC: Quirk PIO log size for certain Intel Root
+Ports") and commit 3b8803494a06 ("PCI/DPC: Quirk PIO log size for Intel Ice
+Lake Root Ports") add quirks for Ice, Tiger and Alder Lake Root Ports.
+System firmware for Raptor Lake still has the bug, so Linux logs the
+warning below on several Raptor Lake systems like Dell Precision 3581 with
+Intel Raptor Lake processor (0W18NX) system firmware/BIOS version 1.10.1.
+
+ pci 0000:00:07.0: [8086:a76e] type 01 class 0x060400
+ pci 0000:00:07.0: DPC: RP PIO log size 0 is invalid
+ pci 0000:00:07.1: [8086:a73f] type 01 class 0x060400
+ pci 0000:00:07.1: DPC: RP PIO log size 0 is invalid
+
+Apply the quirk for Raptor Lake Root Ports as well.
+
+This also enables the DPC driver to dump the RP PIO Log registers when DPC
+is triggered.
+
+Link: https://lore.kernel.org/r/20240305113057.56468-1-pmenzel@molgen.mpg.de
+Reported-by: Niels van Aert <nvaert1986@hotmail.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218560
+Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: <stable@vger.kernel.org>
+Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
+Cc: Niels van Aert <nvaert1986@hotmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index a467e3ce6fb10..eca4ed45bb4ee 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -5944,4 +5944,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2b, dpc_log_size);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa73f, dpc_log_size);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa76e, dpc_log_size);
+ #endif
+--
+2.43.0
+
--- /dev/null
+From 8038aad5e0fd636363cf3b015970cd85fa1475ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Oct 2021 14:59:25 +0200
+Subject: PCI: Drop pci_device_remove() test of pci_dev->driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 097d9d414433315122f759ee6c2d8a7417a8ff0f ]
+
+When the driver core calls pci_device_remove(), there is a driver bound
+to the device, so pci_dev->driver is never NULL.
+
+Remove the unnecessary test of pci_dev->driver.
+
+Link: https://lore.kernel.org/r/20211004125935.2300113-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Stable-dep-of: 9d5286d4e7f6 ("PCI/PM: Drain runtime-idle callbacks before driver removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-driver.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index c22cc20db1a74..dbfeb5c148755 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -444,16 +444,14 @@ static int pci_device_remove(struct device *dev)
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct pci_driver *drv = pci_dev->driver;
+
+- if (drv) {
+- if (drv->remove) {
+- pm_runtime_get_sync(dev);
+- drv->remove(pci_dev);
+- pm_runtime_put_noidle(dev);
+- }
+- pcibios_free_irq(pci_dev);
+- pci_dev->driver = NULL;
+- pci_iov_remove(pci_dev);
++ if (drv->remove) {
++ pm_runtime_get_sync(dev);
++ drv->remove(pci_dev);
++ pm_runtime_put_noidle(dev);
+ }
++ pcibios_free_irq(pci_dev);
++ pci_dev->driver = NULL;
++ pci_iov_remove(pci_dev);
+
+ /* Undo the runtime PM settings in local_pci_probe() */
+ pm_runtime_put_sync(dev);
+--
+2.43.0
+
--- /dev/null
+From 49af6c014b05f47154abdd2e91e78ff816207fae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 12:15:20 +0100
+Subject: PCI: dwc: endpoint: Fix advertised resizable BAR size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Cassel <cassel@kernel.org>
+
+[ Upstream commit 72e34b8593e08a0ee759b7a038e0b178418ea6f8 ]
+
+The commit message in commit fc9a77040b04 ("PCI: designware-ep: Configure
+Resizable BAR cap to advertise the smallest size") claims that it modifies
+the Resizable BAR capability to only advertise support for 1 MB size BARs.
+
+However, the commit writes all zeroes to PCI_REBAR_CAP (the register which
+contains the possible BAR sizes that a BAR be resized to).
+
+According to the spec, it is illegal to not have a bit set in
+PCI_REBAR_CAP, and 1 MB is the smallest size allowed.
+
+Set bit 4 in PCI_REBAR_CAP, so that we actually advertise support for a
+1 MB BAR size.
+
+Before:
+ Capabilities: [2e8 v1] Physical Resizable BAR
+ BAR 0: current size: 1MB
+ BAR 1: current size: 1MB
+ BAR 2: current size: 1MB
+ BAR 3: current size: 1MB
+ BAR 4: current size: 1MB
+ BAR 5: current size: 1MB
+After:
+ Capabilities: [2e8 v1] Physical Resizable BAR
+ BAR 0: current size: 1MB, supported: 1MB
+ BAR 1: current size: 1MB, supported: 1MB
+ BAR 2: current size: 1MB, supported: 1MB
+ BAR 3: current size: 1MB, supported: 1MB
+ BAR 4: current size: 1MB, supported: 1MB
+ BAR 5: current size: 1MB, supported: 1MB
+
+Fixes: fc9a77040b04 ("PCI: designware-ep: Configure Resizable BAR cap to advertise the smallest size")
+Link: https://lore.kernel.org/linux-pci/20240307111520.3303774-1-cassel@kernel.org
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Cc: <stable@vger.kernel.org> # 5.2
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware-ep.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
+index 339318e790e21..8ed1df61f9c7c 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -662,8 +662,13 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
+ nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >>
+ PCI_REBAR_CTRL_NBAR_SHIFT;
+
++ /*
++ * PCIe r6.0, sec 7.8.6.2 require us to support at least one
++ * size in the range from 1 MB to 512 GB. Advertise support
++ * for 1 MB BAR size only.
++ */
+ for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL)
+- dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0);
++ dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, BIT(4));
+ }
+
+ dw_pcie_setup(pci);
+--
+2.43.0
+
--- /dev/null
+From c8c32bec850be0c823a5aaecfb88ce4b4fc4cbef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Nov 2020 16:10:24 -0800
+Subject: PCI/ERR: Cache RCEC EA Capability offset in pci_init_capabilities()
+
+From: Sean V Kelley <sean.v.kelley@intel.com>
+
+[ Upstream commit 90655631988f8f501529e6de5f13614389717ead ]
+
+Extend support for Root Complex Event Collectors by decoding and caching
+the RCEC Endpoint Association Extended Capabilities when enumerating. Use
+that cached information for later error source reporting. See PCIe r5.0,
+sec 7.9.10.
+
+Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Link: https://lore.kernel.org/r/20201121001036.8560-4-sean.v.kelley@intel.com
+Tested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> # non-native/no RCEC
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Sean V Kelley <sean.v.kelley@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 627c6db20703 ("PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.h | 17 +++++++++++
+ drivers/pci/pcie/Makefile | 2 +-
+ drivers/pci/pcie/rcec.c | 59 +++++++++++++++++++++++++++++++++++++++
+ drivers/pci/probe.c | 2 ++
+ include/linux/pci.h | 4 +++
+ 5 files changed, 83 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/pci/pcie/rcec.c
+
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index 32fa07bfc448e..da40f29036d65 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -442,6 +442,15 @@ int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info);
+ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
+ #endif /* CONFIG_PCIEAER */
+
++#ifdef CONFIG_PCIEPORTBUS
++/* Cached RCEC Endpoint Association */
++struct rcec_ea {
++ u8 nextbusn;
++ u8 lastbusn;
++ u32 bitmap;
++};
++#endif
++
+ #ifdef CONFIG_PCIE_DPC
+ void pci_save_dpc_state(struct pci_dev *dev);
+ void pci_restore_dpc_state(struct pci_dev *dev);
+@@ -456,6 +465,14 @@ static inline void pci_dpc_init(struct pci_dev *pdev) {}
+ static inline bool pci_dpc_recovered(struct pci_dev *pdev) { return false; }
+ #endif
+
++#ifdef CONFIG_PCIEPORTBUS
++void pci_rcec_init(struct pci_dev *dev);
++void pci_rcec_exit(struct pci_dev *dev);
++#else
++static inline void pci_rcec_init(struct pci_dev *dev) {}
++static inline void pci_rcec_exit(struct pci_dev *dev) {}
++#endif
++
+ #ifdef CONFIG_PCI_ATS
+ /* Address Translation Service */
+ void pci_ats_init(struct pci_dev *dev);
+diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
+index 9a7085668466f..b2980db88cc09 100644
+--- a/drivers/pci/pcie/Makefile
++++ b/drivers/pci/pcie/Makefile
+@@ -2,7 +2,7 @@
+ #
+ # Makefile for PCI Express features and port driver
+
+-pcieportdrv-y := portdrv_core.o portdrv_pci.o err.o
++pcieportdrv-y := portdrv_core.o portdrv_pci.o err.o rcec.o
+
+ obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
+
+diff --git a/drivers/pci/pcie/rcec.c b/drivers/pci/pcie/rcec.c
+new file mode 100644
+index 0000000000000..038e9d706d5fd
+--- /dev/null
++++ b/drivers/pci/pcie/rcec.c
+@@ -0,0 +1,59 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Root Complex Event Collector Support
++ *
++ * Authors:
++ * Sean V Kelley <sean.v.kelley@intel.com>
++ * Qiuxu Zhuo <qiuxu.zhuo@intel.com>
++ *
++ * Copyright (C) 2020 Intel Corp.
++ */
++
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/pci_regs.h>
++
++#include "../pci.h"
++
++void pci_rcec_init(struct pci_dev *dev)
++{
++ struct rcec_ea *rcec_ea;
++ u32 rcec, hdr, busn;
++ u8 ver;
++
++ /* Only for Root Complex Event Collectors */
++ if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_EC)
++ return;
++
++ rcec = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_RCEC);
++ if (!rcec)
++ return;
++
++ rcec_ea = kzalloc(sizeof(*rcec_ea), GFP_KERNEL);
++ if (!rcec_ea)
++ return;
++
++ pci_read_config_dword(dev, rcec + PCI_RCEC_RCIEP_BITMAP,
++ &rcec_ea->bitmap);
++
++ /* Check whether RCEC BUSN register is present */
++ pci_read_config_dword(dev, rcec, &hdr);
++ ver = PCI_EXT_CAP_VER(hdr);
++ if (ver >= PCI_RCEC_BUSN_REG_VER) {
++ pci_read_config_dword(dev, rcec + PCI_RCEC_BUSN, &busn);
++ rcec_ea->nextbusn = PCI_RCEC_BUSN_NEXT(busn);
++ rcec_ea->lastbusn = PCI_RCEC_BUSN_LAST(busn);
++ } else {
++ /* Avoid later ver check by setting nextbusn */
++ rcec_ea->nextbusn = 0xff;
++ rcec_ea->lastbusn = 0x00;
++ }
++
++ dev->rcec_ea = rcec_ea;
++}
++
++void pci_rcec_exit(struct pci_dev *dev)
++{
++ kfree(dev->rcec_ea);
++ dev->rcec_ea = NULL;
++}
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index ece90a23936d2..ab106d2a99479 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -2216,6 +2216,7 @@ static void pci_configure_device(struct pci_dev *dev)
+ static void pci_release_capabilities(struct pci_dev *dev)
+ {
+ pci_aer_exit(dev);
++ pci_rcec_exit(dev);
+ pci_vpd_release(dev);
+ pci_iov_release(dev);
+ pci_free_cap_save_buffers(dev);
+@@ -2416,6 +2417,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
+ pci_ptm_init(dev); /* Precision Time Measurement */
+ pci_aer_init(dev); /* Advanced Error Reporting */
+ pci_dpc_init(dev); /* Downstream Port Containment */
++ pci_rcec_init(dev); /* Root Complex Event Collector */
+
+ pcie_report_downtraining(dev);
+
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index bf46453475e31..1e3df93b39ca9 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -306,6 +306,7 @@ struct pcie_link_state;
+ struct pci_vpd;
+ struct pci_sriov;
+ struct pci_p2pdma;
++struct rcec_ea;
+
+ /* The pci_dev structure describes PCI devices */
+ struct pci_dev {
+@@ -328,6 +329,9 @@ struct pci_dev {
+ #ifdef CONFIG_PCIEAER
+ u16 aer_cap; /* AER capability offset */
+ struct aer_stats *aer_stats; /* AER stats for this device */
++#endif
++#ifdef CONFIG_PCIEPORTBUS
++ struct rcec_ea *rcec_ea; /* RCEC cached endpoint association */
+ #endif
+ u8 pcie_cap; /* PCIe capability offset */
+ u8 msi_cap; /* MSI capability offset */
+--
+2.43.0
+
--- /dev/null
+From b0274acf92b62e6bfe6b8a6d67b18e36fe5622eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Nov 2020 10:55:30 -0600
+Subject: PCI/ERR: Clear AER status only when we control AER
+
+From: Sean V Kelley <sean.v.kelley@intel.com>
+
+[ Upstream commit aa344bc8b727b47b4350b59d8166216a3f351e55 ]
+
+In some cases a bridge may not exist as the hardware controlling may be
+handled only by firmware and so is not visible to the OS. This scenario is
+also possible in future use cases involving non-native use of RCECs by
+firmware. In this scenario, we expect the platform to retain control of the
+bridge and to clear error status itself.
+
+Clear error status only when the OS has native control of AER.
+
+Signed-off-by: Sean V Kelley <sean.v.kelley@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Stable-dep-of: 002bf2fbc00e ("PCI/AER: Block runtime suspend when handling errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/err.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
+index 984aa023c753f..a806dfd94586c 100644
+--- a/drivers/pci/pcie/err.c
++++ b/drivers/pci/pcie/err.c
+@@ -176,6 +176,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
+ int type = pci_pcie_type(dev);
+ struct pci_dev *bridge;
+ pci_ers_result_t status = PCI_ERS_RESULT_CAN_RECOVER;
++ struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
+
+ /*
+ * If the error was detected by a Root Port, Downstream Port, or
+@@ -227,9 +228,17 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
+ pci_dbg(bridge, "broadcast resume message\n");
+ pci_walk_bridge(bridge, report_resume, &status);
+
+- if (pcie_aer_is_native(bridge))
++ /*
++ * If we have native control of AER, clear error status in the Root
++ * Port or Downstream Port that signaled the error. If the
++ * platform retained control of AER, it is responsible for clearing
++ * this status. In that case, the signaling device may not even be
++ * visible to the OS.
++ */
++ if (host->native_aer || pcie_ports_native) {
+ pcie_clear_device_status(bridge);
+- pci_aer_clear_nonfatal_status(bridge);
++ pci_aer_clear_nonfatal_status(bridge);
++ }
+ pci_info(bridge, "device recovery successful\n");
+ return status;
+
+--
+2.43.0
+
--- /dev/null
+From 8e89b5c7dae50a21b9767175946fbd1406a22fa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 11:45:38 +0100
+Subject: PCI/PM: Drain runtime-idle callbacks before driver removal
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 9d5286d4e7f68beab450deddbb6a32edd5ecf4bf ]
+
+A race condition between the .runtime_idle() callback and the .remove()
+callback in the rtsx_pcr PCI driver leads to a kernel crash due to an
+unhandled page fault [1].
+
+The problem is that rtsx_pci_runtime_idle() is not expected to be running
+after pm_runtime_get_sync() has been called, but the latter doesn't really
+guarantee that. It only guarantees that the suspend and resume callbacks
+will not be running when it returns.
+
+However, if a .runtime_idle() callback is already running when
+pm_runtime_get_sync() is called, the latter will notice that the runtime PM
+status of the device is RPM_ACTIVE and it will return right away without
+waiting for the former to complete. In fact, it cannot wait for
+.runtime_idle() to complete because it may be called from that callback (it
+arguably does not make much sense to do that, but it is not strictly
+prohibited).
+
+Thus in general, whoever is providing a .runtime_idle() callback needs
+to protect it from running in parallel with whatever code runs after
+pm_runtime_get_sync(). [Note that .runtime_idle() will not start after
+pm_runtime_get_sync() has returned, but it may continue running then if it
+has started earlier.]
+
+One way to address that race condition is to call pm_runtime_barrier()
+after pm_runtime_get_sync() (not before it, because a nonzero value of the
+runtime PM usage counter is necessary to prevent runtime PM callbacks from
+being invoked) to wait for the .runtime_idle() callback to complete should
+it be running at that point. A suitable place for doing that is in
+pci_device_remove() which calls pm_runtime_get_sync() before removing the
+driver, so it may as well call pm_runtime_barrier() subsequently, which
+will prevent the race in question from occurring, not just in the rtsx_pcr
+driver, but in any PCI drivers providing .runtime_idle() callbacks.
+
+Link: https://lore.kernel.org/lkml/20240229062201.49500-1-kai.heng.feng@canonical.com/ # [1]
+Link: https://lore.kernel.org/r/5761426.DvuYhMxLoT@kreacher
+Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Ricky Wu <ricky_wu@realtek.com>
+Acked-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-driver.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index dbfeb5c148755..ae675c5a47151 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -446,6 +446,13 @@ static int pci_device_remove(struct device *dev)
+
+ if (drv->remove) {
+ pm_runtime_get_sync(dev);
++ /*
++ * If the driver provides a .runtime_idle() callback and it has
++ * started to run already, it may continue to run in parallel
++ * with the code below, so wait until all of the runtime PM
++ * activity has completed.
++ */
++ pm_runtime_barrier(dev);
+ drv->remove(pci_dev);
+ pm_runtime_put_noidle(dev);
+ }
+--
+2.43.0
+
--- /dev/null
+From 3e74298455ba473846ca385d20598b6600776d44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Dec 2021 10:45:07 -0600
+Subject: PCI: Work around Intel I210 ROM BAR overlap defect
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+[ Upstream commit 500b55b05d0a21c4adddf4c3b29ee6f32b502046 ]
+
+Per PCIe r5, sec 7.5.1.2.4, a device must not claim accesses to its
+Expansion ROM unless both the Memory Space Enable and the Expansion ROM
+Enable bit are set. But apparently some Intel I210 NICs don't work
+correctly if the ROM BAR overlaps another BAR, even if the Expansion ROM is
+disabled.
+
+Michael reported that on a Kontron SMARC-sAL28 ARM64 system with U-Boot
+v2021.01-rc3, the ROM BAR overlaps BAR 3, and networking doesn't work at
+all:
+
+ BAR 0: 0x40000000 (32-bit, non-prefetchable) [size=1M]
+ BAR 3: 0x40200000 (32-bit, non-prefetchable) [size=16K]
+ ROM: 0x40200000 (disabled) [size=1M]
+
+ NETDEV WATCHDOG: enP2p1s0 (igb): transmit queue 0 timed out
+ Hardware name: Kontron SMARC-sAL28 (Single PHY) on SMARC Eval 2.0 carrier (DT)
+ igb 0002:01:00.0 enP2p1s0: Reset adapter
+
+Previously, pci_std_update_resource() wrote the assigned ROM address to the
+BAR only when the ROM was enabled. This meant that the I210 ROM BAR could
+be left with an address assigned by firmware, which might overlap with
+other BARs.
+
+Quirk these I210 devices so pci_std_update_resource() always writes the
+assigned address to the ROM BAR, whether or not the ROM is enabled.
+
+Link: https://lore.kernel.org/r/20211223163754.GA1267351@bhelgaas
+Link: https://lore.kernel.org/r/20201230185317.30915-1-michael@walle.cc
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=211105
+Reported-by: Michael Walle <michael@walle.cc>
+Tested-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Stable-dep-of: 627c6db20703 ("PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/quirks.c | 10 ++++++++++
+ drivers/pci/setup-res.c | 8 ++++++--
+ include/linux/pci.h | 1 +
+ 3 files changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 646807a443e2d..d7c4149855eb6 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -5852,3 +5852,13 @@ static void nvidia_ion_ahci_fixup(struct pci_dev *pdev)
+ pdev->dev_flags |= PCI_DEV_FLAGS_HAS_MSI_MASKING;
+ }
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0ab8, nvidia_ion_ahci_fixup);
++
++static void rom_bar_overlap_defect(struct pci_dev *dev)
++{
++ pci_info(dev, "working around ROM BAR overlap defect\n");
++ dev->rom_bar_overlap = 1;
++}
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1533, rom_bar_overlap_defect);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1536, rom_bar_overlap_defect);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1537, rom_bar_overlap_defect);
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1538, rom_bar_overlap_defect);
+diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
+index 875d50c16f19d..b492e67c3d871 100644
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -75,12 +75,16 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
+ * as zero when disabled, so don't update ROM BARs unless
+ * they're enabled. See
+ * https://lore.kernel.org/r/43147B3D.1030309@vc.cvut.cz/
++ * But we must update ROM BAR for buggy devices where even a
++ * disabled ROM can conflict with other BARs.
+ */
+- if (!(res->flags & IORESOURCE_ROM_ENABLE))
++ if (!(res->flags & IORESOURCE_ROM_ENABLE) &&
++ !dev->rom_bar_overlap)
+ return;
+
+ reg = dev->rom_base_reg;
+- new |= PCI_ROM_ADDRESS_ENABLE;
++ if (res->flags & IORESOURCE_ROM_ENABLE)
++ new |= PCI_ROM_ADDRESS_ENABLE;
+ } else
+ return;
+
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 75f29838d25cf..5b24a6fbfa0be 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -454,6 +454,7 @@ struct pci_dev {
+ unsigned int link_active_reporting:1;/* Device capable of reporting link active */
+ unsigned int no_vf_scan:1; /* Don't scan for VFs after IOV enablement */
+ unsigned int no_command_memory:1; /* No PCI_COMMAND_MEMORY */
++ unsigned int rom_bar_overlap:1; /* ROM BAR disable broken */
+ pci_dev_flags_t dev_flags;
+ atomic_t enable_cnt; /* pci_enable_device has been called */
+
+--
+2.43.0
+
--- /dev/null
+From d9b55b3456dcc7054a26052b6d822db6781c1bec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 11:03:27 +0800
+Subject: phy: tegra: xusb: Add API to retrieve the port number of phy
+
+From: Wayne Chang <waynec@nvidia.com>
+
+[ Upstream commit d843f031d9e90462253015bc0bd9e3852d206bf2 ]
+
+This patch introduces a new API, tegra_xusb_padctl_get_port_number,
+to the Tegra XUSB Pad Controller driver. This API is used to identify
+the USB port that is associated with a given PHY.
+
+The function takes a PHY pointer for either a USB2 PHY or USB3 PHY as input
+and returns the corresponding port number. If the PHY pointer is invalid,
+it returns -ENODEV.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Tested-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://lore.kernel.org/r/20240307030328.1487748-2-waynec@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/tegra/xusb.c | 13 +++++++++++++
+ include/linux/phy/tegra/xusb.h | 2 ++
+ 2 files changed, 15 insertions(+)
+
+diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
+index 8f11b293c48d1..856397def89ac 100644
+--- a/drivers/phy/tegra/xusb.c
++++ b/drivers/phy/tegra/xusb.c
+@@ -1399,6 +1399,19 @@ int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
+ }
+ EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_usb3_companion);
+
++int tegra_xusb_padctl_get_port_number(struct phy *phy)
++{
++ struct tegra_xusb_lane *lane;
++
++ if (!phy)
++ return -ENODEV;
++
++ lane = phy_get_drvdata(phy);
++
++ return lane->index;
++}
++EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_port_number);
++
+ MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
+ MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver");
+ MODULE_LICENSE("GPL v2");
+diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h
+index 71d956935405f..86ccd90e425c7 100644
+--- a/include/linux/phy/tegra/xusb.h
++++ b/include/linux/phy/tegra/xusb.h
+@@ -23,4 +23,6 @@ int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
+ int tegra_phy_xusb_utmi_port_reset(struct phy *phy);
+ int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
+ unsigned int port);
++int tegra_xusb_padctl_get_port_number(struct phy *phy);
++
+ #endif /* PHY_TEGRA_XUSB_H */
+--
+2.43.0
+
--- /dev/null
+From d1a396b671aa0dd5c0865c387debfd32a00d2ae7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 17:26:57 +0800
+Subject: PM: sleep: wakeirq: fix wake irq warning in system suspend
+
+From: Qingliang Li <qingliang.li@mediatek.com>
+
+[ Upstream commit e7a7681c859643f3f2476b2a28a494877fd89442 ]
+
+When driver uses pm_runtime_force_suspend() as the system suspend callback
+function and registers the wake irq with reverse enable ordering, the wake
+irq will be re-enabled when entering system suspend, triggering an
+'Unbalanced enable for IRQ xxx' warning. In this scenario, the call
+sequence during system suspend is as follows:
+ suspend_devices_and_enter()
+ -> dpm_suspend_start()
+ -> dpm_run_callback()
+ -> pm_runtime_force_suspend()
+ -> dev_pm_enable_wake_irq_check()
+ -> dev_pm_enable_wake_irq_complete()
+
+ -> suspend_enter()
+ -> dpm_suspend_noirq()
+ -> device_wakeup_arm_wake_irqs()
+ -> dev_pm_arm_wake_irq()
+
+To fix this issue, complete the setting of WAKE_IRQ_DEDICATED_ENABLED flag
+in dev_pm_enable_wake_irq_complete() to avoid redundant irq enablement.
+
+Fixes: 8527beb12087 ("PM: sleep: wakeirq: fix wake irq arming")
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Signed-off-by: Qingliang Li <qingliang.li@mediatek.com>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Cc: 5.16+ <stable@vger.kernel.org> # 5.16+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/wakeirq.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c
+index aea690c64e394..4f4310724fee5 100644
+--- a/drivers/base/power/wakeirq.c
++++ b/drivers/base/power/wakeirq.c
+@@ -365,8 +365,10 @@ void dev_pm_enable_wake_irq_complete(struct device *dev)
+ return;
+
+ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
+- wirq->status & WAKE_IRQ_DEDICATED_REVERSE)
++ wirq->status & WAKE_IRQ_DEDICATED_REVERSE) {
+ enable_irq(wirq->irq);
++ wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
++ }
+ }
+
+ /**
+--
+2.43.0
+
--- /dev/null
+From c7b2f3d488f5f9e3cf3304d30c9f55c4d8e36bb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 12:14:59 +0530
+Subject: PM: suspend: Set mem_sleep_current during kernel command line setup
+
+From: Maulik Shah <quic_mkshah@quicinc.com>
+
+[ Upstream commit 9bc4ffd32ef8943f5c5a42c9637cfd04771d021b ]
+
+psci_init_system_suspend() invokes suspend_set_ops() very early during
+bootup even before kernel command line for mem_sleep_default is setup.
+This leads to kernel command line mem_sleep_default=s2idle not working
+as mem_sleep_current gets changed to deep via suspend_set_ops() and never
+changes back to s2idle.
+
+Set mem_sleep_current along with mem_sleep_default during kernel command
+line setup as default suspend mode.
+
+Fixes: faf7ec4a92c0 ("drivers: firmware: psci: add system suspend support")
+CC: stable@vger.kernel.org # 5.4+
+Signed-off-by: Maulik Shah <quic_mkshah@quicinc.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/suspend.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
+index 4aa4d5d3947f1..14e981c0588ad 100644
+--- a/kernel/power/suspend.c
++++ b/kernel/power/suspend.c
+@@ -187,6 +187,7 @@ static int __init mem_sleep_default_setup(char *str)
+ if (mem_sleep_labels[state] &&
+ !strcmp(str, mem_sleep_labels[state])) {
+ mem_sleep_default = state;
++ mem_sleep_current = state;
+ break;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 5cedc86d09bc676b441bf201ea45b03747cbf99f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 23:25:19 +1100
+Subject: powerpc/fsl: Fix mfpmr build errors with newer binutils
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 5f491356b7149564ab22323ccce79c8d595bfd0c ]
+
+Binutils 2.38 complains about the use of mfpmr when building
+ppc6xx_defconfig:
+
+ CC arch/powerpc/kernel/pmc.o
+ {standard input}: Assembler messages:
+ {standard input}:45: Error: unrecognized opcode: `mfpmr'
+ {standard input}:56: Error: unrecognized opcode: `mtpmr'
+
+This is because by default the kernel is built with -mcpu=powerpc, and
+the mt/mfpmr instructions are not defined.
+
+It can be avoided by enabling CONFIG_E300C3_CPU, but just adding that to
+the defconfig will leave open the possibility of randconfig failures.
+
+So add machine directives around the mt/mfpmr instructions to tell
+binutils how to assemble them.
+
+Cc: stable@vger.kernel.org
+Reported-by: Jan-Benedict Glaw <jbglaw@lug-owl.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240229122521.762431-3-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/reg_fsl_emb.h | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/reg_fsl_emb.h b/arch/powerpc/include/asm/reg_fsl_emb.h
+index a21f529c43d96..8359c06d92d9f 100644
+--- a/arch/powerpc/include/asm/reg_fsl_emb.h
++++ b/arch/powerpc/include/asm/reg_fsl_emb.h
+@@ -12,9 +12,16 @@
+ #ifndef __ASSEMBLY__
+ /* Performance Monitor Registers */
+ #define mfpmr(rn) ({unsigned int rval; \
+- asm volatile("mfpmr %0," __stringify(rn) \
++ asm volatile(".machine push; " \
++ ".machine e300; " \
++ "mfpmr %0," __stringify(rn) ";" \
++ ".machine pop; " \
+ : "=r" (rval)); rval;})
+-#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
++#define mtpmr(rn, v) asm volatile(".machine push; " \
++ ".machine e300; " \
++ "mtpmr " __stringify(rn) ",%0; " \
++ ".machine pop; " \
++ : : "r" (v))
+ #endif /* __ASSEMBLY__ */
+
+ /* Freescale Book E Performance Monitor APU Registers */
+--
+2.43.0
+
--- /dev/null
+From 1d851aeec58846f44f18d3675fd9d910969eb6f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Nov 2021 14:26:45 +0100
+Subject: printk/console: Split out code that enables default console
+
+From: Petr Mladek <pmladek@suse.com>
+
+[ Upstream commit ed758b30d541e9bf713cd58612a4414e57dc6d73 ]
+
+Put the code enabling a console by default into a separate function
+called try_enable_default_console().
+
+Rename try_enable_new_console() to try_enable_preferred_console() to
+make the purpose of the different variants more clear.
+
+It is a code refactoring without any functional change.
+
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Link: https://lore.kernel.org/r/20211122132649.12737-2-pmladek@suse.com
+Stable-dep-of: 801410b26a0e ("serial: Lock console when calling into driver before registration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/printk/printk.c | 38 +++++++++++++++++++++++---------------
+ 1 file changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
+index 17a310dcb6d96..632d6d5dcfa70 100644
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -2693,7 +2693,8 @@ early_param("keep_bootcon", keep_bootcon_setup);
+ * Care need to be taken with consoles that are statically
+ * enabled such as netconsole
+ */
+-static int try_enable_new_console(struct console *newcon, bool user_specified)
++static int try_enable_preferred_console(struct console *newcon,
++ bool user_specified)
+ {
+ struct console_cmdline *c;
+ int i, err;
+@@ -2741,6 +2742,23 @@ static int try_enable_new_console(struct console *newcon, bool user_specified)
+ return -ENOENT;
+ }
+
++/* Try to enable the console unconditionally */
++static void try_enable_default_console(struct console *newcon)
++{
++ if (newcon->index < 0)
++ newcon->index = 0;
++
++ if (newcon->setup && newcon->setup(newcon, NULL) != 0)
++ return;
++
++ newcon->flags |= CON_ENABLED;
++
++ if (newcon->device) {
++ newcon->flags |= CON_CONSDEV;
++ has_preferred_console = true;
++ }
++}
++
+ /*
+ * The console driver calls this routine during kernel initialization
+ * to register the console printing procedure with printk() and to
+@@ -2797,25 +2815,15 @@ void register_console(struct console *newcon)
+ * didn't select a console we take the first one
+ * that registers here.
+ */
+- if (!has_preferred_console) {
+- if (newcon->index < 0)
+- newcon->index = 0;
+- if (newcon->setup == NULL ||
+- newcon->setup(newcon, NULL) == 0) {
+- newcon->flags |= CON_ENABLED;
+- if (newcon->device) {
+- newcon->flags |= CON_CONSDEV;
+- has_preferred_console = true;
+- }
+- }
+- }
++ if (!has_preferred_console)
++ try_enable_default_console(newcon);
+
+ /* See if this console matches one we selected on the command line */
+- err = try_enable_new_console(newcon, true);
++ err = try_enable_preferred_console(newcon, true);
+
+ /* If not, try to match against the platform default(s) */
+ if (err == -ENOENT)
+- err = try_enable_new_console(newcon, false);
++ err = try_enable_preferred_console(newcon, false);
+
+ /* printk() messages are not printed to the Braille console. */
+ if (err || newcon->flags & CON_BRL)
+--
+2.43.0
+
--- /dev/null
+From 22c9aeac183b003074eb1d1c3ab6f3cfea02b778 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 00:21:31 -0800
+Subject: Revert "Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d""
+
+From: Song Liu <song@kernel.org>
+
+[ Upstream commit 3445139e3a594be77eff48bc17eff67cf983daed ]
+
+This reverts commit bed9e27baf52a09b7ba2a3714f1e24e17ced386d.
+
+The original set [1][2] was expected to undo a suboptimal fix in [2], and
+replace it with a better fix [1]. However, as reported by Dan Moulding [2]
+causes an issue with raid5 with journal device.
+
+Revert [2] for now to close the issue. We will follow up on another issue
+reported by Juxiao Bi, as [2] is expected to fix it. We believe this is a
+good trade-off, because the latter issue happens less freqently.
+
+In the meanwhile, we will NOT revert [1], as it contains the right logic.
+
+[1] commit d6e035aad6c0 ("md: bypass block throttle for superblock update")
+[2] commit bed9e27baf52 ("Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d"")
+
+Reported-by: Dan Moulding <dan@danm.net>
+Closes: https://lore.kernel.org/linux-raid/20240123005700.9302-1-dan@danm.net/
+Fixes: bed9e27baf52 ("Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d"")
+Cc: stable@vger.kernel.org # v5.19+
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240125082131.788600-1-song@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid5.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index 00995e60d46b1..9f114b9d8dc6b 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -36,6 +36,7 @@
+ */
+
+ #include <linux/blkdev.h>
++#include <linux/delay.h>
+ #include <linux/kthread.h>
+ #include <linux/raid/pq.h>
+ #include <linux/async_tx.h>
+@@ -6519,7 +6520,18 @@ static void raid5d(struct md_thread *thread)
+ spin_unlock_irq(&conf->device_lock);
+ md_check_recovery(mddev);
+ spin_lock_irq(&conf->device_lock);
++
++ /*
++ * Waiting on MD_SB_CHANGE_PENDING below may deadlock
++ * seeing md_check_recovery() is needed to clear
++ * the flag when using mdmon.
++ */
++ continue;
+ }
++
++ wait_event_lock_irq(mddev->sb_wait,
++ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags),
++ conf->device_lock);
+ }
+ pr_debug("%d stripes handled\n", handled);
+
+--
+2.43.0
+
--- /dev/null
+From 97a7f84a7a2f0086ff610254ed3c24b62a8627b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 11:56:41 -0400
+Subject: ring-buffer: Do not set shortest_full when full target is hit
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 761d9473e27f0c8782895013a3e7b52a37c8bcfc ]
+
+The rb_watermark_hit() checks if the amount of data in the ring buffer is
+above the percentage level passed in by the "full" variable. If it is, it
+returns true.
+
+But it also sets the "shortest_full" field of the cpu_buffer that informs
+writers that it needs to call the irq_work if the amount of data on the
+ring buffer is above the requested amount.
+
+The rb_watermark_hit() always sets the shortest_full even if the amount in
+the ring buffer is what it wants. As it is not going to wait, because it
+has what it wants, there's no reason to set shortest_full.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240312115641.6aa8ba08@gandalf.local.home
+
+Cc: stable@vger.kernel.org
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Fixes: 42fb0a1e84ff5 ("tracing/ring-buffer: Have polling block on watermark")
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 936b560989a3e..5b665e5991bf7 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -887,9 +887,10 @@ static bool rb_watermark_hit(struct trace_buffer *buffer, int cpu, int full)
+ pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page;
+ ret = !pagebusy && full_hit(buffer, cpu, full);
+
+- if (!cpu_buffer->shortest_full ||
+- cpu_buffer->shortest_full > full)
+- cpu_buffer->shortest_full = full;
++ if (!ret && (!cpu_buffer->shortest_full ||
++ cpu_buffer->shortest_full > full)) {
++ cpu_buffer->shortest_full = full;
++ }
+ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ }
+ return ret;
+--
+2.43.0
+
--- /dev/null
+From c07599c565e5708d4536912493cd59a4a1dcca03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 09:19:20 -0400
+Subject: ring-buffer: Fix full_waiters_pending in poll
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 8145f1c35fa648da662078efab299c4467b85ad5 ]
+
+If a reader of the ring buffer is doing a poll, and waiting for the ring
+buffer to hit a specific watermark, there could be a case where it gets
+into an infinite ping-pong loop.
+
+The poll code has:
+
+ rbwork->full_waiters_pending = true;
+ if (!cpu_buffer->shortest_full ||
+ cpu_buffer->shortest_full > full)
+ cpu_buffer->shortest_full = full;
+
+The writer will see full_waiters_pending and check if the ring buffer is
+filled over the percentage of the shortest_full value. If it is, it calls
+an irq_work to wake up all the waiters.
+
+But the code could get into a circular loop:
+
+ CPU 0 CPU 1
+ ----- -----
+ [ Poll ]
+ [ shortest_full = 0 ]
+ rbwork->full_waiters_pending = true;
+ if (rbwork->full_waiters_pending &&
+ [ buffer percent ] > shortest_full) {
+ rbwork->wakeup_full = true;
+ [ queue_irqwork ]
+
+ cpu_buffer->shortest_full = full;
+
+ [ IRQ work ]
+ if (rbwork->wakeup_full) {
+ cpu_buffer->shortest_full = 0;
+ wakeup poll waiters;
+ [woken]
+ if ([ buffer percent ] > full)
+ break;
+ rbwork->full_waiters_pending = true;
+ if (rbwork->full_waiters_pending &&
+ [ buffer percent ] > shortest_full) {
+ rbwork->wakeup_full = true;
+ [ queue_irqwork ]
+
+ cpu_buffer->shortest_full = full;
+
+ [ IRQ work ]
+ if (rbwork->wakeup_full) {
+ cpu_buffer->shortest_full = 0;
+ wakeup poll waiters;
+ [woken]
+
+ [ Wash, rinse, repeat! ]
+
+In the poll, the shortest_full needs to be set before the
+full_pending_waiters, as once that is set, the writer will compare the
+current shortest_full (which is incorrect) to decide to call the irq_work,
+which will reset the shortest_full (expecting the readers to update it).
+
+Also move the setting of full_waiters_pending after the check if the ring
+buffer has the required percentage filled. There's no reason to tell the
+writer to wake up waiters if there are no waiters.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240312131952.630922155@goodmis.org
+
+Cc: stable@vger.kernel.org
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Fixes: 42fb0a1e84ff5 ("tracing/ring-buffer: Have polling block on watermark")
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 5465f4c950f27..fb87def73a3a4 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -1029,16 +1029,32 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ poll_wait(filp, &rbwork->full_waiters, poll_table);
+
+ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
+- rbwork->full_waiters_pending = true;
+ if (!cpu_buffer->shortest_full ||
+ cpu_buffer->shortest_full > full)
+ cpu_buffer->shortest_full = full;
+ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+- } else {
+- poll_wait(filp, &rbwork->waiters, poll_table);
+- rbwork->waiters_pending = true;
++ if (full_hit(buffer, cpu, full))
++ return EPOLLIN | EPOLLRDNORM;
++ /*
++ * Only allow full_waiters_pending update to be seen after
++ * the shortest_full is set. If the writer sees the
++ * full_waiters_pending flag set, it will compare the
++ * amount in the ring buffer to shortest_full. If the amount
++ * in the ring buffer is greater than the shortest_full
++ * percent, it will call the irq_work handler to wake up
++ * this list. The irq_handler will reset shortest_full
++ * back to zero. That's done under the reader_lock, but
++ * the below smp_mb() makes sure that the update to
++ * full_waiters_pending doesn't leak up into the above.
++ */
++ smp_mb();
++ rbwork->full_waiters_pending = true;
++ return 0;
+ }
+
++ poll_wait(filp, &rbwork->waiters, poll_table);
++ rbwork->waiters_pending = true;
++
+ /*
+ * There's a tight race between setting the waiters_pending and
+ * checking if the ring buffer is empty. Once the waiters_pending bit
+@@ -1054,9 +1070,6 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ */
+ smp_mb();
+
+- if (full)
+- return full_hit(buffer, cpu, full) ? EPOLLIN | EPOLLRDNORM : 0;
+-
+ if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) ||
+ (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu)))
+ return EPOLLIN | EPOLLRDNORM;
+--
+2.43.0
+
--- /dev/null
+From e4410a5b3b89fad247246464c0aa17559f8e52b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 15:24:04 -0500
+Subject: ring-buffer: Fix resetting of shortest_full
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 68282dd930ea38b068ce2c109d12405f40df3f93 ]
+
+The "shortest_full" variable is used to keep track of the waiter that is
+waiting for the smallest amount on the ring buffer before being woken up.
+When a tasks waits on the ring buffer, it passes in a "full" value that is
+a percentage. 0 means wake up on any data. 1-100 means wake up from 1% to
+100% full buffer.
+
+As all waiters are on the same wait queue, the wake up happens for the
+waiter with the smallest percentage.
+
+The problem is that the smallest_full on the cpu_buffer that stores the
+smallest amount doesn't get reset when all the waiters are woken up. It
+does get reset when the ring buffer is reset (echo > /sys/kernel/tracing/trace).
+
+This means that tasks may be woken up more often then when they want to
+be. Instead, have the shortest_full field get reset just before waking up
+all the tasks. If the tasks wait again, they will update the shortest_full
+before sleeping.
+
+Also add locking around setting of shortest_full in the poll logic, and
+change "work" to "rbwork" to match the variable name for rb_irq_work
+structures that are used in other places.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240308202431.948914369@goodmis.org
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: linke li <lilinke99@qq.com>
+Cc: Rabin Vincent <rabin@rab.in>
+Fixes: 2c2b0a78b3739 ("ring-buffer: Add percentage of ring buffer full to wake up reader")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: 8145f1c35fa6 ("ring-buffer: Fix full_waiters_pending in poll")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 30 +++++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 5b665e5991bf7..5465f4c950f27 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -831,8 +831,19 @@ static void rb_wake_up_waiters(struct irq_work *work)
+
+ wake_up_all(&rbwork->waiters);
+ if (rbwork->full_waiters_pending || rbwork->wakeup_full) {
++ /* Only cpu_buffer sets the above flags */
++ struct ring_buffer_per_cpu *cpu_buffer =
++ container_of(rbwork, struct ring_buffer_per_cpu, irq_work);
++
++ /* Called from interrupt context */
++ raw_spin_lock(&cpu_buffer->reader_lock);
+ rbwork->wakeup_full = false;
+ rbwork->full_waiters_pending = false;
++
++ /* Waking up all waiters, they will reset the shortest full */
++ cpu_buffer->shortest_full = 0;
++ raw_spin_unlock(&cpu_buffer->reader_lock);
++
+ wake_up_all(&rbwork->full_waiters);
+ }
+ }
+@@ -999,28 +1010,33 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ struct file *filp, poll_table *poll_table, int full)
+ {
+ struct ring_buffer_per_cpu *cpu_buffer;
+- struct rb_irq_work *work;
++ struct rb_irq_work *rbwork;
+
+ if (cpu == RING_BUFFER_ALL_CPUS) {
+- work = &buffer->irq_work;
++ rbwork = &buffer->irq_work;
+ full = 0;
+ } else {
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ return EPOLLERR;
+
+ cpu_buffer = buffer->buffers[cpu];
+- work = &cpu_buffer->irq_work;
++ rbwork = &cpu_buffer->irq_work;
+ }
+
+ if (full) {
+- poll_wait(filp, &work->full_waiters, poll_table);
+- work->full_waiters_pending = true;
++ unsigned long flags;
++
++ poll_wait(filp, &rbwork->full_waiters, poll_table);
++
++ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
++ rbwork->full_waiters_pending = true;
+ if (!cpu_buffer->shortest_full ||
+ cpu_buffer->shortest_full > full)
+ cpu_buffer->shortest_full = full;
++ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ } else {
+- poll_wait(filp, &work->waiters, poll_table);
+- work->waiters_pending = true;
++ poll_wait(filp, &rbwork->waiters, poll_table);
++ rbwork->waiters_pending = true;
+ }
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From ac9bde7a2edaa578085126745a4434a6a5fc2c91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 15:24:03 -0500
+Subject: ring-buffer: Fix waking up ring buffer readers
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit b3594573681b53316ec0365332681a30463edfd6 ]
+
+A task can wait on a ring buffer for when it fills up to a specific
+watermark. The writer will check the minimum watermark that waiters are
+waiting for and if the ring buffer is past that, it will wake up all the
+waiters.
+
+The waiters are in a wait loop, and will first check if a signal is
+pending and then check if the ring buffer is at the desired level where it
+should break out of the loop.
+
+If a file that uses a ring buffer closes, and there's threads waiting on
+the ring buffer, it needs to wake up those threads. To do this, a
+"wait_index" was used.
+
+Before entering the wait loop, the waiter will read the wait_index. On
+wakeup, it will check if the wait_index is different than when it entered
+the loop, and will exit the loop if it is. The waker will only need to
+update the wait_index before waking up the waiters.
+
+This had a couple of bugs. One trivial one and one broken by design.
+
+The trivial bug was that the waiter checked the wait_index after the
+schedule() call. It had to be checked between the prepare_to_wait() and
+the schedule() which it was not.
+
+The main bug is that the first check to set the default wait_index will
+always be outside the prepare_to_wait() and the schedule(). That's because
+the ring_buffer_wait() doesn't have enough context to know if it should
+break out of the loop.
+
+The loop itself is not needed, because all the callers to the
+ring_buffer_wait() also has their own loop, as the callers have a better
+sense of what the context is to decide whether to break out of the loop
+or not.
+
+Just have the ring_buffer_wait() block once, and if it gets woken up, exit
+the function and let the callers decide what to do next.
+
+Link: https://lore.kernel.org/all/CAHk-=whs5MdtNjzFkTyaUy=vHi=qwWgPi0JgTe6OYUYMNSRZfg@mail.gmail.com/
+Link: https://lore.kernel.org/linux-trace-kernel/20240308202431.792933613@goodmis.org
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: linke li <lilinke99@qq.com>
+Cc: Rabin Vincent <rabin@rab.in>
+Fixes: e30f53aad2202 ("tracing: Do not busy wait in buffer splice")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: 761d9473e27f ("ring-buffer: Do not set shortest_full when full target is hit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 139 ++++++++++++++++++-------------------
+ 1 file changed, 68 insertions(+), 71 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 4a43b8846b49f..936b560989a3e 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -415,7 +415,6 @@ struct rb_irq_work {
+ struct irq_work work;
+ wait_queue_head_t waiters;
+ wait_queue_head_t full_waiters;
+- long wait_index;
+ bool waiters_pending;
+ bool full_waiters_pending;
+ bool wakeup_full;
+@@ -862,14 +861,40 @@ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
+ rbwork = &cpu_buffer->irq_work;
+ }
+
+- rbwork->wait_index++;
+- /* make sure the waiters see the new index */
+- smp_wmb();
+-
+ /* This can be called in any context */
+ irq_work_queue(&rbwork->work);
+ }
+
++static bool rb_watermark_hit(struct trace_buffer *buffer, int cpu, int full)
++{
++ struct ring_buffer_per_cpu *cpu_buffer;
++ bool ret = false;
++
++ /* Reads of all CPUs always waits for any data */
++ if (cpu == RING_BUFFER_ALL_CPUS)
++ return !ring_buffer_empty(buffer);
++
++ cpu_buffer = buffer->buffers[cpu];
++
++ if (!ring_buffer_empty_cpu(buffer, cpu)) {
++ unsigned long flags;
++ bool pagebusy;
++
++ if (!full)
++ return true;
++
++ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
++ pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page;
++ ret = !pagebusy && full_hit(buffer, cpu, full);
++
++ if (!cpu_buffer->shortest_full ||
++ cpu_buffer->shortest_full > full)
++ cpu_buffer->shortest_full = full;
++ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
++ }
++ return ret;
++}
++
+ /**
+ * ring_buffer_wait - wait for input to the ring buffer
+ * @buffer: buffer to wait on
+@@ -885,7 +910,6 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ struct ring_buffer_per_cpu *cpu_buffer;
+ DEFINE_WAIT(wait);
+ struct rb_irq_work *work;
+- long wait_index;
+ int ret = 0;
+
+ /*
+@@ -904,81 +928,54 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ work = &cpu_buffer->irq_work;
+ }
+
+- wait_index = READ_ONCE(work->wait_index);
+-
+- while (true) {
+- if (full)
+- prepare_to_wait(&work->full_waiters, &wait, TASK_INTERRUPTIBLE);
+- else
+- prepare_to_wait(&work->waiters, &wait, TASK_INTERRUPTIBLE);
+-
+- /*
+- * The events can happen in critical sections where
+- * checking a work queue can cause deadlocks.
+- * After adding a task to the queue, this flag is set
+- * only to notify events to try to wake up the queue
+- * using irq_work.
+- *
+- * We don't clear it even if the buffer is no longer
+- * empty. The flag only causes the next event to run
+- * irq_work to do the work queue wake up. The worse
+- * that can happen if we race with !trace_empty() is that
+- * an event will cause an irq_work to try to wake up
+- * an empty queue.
+- *
+- * There's no reason to protect this flag either, as
+- * the work queue and irq_work logic will do the necessary
+- * synchronization for the wake ups. The only thing
+- * that is necessary is that the wake up happens after
+- * a task has been queued. It's OK for spurious wake ups.
+- */
+- if (full)
+- work->full_waiters_pending = true;
+- else
+- work->waiters_pending = true;
+-
+- if (signal_pending(current)) {
+- ret = -EINTR;
+- break;
+- }
+-
+- if (cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer))
+- break;
+-
+- if (cpu != RING_BUFFER_ALL_CPUS &&
+- !ring_buffer_empty_cpu(buffer, cpu)) {
+- unsigned long flags;
+- bool pagebusy;
+- bool done;
+-
+- if (!full)
+- break;
+-
+- raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
+- pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page;
+- done = !pagebusy && full_hit(buffer, cpu, full);
++ if (full)
++ prepare_to_wait(&work->full_waiters, &wait, TASK_INTERRUPTIBLE);
++ else
++ prepare_to_wait(&work->waiters, &wait, TASK_INTERRUPTIBLE);
+
+- if (!cpu_buffer->shortest_full ||
+- cpu_buffer->shortest_full > full)
+- cpu_buffer->shortest_full = full;
+- raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+- if (done)
+- break;
+- }
++ /*
++ * The events can happen in critical sections where
++ * checking a work queue can cause deadlocks.
++ * After adding a task to the queue, this flag is set
++ * only to notify events to try to wake up the queue
++ * using irq_work.
++ *
++ * We don't clear it even if the buffer is no longer
++ * empty. The flag only causes the next event to run
++ * irq_work to do the work queue wake up. The worse
++ * that can happen if we race with !trace_empty() is that
++ * an event will cause an irq_work to try to wake up
++ * an empty queue.
++ *
++ * There's no reason to protect this flag either, as
++ * the work queue and irq_work logic will do the necessary
++ * synchronization for the wake ups. The only thing
++ * that is necessary is that the wake up happens after
++ * a task has been queued. It's OK for spurious wake ups.
++ */
++ if (full)
++ work->full_waiters_pending = true;
++ else
++ work->waiters_pending = true;
+
+- schedule();
++ if (rb_watermark_hit(buffer, cpu, full))
++ goto out;
+
+- /* Make sure to see the new wait index */
+- smp_rmb();
+- if (wait_index != work->wait_index)
+- break;
++ if (signal_pending(current)) {
++ ret = -EINTR;
++ goto out;
+ }
+
++ schedule();
++ out:
+ if (full)
+ finish_wait(&work->full_waiters, &wait);
+ else
+ finish_wait(&work->waiters, &wait);
+
++ if (!ret && !rb_watermark_hit(buffer, cpu, full) && signal_pending(current))
++ ret = -EINTR;
++
+ return ret;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From cfd590ea74ac86f75a14392e1cb49e1d9063a015 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 15:20:09 +0100
+Subject: s390/zcrypt: fix reference counting on zcrypt card objects
+
+From: Harald Freudenberger <freude@linux.ibm.com>
+
+[ Upstream commit 50ed48c80fecbe17218afed4f8bed005c802976c ]
+
+Tests with hot-plugging crytpo cards on KVM guests with debug
+kernel build revealed an use after free for the load field of
+the struct zcrypt_card. The reason was an incorrect reference
+handling of the zcrypt card object which could lead to a free
+of the zcrypt card object while it was still in use.
+
+This is an example of the slab message:
+
+ kernel: 0x00000000885a7512-0x00000000885a7513 @offset=1298. First byte 0x68 instead of 0x6b
+ kernel: Allocated in zcrypt_card_alloc+0x36/0x70 [zcrypt] age=18046 cpu=3 pid=43
+ kernel: kmalloc_trace+0x3f2/0x470
+ kernel: zcrypt_card_alloc+0x36/0x70 [zcrypt]
+ kernel: zcrypt_cex4_card_probe+0x26/0x380 [zcrypt_cex4]
+ kernel: ap_device_probe+0x15c/0x290
+ kernel: really_probe+0xd2/0x468
+ kernel: driver_probe_device+0x40/0xf0
+ kernel: __device_attach_driver+0xc0/0x140
+ kernel: bus_for_each_drv+0x8c/0xd0
+ kernel: __device_attach+0x114/0x198
+ kernel: bus_probe_device+0xb4/0xc8
+ kernel: device_add+0x4d2/0x6e0
+ kernel: ap_scan_adapter+0x3d0/0x7c0
+ kernel: ap_scan_bus+0x5a/0x3b0
+ kernel: ap_scan_bus_wq_callback+0x40/0x60
+ kernel: process_one_work+0x26e/0x620
+ kernel: worker_thread+0x21c/0x440
+ kernel: Freed in zcrypt_card_put+0x54/0x80 [zcrypt] age=9024 cpu=3 pid=43
+ kernel: kfree+0x37e/0x418
+ kernel: zcrypt_card_put+0x54/0x80 [zcrypt]
+ kernel: ap_device_remove+0x4c/0xe0
+ kernel: device_release_driver_internal+0x1c4/0x270
+ kernel: bus_remove_device+0x100/0x188
+ kernel: device_del+0x164/0x3c0
+ kernel: device_unregister+0x30/0x90
+ kernel: ap_scan_adapter+0xc8/0x7c0
+ kernel: ap_scan_bus+0x5a/0x3b0
+ kernel: ap_scan_bus_wq_callback+0x40/0x60
+ kernel: process_one_work+0x26e/0x620
+ kernel: worker_thread+0x21c/0x440
+ kernel: kthread+0x150/0x168
+ kernel: __ret_from_fork+0x3c/0x58
+ kernel: ret_from_fork+0xa/0x30
+ kernel: Slab 0x00000372022169c0 objects=20 used=18 fp=0x00000000885a7c88 flags=0x3ffff00000000a00(workingset|slab|node=0|zone=1|lastcpupid=0x1ffff)
+ kernel: Object 0x00000000885a74b8 @offset=1208 fp=0x00000000885a7c88
+ kernel: Redzone 00000000885a74b0: bb bb bb bb bb bb bb bb ........
+ kernel: Object 00000000885a74b8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a74c8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a74d8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a74e8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a74f8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a7508: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 68 4b 6b 6b 6b a5 kkkkkkkkkkhKkkk.
+ kernel: Redzone 00000000885a7518: bb bb bb bb bb bb bb bb ........
+ kernel: Padding 00000000885a756c: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZ
+ kernel: CPU: 0 PID: 387 Comm: systemd-udevd Not tainted 6.8.0-HF #2
+ kernel: Hardware name: IBM 3931 A01 704 (KVM/Linux)
+ kernel: Call Trace:
+ kernel: [<00000000ca5ab5b8>] dump_stack_lvl+0x90/0x120
+ kernel: [<00000000c99d78bc>] check_bytes_and_report+0x114/0x140
+ kernel: [<00000000c99d53cc>] check_object+0x334/0x3f8
+ kernel: [<00000000c99d820c>] alloc_debug_processing+0xc4/0x1f8
+ kernel: [<00000000c99d852e>] get_partial_node.part.0+0x1ee/0x3e0
+ kernel: [<00000000c99d94ec>] ___slab_alloc+0xaf4/0x13c8
+ kernel: [<00000000c99d9e38>] __slab_alloc.constprop.0+0x78/0xb8
+ kernel: [<00000000c99dc8dc>] __kmalloc+0x434/0x590
+ kernel: [<00000000c9b4c0ce>] ext4_htree_store_dirent+0x4e/0x1c0
+ kernel: [<00000000c9b908a2>] htree_dirblock_to_tree+0x17a/0x3f0
+ kernel: [<00000000c9b919dc>] ext4_htree_fill_tree+0x134/0x400
+ kernel: [<00000000c9b4b3d0>] ext4_dx_readdir+0x160/0x2f0
+ kernel: [<00000000c9b4bedc>] ext4_readdir+0x5f4/0x760
+ kernel: [<00000000c9a7efc4>] iterate_dir+0xb4/0x280
+ kernel: [<00000000c9a7f1ea>] __do_sys_getdents64+0x5a/0x120
+ kernel: [<00000000ca5d6946>] __do_syscall+0x256/0x310
+ kernel: [<00000000ca5eea10>] system_call+0x70/0x98
+ kernel: INFO: lockdep is turned off.
+ kernel: FIX kmalloc-96: Restoring Poison 0x00000000885a7512-0x00000000885a7513=0x6b
+ kernel: FIX kmalloc-96: Marking all objects used
+
+The fix is simple: Before use of the queue not only the queue object
+but also the card object needs to increase it's reference count
+with a call to zcrypt_card_get(). Similar after use of the queue
+not only the queue but also the card object's reference count is
+decreased with zcrypt_card_put().
+
+Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
+Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/crypto/zcrypt_api.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
+index b518009715eeb..dde10a5c7d509 100644
+--- a/drivers/s390/crypto/zcrypt_api.c
++++ b/drivers/s390/crypto/zcrypt_api.c
+@@ -576,6 +576,7 @@ static inline struct zcrypt_queue *zcrypt_pick_queue(struct zcrypt_card *zc,
+ {
+ if (!zq || !try_module_get(zq->queue->ap_dev.drv->driver.owner))
+ return NULL;
++ zcrypt_card_get(zc);
+ zcrypt_queue_get(zq);
+ get_device(&zq->queue->ap_dev.device);
+ atomic_add(weight, &zc->load);
+@@ -595,6 +596,7 @@ static inline void zcrypt_drop_queue(struct zcrypt_card *zc,
+ atomic_sub(weight, &zq->load);
+ put_device(&zq->queue->ap_dev.device);
+ zcrypt_queue_put(zq);
++ zcrypt_card_put(zc);
+ module_put(mod);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From bd8f8c1a2ba8a01dd39780d633d6d94eafce437b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 16:08:02 -0800
+Subject: selftests/mqueue: Set timeout to 180 seconds
+
+From: SeongJae Park <sj@kernel.org>
+
+[ Upstream commit 85506aca2eb4ea41223c91c5fe25125953c19b13 ]
+
+While mq_perf_tests runs with the default kselftest timeout limit, which
+is 45 seconds, the test takes about 60 seconds to complete on i3.metal
+AWS instances. Hence, the test always times out. Increase the timeout
+to 180 seconds.
+
+Fixes: 852c8cbf34d3 ("selftests/kselftest/runner.sh: Add 45 second timeout per test")
+Cc: <stable@vger.kernel.org> # 5.4.x
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/mqueue/setting | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 100644 tools/testing/selftests/mqueue/setting
+
+diff --git a/tools/testing/selftests/mqueue/setting b/tools/testing/selftests/mqueue/setting
+new file mode 100644
+index 0000000000000..a953c96aa16e1
+--- /dev/null
++++ b/tools/testing/selftests/mqueue/setting
+@@ -0,0 +1 @@
++timeout=180
+--
+2.43.0
+
--- /dev/null
+From 0be9c410824c7b9f32bb241477e89cf7d3bfbf61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Mar 2024 13:43:49 -0800
+Subject: serial: Lock console when calling into driver before registration
+
+From: Peter Collingbourne <pcc@google.com>
+
+[ Upstream commit 801410b26a0e8b8a16f7915b2b55c9528b69ca87 ]
+
+During the handoff from earlycon to the real console driver, we have
+two separate drivers operating on the same device concurrently. In the
+case of the 8250 driver these concurrent accesses cause problems due
+to the driver's use of banked registers, controlled by LCR.DLAB. It is
+possible for the setup(), config_port(), pm() and set_mctrl() callbacks
+to set DLAB, which can cause the earlycon code that intends to access
+TX to instead access DLL, leading to missed output and corruption on
+the serial line due to unintended modifications to the baud rate.
+
+In particular, for setup() we have:
+
+univ8250_console_setup()
+-> serial8250_console_setup()
+-> uart_set_options()
+-> serial8250_set_termios()
+-> serial8250_do_set_termios()
+-> serial8250_do_set_divisor()
+
+For config_port() we have:
+
+serial8250_config_port()
+-> autoconfig()
+
+For pm() we have:
+
+serial8250_pm()
+-> serial8250_do_pm()
+-> serial8250_set_sleep()
+
+For set_mctrl() we have (for some devices):
+
+serial8250_set_mctrl()
+-> omap8250_set_mctrl()
+-> __omap8250_set_mctrl()
+
+To avoid such problems, let's make it so that the console is locked
+during pre-registration calls to these callbacks, which will prevent
+the earlycon driver from running concurrently.
+
+Remove the partial solution to this problem in the 8250 driver
+that locked the console only during autoconfig_irq(), as this would
+result in a deadlock with the new approach. The console continues
+to be locked during autoconfig_irq() because it can only be called
+through uart_configure_port().
+
+Although this patch introduces more locking than strictly necessary
+(and in particular it also locks during the call to rs485_config()
+which is not affected by this issue as far as I can tell), it follows
+the principle that it is the responsibility of the generic console
+code to manage the earlycon handoff by ensuring that earlycon and real
+console driver code cannot run concurrently, and not the individual
+drivers.
+
+Signed-off-by: Peter Collingbourne <pcc@google.com>
+Reviewed-by: John Ogness <john.ogness@linutronix.de>
+Link: https://linux-review.googlesource.com/id/I7cf8124dcebf8618e6b2ee543fa5b25532de55d8
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240304214350.501253-1-pcc@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_port.c | 6 ------
+ drivers/tty/serial/serial_core.c | 12 ++++++++++++
+ kernel/printk/printk.c | 21 ++++++++++++++++++---
+ 3 files changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index 8b49ac4856d2c..6098e87a34046 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -1358,9 +1358,6 @@ static void autoconfig_irq(struct uart_8250_port *up)
+ inb_p(ICP);
+ }
+
+- if (uart_console(port))
+- console_lock();
+-
+ /* forget possible initially masked and pending IRQ */
+ probe_irq_off(probe_irq_on());
+ save_mcr = serial8250_in_MCR(up);
+@@ -1391,9 +1388,6 @@ static void autoconfig_irq(struct uart_8250_port *up)
+ if (port->flags & UPF_FOURPORT)
+ outb_p(save_ICP, ICP);
+
+- if (uart_console(port))
+- console_unlock();
+-
+ port->irq = (irq > 0) ? irq : 0;
+ }
+
+diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
+index 40fff38588d4f..10b8785b99827 100644
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -2431,7 +2431,12 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
+ port->type = PORT_UNKNOWN;
+ flags |= UART_CONFIG_TYPE;
+ }
++ /* Synchronize with possible boot console. */
++ if (uart_console(port))
++ console_lock();
+ port->ops->config_port(port, flags);
++ if (uart_console(port))
++ console_unlock();
+ }
+
+ if (port->type != PORT_UNKNOWN) {
+@@ -2439,6 +2444,10 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
+
+ uart_report_port(drv, port);
+
++ /* Synchronize with possible boot console. */
++ if (uart_console(port))
++ console_lock();
++
+ /* Power up port for set_mctrl() */
+ uart_change_pm(state, UART_PM_STATE_ON);
+
+@@ -2455,6 +2464,9 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
+ port->rs485_config(port, &port->rs485);
+ spin_unlock_irqrestore(&port->lock, flags);
+
++ if (uart_console(port))
++ console_unlock();
++
+ /*
+ * If this driver supports console, and it hasn't been
+ * successfully registered yet, try to re-register it.
+diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
+index 632d6d5dcfa70..255654ea12447 100644
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -2684,6 +2684,21 @@ static int __init keep_bootcon_setup(char *str)
+
+ early_param("keep_bootcon", keep_bootcon_setup);
+
++static int console_call_setup(struct console *newcon, char *options)
++{
++ int err;
++
++ if (!newcon->setup)
++ return 0;
++
++ /* Synchronize with possible boot console. */
++ console_lock();
++ err = newcon->setup(newcon, options);
++ console_unlock();
++
++ return err;
++}
++
+ /*
+ * This is called by register_console() to try to match
+ * the newly registered console with any of the ones selected
+@@ -2719,8 +2734,8 @@ static int try_enable_preferred_console(struct console *newcon,
+ if (_braille_register_console(newcon, c))
+ return 0;
+
+- if (newcon->setup &&
+- (err = newcon->setup(newcon, c->options)) != 0)
++ err = console_call_setup(newcon, c->options);
++ if (err)
+ return err;
+ }
+ newcon->flags |= CON_ENABLED;
+@@ -2748,7 +2763,7 @@ static void try_enable_default_console(struct console *newcon)
+ if (newcon->index < 0)
+ newcon->index = 0;
+
+- if (newcon->setup && newcon->setup(newcon, NULL) != 0)
++ if (console_call_setup(newcon, NULL) != 0)
+ return;
+
+ newcon->flags |= CON_ENABLED;
+--
+2.43.0
+
--- /dev/null
+From a2eac1c2416cddda0eade2c6b69dafb921a8bedc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jan 2024 10:21:57 -0500
+Subject: serial: max310x: fix NULL pointer dereference in I2C instantiation
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+[ Upstream commit 0d27056c24efd3d63a03f3edfbcfc4827086b110 ]
+
+When trying to instantiate a max14830 device from userspace:
+
+ echo max14830 0x60 > /sys/bus/i2c/devices/i2c-2/new_device
+
+we get the following error:
+
+ Unable to handle kernel NULL pointer dereference at virtual address...
+ ...
+ Call trace:
+ max310x_i2c_probe+0x48/0x170 [max310x]
+ i2c_device_probe+0x150/0x2a0
+ ...
+
+Add check for validity of devtype to prevent the error, and abort probe
+with a meaningful error message.
+
+Fixes: 2e1f2d9a9bdb ("serial: max310x: implement I2C support")
+Cc: stable@vger.kernel.org
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20240118152213.2644269-2-hugo@hugovil.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/max310x.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
+index 5570fd3b84e15..363b68555fe62 100644
+--- a/drivers/tty/serial/max310x.c
++++ b/drivers/tty/serial/max310x.c
+@@ -1636,13 +1636,16 @@ static unsigned short max310x_i2c_slave_addr(unsigned short addr,
+
+ static int max310x_i2c_probe(struct i2c_client *client)
+ {
+- const struct max310x_devtype *devtype =
+- device_get_match_data(&client->dev);
++ const struct max310x_devtype *devtype;
+ struct i2c_client *port_client;
+ struct regmap *regmaps[4];
+ unsigned int i;
+ u8 port_addr;
+
++ devtype = device_get_match_data(&client->dev);
++ if (!devtype)
++ return dev_err_probe(&client->dev, -ENODEV, "Failed to match device\n");
++
+ if (client->addr < devtype->slave_addr.min ||
+ client->addr > devtype->slave_addr.max)
+ return dev_err_probe(&client->dev, -EINVAL,
+--
+2.43.0
+
documentation-hw-vuln-update-spectre-doc.patch
x86-cpu-support-amd-automatic-ibrs.patch
x86-bugs-use-sysfs_emit.patch
+timers-update-kernel-doc-for-various-functions.patch
+timers-use-del_timer_sync-even-on-up.patch
+timers-rename-del_timer_sync-to-timer_delete_sync.patch
+wifi-brcmfmac-fix-use-after-free-bug-in-brcmf_cfg802.patch
+media-staging-ipu3-imgu-set-fields-before-media_enti.patch
+clk-qcom-gcc-sdm845-add-soft-dependency-on-rpmhpd.patch
+smack-set-smack64transmute-only-for-dirs-in-smack_in.patch
+smack-handle-smack64transmute-in-smack_inode_setsecu.patch
+arm-dts-marvell-fix-maxium-maxim-typo-in-brownstone-.patch
+drm-vmwgfx-stop-using-ttm_bo_create-v2.patch
+drm-vmwgfx-switch-over-to-the-new-pin-interface-v2.patch
+drm-vmwgfx-vmwgfx_cmdbuf_res-remove-unused-variable-.patch
+drm-vmwgfx-fix-some-static-checker-warnings.patch
+drm-vmwgfx-fix-possible-null-pointer-derefence-with-.patch
+serial-max310x-fix-null-pointer-dereference-in-i2c-i.patch
+media-xc4000-fix-atomicity-violation-in-xc4000_get_f.patch
+kvm-always-flush-async-pf-workqueue-when-vcpu-is-bei.patch
+sparc64-nmi-watchdog-fix-return-value-of-__setup-han.patch
+sparc-vdso-fix-return-value-of-__setup-handler.patch
+crypto-qat-fix-double-free-during-reset.patch
+crypto-qat-resolve-race-condition-during-aer-recover.patch
+selftests-mqueue-set-timeout-to-180-seconds.patch
+ext4-correct-best-extent-lstart-adjustment-logic.patch
+block-introduce-zone_write_granularity-limit.patch
+block-clear-zone-limits-for-a-non-zoned-stacked-queu.patch
+bounds-support-non-power-of-two-config_nr_cpus.patch
+fat-fix-uninitialized-field-in-nostale-filehandles.patch
+ubifs-set-page-uptodate-in-the-correct-place.patch
+ubi-check-for-too-small-leb-size-in-vtbl-code.patch
+ubi-correct-the-calculation-of-fastmap-size.patch
+mtd-rawnand-meson-fix-scrambling-mode-value-in-comma.patch
+parisc-avoid-clobbering-the-c-b-bits-in-the-psw-with.patch
+parisc-fix-ip_fast_csum.patch
+parisc-fix-csum_ipv6_magic-on-32-bit-systems.patch
+parisc-fix-csum_ipv6_magic-on-64-bit-systems.patch
+parisc-strip-upper-32-bit-of-sum-in-csum_ipv6_magic-.patch
+pm-suspend-set-mem_sleep_current-during-kernel-comma.patch
+clk-qcom-gcc-ipq6018-fix-terminating-of-frequency-ta.patch
+clk-qcom-gcc-ipq8074-fix-terminating-of-frequency-ta.patch
+clk-qcom-mmcc-apq8084-fix-terminating-of-frequency-t.patch
+clk-qcom-mmcc-msm8974-fix-terminating-of-frequency-t.patch
+powerpc-fsl-fix-mfpmr-build-errors-with-newer-binuti.patch
+usb-serial-ftdi_sio-add-support-for-gmc-z216c-adapte.patch
+usb-serial-add-device-id-for-verifone-adapter.patch
+usb-serial-cp210x-add-id-for-mgp-instruments-pds100.patch
+usb-serial-option-add-meig-smart-slm320-product.patch
+usb-serial-cp210x-add-pid-vid-for-tdk-nc0110013m-and.patch
+pm-sleep-wakeirq-fix-wake-irq-warning-in-system-susp.patch
+mmc-tmio-avoid-concurrent-runs-of-mmc_request_done.patch
+fuse-fix-root-lookup-with-nonzero-generation.patch
+fuse-don-t-unhash-root.patch
+usb-typec-ucsi-clean-up-ucsi_cable_prop-macros.patch
+printk-console-split-out-code-that-enables-default-c.patch
+serial-lock-console-when-calling-into-driver-before-.patch
+btrfs-fix-off-by-one-chunk-length-calculation-at-con.patch
+pci-drop-pci_device_remove-test-of-pci_dev-driver.patch
+pci-pm-drain-runtime-idle-callbacks-before-driver-re.patch
+pci-err-cache-rcec-ea-capability-offset-in-pci_init_.patch
+pci-cache-pcie-device-capabilities-register.patch
+pci-work-around-intel-i210-rom-bar-overlap-defect.patch
+pci-aspm-make-intel-dg2-l1-acceptable-latency-unlimi.patch
+pci-dpc-quirk-pio-log-size-for-certain-intel-root-po.patch
+pci-dpc-quirk-pio-log-size-for-intel-raptor-lake-roo.patch
+revert-revert-md-raid5-wait-for-md_sb_change_pending.patch
+dm-raid-fix-lockdep-waring-in-pers-hot_add_disk.patch
+mac802154-fix-llsec-key-resources-release-in-mac8021.patch
+mm-swap-fix-race-between-free_swap_and_cache-and-swa.patch
+mmc-core-fix-switch-on-gp3-partition.patch
+drm-etnaviv-restore-some-id-values.patch
+hwmon-amc6821-add-of_match-table.patch
+ext4-fix-corruption-during-on-line-resize.patch
+nvmem-meson-efuse-fix-function-pointer-type-mismatch.patch
+slimbus-core-remove-usage-of-the-deprecated-ida_simp.patch
+phy-tegra-xusb-add-api-to-retrieve-the-port-number-o.patch
+usb-gadget-tegra-xudc-use-dev_err_probe.patch
+usb-gadget-tegra-xudc-fix-usb3-phy-retrieval-logic.patch
+speakup-fix-8bit-characters-from-direct-synth.patch
+pci-err-clear-aer-status-only-when-we-control-aer.patch
+pci-aer-block-runtime-suspend-when-handling-errors.patch
+nfs-fix-uaf-in-direct-writes.patch
+kbuild-move-wenum-compare-conditional-enum-conversio.patch
+pci-dwc-endpoint-fix-advertised-resizable-bar-size.patch
+vfio-platform-disable-virqfds-on-cleanup.patch
+ring-buffer-fix-waking-up-ring-buffer-readers.patch
+ring-buffer-do-not-set-shortest_full-when-full-targe.patch
+ring-buffer-fix-resetting-of-shortest_full.patch
+ring-buffer-fix-full_waiters_pending-in-poll.patch
+soc-fsl-qbman-always-disable-interrupts-when-taking-.patch
+soc-fsl-qbman-add-helper-for-sanity-checking-cgr-ops.patch
+soc-fsl-qbman-add-cgr-update-function.patch
+soc-fsl-qbman-use-raw-spinlock-for-cgr_lock.patch
+s390-zcrypt-fix-reference-counting-on-zcrypt-card-ob.patch
+drm-panel-do-not-return-negative-error-codes-from-dr.patch
+drm-exynos-do-not-return-negative-values-from-.get_m.patch
+drm-imx-ipuv3-do-not-return-negative-values-from-.ge.patch
+drm-vc4-hdmi-do-not-return-negative-values-from-.get.patch
+memtest-use-read-write-_once-in-memory-scanning.patch
+nilfs2-fix-failure-to-detect-dat-corruption-in-btree.patch
+nilfs2-prevent-kernel-bug-at-submit_bh_wbc.patch
+cpufreq-dt-always-allocate-zeroed-cpumask.patch
+x86-cpu-amd-update-the-zenbleed-microcode-revisions.patch
+net-hns3-tracing-fix-hclgevf-trace-event-strings.patch
+wireguard-netlink-check-for-dangling-peer-via-is_dea.patch
+wireguard-netlink-access-device-through-ctx-instead-.patch
+ahci-asm1064-correct-count-of-reported-ports.patch
+ahci-asm1064-asm1166-don-t-limit-reported-ports.patch
+drm-amd-display-return-the-correct-hdcp-error-code.patch
+drm-amd-display-fix-noise-issue-on-hdmi-av-mute.patch
+dm-snapshot-fix-lockup-in-dm_exception_table_exit.patch
+vxge-remove-unnecessary-cast-in-kfree.patch
+x86-stackprotector-32-make-the-canary-into-a-regular.patch
+x86-pm-work-around-false-positive-kmemleak-report-in.patch
--- /dev/null
+From cfb70c8e1fa798a496210f456d3d587ac45a2f66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Feb 2024 11:41:37 +0000
+Subject: slimbus: core: Remove usage of the deprecated ida_simple_xx() API
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 89ffa4cccec54467446f141a79b9e36893079fb8 ]
+
+ida_alloc() and ida_free() should be preferred to the deprecated
+ida_simple_get() and ida_simple_remove().
+
+Note that the upper limit of ida_simple_get() is exclusive, but the one of
+ida_alloc_range() is inclusive. So change this change allows one more
+device. Previously address 0xFE was never used.
+
+Fixes: 46a2bb5a7f7e ("slimbus: core: Add slim controllers support")
+Cc: Stable@vger.kernel.org
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114137.85781-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/slimbus/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
+index 1d2bc181da050..69f6178f294c8 100644
+--- a/drivers/slimbus/core.c
++++ b/drivers/slimbus/core.c
+@@ -438,8 +438,8 @@ static int slim_device_alloc_laddr(struct slim_device *sbdev,
+ if (ret < 0)
+ goto err;
+ } else if (report_present) {
+- ret = ida_simple_get(&ctrl->laddr_ida,
+- 0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
++ ret = ida_alloc_max(&ctrl->laddr_ida,
++ SLIM_LA_MANAGER - 1, GFP_KERNEL);
+ if (ret < 0)
+ goto err;
+
+--
+2.43.0
+
--- /dev/null
+From 8beb077362d84d9efd788b8e5b3b37daa3ee34c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 10:01:22 +0100
+Subject: smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity()
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit ac02f007d64eb2769d0bde742aac4d7a5fc6e8a5 ]
+
+If the SMACK64TRANSMUTE xattr is provided, and the inode is a directory,
+update the in-memory inode flags by setting SMK_INODE_TRANSMUTE.
+
+Cc: stable@vger.kernel.org
+Fixes: 5c6d1125f8db ("Smack: Transmute labels on specified directories") # v2.6.38.x
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/smack/smack_lsm.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 0be25e05c1a03..750f6007bbbb0 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -2722,6 +2722,15 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+ if (value == NULL || size > SMK_LONGLABEL || size == 0)
+ return -EINVAL;
+
++ if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
++ if (!S_ISDIR(inode->i_mode) || size != TRANS_TRUE_SIZE ||
++ strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
++ return -EINVAL;
++
++ nsp->smk_flags |= SMK_INODE_TRANSMUTE;
++ return 0;
++ }
++
+ skp = smk_import_entry(value, size);
+ if (IS_ERR(skp))
+ return PTR_ERR(skp);
+--
+2.43.0
+
--- /dev/null
+From 041ee205fd180fafd662a5d4d32e119030d302c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 10:01:21 +0100
+Subject: smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr()
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit 9c82169208dde516510aaba6bbd8b13976690c5d ]
+
+Since the SMACK64TRANSMUTE xattr makes sense only for directories, enforce
+this restriction in smack_inode_setxattr().
+
+Cc: stable@vger.kernel.org
+Fixes: 5c6d1125f8db ("Smack: Transmute labels on specified directories") # v2.6.38.x
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/smack/smack_lsm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 5388f143eecd8..0be25e05c1a03 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -1280,7 +1280,8 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
+ check_star = 1;
+ } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
+ check_priv = 1;
+- if (size != TRANS_TRUE_SIZE ||
++ if (!S_ISDIR(d_backing_inode(dentry)->i_mode) ||
++ size != TRANS_TRUE_SIZE ||
+ strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
+ rc = -EINVAL;
+ } else
+--
+2.43.0
+
--- /dev/null
+From af1e2da42077660ad8a653658234ebbd5bdf2ce9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Sep 2022 17:57:35 -0400
+Subject: soc: fsl: qbman: Add CGR update function
+
+From: Sean Anderson <sean.anderson@seco.com>
+
+[ Upstream commit 914f8b228ede709274b8c80514b352248ec9da00 ]
+
+This adds a function to update a CGR with new parameters. qman_create_cgr
+can almost be used for this (with flags=0), but it's not suitable because
+it also registers the callback function. The _safe variant was modeled off
+of qman_cgr_delete_safe. However, we handle multiple arguments and a return
+value.
+
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Acked-by: Camelia Groza <camelia.groza@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: fbec4e7fed89 ("soc: fsl: qbman: Use raw spinlock for cgr_lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qbman/qman.c | 48 ++++++++++++++++++++++++++++++++++++
+ include/soc/fsl/qman.h | 9 +++++++
+ 2 files changed, 57 insertions(+)
+
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index d581576c9a861..3346593e0bc62 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -2568,6 +2568,54 @@ void qman_delete_cgr_safe(struct qman_cgr *cgr)
+ }
+ EXPORT_SYMBOL(qman_delete_cgr_safe);
+
++static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
++{
++ int ret;
++ unsigned long irqflags;
++ struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
++
++ if (!p)
++ return -EINVAL;
++
++ spin_lock_irqsave(&p->cgr_lock, irqflags);
++ ret = qm_modify_cgr(cgr, 0, opts);
++ spin_unlock_irqrestore(&p->cgr_lock, irqflags);
++ put_affine_portal();
++ return ret;
++}
++
++struct update_cgr_params {
++ struct qman_cgr *cgr;
++ struct qm_mcc_initcgr *opts;
++ int ret;
++};
++
++static void qman_update_cgr_smp_call(void *p)
++{
++ struct update_cgr_params *params = p;
++
++ params->ret = qman_update_cgr(params->cgr, params->opts);
++}
++
++int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
++{
++ struct update_cgr_params params = {
++ .cgr = cgr,
++ .opts = opts,
++ };
++
++ preempt_disable();
++ if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id())
++ smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
++ qman_update_cgr_smp_call, ¶ms,
++ true);
++ else
++ params.ret = qman_update_cgr(cgr, opts);
++ preempt_enable();
++ return params.ret;
++}
++EXPORT_SYMBOL(qman_update_cgr_safe);
++
+ /* Cleanup FQs */
+
+ static int _qm_mr_consume_and_match_verb(struct qm_portal *p, int v)
+diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
+index 9f484113cfda7..3cecbfdb0f8c2 100644
+--- a/include/soc/fsl/qman.h
++++ b/include/soc/fsl/qman.h
+@@ -1170,6 +1170,15 @@ int qman_delete_cgr(struct qman_cgr *cgr);
+ */
+ void qman_delete_cgr_safe(struct qman_cgr *cgr);
+
++/**
++ * qman_update_cgr_safe - Modifies a congestion group object from any CPU
++ * @cgr: the 'cgr' object to modify
++ * @opts: state of the CGR settings
++ *
++ * This will select the proper CPU and modify the CGR settings.
++ */
++int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts);
++
+ /**
+ * qman_query_cgr_congested - Queries CGR's congestion status
+ * @cgr: the 'cgr' object to query
+--
+2.43.0
+
--- /dev/null
+From 539aa15da5892e2a84087d930387bd7bb071a3fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Sep 2022 17:57:34 -0400
+Subject: soc: fsl: qbman: Add helper for sanity checking cgr ops
+
+From: Sean Anderson <sean.anderson@seco.com>
+
+[ Upstream commit d0e17a4653cebc2c8a20251c837dd1fcec5014d9 ]
+
+This breaks out/combines get_affine_portal and the cgr sanity check in
+preparation for the next commit. No functional change intended.
+
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Acked-by: Camelia Groza <camelia.groza@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: fbec4e7fed89 ("soc: fsl: qbman: Use raw spinlock for cgr_lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qbman/qman.c | 29 +++++++++++++++++++----------
+ 1 file changed, 19 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index d8267e6c31a50..d581576c9a861 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -2483,13 +2483,8 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ }
+ EXPORT_SYMBOL(qman_create_cgr);
+
+-int qman_delete_cgr(struct qman_cgr *cgr)
++static struct qman_portal *qman_cgr_get_affine_portal(struct qman_cgr *cgr)
+ {
+- unsigned long irqflags;
+- struct qm_mcr_querycgr cgr_state;
+- struct qm_mcc_initcgr local_opts;
+- int ret = 0;
+- struct qman_cgr *i;
+ struct qman_portal *p = get_affine_portal();
+
+ if (cgr->chan != p->config->channel) {
+@@ -2497,10 +2492,25 @@ int qman_delete_cgr(struct qman_cgr *cgr)
+ dev_err(p->config->dev, "CGR not owned by current portal");
+ dev_dbg(p->config->dev, " create 0x%x, delete 0x%x\n",
+ cgr->chan, p->config->channel);
+-
+- ret = -EINVAL;
+- goto put_portal;
++ put_affine_portal();
++ return NULL;
+ }
++
++ return p;
++}
++
++int qman_delete_cgr(struct qman_cgr *cgr)
++{
++ unsigned long irqflags;
++ struct qm_mcr_querycgr cgr_state;
++ struct qm_mcc_initcgr local_opts;
++ int ret = 0;
++ struct qman_cgr *i;
++ struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
++
++ if (!p)
++ return -EINVAL;
++
+ memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
+ spin_lock_irqsave(&p->cgr_lock, irqflags);
+ list_del(&cgr->node);
+@@ -2528,7 +2538,6 @@ int qman_delete_cgr(struct qman_cgr *cgr)
+ list_add(&cgr->node, &p->cgr_cbs);
+ release_lock:
+ spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+-put_portal:
+ put_affine_portal();
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From 314ca1a5bc024ab8a2987f23d64ba7cb1412f8d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 12:38:29 -0400
+Subject: soc: fsl: qbman: Always disable interrupts when taking cgr_lock
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit 584c2a9184a33a40fceee838f856de3cffa19be3 ]
+
+smp_call_function_single disables IRQs when executing the callback. To
+prevent deadlocks, we must disable IRQs when taking cgr_lock elsewhere.
+This is already done by qman_update_cgr and qman_delete_cgr; fix the
+other lockers.
+
+Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
+CC: stable@vger.kernel.org
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Reviewed-by: Camelia Groza <camelia.groza@nxp.com>
+Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qbman/qman.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index feb97470699d9..d8267e6c31a50 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -1456,11 +1456,11 @@ static void qm_congestion_task(struct work_struct *work)
+ union qm_mc_result *mcr;
+ struct qman_cgr *cgr;
+
+- spin_lock(&p->cgr_lock);
++ spin_lock_irq(&p->cgr_lock);
+ qm_mc_start(&p->p);
+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
+ if (!qm_mc_result_timeout(&p->p, &mcr)) {
+- spin_unlock(&p->cgr_lock);
++ spin_unlock_irq(&p->cgr_lock);
+ dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
+ qman_p_irqsource_add(p, QM_PIRQ_CSCI);
+ return;
+@@ -1476,7 +1476,7 @@ static void qm_congestion_task(struct work_struct *work)
+ list_for_each_entry(cgr, &p->cgr_cbs, node)
+ if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
+ cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
+- spin_unlock(&p->cgr_lock);
++ spin_unlock_irq(&p->cgr_lock);
+ qman_p_irqsource_add(p, QM_PIRQ_CSCI);
+ }
+
+@@ -2440,7 +2440,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ preempt_enable();
+
+ cgr->chan = p->config->channel;
+- spin_lock(&p->cgr_lock);
++ spin_lock_irq(&p->cgr_lock);
+
+ if (opts) {
+ struct qm_mcc_initcgr local_opts = *opts;
+@@ -2477,7 +2477,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
+ cgr->cb(p, cgr, 1);
+ out:
+- spin_unlock(&p->cgr_lock);
++ spin_unlock_irq(&p->cgr_lock);
+ put_affine_portal();
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From 62e375f100723c8171fe72b57fb88effbbf2207c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 12:38:30 -0400
+Subject: soc: fsl: qbman: Use raw spinlock for cgr_lock
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit fbec4e7fed89b579f2483041fabf9650fb0dd6bc ]
+
+smp_call_function always runs its callback in hard IRQ context, even on
+PREEMPT_RT, where spinlocks can sleep. So we need to use a raw spinlock
+for cgr_lock to ensure we aren't waiting on a sleeping task.
+
+Although this bug has existed for a while, it was not apparent until
+commit ef2a8d5478b9 ("net: dpaa: Adjust queue depth on rate change")
+which invokes smp_call_function_single via qman_update_cgr_safe every
+time a link goes up or down.
+
+Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
+CC: stable@vger.kernel.org
+Reported-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej@skbuf/
+Reported-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
+Closes: https://lore.kernel.org/linux-arm-kernel/87wmsyvclu.fsf@pengutronix.de/
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Reviewed-by: Camelia Groza <camelia.groza@nxp.com>
+Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qbman/qman.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index 3346593e0bc62..7abc9b6a04ab6 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -991,7 +991,7 @@ struct qman_portal {
+ /* linked-list of CSCN handlers. */
+ struct list_head cgr_cbs;
+ /* list lock */
+- spinlock_t cgr_lock;
++ raw_spinlock_t cgr_lock;
+ struct work_struct congestion_work;
+ struct work_struct mr_work;
+ char irqname[MAX_IRQNAME];
+@@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal *portal,
+ /* if the given mask is NULL, assume all CGRs can be seen */
+ qman_cgrs_fill(&portal->cgrs[0]);
+ INIT_LIST_HEAD(&portal->cgr_cbs);
+- spin_lock_init(&portal->cgr_lock);
++ raw_spin_lock_init(&portal->cgr_lock);
+ INIT_WORK(&portal->congestion_work, qm_congestion_task);
+ INIT_WORK(&portal->mr_work, qm_mr_process_task);
+ portal->bits = 0;
+@@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct *work)
+ union qm_mc_result *mcr;
+ struct qman_cgr *cgr;
+
+- spin_lock_irq(&p->cgr_lock);
++ /*
++ * FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
++ */
++ raw_spin_lock_irq(&p->cgr_lock);
+ qm_mc_start(&p->p);
+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
+ if (!qm_mc_result_timeout(&p->p, &mcr)) {
+- spin_unlock_irq(&p->cgr_lock);
++ raw_spin_unlock_irq(&p->cgr_lock);
+ dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
+ qman_p_irqsource_add(p, QM_PIRQ_CSCI);
+ return;
+@@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
+ list_for_each_entry(cgr, &p->cgr_cbs, node)
+ if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
+ cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
+- spin_unlock_irq(&p->cgr_lock);
++ raw_spin_unlock_irq(&p->cgr_lock);
+ qman_p_irqsource_add(p, QM_PIRQ_CSCI);
+ }
+
+@@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ preempt_enable();
+
+ cgr->chan = p->config->channel;
+- spin_lock_irq(&p->cgr_lock);
++ raw_spin_lock_irq(&p->cgr_lock);
+
+ if (opts) {
+ struct qm_mcc_initcgr local_opts = *opts;
+@@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
+ cgr->cb(p, cgr, 1);
+ out:
+- spin_unlock_irq(&p->cgr_lock);
++ raw_spin_unlock_irq(&p->cgr_lock);
+ put_affine_portal();
+ return ret;
+ }
+@@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
+ return -EINVAL;
+
+ memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
+- spin_lock_irqsave(&p->cgr_lock, irqflags);
++ raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
+ list_del(&cgr->node);
+ /*
+ * If there are no other CGR objects for this CGRID in the list,
+@@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
+ /* add back to the list */
+ list_add(&cgr->node, &p->cgr_cbs);
+ release_lock:
+- spin_unlock_irqrestore(&p->cgr_lock, irqflags);
++ raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+ put_affine_portal();
+ return ret;
+ }
+@@ -2577,9 +2580,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
+ if (!p)
+ return -EINVAL;
+
+- spin_lock_irqsave(&p->cgr_lock, irqflags);
++ raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
+ ret = qm_modify_cgr(cgr, 0, opts);
+- spin_unlock_irqrestore(&p->cgr_lock, irqflags);
++ raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+ put_affine_portal();
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From 5ea697059e8a7ce877b5e2998863f29a39b1222f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 21:28:08 -0800
+Subject: sparc: vDSO: fix return value of __setup handler
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 5378f00c935bebb846b1fdb0e79cb76c137c56b5 ]
+
+__setup() handlers should return 1 to obsolete_checksetup() in
+init/main.c to indicate that the boot option has been handled.
+A return of 0 causes the boot option/value to be listed as an Unknown
+kernel parameter and added to init's (limited) argument or environment
+strings. Also, error return codes don't mean anything to
+obsolete_checksetup() -- only non-zero (usually 1) or zero.
+So return 1 from vdso_setup().
+
+Fixes: 9a08862a5d2e ("vDSO for sparc")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: Igor Zhbanov <izh1979@gmail.com>
+Link: lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: sparclinux@vger.kernel.org
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: Nick Alcock <nick.alcock@oracle.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: stable@vger.kernel.org
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Andreas Larsson <andreas@gaisler.com>
+Signed-off-by: Andreas Larsson <andreas@gaisler.com>
+Link: https://lore.kernel.org/r/20240211052808.22635-1-rdunlap@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/sparc/vdso/vma.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
+index cc19e09b0fa1e..b073153c711ad 100644
+--- a/arch/sparc/vdso/vma.c
++++ b/arch/sparc/vdso/vma.c
+@@ -449,9 +449,8 @@ static __init int vdso_setup(char *s)
+ unsigned long val;
+
+ err = kstrtoul(s, 10, &val);
+- if (err)
+- return err;
+- vdso_enabled = val;
+- return 0;
++ if (!err)
++ vdso_enabled = val;
++ return 1;
+ }
+ __setup("vdso=", vdso_setup);
+--
+2.43.0
+
--- /dev/null
+From fd51a6f0bd54bf3499b199f2820028718ee6ea11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 21:28:02 -0800
+Subject: sparc64: NMI watchdog: fix return value of __setup handler
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 3ed7c61e49d65dacb96db798c0ab6fcd55a1f20f ]
+
+__setup() handlers should return 1 to obsolete_checksetup() in
+init/main.c to indicate that the boot option has been handled.
+A return of 0 causes the boot option/value to be listed as an Unknown
+kernel parameter and added to init's (limited) argument or environment
+strings. Also, error return codes don't mean anything to
+obsolete_checksetup() -- only non-zero (usually 1) or zero.
+So return 1 from setup_nmi_watchdog().
+
+Fixes: e5553a6d0442 ("sparc64: Implement NMI watchdog on capable cpus.")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: Igor Zhbanov <izh1979@gmail.com>
+Link: lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: sparclinux@vger.kernel.org
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: stable@vger.kernel.org
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Andreas Larsson <andreas@gaisler.com>
+Signed-off-by: Andreas Larsson <andreas@gaisler.com>
+Link: https://lore.kernel.org/r/20240211052802.22612-1-rdunlap@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/sparc/kernel/nmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
+index 060fff95a305c..fbf25e926f67c 100644
+--- a/arch/sparc/kernel/nmi.c
++++ b/arch/sparc/kernel/nmi.c
+@@ -274,7 +274,7 @@ static int __init setup_nmi_watchdog(char *str)
+ if (!strncmp(str, "panic", 5))
+ panic_on_timeout = 1;
+
+- return 0;
++ return 1;
+ }
+ __setup("nmi_watchdog=", setup_nmi_watchdog);
+
+--
+2.43.0
+
--- /dev/null
+From 58e334400f719036a246cbc04ad462bb5f9dbea0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Feb 2024 16:57:36 +0100
+Subject: speakup: Fix 8bit characters from direct synth
+
+From: Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+[ Upstream commit b6c8dafc9d86eb77e502bb018ec4105e8d2fbf78 ]
+
+When userland echoes 8bit characters to /dev/synth with e.g.
+
+echo -e '\xe9' > /dev/synth
+
+synth_write would get characters beyond 0x7f, and thus negative when
+char is signed. When given to synth_buffer_add which takes a u16, this
+would sign-extend and produce a U+ffxy character rather than U+xy.
+Users thus get garbled text instead of accents in their output.
+
+Let's fix this by making sure that we read unsigned characters.
+
+Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Fixes: 89fc2ae80bb1 ("speakup: extend synth buffer to 16bit unicode characters")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240204155736.2oh4ot7tiaa2wpbh@begin
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accessibility/speakup/synth.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/accessibility/speakup/synth.c b/drivers/accessibility/speakup/synth.c
+index ac47dbac72075..82cfc5ec6bdf9 100644
+--- a/drivers/accessibility/speakup/synth.c
++++ b/drivers/accessibility/speakup/synth.c
+@@ -208,8 +208,10 @@ void spk_do_flush(void)
+ wake_up_process(speakup_task);
+ }
+
+-void synth_write(const char *buf, size_t count)
++void synth_write(const char *_buf, size_t count)
+ {
++ const unsigned char *buf = (const unsigned char *) _buf;
++
+ while (count--)
+ synth_buffer_add(*buf++);
+ synth_start();
+--
+2.43.0
+
--- /dev/null
+From e317d6f28dc39f27f561d8cffd1f927282b51ddc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 21:18:44 +0100
+Subject: timers: Rename del_timer_sync() to timer_delete_sync()
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 9b13df3fb64ee95e2397585404e442afee2c7d4f ]
+
+The timer related functions do not have a strict timer_ prefixed namespace
+which is really annoying.
+
+Rename del_timer_sync() to timer_delete_sync() and provide del_timer_sync()
+as a wrapper. Document that del_timer_sync() is not for new code.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/r/20221123201624.954785441@linutronix.de
+Stable-dep-of: 0f7352557a35 ("wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/timer.h | 15 ++++++++++++++-
+ kernel/time/timer.c | 18 +++++++++---------
+ 2 files changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/timer.h b/include/linux/timer.h
+index a3125373139e1..a3d04c4f1263a 100644
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -183,7 +183,20 @@ extern int timer_reduce(struct timer_list *timer, unsigned long expires);
+ extern void add_timer(struct timer_list *timer);
+
+ extern int try_to_del_timer_sync(struct timer_list *timer);
+-extern int del_timer_sync(struct timer_list *timer);
++extern int timer_delete_sync(struct timer_list *timer);
++
++/**
++ * del_timer_sync - Delete a pending timer and wait for a running callback
++ * @timer: The timer to be deleted
++ *
++ * See timer_delete_sync() for detailed explanation.
++ *
++ * Do not use in new code. Use timer_delete_sync() instead.
++ */
++static inline int del_timer_sync(struct timer_list *timer)
++{
++ return timer_delete_sync(timer);
++}
+
+ #define del_singleshot_timer_sync(t) del_timer_sync(t)
+
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index 9edce790b3aa5..c135cefa44ac0 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1030,7 +1030,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int option
+ /*
+ * We are trying to schedule the timer on the new base.
+ * However we can't change timer's base while it is running,
+- * otherwise del_timer_sync() can't detect that the timer's
++ * otherwise timer_delete_sync() can't detect that the timer's
+ * handler yet has not finished. This also guarantees that the
+ * timer is serialized wrt itself.
+ */
+@@ -1206,7 +1206,7 @@ EXPORT_SYMBOL_GPL(add_timer_on);
+ * @timer: The timer to be deactivated
+ *
+ * The function only deactivates a pending timer, but contrary to
+- * del_timer_sync() it does not take into account whether the timer's
++ * timer_delete_sync() it does not take into account whether the timer's
+ * callback function is concurrently executed on a different CPU or not.
+ * It neither prevents rearming of the timer. If @timer can be rearmed
+ * concurrently then the return value of this function is meaningless.
+@@ -1342,7 +1342,7 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ #endif
+
+ /**
+- * del_timer_sync - Deactivate a timer and wait for the handler to finish.
++ * timer_delete_sync - Deactivate a timer and wait for the handler to finish.
+ * @timer: The timer to be deactivated
+ *
+ * Synchronization rules: Callers must prevent restarting of the timer,
+@@ -1364,10 +1364,10 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ * spin_lock_irq(somelock);
+ * <IRQ>
+ * spin_lock(somelock);
+- * del_timer_sync(mytimer);
++ * timer_delete_sync(mytimer);
+ * while (base->running_timer == mytimer);
+ *
+- * Now del_timer_sync() will never return and never release somelock.
++ * Now timer_delete_sync() will never return and never release somelock.
+ * The interrupt on the other CPU is waiting to grab somelock but it has
+ * interrupted the softirq that CPU0 is waiting to finish.
+ *
+@@ -1380,7 +1380,7 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ * * %0 - The timer was not pending
+ * * %1 - The timer was pending and deactivated
+ */
+-int del_timer_sync(struct timer_list *timer)
++int timer_delete_sync(struct timer_list *timer)
+ {
+ int ret;
+
+@@ -1413,7 +1413,7 @@ int del_timer_sync(struct timer_list *timer)
+
+ return ret;
+ }
+-EXPORT_SYMBOL(del_timer_sync);
++EXPORT_SYMBOL(timer_delete_sync);
+
+ static void call_timer_fn(struct timer_list *timer,
+ void (*fn)(struct timer_list *),
+@@ -1435,8 +1435,8 @@ static void call_timer_fn(struct timer_list *timer,
+ #endif
+ /*
+ * Couple the lock chain with the lock chain at
+- * del_timer_sync() by acquiring the lock_map around the fn()
+- * call here and in del_timer_sync().
++ * timer_delete_sync() by acquiring the lock_map around the fn()
++ * call here and in timer_delete_sync().
+ */
+ lock_map_acquire(&lockdep_map);
+
+--
+2.43.0
+
--- /dev/null
+From 1d7953a6a1ee7206baf560ff83ab36a839ac7d49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 21:18:40 +0100
+Subject: timers: Update kernel-doc for various functions
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 14f043f1340bf30bc60af127bff39f55889fef26 ]
+
+The kernel-doc of timer related functions is partially uncomprehensible
+word salad. Rewrite it to make it useful.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/r/20221123201624.828703870@linutronix.de
+Stable-dep-of: 0f7352557a35 ("wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/timer.c | 148 +++++++++++++++++++++++++++-----------------
+ 1 file changed, 90 insertions(+), 58 deletions(-)
+
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index e87e638c31bdf..3157a6434a615 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1068,14 +1068,16 @@ __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int option
+ }
+
+ /**
+- * mod_timer_pending - modify a pending timer's timeout
+- * @timer: the pending timer to be modified
+- * @expires: new timeout in jiffies
++ * mod_timer_pending - Modify a pending timer's timeout
++ * @timer: The pending timer to be modified
++ * @expires: New absolute timeout in jiffies
+ *
+- * mod_timer_pending() is the same for pending timers as mod_timer(),
+- * but will not re-activate and modify already deleted timers.
++ * mod_timer_pending() is the same for pending timers as mod_timer(), but
++ * will not activate inactive timers.
+ *
+- * It is useful for unserialized use of timers.
++ * Return:
++ * * %0 - The timer was inactive and not modified
++ * * %1 - The timer was active and requeued to expire at @expires
+ */
+ int mod_timer_pending(struct timer_list *timer, unsigned long expires)
+ {
+@@ -1084,24 +1086,27 @@ int mod_timer_pending(struct timer_list *timer, unsigned long expires)
+ EXPORT_SYMBOL(mod_timer_pending);
+
+ /**
+- * mod_timer - modify a timer's timeout
+- * @timer: the timer to be modified
+- * @expires: new timeout in jiffies
+- *
+- * mod_timer() is a more efficient way to update the expire field of an
+- * active timer (if the timer is inactive it will be activated)
++ * mod_timer - Modify a timer's timeout
++ * @timer: The timer to be modified
++ * @expires: New absolute timeout in jiffies
+ *
+ * mod_timer(timer, expires) is equivalent to:
+ *
+ * del_timer(timer); timer->expires = expires; add_timer(timer);
+ *
++ * mod_timer() is more efficient than the above open coded sequence. In
++ * case that the timer is inactive, the del_timer() part is a NOP. The
++ * timer is in any case activated with the new expiry time @expires.
++ *
+ * Note that if there are multiple unserialized concurrent users of the
+ * same timer, then mod_timer() is the only safe way to modify the timeout,
+ * since add_timer() cannot modify an already running timer.
+ *
+- * The function returns whether it has modified a pending timer or not.
+- * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an
+- * active timer returns 1.)
++ * Return:
++ * * %0 - The timer was inactive and started
++ * * %1 - The timer was active and requeued to expire at @expires or
++ * the timer was active and not modified because @expires did
++ * not change the effective expiry time
+ */
+ int mod_timer(struct timer_list *timer, unsigned long expires)
+ {
+@@ -1112,11 +1117,18 @@ EXPORT_SYMBOL(mod_timer);
+ /**
+ * timer_reduce - Modify a timer's timeout if it would reduce the timeout
+ * @timer: The timer to be modified
+- * @expires: New timeout in jiffies
++ * @expires: New absolute timeout in jiffies
+ *
+ * timer_reduce() is very similar to mod_timer(), except that it will only
+- * modify a running timer if that would reduce the expiration time (it will
+- * start a timer that isn't running).
++ * modify an enqueued timer if that would reduce the expiration time. If
++ * @timer is not enqueued it starts the timer.
++ *
++ * Return:
++ * * %0 - The timer was inactive and started
++ * * %1 - The timer was active and requeued to expire at @expires or
++ * the timer was active and not modified because @expires
++ * did not change the effective expiry time such that the
++ * timer would expire earlier than already scheduled
+ */
+ int timer_reduce(struct timer_list *timer, unsigned long expires)
+ {
+@@ -1125,18 +1137,21 @@ int timer_reduce(struct timer_list *timer, unsigned long expires)
+ EXPORT_SYMBOL(timer_reduce);
+
+ /**
+- * add_timer - start a timer
+- * @timer: the timer to be added
++ * add_timer - Start a timer
++ * @timer: The timer to be started
+ *
+- * The kernel will do a ->function(@timer) callback from the
+- * timer interrupt at the ->expires point in the future. The
+- * current time is 'jiffies'.
++ * Start @timer to expire at @timer->expires in the future. @timer->expires
++ * is the absolute expiry time measured in 'jiffies'. When the timer expires
++ * timer->function(timer) will be invoked from soft interrupt context.
+ *
+- * The timer's ->expires, ->function fields must be set prior calling this
+- * function.
++ * The @timer->expires and @timer->function fields must be set prior
++ * to calling this function.
++ *
++ * If @timer->expires is already in the past @timer will be queued to
++ * expire at the next timer tick.
+ *
+- * Timers with an ->expires field in the past will be executed in the next
+- * timer tick.
++ * This can only operate on an inactive timer. Attempts to invoke this on
++ * an active timer are rejected with a warning.
+ */
+ void add_timer(struct timer_list *timer)
+ {
+@@ -1146,11 +1161,13 @@ void add_timer(struct timer_list *timer)
+ EXPORT_SYMBOL(add_timer);
+
+ /**
+- * add_timer_on - start a timer on a particular CPU
+- * @timer: the timer to be added
+- * @cpu: the CPU to start it on
++ * add_timer_on - Start a timer on a particular CPU
++ * @timer: The timer to be started
++ * @cpu: The CPU to start it on
++ *
++ * Same as add_timer() except that it starts the timer on the given CPU.
+ *
+- * This is not very scalable on SMP. Double adds are not possible.
++ * See add_timer() for further details.
+ */
+ void add_timer_on(struct timer_list *timer, int cpu)
+ {
+@@ -1185,15 +1202,18 @@ void add_timer_on(struct timer_list *timer, int cpu)
+ EXPORT_SYMBOL_GPL(add_timer_on);
+
+ /**
+- * del_timer - deactivate a timer.
+- * @timer: the timer to be deactivated
+- *
+- * del_timer() deactivates a timer - this works on both active and inactive
+- * timers.
+- *
+- * The function returns whether it has deactivated a pending timer or not.
+- * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
+- * active timer returns 1.)
++ * del_timer - Deactivate a timer.
++ * @timer: The timer to be deactivated
++ *
++ * The function only deactivates a pending timer, but contrary to
++ * del_timer_sync() it does not take into account whether the timer's
++ * callback function is concurrently executed on a different CPU or not.
++ * It neither prevents rearming of the timer. If @timer can be rearmed
++ * concurrently then the return value of this function is meaningless.
++ *
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending and deactivated
+ */
+ int del_timer(struct timer_list *timer)
+ {
+@@ -1215,10 +1235,19 @@ EXPORT_SYMBOL(del_timer);
+
+ /**
+ * try_to_del_timer_sync - Try to deactivate a timer
+- * @timer: timer to delete
++ * @timer: Timer to deactivate
++ *
++ * This function tries to deactivate a timer. On success the timer is not
++ * queued and the timer callback function is not running on any CPU.
+ *
+- * This function tries to deactivate a timer. Upon successful (ret >= 0)
+- * exit the timer is not queued and the handler is not running on any CPU.
++ * This function does not guarantee that the timer cannot be rearmed right
++ * after dropping the base lock. That needs to be prevented by the calling
++ * code if necessary.
++ *
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending and deactivated
++ * * %-1 - The timer callback function is running on a different CPU
+ */
+ int try_to_del_timer_sync(struct timer_list *timer)
+ {
+@@ -1314,23 +1343,19 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+
+ #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+ /**
+- * del_timer_sync - deactivate a timer and wait for the handler to finish.
+- * @timer: the timer to be deactivated
+- *
+- * This function only differs from del_timer() on SMP: besides deactivating
+- * the timer it also makes sure the handler has finished executing on other
+- * CPUs.
++ * del_timer_sync - Deactivate a timer and wait for the handler to finish.
++ * @timer: The timer to be deactivated
+ *
+ * Synchronization rules: Callers must prevent restarting of the timer,
+ * otherwise this function is meaningless. It must not be called from
+ * interrupt contexts unless the timer is an irqsafe one. The caller must
+- * not hold locks which would prevent completion of the timer's
+- * handler. The timer's handler must not call add_timer_on(). Upon exit the
+- * timer is not queued and the handler is not running on any CPU.
++ * not hold locks which would prevent completion of the timer's callback
++ * function. The timer's handler must not call add_timer_on(). Upon exit
++ * the timer is not queued and the handler is not running on any CPU.
+ *
+- * Note: For !irqsafe timers, you must not hold locks that are held in
+- * interrupt context while calling this function. Even if the lock has
+- * nothing to do with the timer in question. Here's why::
++ * For !irqsafe timers, the caller must not hold locks that are held in
++ * interrupt context. Even if the lock has nothing to do with the timer in
++ * question. Here's why::
+ *
+ * CPU0 CPU1
+ * ---- ----
+@@ -1344,10 +1369,17 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ * while (base->running_timer == mytimer);
+ *
+ * Now del_timer_sync() will never return and never release somelock.
+- * The interrupt on the other CPU is waiting to grab somelock but
+- * it has interrupted the softirq that CPU0 is waiting to finish.
++ * The interrupt on the other CPU is waiting to grab somelock but it has
++ * interrupted the softirq that CPU0 is waiting to finish.
++ *
++ * This function cannot guarantee that the timer is not rearmed again by
++ * some concurrent or preempting code, right after it dropped the base
++ * lock. If there is the possibility of a concurrent rearm then the return
++ * value of the function is meaningless.
+ *
+- * The function returns whether it has deactivated a pending timer or not.
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending and deactivated
+ */
+ int del_timer_sync(struct timer_list *timer)
+ {
+--
+2.43.0
+
--- /dev/null
+From d67a1722d1c09e23ff04481508440eb1577b5789 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 21:18:42 +0100
+Subject: timers: Use del_timer_sync() even on UP
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 168f6b6ffbeec0b9333f3582e4cf637300858db5 ]
+
+del_timer_sync() is assumed to be pointless on uniprocessor systems and can
+be mapped to del_timer() because in theory del_timer() can never be invoked
+while the timer callback function is executed.
+
+This is not entirely true because del_timer() can be invoked from interrupt
+context and therefore hit in the middle of a running timer callback.
+
+Contrary to that del_timer_sync() is not allowed to be invoked from
+interrupt context unless the affected timer is marked with TIMER_IRQSAFE.
+del_timer_sync() has proper checks in place to detect such a situation.
+
+Give up on the UP optimization and make del_timer_sync() unconditionally
+available.
+
+Co-developed-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home
+Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org
+Link: https://lore.kernel.org/r/20221123201624.888306160@linutronix.de
+Stable-dep-of: 0f7352557a35 ("wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/timer.h | 7 +------
+ kernel/time/timer.c | 2 --
+ 2 files changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/include/linux/timer.h b/include/linux/timer.h
+index d10bc7e73b41e..a3125373139e1 100644
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -183,12 +183,7 @@ extern int timer_reduce(struct timer_list *timer, unsigned long expires);
+ extern void add_timer(struct timer_list *timer);
+
+ extern int try_to_del_timer_sync(struct timer_list *timer);
+-
+-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+- extern int del_timer_sync(struct timer_list *timer);
+-#else
+-# define del_timer_sync(t) del_timer(t)
+-#endif
++extern int del_timer_sync(struct timer_list *timer);
+
+ #define del_singleshot_timer_sync(t) del_timer_sync(t)
+
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index 3157a6434a615..9edce790b3aa5 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1341,7 +1341,6 @@ static inline void timer_sync_wait_running(struct timer_base *base) { }
+ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ #endif
+
+-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+ /**
+ * del_timer_sync - Deactivate a timer and wait for the handler to finish.
+ * @timer: The timer to be deactivated
+@@ -1415,7 +1414,6 @@ int del_timer_sync(struct timer_list *timer)
+ return ret;
+ }
+ EXPORT_SYMBOL(del_timer_sync);
+-#endif
+
+ static void call_timer_fn(struct timer_list *timer,
+ void (*fn)(struct timer_list *),
+--
+2.43.0
+
--- /dev/null
+From 06db762ffd5f463b2a165ce57dfa72116467db07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 07:37:02 +0100
+Subject: ubi: Check for too small LEB size in VTBL code
+
+From: Richard Weinberger <richard@nod.at>
+
+[ Upstream commit 68a24aba7c593eafa8fd00f2f76407b9b32b47a9 ]
+
+If the LEB size is smaller than a volume table record we cannot
+have volumes.
+In this case abort attaching.
+
+Cc: Chenyuan Yang <cy54@illinois.edu>
+Cc: stable@vger.kernel.org
+Fixes: 801c135ce73d ("UBI: Unsorted Block Images")
+Reported-by: Chenyuan Yang <cy54@illinois.edu>
+Closes: https://lore.kernel.org/linux-mtd/1433EB7A-FC89-47D6-8F47-23BE41B263B3@illinois.edu/
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/vtbl.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
+index f700f0e4f2ec4..6e5489e233dd2 100644
+--- a/drivers/mtd/ubi/vtbl.c
++++ b/drivers/mtd/ubi/vtbl.c
+@@ -791,6 +791,12 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai)
+ * The number of supported volumes is limited by the eraseblock size
+ * and by the UBI_MAX_VOLUMES constant.
+ */
++
++ if (ubi->leb_size < UBI_VTBL_RECORD_SIZE) {
++ ubi_err(ubi, "LEB size too small for a volume record");
++ return -EINVAL;
++ }
++
+ ubi->vtbl_slots = ubi->leb_size / UBI_VTBL_RECORD_SIZE;
+ if (ubi->vtbl_slots > UBI_MAX_VOLUMES)
+ ubi->vtbl_slots = UBI_MAX_VOLUMES;
+--
+2.43.0
+
--- /dev/null
+From fe0a8c8937cd8f5f5288239d7cac11545362cbcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 10:49:03 +0800
+Subject: ubi: correct the calculation of fastmap size
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit 7f174ae4f39e8475adcc09d26c5a43394689ad6c ]
+
+Now that the calculation of fastmap size in ubi_calc_fm_size() is
+incorrect since it miss each user volume's ubi_fm_eba structure and the
+Internal UBI volume info. Let's correct the calculation.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/fastmap.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
+index 6e95c4b1473e6..8081fc760d34f 100644
+--- a/drivers/mtd/ubi/fastmap.c
++++ b/drivers/mtd/ubi/fastmap.c
+@@ -86,9 +86,10 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi)
+ sizeof(struct ubi_fm_scan_pool) +
+ sizeof(struct ubi_fm_scan_pool) +
+ (ubi->peb_count * sizeof(struct ubi_fm_ec)) +
+- (sizeof(struct ubi_fm_eba) +
+- (ubi->peb_count * sizeof(__be32))) +
+- sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
++ ((sizeof(struct ubi_fm_eba) +
++ sizeof(struct ubi_fm_volhdr)) *
++ (UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT)) +
++ (ubi->peb_count * sizeof(__be32));
+ return roundup(size, ubi->leb_size);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 3ec1e0be5928294a005ebaef261102b5b1f5fd38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 17:52:44 +0000
+Subject: ubifs: Set page uptodate in the correct place
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit 723012cab779eee8228376754e22c6594229bf8f ]
+
+Page cache reads are lockless, so setting the freshly allocated page
+uptodate before we've overwritten it with the data it's supposed to have
+in it will allow a simultaneous reader to see old data. Move the call
+to SetPageUptodate into ubifs_write_end(), which is after we copied the
+new data into the page.
+
+Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
+Cc: stable@vger.kernel.org
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/file.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
+index 19fdcda045890..18df7a82517fa 100644
+--- a/fs/ubifs/file.c
++++ b/fs/ubifs/file.c
+@@ -262,9 +262,6 @@ static int write_begin_slow(struct address_space *mapping,
+ return err;
+ }
+ }
+-
+- SetPageUptodate(page);
+- ClearPageError(page);
+ }
+
+ if (PagePrivate(page))
+@@ -463,9 +460,6 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
+ return err;
+ }
+ }
+-
+- SetPageUptodate(page);
+- ClearPageError(page);
+ }
+
+ err = allocate_budget(c, page, ui, appending);
+@@ -475,10 +469,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
+ * If we skipped reading the page because we were going to
+ * write all of it, then it is not up to date.
+ */
+- if (skipped_read) {
++ if (skipped_read)
+ ClearPageChecked(page);
+- ClearPageUptodate(page);
+- }
+ /*
+ * Budgeting failed which means it would have to force
+ * write-back but didn't, because we set the @fast flag in the
+@@ -569,6 +561,9 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
+ goto out;
+ }
+
++ if (len == PAGE_SIZE)
++ SetPageUptodate(page);
++
+ if (!PagePrivate(page)) {
+ attach_page_private(page, (void *)1);
+ atomic_long_inc(&c->dirty_pg_cnt);
+--
+2.43.0
+
--- /dev/null
+From e0743fd7b8a9a20edcd9160c005624b78d754ed8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 11:03:28 +0800
+Subject: usb: gadget: tegra-xudc: Fix USB3 PHY retrieval logic
+
+From: Wayne Chang <waynec@nvidia.com>
+
+[ Upstream commit 84fa943d93c31ee978355e6c6c69592dae3c9f59 ]
+
+This commit resolves an issue in the tegra-xudc USB gadget driver that
+incorrectly fetched USB3 PHY instances. The problem stemmed from the
+assumption of a one-to-one correspondence between USB2 and USB3 PHY
+names and their association with physical USB ports in the device tree.
+
+Previously, the driver associated USB3 PHY names directly with the USB3
+instance number, leading to mismatches when mapping the physical USB
+ports. For instance, if using USB3-1 PHY, the driver expect the
+corresponding PHY name as 'usb3-1'. However, the physical USB ports in
+the device tree were designated as USB2-0 and USB3-0 as we only have
+one device controller, causing a misalignment.
+
+This commit rectifies the issue by adjusting the PHY naming logic.
+Now, the driver correctly correlates the USB2 and USB3 PHY instances,
+allowing the USB2-0 and USB3-1 PHYs to form a physical USB port pair
+while accurately reflecting their configuration in the device tree by
+naming them USB2-0 and USB3-0, respectively.
+
+The change ensures that the PHY and PHY names align appropriately,
+resolving the mismatch between physical USB ports and their associated
+names in the device tree.
+
+Fixes: b4e19931c98a ("usb: gadget: tegra-xudc: Support multiple device modes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Tested-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://lore.kernel.org/r/20240307030328.1487748-3-waynec@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/tegra-xudc.c | 39 ++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index 23e31eec442dc..9d3e36c867e83 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -3480,8 +3480,8 @@ static void tegra_xudc_device_params_init(struct tegra_xudc *xudc)
+
+ static int tegra_xudc_phy_get(struct tegra_xudc *xudc)
+ {
+- int err = 0, usb3;
+- unsigned int i;
++ int err = 0, usb3_companion_port;
++ unsigned int i, j;
+
+ xudc->utmi_phy = devm_kcalloc(xudc->dev, xudc->soc->num_phys,
+ sizeof(*xudc->utmi_phy), GFP_KERNEL);
+@@ -3509,7 +3509,7 @@ static int tegra_xudc_phy_get(struct tegra_xudc *xudc)
+ if (IS_ERR(xudc->utmi_phy[i])) {
+ err = PTR_ERR(xudc->utmi_phy[i]);
+ dev_err_probe(xudc->dev, err,
+- "failed to get usb2-%d PHY\n", i);
++ "failed to get PHY for phy-name usb2-%d\n", i);
+ goto clean_up;
+ } else if (xudc->utmi_phy[i]) {
+ /* Get usb-phy, if utmi phy is available */
+@@ -3528,19 +3528,30 @@ static int tegra_xudc_phy_get(struct tegra_xudc *xudc)
+ }
+
+ /* Get USB3 phy */
+- usb3 = tegra_xusb_padctl_get_usb3_companion(xudc->padctl, i);
+- if (usb3 < 0)
++ usb3_companion_port = tegra_xusb_padctl_get_usb3_companion(xudc->padctl, i);
++ if (usb3_companion_port < 0)
+ continue;
+
+- snprintf(phy_name, sizeof(phy_name), "usb3-%d", usb3);
+- xudc->usb3_phy[i] = devm_phy_optional_get(xudc->dev, phy_name);
+- if (IS_ERR(xudc->usb3_phy[i])) {
+- err = PTR_ERR(xudc->usb3_phy[i]);
+- dev_err_probe(xudc->dev, err,
+- "failed to get usb3-%d PHY\n", usb3);
+- goto clean_up;
+- } else if (xudc->usb3_phy[i])
+- dev_dbg(xudc->dev, "usb3-%d PHY registered", usb3);
++ for (j = 0; j < xudc->soc->num_phys; j++) {
++ snprintf(phy_name, sizeof(phy_name), "usb3-%d", j);
++ xudc->usb3_phy[i] = devm_phy_optional_get(xudc->dev, phy_name);
++ if (IS_ERR(xudc->usb3_phy[i])) {
++ err = PTR_ERR(xudc->usb3_phy[i]);
++ dev_err_probe(xudc->dev, err,
++ "failed to get PHY for phy-name usb3-%d\n", j);
++ goto clean_up;
++ } else if (xudc->usb3_phy[i]) {
++ int usb2_port =
++ tegra_xusb_padctl_get_port_number(xudc->utmi_phy[i]);
++ int usb3_port =
++ tegra_xusb_padctl_get_port_number(xudc->usb3_phy[i]);
++ if (usb3_port == usb3_companion_port) {
++ dev_dbg(xudc->dev, "USB2 port %d is paired with USB3 port %d for device mode port %d\n",
++ usb2_port, usb3_port, i);
++ break;
++ }
++ }
++ }
+ }
+
+ return err;
+--
+2.43.0
+
--- /dev/null
+From fee47f9ccf926f490c48b150cd2231635a115719 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 May 2021 17:35:53 +0100
+Subject: usb: gadget: tegra-xudc: Use dev_err_probe()
+
+From: Jon Hunter <jonathanh@nvidia.com>
+
+[ Upstream commit 77b57218ac2f37da4e8b72e78f002944b9f85091 ]
+
+Rather than testing if the error code is -EPROBE_DEFER before printing
+an error message, use dev_err_probe() instead to simplify the code.
+
+Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://lore.kernel.org/r/20210519163553.212682-2-jonathanh@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 84fa943d93c3 ("usb: gadget: tegra-xudc: Fix USB3 PHY retrieval logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/tegra-xudc.c | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index c5f0fbb8ffe47..23e31eec442dc 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -3508,10 +3508,8 @@ static int tegra_xudc_phy_get(struct tegra_xudc *xudc)
+ xudc->utmi_phy[i] = devm_phy_optional_get(xudc->dev, phy_name);
+ if (IS_ERR(xudc->utmi_phy[i])) {
+ err = PTR_ERR(xudc->utmi_phy[i]);
+- if (err != -EPROBE_DEFER)
+- dev_err(xudc->dev, "failed to get usb2-%d PHY: %d\n",
+- i, err);
+-
++ dev_err_probe(xudc->dev, err,
++ "failed to get usb2-%d PHY\n", i);
+ goto clean_up;
+ } else if (xudc->utmi_phy[i]) {
+ /* Get usb-phy, if utmi phy is available */
+@@ -3538,10 +3536,8 @@ static int tegra_xudc_phy_get(struct tegra_xudc *xudc)
+ xudc->usb3_phy[i] = devm_phy_optional_get(xudc->dev, phy_name);
+ if (IS_ERR(xudc->usb3_phy[i])) {
+ err = PTR_ERR(xudc->usb3_phy[i]);
+- if (err != -EPROBE_DEFER)
+- dev_err(xudc->dev, "failed to get usb3-%d PHY: %d\n",
+- usb3, err);
+-
++ dev_err_probe(xudc->dev, err,
++ "failed to get usb3-%d PHY\n", usb3);
+ goto clean_up;
+ } else if (xudc->usb3_phy[i])
+ dev_dbg(xudc->dev, "usb3-%d PHY registered", usb3);
+@@ -3781,9 +3777,7 @@ static int tegra_xudc_probe(struct platform_device *pdev)
+
+ err = devm_clk_bulk_get(&pdev->dev, xudc->soc->num_clks, xudc->clks);
+ if (err) {
+- if (err != -EPROBE_DEFER)
+- dev_err(xudc->dev, "failed to request clocks: %d\n", err);
+-
++ dev_err_probe(xudc->dev, err, "failed to request clocks\n");
+ return err;
+ }
+
+@@ -3798,9 +3792,7 @@ static int tegra_xudc_probe(struct platform_device *pdev)
+ err = devm_regulator_bulk_get(&pdev->dev, xudc->soc->num_supplies,
+ xudc->supplies);
+ if (err) {
+- if (err != -EPROBE_DEFER)
+- dev_err(xudc->dev, "failed to request regulators: %d\n", err);
+-
++ dev_err_probe(xudc->dev, err, "failed to request regulators\n");
+ return err;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 183ea6027af65572ee949c37376b4509e321ede2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 21:53:29 +0000
+Subject: USB: serial: add device ID for VeriFone adapter
+
+From: Cameron Williams <cang1@live.co.uk>
+
+[ Upstream commit cda704809797a8a86284f9df3eef5e62ec8a3175 ]
+
+Add device ID for a (probably fake) CP2102 UART device.
+
+lsusb -v output:
+
+Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 1.10
+ bDeviceClass 0 [unknown]
+ bDeviceSubClass 0 [unknown]
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ idVendor 0x11ca VeriFone Inc
+ idProduct 0x0212 Verifone USB to Printer
+ bcdDevice 1.00
+ iManufacturer 1 Silicon Labs
+ iProduct 2 Verifone USB to Printer
+ iSerial 3 0001
+ bNumConfigurations 1
+ Configuration Descriptor:
+ bLength 9
+ bDescriptorType 2
+ wTotalLength 0x0020
+ bNumInterfaces 1
+ bConfigurationValue 1
+ iConfiguration 0
+ bmAttributes 0x80
+ (Bus Powered)
+ MaxPower 100mA
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 0
+ bAlternateSetting 0
+ bNumEndpoints 2
+ bInterfaceClass 255 Vendor Specific Class
+ bInterfaceSubClass 0 [unknown]
+ bInterfaceProtocol 0
+ iInterface 2 Verifone USB to Printer
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x81 EP 1 IN
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0040 1x 64 bytes
+ bInterval 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x01 EP 1 OUT
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0040 1x 64 bytes
+ bInterval 0
+Device Status: 0x0000
+ (Bus Powered)
+
+Signed-off-by: Cameron Williams <cang1@live.co.uk>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/cp210x.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index d161b64416a48..f4c982a323df2 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -181,6 +181,7 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
+ { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
+ { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */
++ { USB_DEVICE(0x11CA, 0x0212) }, /* Verifone USB to Printer (UART, CP2102) */
+ { USB_DEVICE(0x12B8, 0xEC60) }, /* Link G4 ECU */
+ { USB_DEVICE(0x12B8, 0xEC62) }, /* Link G4+ ECU */
+ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
+--
+2.43.0
+
--- /dev/null
+From c75bdb2c0b1e1df9f8f045cb5a39d26f7934bad1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 11:47:29 +0100
+Subject: USB: serial: cp210x: add ID for MGP Instruments PDS100
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian Häggström <christian.haggstrom@orexplore.com>
+
+[ Upstream commit a0d9d868491a362d421521499d98308c8e3a0398 ]
+
+The radiation meter has the text MGP Instruments PDS-100G or PDS-100GN
+produced by Mirion Technologies. Tested by forcing the driver
+association with
+
+ echo 10c4 863c > /sys/bus/usb-serial/drivers/cp210x/new_id
+
+and then setting the serial port in 115200 8N1 mode. The device
+announces ID_USB_VENDOR_ENC=Silicon\x20Labs and ID_USB_MODEL_ENC=PDS100
+
+Signed-off-by: Christian Häggström <christian.haggstrom@orexplore.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/cp210x.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index f4c982a323df2..12d0be4d15101 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -148,6 +148,7 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */
+ { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
+ { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
++ { USB_DEVICE(0x10C4, 0x863C) }, /* MGP Instruments PDS100 */
+ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
+ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
+ { USB_DEVICE(0x10C4, 0x87ED) }, /* IMST USB-Stick for Smart Meter */
+--
+2.43.0
+
--- /dev/null
+From d79e8827ab33555999be193d8b0610f0029b5356 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 08:46:14 +0900
+Subject: USB: serial: cp210x: add pid/vid for TDK NC0110013M and MM0110113M
+
+From: Toru Katagiri <Toru.Katagiri@tdk.com>
+
+[ Upstream commit b1a8da9ff1395c4879b4bd41e55733d944f3d613 ]
+
+TDK NC0110013M and MM0110113M have custom USB IDs for CP210x,
+so we need to add them to the driver.
+
+Signed-off-by: Toru Katagiri <Toru.Katagiri@tdk.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/cp210x.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 12d0be4d15101..294f7f01656aa 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -60,6 +60,8 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
+ { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
+ { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
++ { USB_DEVICE(0x04BF, 0x1301) }, /* TDK Corporation NC0110013M - Network Controller */
++ { USB_DEVICE(0x04BF, 0x1303) }, /* TDK Corporation MM0110113M - i3 Micro Module */
+ { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
+ { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */
+ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
+--
+2.43.0
+
--- /dev/null
+From 736aa4d470aef7f71f480c3d782a18afdf9f2802 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Feb 2024 15:42:46 +0100
+Subject: USB: serial: ftdi_sio: add support for GMC Z216C Adapter IR-USB
+
+From: Daniel Vogelbacher <daniel@chaospixel.com>
+
+[ Upstream commit 3fb7bc4f3a98c48981318b87cf553c5f115fd5ca ]
+
+The GMC IR-USB adapter cable utilizes a FTDI FT232R chip.
+
+Add VID/PID for this adapter so it can be used as serial device via
+ftdi_sio.
+
+Signed-off-by: Daniel Vogelbacher <daniel@chaospixel.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/ftdi_sio.c | 2 ++
+ drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 4d7f4a4ab69fb..66aa999efa6d5 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1055,6 +1055,8 @@ static const struct usb_device_id id_table_combined[] = {
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ /* GMC devices */
++ { USB_DEVICE(GMC_VID, GMC_Z216C_PID) },
+ { } /* Terminating entry */
+ };
+
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index 9a0f9fc991246..b2aec1106678a 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -1599,3 +1599,9 @@
+ #define UBLOX_VID 0x1546
+ #define UBLOX_C099F9P_ZED_PID 0x0502
+ #define UBLOX_C099F9P_ODIN_PID 0x0503
++
++/*
++ * GMC devices
++ */
++#define GMC_VID 0x1cd7
++#define GMC_Z216C_PID 0x0217 /* GMC Z216C Adapter IR-USB */
+--
+2.43.0
+
--- /dev/null
+From 2368cc984c4f8d2796525f25f73f012337187099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 18:49:17 +0100
+Subject: USB: serial: option: add MeiG Smart SLM320 product
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aurélien Jacobs <aurel@gnuage.org>
+
+[ Upstream commit 46809c51565b83881aede6cdf3b0d25254966a41 ]
+
+Update the USB serial option driver to support MeiG Smart SLM320.
+
+ID 2dee:4d41 UNISOC UNISOC-8910
+
+T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 9 Spd=480 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=2dee ProdID=4d41 Rev=00.00
+S: Manufacturer=UNISOC
+S: Product=UNISOC-8910
+C: #Ifs= 8 Cfg#= 1 Atr=e0 MxPwr=400mA
+I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 7 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=08(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Tested successfully a PPP LTE connection using If#= 0.
+Not sure of the purpose of every other serial interfaces.
+
+Signed-off-by: Aurélien Jacobs <aurel@gnuage.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/option.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 43e8cb17b4c7a..fb1eba835e508 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -613,6 +613,11 @@ static void option_instat_callback(struct urb *urb);
+ /* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */
+ #define LUAT_PRODUCT_AIR720U 0x4e00
+
++/* MeiG Smart Technology products */
++#define MEIGSMART_VENDOR_ID 0x2dee
++/* MeiG Smart SLM320 based on UNISOC UIS8910 */
++#define MEIGSMART_PRODUCT_SLM320 0x4d41
++
+ /* Device flags */
+
+ /* Highest interface number which can be used with NCTRL() and RSVD() */
+@@ -2282,6 +2287,7 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+--
+2.43.0
+
--- /dev/null
+From d6ec93faf7b40220b32c6d1da73917c140957569 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 02:58:01 +0000
+Subject: usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
+
+From: Jameson Thies <jthies@google.com>
+
+[ Upstream commit 4d0a5a9915793377c0fe1a8d78de6bcd92cea963 ]
+
+Clean up UCSI_CABLE_PROP macros by fixing a bitmask shifting error for
+plug type and updating the modal support macro for consistent naming.
+
+Fixes: 3cf657f07918 ("usb: typec: ucsi: Remove all bit-fields")
+Cc: stable@vger.kernel.org
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Reviewed-by: Prashant Malani <pmalani@chromium.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Jameson Thies <jthies@google.com>
+Link: https://lore.kernel.org/r/20240305025804.1290919-2-jthies@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
+index fce23ad16c6d0..41e1a64da82e8 100644
+--- a/drivers/usb/typec/ucsi/ucsi.h
++++ b/drivers/usb/typec/ucsi/ucsi.h
+@@ -219,12 +219,12 @@ struct ucsi_cable_property {
+ #define UCSI_CABLE_PROP_FLAG_VBUS_IN_CABLE BIT(0)
+ #define UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE BIT(1)
+ #define UCSI_CABLE_PROP_FLAG_DIRECTIONALITY BIT(2)
+-#define UCSI_CABLE_PROP_FLAG_PLUG_TYPE(_f_) ((_f_) & GENMASK(3, 0))
++#define UCSI_CABLE_PROP_FLAG_PLUG_TYPE(_f_) (((_f_) & GENMASK(4, 3)) >> 3)
+ #define UCSI_CABLE_PROPERTY_PLUG_TYPE_A 0
+ #define UCSI_CABLE_PROPERTY_PLUG_TYPE_B 1
+ #define UCSI_CABLE_PROPERTY_PLUG_TYPE_C 2
+ #define UCSI_CABLE_PROPERTY_PLUG_OTHER 3
+-#define UCSI_CABLE_PROP_MODE_SUPPORT BIT(5)
++#define UCSI_CABLE_PROP_FLAG_MODE_SUPPORT BIT(5)
+ u8 latency;
+ } __packed;
+
+--
+2.43.0
+
--- /dev/null
+From a3c1763e61d6ff1f11d59c21006c8850ed7748a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 16:05:26 -0700
+Subject: vfio/platform: Disable virqfds on cleanup
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+[ Upstream commit fcdc0d3d40bc26c105acf8467f7d9018970944ae ]
+
+irqfds for mask and unmask that are not specifically disabled by the
+user are leaked. Remove any irqfds during cleanup
+
+Cc: Eric Auger <eric.auger@redhat.com>
+Cc: <stable@vger.kernel.org>
+Fixes: a7fa7c77cf15 ("vfio/platform: implement IRQ masking/unmasking via an eventfd")
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Link: https://lore.kernel.org/r/20240308230557.805580-6-alex.williamson@redhat.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/platform/vfio_platform_irq.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
+index c5b09ec0a3c98..f2893f2fcaabd 100644
+--- a/drivers/vfio/platform/vfio_platform_irq.c
++++ b/drivers/vfio/platform/vfio_platform_irq.c
+@@ -321,8 +321,11 @@ void vfio_platform_irq_cleanup(struct vfio_platform_device *vdev)
+ {
+ int i;
+
+- for (i = 0; i < vdev->num_irqs; i++)
++ for (i = 0; i < vdev->num_irqs; i++) {
++ vfio_virqfd_disable(&vdev->irqs[i].mask);
++ vfio_virqfd_disable(&vdev->irqs[i].unmask);
+ vfio_set_trigger(vdev, i, -1, NULL);
++ }
+
+ vdev->num_irqs = 0;
+ kfree(vdev->irqs);
+--
+2.43.0
+
--- /dev/null
+From b1a83b715ca435c787ea0a48ddadcdbf320dcaea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Oct 2020 16:55:33 +0800
+Subject: vxge: remove unnecessary cast in kfree()
+
+From: Xu Wang <vulab@iscas.ac.cn>
+
+[ Upstream commit b6bf4776d9e2ed4b2552d1c252fff8de3786309a ]
+
+Remove unnecessary cast in the argument to kfree.
+
+Signed-off-by: Xu Wang <vulab@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20201023085533.4792-1-vulab@iscas.ac.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: e3f269ed0acc ("x86/pm: Work around false positive kmemleak report in msr_build_context()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/neterion/vxge/vxge-config.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c
+index f5d48d7c4ce28..da48dd85770c0 100644
+--- a/drivers/net/ethernet/neterion/vxge/vxge-config.c
++++ b/drivers/net/ethernet/neterion/vxge/vxge-config.c
+@@ -1121,7 +1121,7 @@ static void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool)
+
+ list_for_each_safe(p, n, &blockpool->free_entry_list) {
+ list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
+- kfree((void *)p);
++ kfree(p);
+ }
+
+ return;
+--
+2.43.0
+
--- /dev/null
+From 2dff90d4ac19d5f7902c8ce0a656a282b23be185 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jan 2024 08:25:04 +0100
+Subject: wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach
+
+From: Zheng Wang <zyytlz.wz@163.com>
+
+[ Upstream commit 0f7352557a35ab7888bc7831411ec8a3cbe20d78 ]
+
+This is the candidate patch of CVE-2023-47233 :
+https://nvd.nist.gov/vuln/detail/CVE-2023-47233
+
+In brcm80211 driver,it starts with the following invoking chain
+to start init a timeout worker:
+
+->brcmf_usb_probe
+ ->brcmf_usb_probe_cb
+ ->brcmf_attach
+ ->brcmf_bus_started
+ ->brcmf_cfg80211_attach
+ ->wl_init_priv
+ ->brcmf_init_escan
+ ->INIT_WORK(&cfg->escan_timeout_work,
+ brcmf_cfg80211_escan_timeout_worker);
+
+If we disconnect the USB by hotplug, it will call
+brcmf_usb_disconnect to make cleanup. The invoking chain is :
+
+brcmf_usb_disconnect
+ ->brcmf_usb_disconnect_cb
+ ->brcmf_detach
+ ->brcmf_cfg80211_detach
+ ->kfree(cfg);
+
+While the timeout woker may still be running. This will cause
+a use-after-free bug on cfg in brcmf_cfg80211_escan_timeout_worker.
+
+Fix it by deleting the timer and canceling the worker in
+brcmf_cfg80211_detach.
+
+Fixes: e756af5b30b0 ("brcmfmac: add e-scan support.")
+Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
+Cc: stable@vger.kernel.org
+[arend.vanspriel@broadcom.com: keep timer delete as is and cancel work just before free]
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240107072504.392713-1-arend.vanspriel@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+index baf5f0afe802e..fbb5e29530e3d 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -790,8 +790,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
+ scan_request = cfg->scan_request;
+ cfg->scan_request = NULL;
+
+- if (timer_pending(&cfg->escan_timeout))
+- del_timer_sync(&cfg->escan_timeout);
++ timer_delete_sync(&cfg->escan_timeout);
+
+ if (fw_abort) {
+ /* Do a scan abort to stop the driver's scan engine */
+@@ -7674,6 +7673,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
+ brcmf_btcoex_detach(cfg);
+ wiphy_unregister(cfg->wiphy);
+ wl_deinit_priv(cfg);
++ cancel_work_sync(&cfg->escan_timeout_work);
+ brcmf_free_wiphy(cfg->wiphy);
+ kfree(cfg);
+ }
+--
+2.43.0
+
--- /dev/null
+From 1a63fa3bb9ebd214a552a5a02f51543a2abcb30b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Mar 2024 16:49:10 -0600
+Subject: wireguard: netlink: access device through ctx instead of peer
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+[ Upstream commit 71cbd32e3db82ea4a74e3ef9aeeaa6971969c86f ]
+
+The previous commit fixed a bug that led to a NULL peer->device being
+dereferenced. It's actually easier and faster performance-wise to
+instead get the device from ctx->wg. This semantically makes more sense
+too, since ctx->wg->peer_allowedips.seq is compared with
+ctx->allowedips_seq, basing them both in ctx. This also acts as a
+defence in depth provision against freed peers.
+
+Cc: stable@vger.kernel.org
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireguard/netlink.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
+index 6523f9d5a1527..9dc02fa51ed09 100644
+--- a/drivers/net/wireguard/netlink.c
++++ b/drivers/net/wireguard/netlink.c
+@@ -164,8 +164,8 @@ get_peer(struct wg_peer *peer, struct sk_buff *skb, struct dump_ctx *ctx)
+ if (!allowedips_node)
+ goto no_allowedips;
+ if (!ctx->allowedips_seq)
+- ctx->allowedips_seq = peer->device->peer_allowedips.seq;
+- else if (ctx->allowedips_seq != peer->device->peer_allowedips.seq)
++ ctx->allowedips_seq = ctx->wg->peer_allowedips.seq;
++ else if (ctx->allowedips_seq != ctx->wg->peer_allowedips.seq)
+ goto no_allowedips;
+
+ allowedips_nest = nla_nest_start(skb, WGPEER_A_ALLOWEDIPS);
+--
+2.43.0
+
--- /dev/null
+From efedb4621f4e9f0530a5c2c804805fe7ff85184e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Mar 2024 16:49:09 -0600
+Subject: wireguard: netlink: check for dangling peer via is_dead instead of
+ empty list
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+[ Upstream commit 55b6c738673871c9b0edae05d0c97995c1ff08c4 ]
+
+If all peers are removed via wg_peer_remove_all(), rather than setting
+peer_list to empty, the peer is added to a temporary list with a head on
+the stack of wg_peer_remove_all(). If a netlink dump is resumed and the
+cursored peer is one that has been removed via wg_peer_remove_all(), it
+will iterate from that peer and then attempt to dump freed peers.
+
+Fix this by instead checking peer->is_dead, which was explictly created
+for this purpose. Also move up the device_update_lock lockdep assertion,
+since reading is_dead relies on that.
+
+It can be reproduced by a small script like:
+
+ echo "Setting config..."
+ ip link add dev wg0 type wireguard
+ wg setconf wg0 /big-config
+ (
+ while true; do
+ echo "Showing config..."
+ wg showconf wg0 > /dev/null
+ done
+ ) &
+ sleep 4
+ wg setconf wg0 <(printf "[Peer]\nPublicKey=$(wg genkey)\n")
+
+Resulting in:
+
+ BUG: KASAN: slab-use-after-free in __lock_acquire+0x182a/0x1b20
+ Read of size 8 at addr ffff88811956ec70 by task wg/59
+ CPU: 2 PID: 59 Comm: wg Not tainted 6.8.0-rc2-debug+ #5
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x47/0x70
+ print_address_description.constprop.0+0x2c/0x380
+ print_report+0xab/0x250
+ kasan_report+0xba/0xf0
+ __lock_acquire+0x182a/0x1b20
+ lock_acquire+0x191/0x4b0
+ down_read+0x80/0x440
+ get_peer+0x140/0xcb0
+ wg_get_device_dump+0x471/0x1130
+
+Cc: stable@vger.kernel.org
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Reported-by: Lillian Berry <lillian@star-ark.net>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireguard/netlink.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
+index f5bc279c9a8c2..6523f9d5a1527 100644
+--- a/drivers/net/wireguard/netlink.c
++++ b/drivers/net/wireguard/netlink.c
+@@ -255,17 +255,17 @@ static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ if (!peers_nest)
+ goto out;
+ ret = 0;
+- /* If the last cursor was removed via list_del_init in peer_remove, then
++ lockdep_assert_held(&wg->device_update_lock);
++ /* If the last cursor was removed in peer_remove or peer_remove_all, then
+ * we just treat this the same as there being no more peers left. The
+ * reason is that seq_nr should indicate to userspace that this isn't a
+ * coherent dump anyway, so they'll try again.
+ */
+ if (list_empty(&wg->peer_list) ||
+- (ctx->next_peer && list_empty(&ctx->next_peer->peer_list))) {
++ (ctx->next_peer && ctx->next_peer->is_dead)) {
+ nla_nest_cancel(skb, peers_nest);
+ goto out;
+ }
+- lockdep_assert_held(&wg->device_update_lock);
+ peer = list_prepare_entry(ctx->next_peer, &wg->peer_list, peer_list);
+ list_for_each_entry_continue(peer, &wg->peer_list, peer_list) {
+ if (get_peer(peer, skb, ctx)) {
+--
+2.43.0
+
--- /dev/null
+From b90f611ef088960435592d13bf5dad5bd1d678e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Mar 2024 22:42:27 +0100
+Subject: x86/CPU/AMD: Update the Zenbleed microcode revisions
+
+From: Borislav Petkov (AMD) <bp@alien8.de>
+
+[ Upstream commit 5c84b051bd4e777cf37aaff983277e58c99618d5 ]
+
+Update them to the correct revision numbers.
+
+Fixes: 522b1d69219d ("x86/cpu/amd: Add a Zenbleed fix")
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: <stable@kernel.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/amd.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index f29c6bed9d657..3b02cb8b05338 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -1049,11 +1049,11 @@ static bool cpu_has_zenbleed_microcode(void)
+ u32 good_rev = 0;
+
+ switch (boot_cpu_data.x86_model) {
+- case 0x30 ... 0x3f: good_rev = 0x0830107a; break;
+- case 0x60 ... 0x67: good_rev = 0x0860010b; break;
+- case 0x68 ... 0x6f: good_rev = 0x08608105; break;
+- case 0x70 ... 0x7f: good_rev = 0x08701032; break;
+- case 0xa0 ... 0xaf: good_rev = 0x08a00008; break;
++ case 0x30 ... 0x3f: good_rev = 0x0830107b; break;
++ case 0x60 ... 0x67: good_rev = 0x0860010c; break;
++ case 0x68 ... 0x6f: good_rev = 0x08608107; break;
++ case 0x70 ... 0x7f: good_rev = 0x08701033; break;
++ case 0xa0 ... 0xaf: good_rev = 0x08a00009; break;
+
+ default:
+ return false;
+--
+2.43.0
+
--- /dev/null
+From cac5c3a51ca8b58c26051b28ff4f1876622ba5de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Mar 2024 14:26:56 +0000
+Subject: x86/pm: Work around false positive kmemleak report in
+ msr_build_context()
+
+From: Anton Altaparmakov <anton@tuxera.com>
+
+[ Upstream commit e3f269ed0accbb22aa8f25d2daffa23c3fccd407 ]
+
+Since:
+
+ 7ee18d677989 ("x86/power: Make restore_processor_context() sane")
+
+kmemleak reports this issue:
+
+ unreferenced object 0xf68241e0 (size 32):
+ comm "swapper/0", pid 1, jiffies 4294668610 (age 68.432s)
+ hex dump (first 32 bytes):
+ 00 cc cc cc 29 10 01 c0 00 00 00 00 00 00 00 00 ....)...........
+ 00 42 82 f6 cc cc cc cc cc cc cc cc cc cc cc cc .B..............
+ backtrace:
+ [<461c1d50>] __kmem_cache_alloc_node+0x106/0x260
+ [<ea65e13b>] __kmalloc+0x54/0x160
+ [<c3858cd2>] msr_build_context.constprop.0+0x35/0x100
+ [<46635aff>] pm_check_save_msr+0x63/0x80
+ [<6b6bb938>] do_one_initcall+0x41/0x1f0
+ [<3f3add60>] kernel_init_freeable+0x199/0x1e8
+ [<3b538fde>] kernel_init+0x1a/0x110
+ [<938ae2b2>] ret_from_fork+0x1c/0x28
+
+Which is a false positive.
+
+Reproducer:
+
+ - Run rsync of whole kernel tree (multiple times if needed).
+ - start a kmemleak scan
+ - Note this is just an example: a lot of our internal tests hit these.
+
+The root cause is similar to the fix in:
+
+ b0b592cf0836 x86/pm: Fix false positive kmemleak report in msr_build_context()
+
+ie. the alignment within the packed struct saved_context
+which has everything unaligned as there is only "u16 gs;" at start of
+struct where in the past there were four u16 there thus aligning
+everything afterwards. The issue is with the fact that Kmemleak only
+searches for pointers that are aligned (see how pointers are scanned in
+kmemleak.c) so when the struct members are not aligned it doesn't see
+them.
+
+Testing:
+
+We run a lot of tests with our CI, and after applying this fix we do not
+see any kmemleak issues any more whilst without it we see hundreds of
+the above report. From a single, simple test run consisting of 416 individual test
+cases on kernel 5.10 x86 with kmemleak enabled we got 20 failures due to this,
+which is quite a lot. With this fix applied we get zero kmemleak related failures.
+
+Fixes: 7ee18d677989 ("x86/power: Make restore_processor_context() sane")
+Signed-off-by: Anton Altaparmakov <anton@tuxera.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: stable@vger.kernel.org
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/20240314142656.17699-1-anton@tuxera.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/suspend_32.h | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h
+index a800abb1a9925..d8416b3bf832e 100644
+--- a/arch/x86/include/asm/suspend_32.h
++++ b/arch/x86/include/asm/suspend_32.h
+@@ -12,11 +12,6 @@
+
+ /* image of the saved processor state */
+ struct saved_context {
+- /*
+- * On x86_32, all segment registers except gs are saved at kernel
+- * entry in pt_regs.
+- */
+- u16 gs;
+ unsigned long cr0, cr2, cr3, cr4;
+ u64 misc_enable;
+ struct saved_msrs saved_msrs;
+@@ -27,6 +22,11 @@ struct saved_context {
+ unsigned long tr;
+ unsigned long safety;
+ unsigned long return_address;
++ /*
++ * On x86_32, all segment registers except gs are saved at kernel
++ * entry in pt_regs.
++ */
++ u16 gs;
+ bool misc_enable_saved;
+ } __attribute__((packed));
+
+--
+2.43.0
+
--- /dev/null
+From b701dea6dc812612ab54e2b524182f1eea7dc78a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Feb 2021 11:19:44 -0800
+Subject: x86/stackprotector/32: Make the canary into a regular percpu variable
+
+From: Andy Lutomirski <luto@kernel.org>
+
+[ Upstream commit 3fb0fdb3bbe7aed495109b3296b06c2409734023 ]
+
+On 32-bit kernels, the stackprotector canary is quite nasty -- it is
+stored at %gs:(20), which is nasty because 32-bit kernels use %fs for
+percpu storage. It's even nastier because it means that whether %gs
+contains userspace state or kernel state while running kernel code
+depends on whether stackprotector is enabled (this is
+CONFIG_X86_32_LAZY_GS), and this setting radically changes the way
+that segment selectors work. Supporting both variants is a
+maintenance and testing mess.
+
+Merely rearranging so that percpu and the stack canary
+share the same segment would be messy as the 32-bit percpu address
+layout isn't currently compatible with putting a variable at a fixed
+offset.
+
+Fortunately, GCC 8.1 added options that allow the stack canary to be
+accessed as %fs:__stack_chk_guard, effectively turning it into an ordinary
+percpu variable. This lets us get rid of all of the code to manage the
+stack canary GDT descriptor and the CONFIG_X86_32_LAZY_GS mess.
+
+(That name is special. We could use any symbol we want for the
+ %fs-relative mode, but for CONFIG_SMP=n, gcc refuses to let us use any
+ name other than __stack_chk_guard.)
+
+Forcibly disable stackprotector on older compilers that don't support
+the new options and turn the stack canary into a percpu variable. The
+"lazy GS" approach is now used for all 32-bit configurations.
+
+Also makes load_gs_index() work on 32-bit kernels. On 64-bit kernels,
+it loads the GS selector and updates the user GSBASE accordingly. (This
+is unchanged.) On 32-bit kernels, it loads the GS selector and updates
+GSBASE, which is now always the user base. This means that the overall
+effect is the same on 32-bit and 64-bit, which avoids some ifdeffery.
+
+ [ bp: Massage commit message. ]
+
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Link: https://lkml.kernel.org/r/c0ff7dba14041c7e5d1cae5d4df052f03759bef3.1613243844.git.luto@kernel.org
+Stable-dep-of: e3f269ed0acc ("x86/pm: Work around false positive kmemleak report in msr_build_context()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/Kconfig | 7 +-
+ arch/x86/Makefile | 8 +++
+ arch/x86/entry/entry_32.S | 56 ++--------------
+ arch/x86/include/asm/processor.h | 15 ++---
+ arch/x86/include/asm/ptrace.h | 5 +-
+ arch/x86/include/asm/segment.h | 30 +++------
+ arch/x86/include/asm/stackprotector.h | 79 +++++------------------
+ arch/x86/include/asm/suspend_32.h | 6 +-
+ arch/x86/kernel/asm-offsets_32.c | 5 --
+ arch/x86/kernel/cpu/common.c | 5 +-
+ arch/x86/kernel/doublefault_32.c | 4 +-
+ arch/x86/kernel/head_32.S | 18 +-----
+ arch/x86/kernel/setup_percpu.c | 1 -
+ arch/x86/kernel/tls.c | 8 +--
+ arch/x86/lib/insn-eval.c | 4 --
+ arch/x86/platform/pvh/head.S | 14 ----
+ arch/x86/power/cpu.c | 6 +-
+ arch/x86/xen/enlighten_pv.c | 1 -
+ scripts/gcc-x86_32-has-stack-protector.sh | 6 +-
+ 19 files changed, 60 insertions(+), 218 deletions(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 6dc670e363939..47c94e9de03e4 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -352,10 +352,6 @@ config X86_64_SMP
+ def_bool y
+ depends on X86_64 && SMP
+
+-config X86_32_LAZY_GS
+- def_bool y
+- depends on X86_32 && !STACKPROTECTOR
+-
+ config ARCH_SUPPORTS_UPROBES
+ def_bool y
+
+@@ -378,7 +374,8 @@ config CC_HAS_SANE_STACKPROTECTOR
+ default $(success,$(srctree)/scripts/gcc-x86_32-has-stack-protector.sh $(CC))
+ help
+ We have to make sure stack protector is unconditionally disabled if
+- the compiler produces broken code.
++ the compiler produces broken code or if it does not let us control
++ the segment on 32-bit kernels.
+
+ menu "Processor type and features"
+
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 1f796050c6dde..8b9fa777f513b 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -87,6 +87,14 @@ ifeq ($(CONFIG_X86_32),y)
+
+ # temporary until string.h is fixed
+ KBUILD_CFLAGS += -ffreestanding
++
++ ifeq ($(CONFIG_STACKPROTECTOR),y)
++ ifeq ($(CONFIG_SMP),y)
++ KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard
++ else
++ KBUILD_CFLAGS += -mstack-protector-guard=global
++ endif
++ endif
+ else
+ BITS := 64
+ UTS_MACHINE := x86_64
+diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
+index 70bd81b6c612e..10b7c62a3e97a 100644
+--- a/arch/x86/entry/entry_32.S
++++ b/arch/x86/entry/entry_32.S
+@@ -20,7 +20,7 @@
+ * 1C(%esp) - %ds
+ * 20(%esp) - %es
+ * 24(%esp) - %fs
+- * 28(%esp) - %gs saved iff !CONFIG_X86_32_LAZY_GS
++ * 28(%esp) - unused -- was %gs on old stackprotector kernels
+ * 2C(%esp) - orig_eax
+ * 30(%esp) - %eip
+ * 34(%esp) - %cs
+@@ -56,14 +56,9 @@
+ /*
+ * User gs save/restore
+ *
+- * %gs is used for userland TLS and kernel only uses it for stack
+- * canary which is required to be at %gs:20 by gcc. Read the comment
+- * at the top of stackprotector.h for more info.
+- *
+- * Local labels 98 and 99 are used.
++ * This is leftover junk from CONFIG_X86_32_LAZY_GS. A subsequent patch
++ * will remove it entirely.
+ */
+-#ifdef CONFIG_X86_32_LAZY_GS
+-
+ /* unfortunately push/pop can't be no-op */
+ .macro PUSH_GS
+ pushl $0
+@@ -86,49 +81,6 @@
+ .macro SET_KERNEL_GS reg
+ .endm
+
+-#else /* CONFIG_X86_32_LAZY_GS */
+-
+-.macro PUSH_GS
+- pushl %gs
+-.endm
+-
+-.macro POP_GS pop=0
+-98: popl %gs
+- .if \pop <> 0
+- add $\pop, %esp
+- .endif
+-.endm
+-.macro POP_GS_EX
+-.pushsection .fixup, "ax"
+-99: movl $0, (%esp)
+- jmp 98b
+-.popsection
+- _ASM_EXTABLE(98b, 99b)
+-.endm
+-
+-.macro PTGS_TO_GS
+-98: mov PT_GS(%esp), %gs
+-.endm
+-.macro PTGS_TO_GS_EX
+-.pushsection .fixup, "ax"
+-99: movl $0, PT_GS(%esp)
+- jmp 98b
+-.popsection
+- _ASM_EXTABLE(98b, 99b)
+-.endm
+-
+-.macro GS_TO_REG reg
+- movl %gs, \reg
+-.endm
+-.macro REG_TO_PTGS reg
+- movl \reg, PT_GS(%esp)
+-.endm
+-.macro SET_KERNEL_GS reg
+- movl $(__KERNEL_STACK_CANARY), \reg
+- movl \reg, %gs
+-.endm
+-
+-#endif /* CONFIG_X86_32_LAZY_GS */
+
+ /* Unconditionally switch to user cr3 */
+ .macro SWITCH_TO_USER_CR3 scratch_reg:req
+@@ -779,7 +731,7 @@ SYM_CODE_START(__switch_to_asm)
+
+ #ifdef CONFIG_STACKPROTECTOR
+ movl TASK_stack_canary(%edx), %ebx
+- movl %ebx, PER_CPU_VAR(stack_canary)+stack_canary_offset
++ movl %ebx, PER_CPU_VAR(__stack_chk_guard)
+ #endif
+
+ /*
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index d7e017b0b4c3b..6dc3c5f0be076 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -441,6 +441,9 @@ struct fixed_percpu_data {
+ * GCC hardcodes the stack canary as %gs:40. Since the
+ * irq_stack is the object at %gs:0, we reserve the bottom
+ * 48 bytes of the irq stack for the canary.
++ *
++ * Once we are willing to require -mstack-protector-guard-symbol=
++ * support for x86_64 stackprotector, we can get rid of this.
+ */
+ char gs_base[40];
+ unsigned long stack_canary;
+@@ -461,17 +464,7 @@ extern asmlinkage void ignore_sysret(void);
+ void current_save_fsgs(void);
+ #else /* X86_64 */
+ #ifdef CONFIG_STACKPROTECTOR
+-/*
+- * Make sure stack canary segment base is cached-aligned:
+- * "For Intel Atom processors, avoid non zero segment base address
+- * that is not aligned to cache line boundary at all cost."
+- * (Optim Ref Manual Assembly/Compiler Coding Rule 15.)
+- */
+-struct stack_canary {
+- char __pad[20]; /* canary at %gs:20 */
+- unsigned long canary;
+-};
+-DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
++DECLARE_PER_CPU(unsigned long, __stack_chk_guard);
+ #endif
+ /* Per CPU softirq stack pointer */
+ DECLARE_PER_CPU(struct irq_stack *, softirq_stack_ptr);
+diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
+index 409f661481e11..b94f615600d57 100644
+--- a/arch/x86/include/asm/ptrace.h
++++ b/arch/x86/include/asm/ptrace.h
+@@ -37,7 +37,10 @@ struct pt_regs {
+ unsigned short __esh;
+ unsigned short fs;
+ unsigned short __fsh;
+- /* On interrupt, gs and __gsh store the vector number. */
++ /*
++ * On interrupt, gs and __gsh store the vector number. They never
++ * store gs any more.
++ */
+ unsigned short gs;
+ unsigned short __gsh;
+ /* On interrupt, this is the error code. */
+diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
+index 7fdd4facfce71..72044026eb3c2 100644
+--- a/arch/x86/include/asm/segment.h
++++ b/arch/x86/include/asm/segment.h
+@@ -95,7 +95,7 @@
+ *
+ * 26 - ESPFIX small SS
+ * 27 - per-cpu [ offset to per-cpu data area ]
+- * 28 - stack_canary-20 [ for stack protector ] <=== cacheline #8
++ * 28 - unused
+ * 29 - unused
+ * 30 - unused
+ * 31 - TSS for double fault handler
+@@ -118,7 +118,6 @@
+
+ #define GDT_ENTRY_ESPFIX_SS 26
+ #define GDT_ENTRY_PERCPU 27
+-#define GDT_ENTRY_STACK_CANARY 28
+
+ #define GDT_ENTRY_DOUBLEFAULT_TSS 31
+
+@@ -158,12 +157,6 @@
+ # define __KERNEL_PERCPU 0
+ #endif
+
+-#ifdef CONFIG_STACKPROTECTOR
+-# define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8)
+-#else
+-# define __KERNEL_STACK_CANARY 0
+-#endif
+-
+ #else /* 64-bit: */
+
+ #include <asm/cache.h>
+@@ -364,22 +357,15 @@ static inline void __loadsegment_fs(unsigned short value)
+ asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
+
+ /*
+- * x86-32 user GS accessors:
++ * x86-32 user GS accessors. This is ugly and could do with some cleaning up.
+ */
+ #ifdef CONFIG_X86_32
+-# ifdef CONFIG_X86_32_LAZY_GS
+-# define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; })
+-# define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v))
+-# define task_user_gs(tsk) ((tsk)->thread.gs)
+-# define lazy_save_gs(v) savesegment(gs, (v))
+-# define lazy_load_gs(v) loadsegment(gs, (v))
+-# else /* X86_32_LAZY_GS */
+-# define get_user_gs(regs) (u16)((regs)->gs)
+-# define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0)
+-# define task_user_gs(tsk) (task_pt_regs(tsk)->gs)
+-# define lazy_save_gs(v) do { } while (0)
+-# define lazy_load_gs(v) do { } while (0)
+-# endif /* X86_32_LAZY_GS */
++# define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; })
++# define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v))
++# define task_user_gs(tsk) ((tsk)->thread.gs)
++# define lazy_save_gs(v) savesegment(gs, (v))
++# define lazy_load_gs(v) loadsegment(gs, (v))
++# define load_gs_index(v) loadsegment(gs, (v))
+ #endif /* X86_32 */
+
+ #endif /* !__ASSEMBLY__ */
+diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
+index 7fb482f0f25b0..b6ffe58c70fab 100644
+--- a/arch/x86/include/asm/stackprotector.h
++++ b/arch/x86/include/asm/stackprotector.h
+@@ -5,30 +5,23 @@
+ * Stack protector works by putting predefined pattern at the start of
+ * the stack frame and verifying that it hasn't been overwritten when
+ * returning from the function. The pattern is called stack canary
+- * and unfortunately gcc requires it to be at a fixed offset from %gs.
+- * On x86_64, the offset is 40 bytes and on x86_32 20 bytes. x86_64
+- * and x86_32 use segment registers differently and thus handles this
+- * requirement differently.
++ * and unfortunately gcc historically required it to be at a fixed offset
++ * from the percpu segment base. On x86_64, the offset is 40 bytes.
+ *
+- * On x86_64, %gs is shared by percpu area and stack canary. All
+- * percpu symbols are zero based and %gs points to the base of percpu
+- * area. The first occupant of the percpu area is always
+- * fixed_percpu_data which contains stack_canary at offset 40. Userland
+- * %gs is always saved and restored on kernel entry and exit using
+- * swapgs, so stack protector doesn't add any complexity there.
++ * The same segment is shared by percpu area and stack canary. On
++ * x86_64, percpu symbols are zero based and %gs (64-bit) points to the
++ * base of percpu area. The first occupant of the percpu area is always
++ * fixed_percpu_data which contains stack_canary at the approproate
++ * offset. On x86_32, the stack canary is just a regular percpu
++ * variable.
+ *
+- * On x86_32, it's slightly more complicated. As in x86_64, %gs is
+- * used for userland TLS. Unfortunately, some processors are much
+- * slower at loading segment registers with different value when
+- * entering and leaving the kernel, so the kernel uses %fs for percpu
+- * area and manages %gs lazily so that %gs is switched only when
+- * necessary, usually during task switch.
++ * Putting percpu data in %fs on 32-bit is a minor optimization compared to
++ * using %gs. Since 32-bit userspace normally has %fs == 0, we are likely
++ * to load 0 into %fs on exit to usermode, whereas with percpu data in
++ * %gs, we are likely to load a non-null %gs on return to user mode.
+ *
+- * As gcc requires the stack canary at %gs:20, %gs can't be managed
+- * lazily if stack protector is enabled, so the kernel saves and
+- * restores userland %gs on kernel entry and exit. This behavior is
+- * controlled by CONFIG_X86_32_LAZY_GS and accessors are defined in
+- * system.h to hide the details.
++ * Once we are willing to require GCC 8.1 or better for 64-bit stackprotector
++ * support, we can remove some of this complexity.
+ */
+
+ #ifndef _ASM_STACKPROTECTOR_H
+@@ -44,14 +37,6 @@
+ #include <linux/random.h>
+ #include <linux/sched.h>
+
+-/*
+- * 24 byte read-only segment initializer for stack canary. Linker
+- * can't handle the address bit shifting. Address will be set in
+- * head_32 for boot CPU and setup_per_cpu_areas() for others.
+- */
+-#define GDT_STACK_CANARY_INIT \
+- [GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18),
+-
+ /*
+ * Initialize the stackprotector canary value.
+ *
+@@ -86,7 +71,7 @@ static __always_inline void boot_init_stack_canary(void)
+ #ifdef CONFIG_X86_64
+ this_cpu_write(fixed_percpu_data.stack_canary, canary);
+ #else
+- this_cpu_write(stack_canary.canary, canary);
++ this_cpu_write(__stack_chk_guard, canary);
+ #endif
+ }
+
+@@ -95,48 +80,16 @@ static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle)
+ #ifdef CONFIG_X86_64
+ per_cpu(fixed_percpu_data.stack_canary, cpu) = idle->stack_canary;
+ #else
+- per_cpu(stack_canary.canary, cpu) = idle->stack_canary;
+-#endif
+-}
+-
+-static inline void setup_stack_canary_segment(int cpu)
+-{
+-#ifdef CONFIG_X86_32
+- unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
+- struct desc_struct *gdt_table = get_cpu_gdt_rw(cpu);
+- struct desc_struct desc;
+-
+- desc = gdt_table[GDT_ENTRY_STACK_CANARY];
+- set_desc_base(&desc, canary);
+- write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S);
+-#endif
+-}
+-
+-static inline void load_stack_canary_segment(void)
+-{
+-#ifdef CONFIG_X86_32
+- asm("mov %0, %%gs" : : "r" (__KERNEL_STACK_CANARY) : "memory");
++ per_cpu(__stack_chk_guard, cpu) = idle->stack_canary;
+ #endif
+ }
+
+ #else /* STACKPROTECTOR */
+
+-#define GDT_STACK_CANARY_INIT
+-
+ /* dummy boot_init_stack_canary() is defined in linux/stackprotector.h */
+
+-static inline void setup_stack_canary_segment(int cpu)
+-{ }
+-
+ static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle)
+ { }
+
+-static inline void load_stack_canary_segment(void)
+-{
+-#ifdef CONFIG_X86_32
+- asm volatile ("mov %0, %%gs" : : "r" (0));
+-#endif
+-}
+-
+ #endif /* STACKPROTECTOR */
+ #endif /* _ASM_STACKPROTECTOR_H */
+diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h
+index 3b97aa9215430..a800abb1a9925 100644
+--- a/arch/x86/include/asm/suspend_32.h
++++ b/arch/x86/include/asm/suspend_32.h
+@@ -13,12 +13,10 @@
+ /* image of the saved processor state */
+ struct saved_context {
+ /*
+- * On x86_32, all segment registers, with the possible exception of
+- * gs, are saved at kernel entry in pt_regs.
++ * On x86_32, all segment registers except gs are saved at kernel
++ * entry in pt_regs.
+ */
+-#ifdef CONFIG_X86_32_LAZY_GS
+ u16 gs;
+-#endif
+ unsigned long cr0, cr2, cr3, cr4;
+ u64 misc_enable;
+ struct saved_msrs saved_msrs;
+diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
+index 6e043f295a605..2b411cd00a4e2 100644
+--- a/arch/x86/kernel/asm-offsets_32.c
++++ b/arch/x86/kernel/asm-offsets_32.c
+@@ -53,11 +53,6 @@ void foo(void)
+ offsetof(struct cpu_entry_area, tss.x86_tss.sp1) -
+ offsetofend(struct cpu_entry_area, entry_stack_page.stack));
+
+-#ifdef CONFIG_STACKPROTECTOR
+- BLANK();
+- OFFSET(stack_canary_offset, stack_canary, canary);
+-#endif
+-
+ BLANK();
+ DEFINE(EFI_svam, offsetof(efi_runtime_services_t, set_virtual_address_map));
+ }
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 0c72ff732aa08..33002cb5a1c62 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -166,7 +166,6 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
+
+ [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
+ [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
+- GDT_STACK_CANARY_INIT
+ #endif
+ } };
+ EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
+@@ -600,7 +599,6 @@ void load_percpu_segment(int cpu)
+ __loadsegment_simple(gs, 0);
+ wrmsrl(MSR_GS_BASE, cpu_kernelmode_gs_base(cpu));
+ #endif
+- load_stack_canary_segment();
+ }
+
+ #ifdef CONFIG_X86_32
+@@ -1940,7 +1938,8 @@ DEFINE_PER_CPU(unsigned long, cpu_current_top_of_stack) =
+ EXPORT_PER_CPU_SYMBOL(cpu_current_top_of_stack);
+
+ #ifdef CONFIG_STACKPROTECTOR
+-DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
++DEFINE_PER_CPU(unsigned long, __stack_chk_guard);
++EXPORT_PER_CPU_SYMBOL(__stack_chk_guard);
+ #endif
+
+ #endif /* CONFIG_X86_64 */
+diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
+index 759d392cbe9f0..d1d49e3d536b8 100644
+--- a/arch/x86/kernel/doublefault_32.c
++++ b/arch/x86/kernel/doublefault_32.c
+@@ -100,9 +100,7 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct doublefault_stack, doublefault_stack) = {
+ .ss = __KERNEL_DS,
+ .ds = __USER_DS,
+ .fs = __KERNEL_PERCPU,
+-#ifndef CONFIG_X86_32_LAZY_GS
+- .gs = __KERNEL_STACK_CANARY,
+-#endif
++ .gs = 0,
+
+ .__cr3 = __pa_nodebug(swapper_pg_dir),
+ },
+diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
+index 3f1691b89231f..0359333f6bdee 100644
+--- a/arch/x86/kernel/head_32.S
++++ b/arch/x86/kernel/head_32.S
+@@ -319,8 +319,8 @@ SYM_FUNC_START(startup_32_smp)
+ movl $(__KERNEL_PERCPU), %eax
+ movl %eax,%fs # set this cpu's percpu
+
+- movl $(__KERNEL_STACK_CANARY),%eax
+- movl %eax,%gs
++ xorl %eax,%eax
++ movl %eax,%gs # clear possible garbage in %gs
+
+ xorl %eax,%eax # Clear LDT
+ lldt %ax
+@@ -340,20 +340,6 @@ SYM_FUNC_END(startup_32_smp)
+ */
+ __INIT
+ setup_once:
+-#ifdef CONFIG_STACKPROTECTOR
+- /*
+- * Configure the stack canary. The linker can't handle this by
+- * relocation. Manually set base address in stack canary
+- * segment descriptor.
+- */
+- movl $gdt_page,%eax
+- movl $stack_canary,%ecx
+- movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
+- shrl $16, %ecx
+- movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
+- movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
+-#endif
+-
+ andl $0,setup_once_ref /* Once is enough, thanks */
+ RET
+
+diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
+index fd945ce78554e..0941d2f44f2a2 100644
+--- a/arch/x86/kernel/setup_percpu.c
++++ b/arch/x86/kernel/setup_percpu.c
+@@ -224,7 +224,6 @@ void __init setup_per_cpu_areas(void)
+ per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
+ per_cpu(cpu_number, cpu) = cpu;
+ setup_percpu_segment(cpu);
+- setup_stack_canary_segment(cpu);
+ /*
+ * Copy data used in early init routines from the
+ * initial arrays to the per cpu data areas. These
+diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
+index 64a496a0687f6..3c883e0642424 100644
+--- a/arch/x86/kernel/tls.c
++++ b/arch/x86/kernel/tls.c
+@@ -164,17 +164,11 @@ int do_set_thread_area(struct task_struct *p, int idx,
+ savesegment(fs, sel);
+ if (sel == modified_sel)
+ loadsegment(fs, sel);
+-
+- savesegment(gs, sel);
+- if (sel == modified_sel)
+- load_gs_index(sel);
+ #endif
+
+-#ifdef CONFIG_X86_32_LAZY_GS
+ savesegment(gs, sel);
+ if (sel == modified_sel)
+- loadsegment(gs, sel);
+-#endif
++ load_gs_index(sel);
+ } else {
+ #ifdef CONFIG_X86_64
+ if (p->thread.fsindex == modified_sel)
+diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
+index ffc8b7dcf1feb..6ed542e310adc 100644
+--- a/arch/x86/lib/insn-eval.c
++++ b/arch/x86/lib/insn-eval.c
+@@ -404,10 +404,6 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
+ case INAT_SEG_REG_FS:
+ return (unsigned short)(regs->fs & 0xffff);
+ case INAT_SEG_REG_GS:
+- /*
+- * GS may or may not be in regs as per CONFIG_X86_32_LAZY_GS.
+- * The macro below takes care of both cases.
+- */
+ return get_user_gs(regs);
+ case INAT_SEG_REG_IGNORE:
+ default:
+diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S
+index 43b4d864817ec..afbf0bb252da5 100644
+--- a/arch/x86/platform/pvh/head.S
++++ b/arch/x86/platform/pvh/head.S
+@@ -45,10 +45,8 @@
+
+ #define PVH_GDT_ENTRY_CS 1
+ #define PVH_GDT_ENTRY_DS 2
+-#define PVH_GDT_ENTRY_CANARY 3
+ #define PVH_CS_SEL (PVH_GDT_ENTRY_CS * 8)
+ #define PVH_DS_SEL (PVH_GDT_ENTRY_DS * 8)
+-#define PVH_CANARY_SEL (PVH_GDT_ENTRY_CANARY * 8)
+
+ SYM_CODE_START_LOCAL(pvh_start_xen)
+ cld
+@@ -109,17 +107,6 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
+
+ #else /* CONFIG_X86_64 */
+
+- /* Set base address in stack canary descriptor. */
+- movl $_pa(gdt_start),%eax
+- movl $_pa(canary),%ecx
+- movw %cx, (PVH_GDT_ENTRY_CANARY * 8) + 2(%eax)
+- shrl $16, %ecx
+- movb %cl, (PVH_GDT_ENTRY_CANARY * 8) + 4(%eax)
+- movb %ch, (PVH_GDT_ENTRY_CANARY * 8) + 7(%eax)
+-
+- mov $PVH_CANARY_SEL,%eax
+- mov %eax,%gs
+-
+ call mk_early_pgtbl_32
+
+ mov $_pa(initial_page_table), %eax
+@@ -163,7 +150,6 @@ SYM_DATA_START_LOCAL(gdt_start)
+ .quad GDT_ENTRY(0xc09a, 0, 0xfffff) /* PVH_CS_SEL */
+ #endif
+ .quad GDT_ENTRY(0xc092, 0, 0xfffff) /* PVH_DS_SEL */
+- .quad GDT_ENTRY(0x4090, 0, 0x18) /* PVH_CANARY_SEL */
+ SYM_DATA_END_LABEL(gdt_start, SYM_L_LOCAL, gdt_end)
+
+ .balign 16
+diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
+index 4e4e76ecd3ecd..84c7b2312ea9e 100644
+--- a/arch/x86/power/cpu.c
++++ b/arch/x86/power/cpu.c
+@@ -101,11 +101,8 @@ static void __save_processor_state(struct saved_context *ctxt)
+ /*
+ * segment registers
+ */
+-#ifdef CONFIG_X86_32_LAZY_GS
+ savesegment(gs, ctxt->gs);
+-#endif
+ #ifdef CONFIG_X86_64
+- savesegment(gs, ctxt->gs);
+ savesegment(fs, ctxt->fs);
+ savesegment(ds, ctxt->ds);
+ savesegment(es, ctxt->es);
+@@ -234,7 +231,6 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
+ wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base);
+ #else
+ loadsegment(fs, __KERNEL_PERCPU);
+- loadsegment(gs, __KERNEL_STACK_CANARY);
+ #endif
+
+ /* Restore the TSS, RO GDT, LDT, and usermode-relevant MSRs. */
+@@ -257,7 +253,7 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
+ */
+ wrmsrl(MSR_FS_BASE, ctxt->fs_base);
+ wrmsrl(MSR_KERNEL_GS_BASE, ctxt->usermode_gs_base);
+-#elif defined(CONFIG_X86_32_LAZY_GS)
++#else
+ loadsegment(gs, ctxt->gs);
+ #endif
+
+diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
+index 815030b7f6fa8..94804670caab8 100644
+--- a/arch/x86/xen/enlighten_pv.c
++++ b/arch/x86/xen/enlighten_pv.c
+@@ -1193,7 +1193,6 @@ static void __init xen_setup_gdt(int cpu)
+ pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry_boot;
+ pv_ops.cpu.load_gdt = xen_load_gdt_boot;
+
+- setup_stack_canary_segment(cpu);
+ switch_to_new_gdt(cpu);
+
+ pv_ops.cpu.write_gdt_entry = xen_write_gdt_entry;
+diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh
+index f5c1194952540..825c75c5b7150 100755
+--- a/scripts/gcc-x86_32-has-stack-protector.sh
++++ b/scripts/gcc-x86_32-has-stack-protector.sh
+@@ -1,4 +1,8 @@
+ #!/bin/sh
+ # SPDX-License-Identifier: GPL-2.0
+
+-echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
++# This requires GCC 8.1 or better. Specifically, we require
++# -mstack-protector-guard-reg, added by
++# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81708
++
++echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard - -o - 2> /dev/null | grep -q "%fs"
+--
+2.43.0
+