--- /dev/null
+From 1948fa64727685ac3f6584755212e2e738b6b051 Mon Sep 17 00:00:00 2001
+From: Sven Frotscher <sven.frotscher@gmail.com>
+Date: Thu, 28 Sep 2023 00:36:07 +0200
+Subject: ASoC: amd: yc: Fix non-functional mic on Lenovo 82YM
+
+From: Sven Frotscher <sven.frotscher@gmail.com>
+
+commit 1948fa64727685ac3f6584755212e2e738b6b051 upstream.
+
+Like the Lenovo 82TL, 82V2, 82QF and 82UG, the 82YM (Yoga 7 14ARP8)
+requires an entry in the quirk list to enable the internal microphone.
+The latter two received similar fixes in commit 1263cc0f414d
+("ASoC: amd: yc: Fix non-functional mic on Lenovo 82QF and 82UG").
+
+Fixes: c008323fe361 ("ASoC: amd: yc: Fix a non-functional mic on Lenovo 82SJ")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sven Frotscher <sven.frotscher@gmail.com>
+Link: https://lore.kernel.org/r/20230927223758.18870-1-sven.frotscher@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -238,6 +238,13 @@ static const struct dmi_system_id yc_acp
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "82YM"),
++ }
++ },
++ {
++ .driver_data = &acp6x_card,
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "82UG"),
+ }
+ },
--- /dev/null
+From b84b53149476b22cc3b8677b771fb4cf06d1d455 Mon Sep 17 00:00:00 2001
+From: Matthias Reichl <hias@horus.com>
+Date: Fri, 29 Sep 2023 21:50:28 +0200
+Subject: ASoC: hdmi-codec: Fix broken channel map reporting
+
+From: Matthias Reichl <hias@horus.com>
+
+commit b84b53149476b22cc3b8677b771fb4cf06d1d455 upstream.
+
+Commit 4e0871333661 ("ASoC: hdmi-codec: fix channel info for
+compressed formats") accidentally changed hcp->chmap_idx from
+ca_id, the CEA channel allocation ID, to idx, the index to
+the table of channel mappings ordered by preference.
+
+This resulted in wrong channel maps being reported to userspace,
+eg for 5.1 "FL,FR,LFE,FC" was reported instead of the expected
+"FL,FR,LFE,FC,RL,RR":
+
+~ # speaker-test -c 6 -t sine
+...
+ 0 - Front Left
+ 3 - Front Center
+ 1 - Front Right
+ 2 - LFE
+ 4 - Unknown
+ 5 - Unknown
+
+~ # amixer cget iface=PCM,name='Playback Channel Map' | grep ': values'
+ : values=3,4,8,7,0,0,0,0
+
+Switch this back to ca_id in case of PCM audio so the correct channel
+map is reported again and set it to HDMI_CODEC_CHMAP_IDX_UNKNOWN in
+case of non-PCM audio so the PCM channel map control returns "Unknown"
+channels (value 0).
+
+Fixes: 4e0871333661 ("ASoC: hdmi-codec: fix channel info for compressed formats")
+Cc: stable@vger.kernel.org
+Signed-off-by: Matthias Reichl <hias@horus.com>
+Link: https://lore.kernel.org/r/20230929195027.97136-1-hias@horus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/hdmi-codec.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/codecs/hdmi-codec.c
++++ b/sound/soc/codecs/hdmi-codec.c
+@@ -531,7 +531,10 @@ static int hdmi_codec_fill_codec_params(
+ hp->sample_rate = sample_rate;
+ hp->channels = channels;
+
+- hcp->chmap_idx = idx;
++ if (pcm_audio)
++ hcp->chmap_idx = ca_id;
++ else
++ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
+
+ return 0;
+ }
--- /dev/null
+From aa3998dbeb3abce63653b7f6d4542e7dcd022590 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Sat, 26 Aug 2023 09:43:39 +0900
+Subject: ata: libata-scsi: Disable scsi device manage_system_start_stop
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit aa3998dbeb3abce63653b7f6d4542e7dcd022590 upstream.
+
+The introduction of a device link to create a consumer/supplier
+relationship between the scsi device of an ATA device and the ATA port
+of that ATA device fixes the ordering of system suspend and resume
+operations. For suspend, the scsi device is suspended first and the ata
+port after it. This is fine as this allows the synchronize cache and
+START STOP UNIT commands issued by the scsi disk driver to be executed
+before the ata port is disabled.
+
+For resume operations, the ata port is resumed first, followed
+by the scsi device. This allows having the request queue of the scsi
+device to be unfrozen after the ata port resume is scheduled in EH,
+thus avoiding to see new requests prematurely issued to the ATA device.
+Since libata sets manage_system_start_stop to 1, the scsi disk resume
+operation also results in issuing a START STOP UNIT command to the
+device being resumed so that the device exits standby power mode.
+
+However, restoring the ATA device to the active power mode must be
+synchronized with libata EH processing of the port resume operation to
+avoid either 1) seeing the start stop unit command being received too
+early when the port is not yet resumed and ready to accept commands, or
+after the port resume process issues commands such as IDENTIFY to
+revalidate the device. In this last case, the risk is that the device
+revalidation fails with timeout errors as the drive is still spun down.
+
+Commit 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
+disabled issuing the START STOP UNIT command to avoid issues with it.
+But this is incorrect as transitioning a device to the active power
+mode from the standby power mode set on suspend requires a media access
+command. The IDENTIFY, READ LOG and SET FEATURES commands executed in
+libata EH context triggered by the ata port resume operation may thus
+fail.
+
+Fix these synchronization issues is by handling a device power mode
+transitions for system suspend and resume directly in libata EH context,
+without relying on the scsi disk driver management triggered with the
+manage_system_start_stop flag.
+
+To do this, the following libata helper functions are introduced:
+
+1) ata_dev_power_set_standby():
+
+This function issues a STANDBY IMMEDIATE command to transitiom a device
+to the standby power mode. For HDDs, this spins down the disks. This
+function applies only to ATA and ZAC devices and does nothing otherwise.
+This function also does nothing for devices that have the
+ATA_FLAG_NO_POWEROFF_SPINDOWN or ATA_FLAG_NO_HIBERNATE_SPINDOWN flag
+set.
+
+For suspend, call ata_dev_power_set_standby() in
+ata_eh_handle_port_suspend() before the port is disabled and frozen.
+ata_eh_unload() is also modified to transition all enabled devices to
+the standby power mode when the system is shutdown or devices removed.
+
+2) ata_dev_power_set_active() and
+
+This function applies to ATA or ZAC devices and issues a VERIFY command
+for 1 sector at LBA 0 to transition the device to the active power mode.
+For HDDs, since this function will complete only once the disk spin up.
+Its execution uses the same timeouts as for reset, to give the drive
+enough time to complete spinup without triggering a command timeout.
+
+For resume, call ata_dev_power_set_active() in
+ata_eh_revalidate_and_attach() after the port has been enabled and
+before any other command is issued to the device.
+
+With these changes, the manage_system_start_stop and no_start_on_resume
+scsi device flags do not need to be set in ata_scsi_dev_config(). The
+flag manage_runtime_start_stop is still set to allow the sd driver to
+spinup/spindown a disk through the sd runtime operations.
+
+Fixes: 0a8589055936 ("ata,scsi: do not issue START STOP UNIT on resume")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-core.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/ata/libata-eh.c | 54 +++++++++++++++++++++++++++
+ drivers/ata/libata-scsi.c | 16 +++-----
+ drivers/ata/libata.h | 2 +
+ include/linux/libata.h | 6 ++-
+ 5 files changed, 156 insertions(+), 12 deletions(-)
+
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -1978,6 +1978,96 @@ retry:
+ }
+
+ /**
++ * ata_dev_power_set_standby - Set a device power mode to standby
++ * @dev: target device
++ *
++ * Issue a STANDBY IMMEDIATE command to set a device power mode to standby.
++ * For an HDD device, this spins down the disks.
++ *
++ * LOCKING:
++ * Kernel thread context (may sleep).
++ */
++void ata_dev_power_set_standby(struct ata_device *dev)
++{
++ unsigned long ap_flags = dev->link->ap->flags;
++ struct ata_taskfile tf;
++ unsigned int err_mask;
++
++ /* Issue STANDBY IMMEDIATE command only if supported by the device */
++ if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC)
++ return;
++
++ /*
++ * Some odd clown BIOSes issue spindown on power off (ACPI S4 or S5)
++ * causing some drives to spin up and down again. For these, do nothing
++ * if we are being called on shutdown.
++ */
++ if ((ap_flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) &&
++ system_state == SYSTEM_POWER_OFF)
++ return;
++
++ if ((ap_flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) &&
++ system_entering_hibernation())
++ return;
++
++ ata_tf_init(dev, &tf);
++ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
++ tf.protocol = ATA_PROT_NODATA;
++ tf.command = ATA_CMD_STANDBYNOW1;
++
++ ata_dev_notice(dev, "Entering standby power mode\n");
++
++ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
++ if (err_mask)
++ ata_dev_err(dev, "STANDBY IMMEDIATE failed (err_mask=0x%x)\n",
++ err_mask);
++}
++
++/**
++ * ata_dev_power_set_active - Set a device power mode to active
++ * @dev: target device
++ *
++ * Issue a VERIFY command to enter to ensure that the device is in the
++ * active power mode. For a spun-down HDD (standby or idle power mode),
++ * the VERIFY command will complete after the disk spins up.
++ *
++ * LOCKING:
++ * Kernel thread context (may sleep).
++ */
++void ata_dev_power_set_active(struct ata_device *dev)
++{
++ struct ata_taskfile tf;
++ unsigned int err_mask;
++
++ /*
++ * Issue READ VERIFY SECTORS command for 1 sector at lba=0 only
++ * if supported by the device.
++ */
++ if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC)
++ return;
++
++ ata_tf_init(dev, &tf);
++ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
++ tf.protocol = ATA_PROT_NODATA;
++ tf.command = ATA_CMD_VERIFY;
++ tf.nsect = 1;
++ if (dev->flags & ATA_DFLAG_LBA) {
++ tf.flags |= ATA_TFLAG_LBA;
++ tf.device |= ATA_LBA;
++ } else {
++ /* CHS */
++ tf.lbal = 0x1; /* sect */
++ }
++
++ ata_dev_notice(dev, "Entering active power mode\n");
++
++ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
++ if (err_mask)
++ ata_dev_err(dev, "VERIFY failed (err_mask=0x%x)\n",
++ err_mask);
++}
++
++/**
+ * ata_read_log_page - read a specific log page
+ * @dev: target device
+ * @log: log to read
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -106,6 +106,14 @@ static const unsigned int ata_eh_flush_t
+ UINT_MAX,
+ };
+
++static const unsigned int ata_eh_pm_timeouts[] = {
++ 10000, /* most drives spin up by 10sec */
++ 10000, /* > 99% working drives spin up before 20sec */
++ 35000, /* give > 30 secs of idleness for outlier devices */
++ 5000, /* and sweet one last chance */
++ UINT_MAX, /* > 1 min has elapsed, give up */
++};
++
+ static const unsigned int ata_eh_other_timeouts[] = {
+ 5000, /* same rationale as identify timeout */
+ 10000, /* ditto */
+@@ -147,6 +155,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIME
+ .timeouts = ata_eh_other_timeouts, },
+ { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT),
+ .timeouts = ata_eh_flush_timeouts },
++ { .commands = CMDS(ATA_CMD_VERIFY),
++ .timeouts = ata_eh_pm_timeouts },
+ };
+ #undef CMDS
+
+@@ -498,7 +508,19 @@ static void ata_eh_unload(struct ata_por
+ struct ata_device *dev;
+ unsigned long flags;
+
+- /* Restore SControl IPM and SPD for the next driver and
++ /*
++ * Unless we are restarting, transition all enabled devices to
++ * standby power mode.
++ */
++ if (system_state != SYSTEM_RESTART) {
++ ata_for_each_link(link, ap, PMP_FIRST) {
++ ata_for_each_dev(dev, link, ENABLED)
++ ata_dev_power_set_standby(dev);
++ }
++ }
++
++ /*
++ * Restore SControl IPM and SPD for the next driver and
+ * disable attached devices.
+ */
+ ata_for_each_link(link, ap, PMP_FIRST) {
+@@ -690,6 +712,10 @@ void ata_scsi_port_error_handler(struct
+ ehc->saved_xfer_mode[devno] = dev->xfer_mode;
+ if (ata_ncq_enabled(dev))
+ ehc->saved_ncq_enabled |= 1 << devno;
++
++ /* If we are resuming, wake up the device */
++ if (ap->pflags & ATA_PFLAG_RESUMING)
++ ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE;
+ }
+ }
+
+@@ -753,6 +779,8 @@ void ata_scsi_port_error_handler(struct
+ /* clean up */
+ spin_lock_irqsave(ap->lock, flags);
+
++ ap->pflags &= ~ATA_PFLAG_RESUMING;
++
+ if (ap->pflags & ATA_PFLAG_LOADING)
+ ap->pflags &= ~ATA_PFLAG_LOADING;
+ else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) &&
+@@ -1244,6 +1272,13 @@ void ata_eh_detach_dev(struct ata_device
+ struct ata_eh_context *ehc = &link->eh_context;
+ unsigned long flags;
+
++ /*
++ * If the device is still enabled, transition it to standby power mode
++ * (i.e. spin down HDDs).
++ */
++ if (ata_dev_enabled(dev))
++ ata_dev_power_set_standby(dev);
++
+ ata_dev_disable(dev);
+
+ spin_lock_irqsave(ap->lock, flags);
+@@ -3042,6 +3077,15 @@ static int ata_eh_revalidate_and_attach(
+ if (ehc->i.flags & ATA_EHI_DID_RESET)
+ readid_flags |= ATA_READID_POSTRESET;
+
++ /*
++ * When resuming, before executing any command, make sure to
++ * transition the device to the active power mode.
++ */
++ if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) {
++ ata_dev_power_set_active(dev);
++ ata_eh_done(link, dev, ATA_EH_SET_ACTIVE);
++ }
++
+ if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
+ WARN_ON(dev->class == ATA_DEV_PMP);
+
+@@ -4015,6 +4059,7 @@ static void ata_eh_handle_port_suspend(s
+ unsigned long flags;
+ int rc = 0;
+ struct ata_device *dev;
++ struct ata_link *link;
+
+ /* are we suspending? */
+ spin_lock_irqsave(ap->lock, flags);
+@@ -4027,6 +4072,12 @@ static void ata_eh_handle_port_suspend(s
+
+ WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
+
++ /* Set all devices attached to the port in standby mode */
++ ata_for_each_link(link, ap, HOST_FIRST) {
++ ata_for_each_dev(dev, link, ENABLED)
++ ata_dev_power_set_standby(dev);
++ }
++
+ /*
+ * If we have a ZPODD attached, check its zero
+ * power ready status before the port is frozen.
+@@ -4109,6 +4160,7 @@ static void ata_eh_handle_port_resume(st
+ /* update the flags */
+ spin_lock_irqsave(ap->lock, flags);
+ ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
++ ap->pflags |= ATA_PFLAG_RESUMING;
+ spin_unlock_irqrestore(ap->lock, flags);
+ }
+ #endif /* CONFIG_PM */
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -1100,15 +1100,13 @@ int ata_scsi_dev_config(struct scsi_devi
+ }
+ } else {
+ sdev->sector_size = ata_id_logical_sector_size(dev->id);
++
+ /*
+- * Stop the drive on suspend but do not issue START STOP UNIT
+- * on resume as this is not necessary and may fail: the device
+- * will be woken up by ata_port_pm_resume() with a port reset
+- * and device revalidation.
++ * Ask the sd driver to issue START STOP UNIT on runtime suspend
++ * and resume only. For system level suspend/resume, devices
++ * power state is handled directly by libata EH.
+ */
+- sdev->manage_system_start_stop = true;
+ sdev->manage_runtime_start_stop = true;
+- sdev->no_start_on_resume = 1;
+ }
+
+ /*
+@@ -1284,7 +1282,7 @@ static unsigned int ata_scsi_start_stop_
+ }
+
+ if (cdb[4] & 0x1) {
+- tf->nsect = 1; /* 1 sector, lba=0 */
++ tf->nsect = 1; /* 1 sector, lba=0 */
+
+ if (qc->dev->flags & ATA_DFLAG_LBA) {
+ tf->flags |= ATA_TFLAG_LBA;
+@@ -1300,7 +1298,7 @@ static unsigned int ata_scsi_start_stop_
+ tf->lbah = 0x0; /* cyl high */
+ }
+
+- tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
++ tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
+ } else {
+ /* Some odd clown BIOSen issue spindown on power off (ACPI S4
+ * or S5) causing some drives to spin up and down again.
+@@ -1310,7 +1308,7 @@ static unsigned int ata_scsi_start_stop_
+ goto skip;
+
+ if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) &&
+- system_entering_hibernation())
++ system_entering_hibernation())
+ goto skip;
+
+ /* Issue ATA STANDBY IMMEDIATE command */
+--- a/drivers/ata/libata.h
++++ b/drivers/ata/libata.h
+@@ -62,6 +62,8 @@ extern int ata_dev_reread_id(struct ata_
+ extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
+ unsigned int readid_flags);
+ extern int ata_dev_configure(struct ata_device *dev);
++extern void ata_dev_power_set_standby(struct ata_device *dev);
++extern void ata_dev_power_set_active(struct ata_device *dev);
+ extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
+ extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
+ extern unsigned int ata_dev_set_feature(struct ata_device *dev,
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -192,6 +192,7 @@ enum {
+ ATA_PFLAG_UNLOADING = (1 << 9), /* driver is being unloaded */
+ ATA_PFLAG_UNLOADED = (1 << 10), /* driver is unloaded */
+
++ ATA_PFLAG_RESUMING = (1 << 16), /* port is being resumed */
+ ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
+ ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
+ ATA_PFLAG_INIT_GTM_VALID = (1 << 19), /* initial gtm data valid */
+@@ -318,9 +319,10 @@ enum {
+ ATA_EH_ENABLE_LINK = (1 << 3),
+ ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */
+ ATA_EH_GET_SUCCESS_SENSE = (1 << 6), /* Get sense data for successful cmd */
++ ATA_EH_SET_ACTIVE = (1 << 7), /* Set a device to active power mode */
+
+ ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK |
+- ATA_EH_GET_SUCCESS_SENSE,
++ ATA_EH_GET_SUCCESS_SENSE | ATA_EH_SET_ACTIVE,
+ ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET |
+ ATA_EH_ENABLE_LINK,
+
+@@ -358,7 +360,7 @@ enum {
+ /* This should match the actual table size of
+ * ata_eh_cmd_timeout_table in libata-eh.c.
+ */
+- ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 7,
++ ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 8,
+
+ /* Horkage types. May be set by libata or controller on drives
+ (some horkage may be drive/controller pair dependent */
--- /dev/null
+From b555aa66760f17df4a0a5e4b440816e390311a38 Mon Sep 17 00:00:00 2001
+From: Ondrej Zary <linux@zary.sk>
+Date: Thu, 5 Oct 2023 22:55:56 +0200
+Subject: ata: pata_parport: fix pata_parport_devchk
+
+From: Ondrej Zary <linux@zary.sk>
+
+commit b555aa66760f17df4a0a5e4b440816e390311a38 upstream.
+
+There's a 'x' missing in 0x55 in pata_parport_devchk(), causing the
+detection to always fail. Fix it.
+
+Fixes: 246a1c4c6b7f ("ata: pata_parport: add driver (PARIDE replacement)")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ondrej Zary <linux@zary.sk>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/pata_parport/pata_parport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/ata/pata_parport/pata_parport.c
++++ b/drivers/ata/pata_parport/pata_parport.c
+@@ -64,7 +64,7 @@ static bool pata_parport_devchk(struct a
+ pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0xaa);
+ pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0x55);
+
+- pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 055);
++ pi->proto->write_regr(pi, 0, ATA_REG_NSECT, 0x55);
+ pi->proto->write_regr(pi, 0, ATA_REG_LBAL, 0xaa);
+
+ nsect = pi->proto->read_regr(pi, 0, ATA_REG_NSECT);
--- /dev/null
+From d2302427c12277929c9f390adeda19fbf403c0bb Mon Sep 17 00:00:00 2001
+From: Ondrej Zary <linux@zary.sk>
+Date: Thu, 5 Oct 2023 22:55:57 +0200
+Subject: ata: pata_parport: implement set_devctl
+
+From: Ondrej Zary <linux@zary.sk>
+
+commit d2302427c12277929c9f390adeda19fbf403c0bb upstream.
+
+Add missing ops->sff_set_devctl implementation.
+
+Fixes: 246a1c4c6b7f ("ata: pata_parport: add driver (PARIDE replacement)")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ondrej Zary <linux@zary.sk>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/pata_parport/pata_parport.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c
+index 258d189f42e5..cf87bbb52f1f 100644
+--- a/drivers/ata/pata_parport/pata_parport.c
++++ b/drivers/ata/pata_parport/pata_parport.c
+@@ -51,6 +51,13 @@ static void pata_parport_dev_select(struct ata_port *ap, unsigned int device)
+ ata_sff_pause(ap);
+ }
+
++static void pata_parport_set_devctl(struct ata_port *ap, u8 ctl)
++{
++ struct pi_adapter *pi = ap->host->private_data;
++
++ pi->proto->write_regr(pi, 1, 6, ctl);
++}
++
+ static bool pata_parport_devchk(struct ata_port *ap, unsigned int device)
+ {
+ struct pi_adapter *pi = ap->host->private_data;
+@@ -252,6 +259,7 @@ static struct ata_port_operations pata_parport_port_ops = {
+ .hardreset = NULL,
+
+ .sff_dev_select = pata_parport_dev_select,
++ .sff_set_devctl = pata_parport_set_devctl,
+ .sff_check_status = pata_parport_check_status,
+ .sff_check_altstatus = pata_parport_check_altstatus,
+ .sff_tf_load = pata_parport_tf_load,
+--
+2.42.0
+
--- /dev/null
+From 152d0bcdf1efcb54a4fa20f694e9c7bbb6d06cbf Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Fri, 6 Oct 2023 09:41:55 +0800
+Subject: dm crypt: Fix reqsize in crypt_iv_eboiv_gen
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit 152d0bcdf1efcb54a4fa20f694e9c7bbb6d06cbf upstream.
+
+A skcipher_request object is made up of struct skcipher_request
+followed by a variable-sized trailer. The allocation of the
+skcipher_request and IV in crypt_iv_eboiv_gen is missing the
+memory for struct skcipher_request. Fix it by adding it to
+reqsize.
+
+Fixes: e3023094dffb ("dm crypt: Avoid using MAX_CIPHER_BLOCKSIZE")
+Cc: <stable@vger.kernel.org> #6.5+
+Reported-by: Tatu Heikkilä <tatu.heikkila@gmail.com>
+Reviewed-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-crypt.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index f2662c21a6df..5315fd261c23 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -753,7 +753,8 @@ static int crypt_iv_eboiv_gen(struct crypt_config *cc, u8 *iv,
+ int err;
+ u8 *buf;
+
+- reqsize = ALIGN(crypto_skcipher_reqsize(tfm), __alignof__(__le64));
++ reqsize = sizeof(*req) + crypto_skcipher_reqsize(tfm);
++ reqsize = ALIGN(reqsize, __alignof__(__le64));
+
+ req = kmalloc(reqsize + cc->iv_size, GFP_NOIO);
+ if (!req)
+--
+2.42.0
+
--- /dev/null
+From dac501397b9d81e4782232c39f94f4307b137452 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 5 Oct 2023 20:26:38 +0200
+Subject: HID: logitech-hidpp: Fix kernel crash on receiver USB disconnect
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit dac501397b9d81e4782232c39f94f4307b137452 upstream.
+
+hidpp_connect_event() has *four* time-of-check vs time-of-use (TOCTOU)
+races when it races with itself.
+
+hidpp_connect_event() primarily runs from a workqueue but it also runs
+on probe() and if a "device-connected" packet is received by the hw
+when the thread running hidpp_connect_event() from probe() is waiting on
+the hw, then a second thread running hidpp_connect_event() will be
+started from the workqueue.
+
+This opens the following races (note the below code is simplified):
+
+1. Retrieving + printing the protocol (harmless race):
+
+ if (!hidpp->protocol_major) {
+ hidpp_root_get_protocol_version()
+ hidpp->protocol_major = response.rap.params[0];
+ }
+
+We can actually see this race hit in the dmesg in the abrt output
+attached to rhbz#2227968:
+
+[ 3064.624215] logitech-hidpp-device 0003:046D:4071.0049: HID++ 4.5 device connected.
+[ 3064.658184] logitech-hidpp-device 0003:046D:4071.0049: HID++ 4.5 device connected.
+
+Testing with extra logging added has shown that after this the 2 threads
+take turn grabbing the hw access mutex (send_mutex) so they ping-pong
+through all the other TOCTOU cases managing to hit all of them:
+
+2. Updating the name to the HIDPP name (harmless race):
+
+ if (hidpp->name == hdev->name) {
+ ...
+ hidpp->name = new_name;
+ }
+
+3. Initializing the power_supply class for the battery (problematic!):
+
+hidpp_initialize_battery()
+{
+ if (hidpp->battery.ps)
+ return 0;
+
+ probe_battery(); /* Blocks, threads take turns executing this */
+
+ hidpp->battery.desc.properties =
+ devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);
+
+ hidpp->battery.ps =
+ devm_power_supply_register(&hidpp->hid_dev->dev,
+ &hidpp->battery.desc, cfg);
+}
+
+4. Creating delayed input_device (potentially problematic):
+
+ if (hidpp->delayed_input)
+ return;
+
+ hidpp->delayed_input = hidpp_allocate_input(hdev);
+
+The really big problem here is 3. Hitting the race leads to the following
+sequence:
+
+ hidpp->battery.desc.properties =
+ devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);
+
+ hidpp->battery.ps =
+ devm_power_supply_register(&hidpp->hid_dev->dev,
+ &hidpp->battery.desc, cfg);
+
+ ...
+
+ hidpp->battery.desc.properties =
+ devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);
+
+ hidpp->battery.ps =
+ devm_power_supply_register(&hidpp->hid_dev->dev,
+ &hidpp->battery.desc, cfg);
+
+So now we have registered 2 power supplies for the same battery,
+which looks a bit weird from userspace's pov but this is not even
+the really big problem.
+
+Notice how:
+
+1. This is all devm-maganaged
+2. The hidpp->battery.desc struct is shared between the 2 power supplies
+3. hidpp->battery.desc.properties points to the result from the second
+ devm_kmemdup()
+
+This causes a use after free scenario on USB disconnect of the receiver:
+1. The last registered power supply class device gets unregistered
+2. The memory from the last devm_kmemdup() call gets freed,
+ hidpp->battery.desc.properties now points to freed memory
+3. The first registered power supply class device gets unregistered,
+ this involves sending a remove uevent to userspace which invokes
+ power_supply_uevent() to fill the uevent data
+4. power_supply_uevent() uses hidpp->battery.desc.properties which
+ now points to freed memory leading to backtraces like this one:
+
+Sep 22 20:01:35 eric kernel: BUG: unable to handle page fault for address: ffffb2140e017f08
+...
+Sep 22 20:01:35 eric kernel: Workqueue: usb_hub_wq hub_event
+Sep 22 20:01:35 eric kernel: RIP: 0010:power_supply_uevent+0xee/0x1d0
+...
+Sep 22 20:01:35 eric kernel: ? asm_exc_page_fault+0x26/0x30
+Sep 22 20:01:35 eric kernel: ? power_supply_uevent+0xee/0x1d0
+Sep 22 20:01:35 eric kernel: ? power_supply_uevent+0x10d/0x1d0
+Sep 22 20:01:35 eric kernel: dev_uevent+0x10f/0x2d0
+Sep 22 20:01:35 eric kernel: kobject_uevent_env+0x291/0x680
+Sep 22 20:01:35 eric kernel: power_supply_unregister+0x8e/0xa0
+Sep 22 20:01:35 eric kernel: release_nodes+0x3d/0xb0
+Sep 22 20:01:35 eric kernel: devres_release_group+0xfc/0x130
+Sep 22 20:01:35 eric kernel: hid_device_remove+0x56/0xa0
+Sep 22 20:01:35 eric kernel: device_release_driver_internal+0x19f/0x200
+Sep 22 20:01:35 eric kernel: bus_remove_device+0xc6/0x130
+Sep 22 20:01:35 eric kernel: device_del+0x15c/0x3f0
+Sep 22 20:01:35 eric kernel: ? __queue_work+0x1df/0x440
+Sep 22 20:01:35 eric kernel: hid_destroy_device+0x4b/0x60
+Sep 22 20:01:35 eric kernel: logi_dj_remove+0x9a/0x100 [hid_logitech_dj 5c91534a0ead2b65e04dd799a0437e3b99b21bc4]
+Sep 22 20:01:35 eric kernel: hid_device_remove+0x44/0xa0
+Sep 22 20:01:35 eric kernel: device_release_driver_internal+0x19f/0x200
+Sep 22 20:01:35 eric kernel: bus_remove_device+0xc6/0x130
+Sep 22 20:01:35 eric kernel: device_del+0x15c/0x3f0
+Sep 22 20:01:35 eric kernel: ? __queue_work+0x1df/0x440
+Sep 22 20:01:35 eric kernel: hid_destroy_device+0x4b/0x60
+Sep 22 20:01:35 eric kernel: usbhid_disconnect+0x47/0x60 [usbhid 727dcc1c0b94e6b4418727a468398ac3bca492f3]
+Sep 22 20:01:35 eric kernel: usb_unbind_interface+0x90/0x270
+Sep 22 20:01:35 eric kernel: device_release_driver_internal+0x19f/0x200
+Sep 22 20:01:35 eric kernel: bus_remove_device+0xc6/0x130
+Sep 22 20:01:35 eric kernel: device_del+0x15c/0x3f0
+Sep 22 20:01:35 eric kernel: ? kobject_put+0xa0/0x1d0
+Sep 22 20:01:35 eric kernel: usb_disable_device+0xcd/0x1e0
+Sep 22 20:01:35 eric kernel: usb_disconnect+0xde/0x2c0
+Sep 22 20:01:35 eric kernel: usb_disconnect+0xc3/0x2c0
+Sep 22 20:01:35 eric kernel: hub_event+0xe80/0x1c10
+
+There have been quite a few bug reports (see Link tags) about this crash.
+
+Fix all the TOCTOU issues, including the really bad power-supply related
+system crash on USB disconnect, by making probe() use the workqueue for
+running hidpp_connect_event() too, so that it can never run more then once.
+
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227221
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227968
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227968
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=2242189
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217412#c58
+Cc: stable@vger.kernel.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20231005182638.3776-1-hdegoede@redhat.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -4515,7 +4515,8 @@ static int hidpp_probe(struct hid_device
+ goto hid_hw_init_fail;
+ }
+
+- hidpp_connect_event(hidpp);
++ schedule_work(&hidpp->work);
++ flush_work(&hidpp->work);
+
+ if (will_restart) {
+ /* Reset the HID node state */
--- /dev/null
+From c889a99a21bf124c3db08d09df919f0eccc5ea4c Mon Sep 17 00:00:00 2001
+From: Jordan Rife <jrife@google.com>
+Date: Thu, 21 Sep 2023 18:46:42 -0500
+Subject: net: prevent address rewrite in kernel_bind()
+
+From: Jordan Rife <jrife@google.com>
+
+commit c889a99a21bf124c3db08d09df919f0eccc5ea4c upstream.
+
+Similar to the change in commit 0bdf399342c5("net: Avoid address
+overwrite in kernel_connect"), BPF hooks run on bind may rewrite the
+address passed to kernel_bind(). This change
+
+1) Makes a copy of the bind address in kernel_bind() to insulate
+ callers.
+2) Replaces direct calls to sock->ops->bind() in net with kernel_bind()
+
+Link: https://lore.kernel.org/netdev/20230912013332.2048422-1-jrife@google.com/
+Fixes: 4fbac77d2d09 ("bpf: Hooks for sys_bind")
+Cc: stable@vger.kernel.org
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Jordan Rife <jrife@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/ipvs/ip_vs_sync.c | 4 ++--
+ net/rds/tcp_connect.c | 2 +-
+ net/rds/tcp_listen.c | 2 +-
+ net/socket.c | 6 +++++-
+ 4 files changed, 9 insertions(+), 5 deletions(-)
+
+--- a/net/netfilter/ipvs/ip_vs_sync.c
++++ b/net/netfilter/ipvs/ip_vs_sync.c
+@@ -1441,7 +1441,7 @@ static int bind_mcastif_addr(struct sock
+ sin.sin_addr.s_addr = addr;
+ sin.sin_port = 0;
+
+- return sock->ops->bind(sock, (struct sockaddr*)&sin, sizeof(sin));
++ return kernel_bind(sock, (struct sockaddr *)&sin, sizeof(sin));
+ }
+
+ static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen,
+@@ -1548,7 +1548,7 @@ static int make_receive_sock(struct netn
+
+ get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
+ sock->sk->sk_bound_dev_if = dev->ifindex;
+- result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
++ result = kernel_bind(sock, (struct sockaddr *)&mcast_addr, salen);
+ if (result < 0) {
+ pr_err("Error binding to the multicast addr\n");
+ goto error;
+--- a/net/rds/tcp_connect.c
++++ b/net/rds/tcp_connect.c
+@@ -145,7 +145,7 @@ int rds_tcp_conn_path_connect(struct rds
+ addrlen = sizeof(sin);
+ }
+
+- ret = sock->ops->bind(sock, addr, addrlen);
++ ret = kernel_bind(sock, addr, addrlen);
+ if (ret) {
+ rdsdebug("bind failed with %d at address %pI6c\n",
+ ret, &conn->c_laddr);
+--- a/net/rds/tcp_listen.c
++++ b/net/rds/tcp_listen.c
+@@ -306,7 +306,7 @@ struct socket *rds_tcp_listen_init(struc
+ addr_len = sizeof(*sin);
+ }
+
+- ret = sock->ops->bind(sock, (struct sockaddr *)&ss, addr_len);
++ ret = kernel_bind(sock, (struct sockaddr *)&ss, addr_len);
+ if (ret < 0) {
+ rdsdebug("could not bind %s listener socket: %d\n",
+ isv6 ? "IPv6" : "IPv4", ret);
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -3467,7 +3467,11 @@ static long compat_sock_ioctl(struct fil
+
+ int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
+ {
+- return sock->ops->bind(sock, addr, addrlen);
++ struct sockaddr_storage address;
++
++ memcpy(&address, addr, addrlen);
++
++ return sock->ops->bind(sock, (struct sockaddr *)&address, addrlen);
+ }
+ EXPORT_SYMBOL(kernel_bind);
+
--- /dev/null
+From 869b6ea1609f655a43251bf41757aa44e5350a8f Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 4 Oct 2023 15:32:01 +0200
+Subject: quota: Fix slow quotaoff
+
+From: Jan Kara <jack@suse.cz>
+
+commit 869b6ea1609f655a43251bf41757aa44e5350a8f upstream.
+
+Eric has reported that commit dabc8b207566 ("quota: fix dqput() to
+follow the guarantees dquot_srcu should provide") heavily increases
+runtime of generic/270 xfstest for ext4 in nojournal mode. The reason
+for this is that ext4 in nojournal mode leaves dquots dirty until the last
+dqput() and thus the cleanup done in quota_release_workfn() has to write
+them all. Due to the way quota_release_workfn() is written this results
+in synchronize_srcu() call for each dirty dquot which makes the dquot
+cleanup when turning quotas off extremely slow.
+
+To be able to avoid synchronize_srcu() for each dirty dquot we need to
+rework how we track dquots to be cleaned up. Instead of keeping the last
+dquot reference while it is on releasing_dquots list, we drop it right
+away and mark the dquot with new DQ_RELEASING_B bit instead. This way we
+can we can remove dquot from releasing_dquots list when new reference to
+it is acquired and thus there's no need to call synchronize_srcu() each
+time we drop dq_list_lock.
+
+References: https://lore.kernel.org/all/ZRytn6CxFK2oECUt@debian-BULLSEYE-live-builder-AMD64
+Reported-by: Eric Whitney <enwlinux@gmail.com>
+Fixes: dabc8b207566 ("quota: fix dqput() to follow the guarantees dquot_srcu should provide")
+CC: stable@vger.kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/quota/dquot.c | 66 +++++++++++++++++++++++++++--------------------
+ include/linux/quota.h | 4 ++
+ include/linux/quotaops.h | 2 -
+ 3 files changed, 43 insertions(+), 29 deletions(-)
+
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -233,19 +233,18 @@ static void put_quota_format(struct quot
+ * All dquots are placed to the end of inuse_list when first created, and this
+ * list is used for invalidate operation, which must look at every dquot.
+ *
+- * When the last reference of a dquot will be dropped, the dquot will be
+- * added to releasing_dquots. We'd then queue work item which would call
++ * When the last reference of a dquot is dropped, the dquot is added to
++ * releasing_dquots. We'll then queue work item which will call
+ * synchronize_srcu() and after that perform the final cleanup of all the
+- * dquots on the list. Both releasing_dquots and free_dquots use the
+- * dq_free list_head in the dquot struct. When a dquot is removed from
+- * releasing_dquots, a reference count is always subtracted, and if
+- * dq_count == 0 at that point, the dquot will be added to the free_dquots.
++ * dquots on the list. Each cleaned up dquot is moved to free_dquots list.
++ * Both releasing_dquots and free_dquots use the dq_free list_head in the dquot
++ * struct.
+ *
+- * Unused dquots (dq_count == 0) are added to the free_dquots list when freed,
+- * and this list is searched whenever we need an available dquot. Dquots are
+- * removed from the list as soon as they are used again, and
+- * dqstats.free_dquots gives the number of dquots on the list. When
+- * dquot is invalidated it's completely released from memory.
++ * Unused and cleaned up dquots are in the free_dquots list and this list is
++ * searched whenever we need an available dquot. Dquots are removed from the
++ * list as soon as they are used again and dqstats.free_dquots gives the number
++ * of dquots on the list. When dquot is invalidated it's completely released
++ * from memory.
+ *
+ * Dirty dquots are added to the dqi_dirty_list of quota_info when mark
+ * dirtied, and this list is searched when writing dirty dquots back to
+@@ -321,6 +320,7 @@ static inline void put_dquot_last(struct
+ static inline void put_releasing_dquots(struct dquot *dquot)
+ {
+ list_add_tail(&dquot->dq_free, &releasing_dquots);
++ set_bit(DQ_RELEASING_B, &dquot->dq_flags);
+ }
+
+ static inline void remove_free_dquot(struct dquot *dquot)
+@@ -328,8 +328,10 @@ static inline void remove_free_dquot(str
+ if (list_empty(&dquot->dq_free))
+ return;
+ list_del_init(&dquot->dq_free);
+- if (!atomic_read(&dquot->dq_count))
++ if (!test_bit(DQ_RELEASING_B, &dquot->dq_flags))
+ dqstats_dec(DQST_FREE_DQUOTS);
++ else
++ clear_bit(DQ_RELEASING_B, &dquot->dq_flags);
+ }
+
+ static inline void put_inuse(struct dquot *dquot)
+@@ -581,12 +583,6 @@ restart:
+ continue;
+ /* Wait for dquot users */
+ if (atomic_read(&dquot->dq_count)) {
+- /* dquot in releasing_dquots, flush and retry */
+- if (!list_empty(&dquot->dq_free)) {
+- spin_unlock(&dq_list_lock);
+- goto restart;
+- }
+-
+ atomic_inc(&dquot->dq_count);
+ spin_unlock(&dq_list_lock);
+ /*
+@@ -606,6 +602,15 @@ restart:
+ goto restart;
+ }
+ /*
++ * The last user already dropped its reference but dquot didn't
++ * get fully cleaned up yet. Restart the scan which flushes the
++ * work cleaning up released dquots.
++ */
++ if (test_bit(DQ_RELEASING_B, &dquot->dq_flags)) {
++ spin_unlock(&dq_list_lock);
++ goto restart;
++ }
++ /*
+ * Quota now has no users and it has been written on last
+ * dqput()
+ */
+@@ -696,6 +701,13 @@ int dquot_writeback_dquots(struct super_
+ dq_dirty);
+
+ WARN_ON(!dquot_active(dquot));
++ /* If the dquot is releasing we should not touch it */
++ if (test_bit(DQ_RELEASING_B, &dquot->dq_flags)) {
++ spin_unlock(&dq_list_lock);
++ flush_delayed_work("a_release_work);
++ spin_lock(&dq_list_lock);
++ continue;
++ }
+
+ /* Now we have active dquot from which someone is
+ * holding reference so we can safely just increase
+@@ -809,18 +821,18 @@ static void quota_release_workfn(struct
+ /* Exchange the list head to avoid livelock. */
+ list_replace_init(&releasing_dquots, &rls_head);
+ spin_unlock(&dq_list_lock);
++ synchronize_srcu(&dquot_srcu);
+
+ restart:
+- synchronize_srcu(&dquot_srcu);
+ spin_lock(&dq_list_lock);
+ while (!list_empty(&rls_head)) {
+ dquot = list_first_entry(&rls_head, struct dquot, dq_free);
+- /* Dquot got used again? */
+- if (atomic_read(&dquot->dq_count) > 1) {
+- remove_free_dquot(dquot);
+- atomic_dec(&dquot->dq_count);
+- continue;
+- }
++ WARN_ON_ONCE(atomic_read(&dquot->dq_count));
++ /*
++ * Note that DQ_RELEASING_B protects us from racing with
++ * invalidate_dquots() calls so we are safe to work with the
++ * dquot even after we drop dq_list_lock.
++ */
+ if (dquot_dirty(dquot)) {
+ spin_unlock(&dq_list_lock);
+ /* Commit dquot before releasing */
+@@ -834,7 +846,6 @@ restart:
+ }
+ /* Dquot is inactive and clean, now move it to free list */
+ remove_free_dquot(dquot);
+- atomic_dec(&dquot->dq_count);
+ put_dquot_last(dquot);
+ }
+ spin_unlock(&dq_list_lock);
+@@ -875,6 +886,7 @@ void dqput(struct dquot *dquot)
+ BUG_ON(!list_empty(&dquot->dq_free));
+ #endif
+ put_releasing_dquots(dquot);
++ atomic_dec(&dquot->dq_count);
+ spin_unlock(&dq_list_lock);
+ queue_delayed_work(system_unbound_wq, "a_release_work, 1);
+ }
+@@ -963,7 +975,7 @@ we_slept:
+ dqstats_inc(DQST_LOOKUPS);
+ }
+ /* Wait for dq_lock - after this we know that either dquot_release() is
+- * already finished or it will be canceled due to dq_count > 1 test */
++ * already finished or it will be canceled due to dq_count > 0 test */
+ wait_on_dquot(dquot);
+ /* Read the dquot / allocate space in quota file */
+ if (!dquot_active(dquot)) {
+--- a/include/linux/quota.h
++++ b/include/linux/quota.h
+@@ -285,7 +285,9 @@ static inline void dqstats_dec(unsigned
+ #define DQ_FAKE_B 3 /* no limits only usage */
+ #define DQ_READ_B 4 /* dquot was read into memory */
+ #define DQ_ACTIVE_B 5 /* dquot is active (dquot_release not called) */
+-#define DQ_LASTSET_B 6 /* Following 6 bits (see QIF_) are reserved\
++#define DQ_RELEASING_B 6 /* dquot is in releasing_dquots list waiting
++ * to be cleaned up */
++#define DQ_LASTSET_B 7 /* Following 6 bits (see QIF_) are reserved\
+ * for the mask of entries set via SETQUOTA\
+ * quotactl. They are set under dq_data_lock\
+ * and the quota format handling dquot can\
+--- a/include/linux/quotaops.h
++++ b/include/linux/quotaops.h
+@@ -57,7 +57,7 @@ static inline bool dquot_is_busy(struct
+ {
+ if (test_bit(DQ_MOD_B, &dquot->dq_flags))
+ return true;
+- if (atomic_read(&dquot->dq_count) > 1)
++ if (atomic_read(&dquot->dq_count) > 0)
+ return true;
+ return false;
+ }
--- /dev/null
+From 626b13f015e080e434b1dee9a0c116ddbf4fb695 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Wed, 4 Oct 2023 17:50:49 +0900
+Subject: scsi: Do not rescan devices with a suspended queue
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit 626b13f015e080e434b1dee9a0c116ddbf4fb695 upstream.
+
+Commit ff48b37802e5 ("scsi: Do not attempt to rescan suspended devices")
+modified scsi_rescan_device() to avoid attempting rescanning a suspended
+device. However, the modification added a check to verify that a SCSI
+device is in the running state without checking if the device request
+queue (in the case of block device) is also running, thus allowing the
+exectuion of internal requests. Without checking the device request
+queue, commit ff48b37802e5 fix is incomplete and deadlocks on resume can
+still happen. Use blk_queue_pm_only() to check if the device request
+queue allows executing commands in addition to checking the SCSI device
+state.
+
+Reported-by: Petr Tesarik <petr@tesarici.cz>
+Fixes: ff48b37802e5 ("scsi: Do not attempt to rescan suspended devices")
+Cc: stable@vger.kernel.org
+Tested-by: Petr Tesarik <petr@tesarici.cz>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/scsi_scan.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -1627,12 +1627,13 @@ int scsi_rescan_device(struct scsi_devic
+ device_lock(dev);
+
+ /*
+- * Bail out if the device is not running. Otherwise, the rescan may
+- * block waiting for commands to be executed, with us holding the
+- * device lock. This can result in a potential deadlock in the power
+- * management core code when system resume is on-going.
++ * Bail out if the device or its queue are not running. Otherwise,
++ * the rescan may block waiting for commands to be executed, with us
++ * holding the device lock. This can result in a potential deadlock
++ * in the power management core code when system resume is on-going.
+ */
+- if (sdev->sdev_state != SDEV_RUNNING) {
++ if (sdev->sdev_state != SDEV_RUNNING ||
++ blk_queue_pm_only(sdev->request_queue)) {
+ ret = -EWOULDBLOCK;
+ goto unlock;
+ }
media-dt-bindings-imx7-csi-make-power-domains-not-re.patch
drm-amd-display-implement-pipe-type-definition-and-adding-accessors.patch
drm-amd-display-apply-edge-case-dispclk-wdivider-changes-to-master-otg-pipes-only.patch
+scsi-do-not-rescan-devices-with-a-suspended-queue.patch
+ata-pata_parport-fix-pata_parport_devchk.patch
+ata-pata_parport-implement-set_devctl.patch
+hid-logitech-hidpp-fix-kernel-crash-on-receiver-usb-disconnect.patch
+quota-fix-slow-quotaoff.patch
+dm-crypt-fix-reqsize-in-crypt_iv_eboiv_gen.patch
+asoc-amd-yc-fix-non-functional-mic-on-lenovo-82ym.patch
+asoc-hdmi-codec-fix-broken-channel-map-reporting.patch
+ata-libata-scsi-disable-scsi-device-manage_system_start_stop.patch
+net-prevent-address-rewrite-in-kernel_bind.patch