From: Greg Kroah-Hartman Date: Thu, 12 Oct 2023 17:40:46 +0000 (+0200) Subject: 6.5-stable patches X-Git-Tag: v6.1.58~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c9460886904a7de3c02ebc82c4000d090ea62c42;p=thirdparty%2Fkernel%2Fstable-queue.git 6.5-stable patches added patches: 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 ata-pata_parport-fix-pata_parport_devchk.patch ata-pata_parport-implement-set_devctl.patch dm-crypt-fix-reqsize-in-crypt_iv_eboiv_gen.patch hid-logitech-hidpp-fix-kernel-crash-on-receiver-usb-disconnect.patch net-prevent-address-rewrite-in-kernel_bind.patch quota-fix-slow-quotaoff.patch scsi-do-not-rescan-devices-with-a-suspended-queue.patch --- diff --git a/queue-6.5/asoc-amd-yc-fix-non-functional-mic-on-lenovo-82ym.patch b/queue-6.5/asoc-amd-yc-fix-non-functional-mic-on-lenovo-82ym.patch new file mode 100644 index 00000000000..679f9387fb5 --- /dev/null +++ b/queue-6.5/asoc-amd-yc-fix-non-functional-mic-on-lenovo-82ym.patch @@ -0,0 +1,40 @@ +From 1948fa64727685ac3f6584755212e2e738b6b051 Mon Sep 17 00:00:00 2001 +From: Sven Frotscher +Date: Thu, 28 Sep 2023 00:36:07 +0200 +Subject: ASoC: amd: yc: Fix non-functional mic on Lenovo 82YM + +From: Sven Frotscher + +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 +Link: https://lore.kernel.org/r/20230927223758.18870-1-sven.frotscher@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + 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"), + } + }, diff --git a/queue-6.5/asoc-hdmi-codec-fix-broken-channel-map-reporting.patch b/queue-6.5/asoc-hdmi-codec-fix-broken-channel-map-reporting.patch new file mode 100644 index 00000000000..23305b32fd3 --- /dev/null +++ b/queue-6.5/asoc-hdmi-codec-fix-broken-channel-map-reporting.patch @@ -0,0 +1,59 @@ +From b84b53149476b22cc3b8677b771fb4cf06d1d455 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Fri, 29 Sep 2023 21:50:28 +0200 +Subject: ASoC: hdmi-codec: Fix broken channel map reporting + +From: Matthias Reichl + +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 +Link: https://lore.kernel.org/r/20230929195027.97136-1-hias@horus.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } diff --git a/queue-6.5/ata-libata-scsi-disable-scsi-device-manage_system_start_stop.patch b/queue-6.5/ata-libata-scsi-disable-scsi-device-manage_system_start_stop.patch new file mode 100644 index 00000000000..9b4c16d8ca5 --- /dev/null +++ b/queue-6.5/ata-libata-scsi-disable-scsi-device-manage_system_start_stop.patch @@ -0,0 +1,410 @@ +From aa3998dbeb3abce63653b7f6d4542e7dcd022590 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Sat, 26 Aug 2023 09:43:39 +0900 +Subject: ata: libata-scsi: Disable scsi device manage_system_start_stop + +From: Damien Le Moal + +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 +Reviewed-by: Hannes Reinecke +Tested-by: Geert Uytterhoeven +Reviewed-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + 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 */ diff --git a/queue-6.5/ata-pata_parport-fix-pata_parport_devchk.patch b/queue-6.5/ata-pata_parport-fix-pata_parport_devchk.patch new file mode 100644 index 00000000000..78cc8ba8d54 --- /dev/null +++ b/queue-6.5/ata-pata_parport-fix-pata_parport_devchk.patch @@ -0,0 +1,33 @@ +From b555aa66760f17df4a0a5e4b440816e390311a38 Mon Sep 17 00:00:00 2001 +From: Ondrej Zary +Date: Thu, 5 Oct 2023 22:55:56 +0200 +Subject: ata: pata_parport: fix pata_parport_devchk + +From: Ondrej Zary + +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 +Reviewed-by: Sergey Shtylyov +Signed-off-by: Damien Le Moal +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/queue-6.5/ata-pata_parport-implement-set_devctl.patch b/queue-6.5/ata-pata_parport-implement-set_devctl.patch new file mode 100644 index 00000000000..2a83e8ff4ea --- /dev/null +++ b/queue-6.5/ata-pata_parport-implement-set_devctl.patch @@ -0,0 +1,50 @@ +From d2302427c12277929c9f390adeda19fbf403c0bb Mon Sep 17 00:00:00 2001 +From: Ondrej Zary +Date: Thu, 5 Oct 2023 22:55:57 +0200 +Subject: ata: pata_parport: implement set_devctl + +From: Ondrej Zary + +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 +Reviewed-by: Sergey Shtylyov +Signed-off-by: Damien Le Moal +Signed-off-by: Greg Kroah-Hartman +--- + 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 + diff --git a/queue-6.5/dm-crypt-fix-reqsize-in-crypt_iv_eboiv_gen.patch b/queue-6.5/dm-crypt-fix-reqsize-in-crypt_iv_eboiv_gen.patch new file mode 100644 index 00000000000..1d345d62cdf --- /dev/null +++ b/queue-6.5/dm-crypt-fix-reqsize-in-crypt_iv_eboiv_gen.patch @@ -0,0 +1,45 @@ +From 152d0bcdf1efcb54a4fa20f694e9c7bbb6d06cbf Mon Sep 17 00:00:00 2001 +From: Herbert Xu +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 + +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: #6.5+ +Reported-by: Tatu Heikkilä +Reviewed-by: Mike Snitzer +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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 + diff --git a/queue-6.5/hid-logitech-hidpp-fix-kernel-crash-on-receiver-usb-disconnect.patch b/queue-6.5/hid-logitech-hidpp-fix-kernel-crash-on-receiver-usb-disconnect.patch new file mode 100644 index 00000000000..fe3748b6823 --- /dev/null +++ b/queue-6.5/hid-logitech-hidpp-fix-kernel-crash-on-receiver-usb-disconnect.patch @@ -0,0 +1,177 @@ +From dac501397b9d81e4782232c39f94f4307b137452 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 5 Oct 2023 20:26:38 +0200 +Subject: HID: logitech-hidpp: Fix kernel crash on receiver USB disconnect + +From: Hans de Goede + +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 +Link: https://lore.kernel.org/r/20231005182638.3776-1-hdegoede@redhat.com +Signed-off-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman +--- + 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 */ diff --git a/queue-6.5/net-prevent-address-rewrite-in-kernel_bind.patch b/queue-6.5/net-prevent-address-rewrite-in-kernel_bind.patch new file mode 100644 index 00000000000..de8468ea5a0 --- /dev/null +++ b/queue-6.5/net-prevent-address-rewrite-in-kernel_bind.patch @@ -0,0 +1,89 @@ +From c889a99a21bf124c3db08d09df919f0eccc5ea4c Mon Sep 17 00:00:00 2001 +From: Jordan Rife +Date: Thu, 21 Sep 2023 18:46:42 -0500 +Subject: net: prevent address rewrite in kernel_bind() + +From: Jordan Rife + +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 +Signed-off-by: Jordan Rife +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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); + diff --git a/queue-6.5/quota-fix-slow-quotaoff.patch b/queue-6.5/quota-fix-slow-quotaoff.patch new file mode 100644 index 00000000000..36b1a5a52ab --- /dev/null +++ b/queue-6.5/quota-fix-slow-quotaoff.patch @@ -0,0 +1,208 @@ +From 869b6ea1609f655a43251bf41757aa44e5350a8f Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 4 Oct 2023 15:32:01 +0200 +Subject: quota: Fix slow quotaoff + +From: Jan Kara + +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 +Fixes: dabc8b207566 ("quota: fix dqput() to follow the guarantees dquot_srcu should provide") +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } diff --git a/queue-6.5/scsi-do-not-rescan-devices-with-a-suspended-queue.patch b/queue-6.5/scsi-do-not-rescan-devices-with-a-suspended-queue.patch new file mode 100644 index 00000000000..e12f24947a6 --- /dev/null +++ b/queue-6.5/scsi-do-not-rescan-devices-with-a-suspended-queue.patch @@ -0,0 +1,52 @@ +From 626b13f015e080e434b1dee9a0c116ddbf4fb695 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Wed, 4 Oct 2023 17:50:49 +0900 +Subject: scsi: Do not rescan devices with a suspended queue + +From: Damien Le Moal + +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 +Fixes: ff48b37802e5 ("scsi: Do not attempt to rescan suspended devices") +Cc: stable@vger.kernel.org +Tested-by: Petr Tesarik +Reviewed-by: Martin K. Petersen +Signed-off-by: Damien Le Moal +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } diff --git a/queue-6.5/series b/queue-6.5/series index 9f0c10404c3..1f319daeffd 100644 --- a/queue-6.5/series +++ b/queue-6.5/series @@ -10,3 +10,13 @@ platform-x86-hp-wmi-mark-driver-struct-with-__refdat.patch 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