--- /dev/null
+From e570a5ca307f6d7a6acd080fc219db2ce3c0737b Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Thu, 12 Feb 2026 10:18:28 +0800
+Subject: ASoC: dt-bindings: asahi-kasei,ak4458: Fix the supply names
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit e570a5ca307f6d7a6acd080fc219db2ce3c0737b upstream.
+
+In the original txt format binding document ak4458.txt, the supply names
+are 'AVDD-supply', 'DVDD-supply', and they are also used in driver. But in
+the commit converting to yaml format, they are changed to 'avdd-supply',
+'dvdd-supply'. After search all the dts file, these names 'AVDD-supply',
+'DVDD-supply', 'avdd-supply', 'dvdd-supply' are not used in any dts
+file. So it is safe to fix this yaml binding document.
+
+Fixes: 009e83b591dd ("ASoC: dt-bindings: ak4458: Convert to dtschema")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260212021829.3244736-3-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml
++++ b/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml
+@@ -18,10 +18,10 @@ properties:
+ reg:
+ maxItems: 1
+
+- avdd-supply:
++ AVDD-supply:
+ description: Analog power supply
+
+- dvdd-supply:
++ DVDD-supply:
+ description: Digital power supply
+
+ reset-gpios:
--- /dev/null
+From 50a634f1d795721ce68583c78ba493f1d7aa8bc2 Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Thu, 12 Feb 2026 10:18:27 +0800
+Subject: ASoC: dt-bindings: asahi-kasei,ak4458: set unevaluatedProperties:false
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit 50a634f1d795721ce68583c78ba493f1d7aa8bc2 upstream.
+
+When including the dai-common.yaml, and allow '#sound-dai-cells' and
+"sound-name-prefix' to be used, should use unevaluatedProperties:false
+according to writing-bindings.rst.
+
+Fixes: 8d7de4a014f5 ("ASoC: dt-bindings: asahi-kasei,ak4458: Reference common DAI properties")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260212021829.3244736-2-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml
++++ b/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml
+@@ -56,7 +56,7 @@ allOf:
+ properties:
+ dsd-path: false
+
+-additionalProperties: false
++unevaluatedProperties: false
+
+ examples:
+ - |
--- /dev/null
+From 80ca113671a005430207d351cb403c1637106212 Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Thu, 12 Feb 2026 10:18:29 +0800
+Subject: ASoC: dt-bindings: asahi-kasei,ak5558: Fix the supply names
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit 80ca113671a005430207d351cb403c1637106212 upstream.
+
+In the original txt format binding document ak4458.txt, the supply names
+are 'AVDD-supply', 'DVDD-supply', and they are also used in driver. But in
+the commit converting to yaml format, they are changed to 'avdd-supply',
+'dvdd-supply'. After search all the dts file, these names 'AVDD-supply',
+'DVDD-supply', 'avdd-supply', 'dvdd-supply' are not used in any dts
+file. So it is safe to fix the yaml binding document.
+
+Fixes: 829d78e3ea32 ("ASoC: dt-bindings: ak5558: Convert to dtschema")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260212021829.3244736-4-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml
++++ b/Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml
+@@ -19,10 +19,10 @@ properties:
+ reg:
+ maxItems: 1
+
+- avdd-supply:
++ AVDD-supply:
+ description: A 1.8V supply that powers up the AVDD pin.
+
+- dvdd-supply:
++ DVDD-supply:
+ description: A 1.2V supply that powers up the DVDD pin.
+
+ reset-gpios:
--- /dev/null
+From 0ea84089dbf62a92dc7889c79e6b18fc89260808 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Wed, 17 Dec 2025 16:40:48 +0900
+Subject: ata: libata-scsi: avoid Non-NCQ command starvation
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit 0ea84089dbf62a92dc7889c79e6b18fc89260808 upstream.
+
+When a non-NCQ command is issued while NCQ commands are being executed,
+ata_scsi_qc_issue() indicates to the SCSI layer that the command issuing
+should be deferred by returning SCSI_MLQUEUE_XXX_BUSY. This command
+deferring is correct and as mandated by the ACS specifications since
+NCQ and non-NCQ commands cannot be mixed.
+
+However, in the case of a host adapter using multiple submission queues,
+when the target device is under a constant load of NCQ commands, there
+are no guarantees that requeueing the non-NCQ command will be executed
+later and it may be deferred again repeatedly as other submission queues
+can constantly issue NCQ commands from different CPUs ahead of the
+non-NCQ command. This can lead to very long delays for the execution of
+non-NCQ commands, and even complete starvation for these commands in the
+worst case scenario.
+
+Since the block layer and the SCSI layer do not distinguish between
+queueable (NCQ) and non queueable (non-NCQ) commands, libata-scsi SAT
+implementation must ensure forward progress for non-NCQ commands in the
+presence of NCQ command traffic. This is similar to what SAS HBAs with a
+hardware/firmware based SAT implementation do.
+
+Implement such forward progress guarantee by limiting requeueing of
+non-NCQ commands from ata_scsi_qc_issue(): when a non-NCQ command is
+received and NCQ commands are in-flight, do not force a requeue of the
+non-NCQ command by returning SCSI_MLQUEUE_XXX_BUSY and instead return 0
+to indicate that the command was accepted but hold on to the qc using
+the new deferred_qc field of struct ata_port.
+
+This deferred qc will be issued using the work item deferred_qc_work
+running the function ata_scsi_deferred_qc_work() once all in-flight
+commands complete, which is checked with the port qc_defer() callback
+return value indicating that no further delay is necessary. This check
+is done using the helper function ata_scsi_schedule_deferred_qc() which
+is called from ata_scsi_qc_complete(). This thus excludes this mechanism
+from all internal non-NCQ commands issued by ATA EH.
+
+When a port deferred_qc is non NULL, that is, the port has a command
+waiting for the device queue to drain, the issuing of all incoming
+commands (both NCQ and non-NCQ) is deferred using the regular busy
+mechanism. This simplifies the code and also avoids potential denial of
+service problems if a user issues too many non-NCQ commands.
+
+Finally, whenever ata EH is scheduled, regardless of the reason, a
+deferred qc is always requeued so that it can be retried once EH
+completes. This is done by calling the function
+ata_scsi_requeue_deferred_qc() from ata_eh_set_pending(). This avoids
+the need for any special processing for the deferred qc in case of NCQ
+error, link or device reset, or device timeout.
+
+Reported-by: Xingui Yang <yangxingui@huawei.com>
+Reported-by: Igor Pylypiv <ipylypiv@google.com>
+Fixes: bdb01301f3ea ("scsi: Add host and host template flag 'host_tagset'")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Tested-by: Igor Pylypiv <ipylypiv@google.com>
+Tested-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-core.c | 5 ++
+ drivers/ata/libata-eh.c | 6 ++
+ drivers/ata/libata-scsi.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/ata/libata.h | 2
+ include/linux/libata.h | 3 +
+ 5 files changed, 109 insertions(+)
+
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -5518,6 +5518,7 @@ struct ata_port *ata_port_alloc(struct a
+ mutex_init(&ap->scsi_scan_mutex);
+ INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
+ INIT_DELAYED_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
++ INIT_WORK(&ap->deferred_qc_work, ata_scsi_deferred_qc_work);
+ INIT_LIST_HEAD(&ap->eh_done_q);
+ init_waitqueue_head(&ap->eh_wait_q);
+ init_completion(&ap->park_req_pending);
+@@ -6123,6 +6124,10 @@ static void ata_port_detach(struct ata_p
+ }
+ }
+
++ /* Make sure the deferred qc work finished. */
++ cancel_work_sync(&ap->deferred_qc_work);
++ WARN_ON(ap->deferred_qc);
++
+ /* Tell EH to disable all devices */
+ ap->pflags |= ATA_PFLAG_UNLOADING;
+ ata_port_schedule_eh(ap);
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -904,6 +904,12 @@ static void ata_eh_set_pending(struct at
+
+ ap->pflags |= ATA_PFLAG_EH_PENDING;
+
++ /*
++ * If we have a deferred qc, requeue it so that it is retried once EH
++ * completes.
++ */
++ ata_scsi_requeue_deferred_qc(ap);
++
+ if (!fastdrain)
+ return;
+
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -1705,8 +1705,77 @@ static void ata_qc_done(struct ata_queue
+ done(cmd);
+ }
+
++void ata_scsi_deferred_qc_work(struct work_struct *work)
++{
++ struct ata_port *ap =
++ container_of(work, struct ata_port, deferred_qc_work);
++ struct ata_queued_cmd *qc;
++ unsigned long flags;
++
++ spin_lock_irqsave(ap->lock, flags);
++
++ /*
++ * If we still have a deferred qc and we are not in EH, issue it. In
++ * such case, we should not need any more deferring the qc, so warn if
++ * qc_defer() says otherwise.
++ */
++ qc = ap->deferred_qc;
++ if (qc && !ata_port_eh_scheduled(ap)) {
++ WARN_ON_ONCE(ap->ops->qc_defer(qc));
++ ap->deferred_qc = NULL;
++ ata_qc_issue(qc);
++ }
++
++ spin_unlock_irqrestore(ap->lock, flags);
++}
++
++void ata_scsi_requeue_deferred_qc(struct ata_port *ap)
++{
++ struct ata_queued_cmd *qc = ap->deferred_qc;
++ struct scsi_cmnd *scmd;
++
++ lockdep_assert_held(ap->lock);
++
++ /*
++ * If we have a deferred qc when a reset occurs or NCQ commands fail,
++ * do not try to be smart about what to do with this deferred command
++ * and simply retry it by completing it with DID_SOFT_ERROR.
++ */
++ if (!qc)
++ return;
++
++ scmd = qc->scsicmd;
++ ap->deferred_qc = NULL;
++ ata_qc_free(qc);
++ scmd->result = (DID_SOFT_ERROR << 16);
++ scsi_done(scmd);
++}
++
++static void ata_scsi_schedule_deferred_qc(struct ata_port *ap)
++{
++ struct ata_queued_cmd *qc = ap->deferred_qc;
++
++ lockdep_assert_held(ap->lock);
++
++ /*
++ * If we have a deferred qc, then qc_defer() is defined and we can use
++ * this callback to determine if this qc is good to go, unless EH has
++ * been scheduled.
++ */
++ if (!qc)
++ return;
++
++ if (ata_port_eh_scheduled(ap)) {
++ ata_scsi_requeue_deferred_qc(ap);
++ return;
++ }
++ if (!ap->ops->qc_defer(qc))
++ queue_work(system_highpri_wq, &ap->deferred_qc_work);
++}
++
+ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
+ {
++ struct ata_port *ap = qc->ap;
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ u8 *cdb = cmd->cmnd;
+ bool have_sense = qc->flags & ATA_QCFLAG_SENSE_VALID;
+@@ -1734,6 +1803,8 @@ static void ata_scsi_qc_complete(struct
+ }
+
+ ata_qc_done(qc);
++
++ ata_scsi_schedule_deferred_qc(ap);
+ }
+
+ static int ata_scsi_qc_issue(struct ata_port *ap, struct ata_queued_cmd *qc)
+@@ -1743,6 +1814,16 @@ static int ata_scsi_qc_issue(struct ata_
+ if (!ap->ops->qc_defer)
+ goto issue;
+
++ /*
++ * If we already have a deferred qc, then rely on the SCSI layer to
++ * requeue and defer all incoming commands until the deferred qc is
++ * processed, once all on-going commands complete.
++ */
++ if (ap->deferred_qc) {
++ ata_qc_free(qc);
++ return SCSI_MLQUEUE_DEVICE_BUSY;
++ }
++
+ /* Check if the command needs to be deferred. */
+ ret = ap->ops->qc_defer(qc);
+ switch (ret) {
+@@ -1761,6 +1842,18 @@ static int ata_scsi_qc_issue(struct ata_
+ }
+
+ if (ret) {
++ /*
++ * We must defer this qc: if this is not an NCQ command, keep
++ * this qc as a deferred one and report to the SCSI layer that
++ * we issued it so that it is not requeued. The deferred qc will
++ * be issued with the port deferred_qc_work once all on-going
++ * commands complete.
++ */
++ if (!ata_is_ncq(qc->tf.protocol)) {
++ ap->deferred_qc = qc;
++ return 0;
++ }
++
+ /* Force a requeue of the command to defer its execution. */
+ ata_qc_free(qc);
+ return ret;
+--- a/drivers/ata/libata.h
++++ b/drivers/ata/libata.h
+@@ -131,6 +131,8 @@ extern int ata_scsi_user_scan(struct Scs
+ void ata_scsi_sdev_config(struct scsi_device *sdev);
+ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev);
+ int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev);
++void ata_scsi_deferred_qc_work(struct work_struct *work);
++void ata_scsi_requeue_deferred_qc(struct ata_port *ap);
+
+ /* libata-eh.c */
+ extern unsigned int ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -838,6 +838,9 @@ struct ata_port {
+ u64 qc_active;
+ int nr_active_links; /* #links with active qcs */
+
++ struct work_struct deferred_qc_work;
++ struct ata_queued_cmd *deferred_qc;
++
+ struct ata_link link; /* host default link */
+ struct ata_link *slave_link; /* see ata_slave_link_init() */
+
--- /dev/null
+From bb3a8154b1a1dc2c86d037482c0a2cf9186829ed Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Wed, 17 Dec 2025 14:05:25 +0900
+Subject: ata: libata-scsi: refactor ata_scsi_translate()
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit bb3a8154b1a1dc2c86d037482c0a2cf9186829ed upstream.
+
+Factor out of ata_scsi_translate() the code handling queued command
+deferral using the port qc_defer callback and issuing the queued
+command with ata_qc_issue() into the new function ata_scsi_qc_issue(),
+and simplify the goto used in ata_scsi_translate().
+While at it, also add a lockdep annotation to check that the port lock
+is held when ata_scsi_translate() is called.
+
+No functional changes.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-scsi.c | 81 ++++++++++++++++++++++++++++------------------
+ 1 file changed, 50 insertions(+), 31 deletions(-)
+
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -1736,6 +1736,42 @@ static void ata_scsi_qc_complete(struct
+ ata_qc_done(qc);
+ }
+
++static int ata_scsi_qc_issue(struct ata_port *ap, struct ata_queued_cmd *qc)
++{
++ int ret;
++
++ if (!ap->ops->qc_defer)
++ goto issue;
++
++ /* Check if the command needs to be deferred. */
++ ret = ap->ops->qc_defer(qc);
++ switch (ret) {
++ case 0:
++ break;
++ case ATA_DEFER_LINK:
++ ret = SCSI_MLQUEUE_DEVICE_BUSY;
++ break;
++ case ATA_DEFER_PORT:
++ ret = SCSI_MLQUEUE_HOST_BUSY;
++ break;
++ default:
++ WARN_ON_ONCE(1);
++ ret = SCSI_MLQUEUE_HOST_BUSY;
++ break;
++ }
++
++ if (ret) {
++ /* Force a requeue of the command to defer its execution. */
++ ata_qc_free(qc);
++ return ret;
++ }
++
++issue:
++ ata_qc_issue(qc);
++
++ return 0;
++}
++
+ /**
+ * ata_scsi_translate - Translate then issue SCSI command to ATA device
+ * @dev: ATA device to which the command is addressed
+@@ -1759,66 +1795,49 @@ static void ata_scsi_qc_complete(struct
+ * spin_lock_irqsave(host lock)
+ *
+ * RETURNS:
+- * 0 on success, SCSI_ML_QUEUE_DEVICE_BUSY if the command
+- * needs to be deferred.
++ * 0 on success, SCSI_ML_QUEUE_DEVICE_BUSY or SCSI_MLQUEUE_HOST_BUSY if the
++ * command needs to be deferred.
+ */
+ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
+ ata_xlat_func_t xlat_func)
+ {
+ struct ata_port *ap = dev->link->ap;
+ struct ata_queued_cmd *qc;
+- int rc;
+
++ lockdep_assert_held(ap->lock);
++
++ /*
++ * ata_scsi_qc_new() calls scsi_done(cmd) in case of failure. So we
++ * have nothing further to do when allocating a qc fails.
++ */
+ qc = ata_scsi_qc_new(dev, cmd);
+ if (!qc)
+- goto err_mem;
++ return 0;
+
+ /* data is present; dma-map it */
+ if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
+ cmd->sc_data_direction == DMA_TO_DEVICE) {
+ if (unlikely(scsi_bufflen(cmd) < 1)) {
+ ata_dev_warn(dev, "WARNING: zero len r/w req\n");
+- goto err_did;
++ cmd->result = (DID_ERROR << 16);
++ goto done;
+ }
+
+ ata_sg_init(qc, scsi_sglist(cmd), scsi_sg_count(cmd));
+-
+ qc->dma_dir = cmd->sc_data_direction;
+ }
+
+ qc->complete_fn = ata_scsi_qc_complete;
+
+ if (xlat_func(qc))
+- goto early_finish;
+-
+- if (ap->ops->qc_defer) {
+- if ((rc = ap->ops->qc_defer(qc)))
+- goto defer;
+- }
+-
+- /* select device, send command to hardware */
+- ata_qc_issue(qc);
+-
+- return 0;
++ goto done;
+
+-early_finish:
+- ata_qc_free(qc);
+- scsi_done(cmd);
+- return 0;
++ return ata_scsi_qc_issue(ap, qc);
+
+-err_did:
++done:
+ ata_qc_free(qc);
+- cmd->result = (DID_ERROR << 16);
+ scsi_done(cmd);
+-err_mem:
+ return 0;
+-
+-defer:
+- ata_qc_free(qc);
+- if (rc == ATA_DEFER_LINK)
+- return SCSI_MLQUEUE_DEVICE_BUSY;
+- else
+- return SCSI_MLQUEUE_HOST_BUSY;
+ }
+
+ struct ata_scsi_args {
--- /dev/null
+From ff4a46c278ac6a4b3f39be1492a4568b6dcc6105 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linusw@kernel.org>
+Date: Tue, 3 Feb 2026 11:23:01 +0100
+Subject: ata: pata_ftide010: Fix some DMA timings
+
+From: Linus Walleij <linusw@kernel.org>
+
+commit ff4a46c278ac6a4b3f39be1492a4568b6dcc6105 upstream.
+
+The FTIDE010 has been missing some timing settings since its
+inception, since the upstream OpenWrt patch was missing these.
+
+The community has since come up with the appropriate timings.
+
+Fixes: be4e456ed3a5 ("ata: Add driver for Faraday Technology FTIDE010")
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Walleij <linusw@kernel.org>
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/pata_ftide010.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/ata/pata_ftide010.c
++++ b/drivers/ata/pata_ftide010.c
+@@ -122,10 +122,10 @@ static const u8 mwdma_50_active_time[3]
+ static const u8 mwdma_50_recovery_time[3] = {6, 2, 1};
+ static const u8 mwdma_66_active_time[3] = {8, 3, 3};
+ static const u8 mwdma_66_recovery_time[3] = {8, 2, 1};
+-static const u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 1};
++static const u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 9};
+ static const u8 udma_50_hold_time[6] = {3, 1, 1, 1, 1, 1};
+-static const u8 udma_66_setup_time[7] = {4, 4, 3, 2, };
+-static const u8 udma_66_hold_time[7] = {};
++static const u8 udma_66_setup_time[7] = {4, 4, 3, 2, 1, 9, 9};
++static const u8 udma_66_hold_time[7] = {4, 2, 1, 1, 1, 1, 1};
+
+ /*
+ * We set 66 MHz for all MWDMA modes
--- /dev/null
+From 8b4b19a2f96348d70bfa306ef7d4a13b0bcbea79 Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Sat, 29 Nov 2025 18:32:37 +0800
+Subject: ext4: don't cache extent during splitting extent
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 8b4b19a2f96348d70bfa306ef7d4a13b0bcbea79 upstream.
+
+Caching extents during the splitting process is risky, as it may result
+in stale extents remaining in the status tree. Moreover, in most cases,
+the corresponding extent block entries are likely already cached before
+the split happens, making caching here not particularly useful.
+
+Assume we have an unwritten extent, and then DIO writes the first half.
+
+ [UUUUUUUUUUUUUUUU] on-disk extent U: unwritten extent
+ [UUUUUUUUUUUUUUUU] extent status tree
+ |<- ->| ----> dio write this range
+
+First, when ext4_split_extent_at() splits this extent, it truncates the
+existing extent and then inserts a new one. During this process, this
+extent status entry may be shrunk, and calls to ext4_find_extent() and
+ext4_cache_extents() may occur, which could potentially insert the
+truncated range as a hole into the extent status tree. After the split
+is completed, this hole is not replaced with the correct status.
+
+ [UUUUUUU|UUUUUUUU] on-disk extent U: unwritten extent
+ [UUUUUUU|HHHHHHHH] extent status tree H: hole
+
+Then, the outer calling functions will not correct this remaining hole
+extent either. Finally, if we perform a delayed buffer write on this
+latter part, it will re-insert the delayed extent and cause an error in
+space accounting.
+
+In adition, if the unwritten extent cache is not shrunk during the
+splitting, ext4_cache_extents() also conflicts with existing extents
+when caching extents. In the future, we will add checks when caching
+extents, which will trigger a warning. Therefore, Do not cache extents
+that are being split.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Cc: stable@kernel.org
+Message-ID: <20251129103247.686136-6-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3172,6 +3172,9 @@ static int ext4_split_extent_at(handle_t
+ BUG_ON((split_flag & (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)) ==
+ (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2));
+
++ /* Do not cache extents that are in the process of being modified. */
++ flags |= EXT4_EX_NOCACHE;
++
+ ext_debug(inode, "logical block %llu\n", (unsigned long long)split);
+
+ ext4_ext_show_leaf(inode, path);
+@@ -3342,6 +3345,9 @@ static int ext4_split_extent(handle_t *h
+ ee_len = ext4_ext_get_actual_len(ex);
+ unwritten = ext4_ext_is_unwritten(ex);
+
++ /* Do not cache extents that are in the process of being modified. */
++ flags |= EXT4_EX_NOCACHE;
++
+ if (map->m_lblk + map->m_len < ee_block + ee_len) {
+ split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT;
+ flags1 = flags | EXT4_GET_BLOCKS_PRE_IO;
--- /dev/null
+From ca81109d4a8f192dc1cbad4a1ee25246363c2833 Mon Sep 17 00:00:00 2001
+From: Zilin Guan <zilin@seu.edu.cn>
+Date: Thu, 25 Dec 2025 08:48:00 +0000
+Subject: ext4: fix memory leak in ext4_ext_shift_extents()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+commit ca81109d4a8f192dc1cbad4a1ee25246363c2833 upstream.
+
+In ext4_ext_shift_extents(), if the extent is NULL in the while loop, the
+function returns immediately without releasing the path obtained via
+ext4_find_extent(), leading to a memory leak.
+
+Fix this by jumping to the out label to ensure the path is properly
+released.
+
+Fixes: a18ed359bdddc ("ext4: always check ext4_ext_find_extent result")
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Link: https://patch.msgid.link/20251225084800.905701-1-zilin@seu.edu.cn
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5258,7 +5258,8 @@ again:
+ if (!extent) {
+ EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
+ (unsigned long) *iterator);
+- return -EFSCORRUPTED;
++ ret = -EFSCORRUPTED;
++ goto out;
+ }
+ if (SHIFT == SHIFT_LEFT && *iterator >
+ le32_to_cpu(extent->ee_block)) {
--- /dev/null
+From 3574c322b1d0eb32dbd76b469cb08f9a67641599 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 14 Jan 2026 19:28:19 +0100
+Subject: ext4: use optimized mballoc scanning regardless of inode format
+
+From: Jan Kara <jack@suse.cz>
+
+commit 3574c322b1d0eb32dbd76b469cb08f9a67641599 upstream.
+
+Currently we don't used mballoc optimized scanning (using max free
+extent order and avg free extent order group lists) for inodes with
+indirect block based format. This is confusing for users and I don't see
+a good reason for that. Even with indirect block based inode format we
+can spend big amount of time searching for free blocks for large
+filesystems with fragmented free space. To add to the confusion before
+commit 077d0c2c78df ("ext4: make mb_optimize_scan performance mount
+option work with extents") optimized scanning was applied *only* to
+indirect block based inodes so that commit appears as a performance
+regression to some users. Just use optimized scanning whenever it is
+enabled by mount options.
+
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Cc: stable@kernel.org
+Link: https://patch.msgid.link/20260114182836.14120-4-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -1090,8 +1090,6 @@ static inline int should_optimize_scan(s
+ return 0;
+ if (ac->ac_criteria >= CR_GOAL_LEN_SLOW)
+ return 0;
+- if (!ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS))
+- return 0;
+ return 1;
+ }
+
--- /dev/null
+From 30bfc2d6a1132a89a5f1c3b96c59cf3e4d076ea3 Mon Sep 17 00:00:00 2001
+From: Yao Zi <me@ziyao.cc>
+Date: Thu, 5 Feb 2026 15:56:44 +0000
+Subject: MIPS: Work around LLVM bug when gp is used as global register variable
+
+From: Yao Zi <me@ziyao.cc>
+
+commit 30bfc2d6a1132a89a5f1c3b96c59cf3e4d076ea3 upstream.
+
+On MIPS, __current_thread_info is defined as global register variable
+locating in $gp, and is simply assigned with new address during kernel
+relocation.
+
+This however is broken with LLVM, which always restores $gp if it finds
+$gp is clobbered in any form, including when intentionally through a
+global register variable. This is against GCC's documentation[1], which
+requires a callee-saved register used as global register variable not to
+be restored if it's clobbered.
+
+As a result, $gp will continue to point to the unrelocated kernel after
+the epilog of relocate_kernel(), leading to an early crash in init_idle,
+
+[ 0.000000] CPU 0 Unable to handle kernel paging request at virtual address 0000000000000000, epc == ffffffff81afada8, ra == ffffffff81afad90
+[ 0.000000] Oops[#1]:
+[ 0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Tainted: G W 6.19.0-rc5-00262-gd3eeb99bbc99-dirty #188 VOLUNTARY
+[ 0.000000] Tainted: [W]=WARN
+[ 0.000000] Hardware name: loongson,loongson64v-4core-virtio
+[ 0.000000] $ 0 : 0000000000000000 0000000000000000 0000000000000001 0000000000000000
+[ 0.000000] $ 4 : ffffffff80b80ec0 ffffffff80b53d48 0000000000000000 00000000000f4240
+[ 0.000000] $ 8 : 0000000000000100 ffffffff81d82f80 ffffffff81d82f80 0000000000000001
+[ 0.000000] $12 : 0000000000000000 ffffffff81776f58 00000000000005da 0000000000000002
+[ 0.000000] $16 : ffffffff80b80e40 0000000000000000 ffffffff80b81614 9800000005dfbe80
+[ 0.000000] $20 : 00000000540000e0 ffffffff81980000 0000000000000000 ffffffff80f81c80
+[ 0.000000] $24 : 0000000000000a26 ffffffff8114fb90
+[ 0.000000] $28 : ffffffff80b50000 ffffffff80b53d40 0000000000000000 ffffffff81afad90
+[ 0.000000] Hi : 0000000000000000
+[ 0.000000] Lo : 0000000000000000
+[ 0.000000] epc : ffffffff81afada8 init_idle+0x130/0x270
+[ 0.000000] ra : ffffffff81afad90 init_idle+0x118/0x270
+[ 0.000000] Status: 540000e2 KX SX UX KERNEL EXL
+[ 0.000000] Cause : 00000008 (ExcCode 02)
+[ 0.000000] BadVA : 0000000000000000
+[ 0.000000] PrId : 00006305 (ICT Loongson-3)
+[ 0.000000] Process swapper (pid: 0, threadinfo=(____ptrval____), task=(____ptrval____), tls=0000000000000000)
+[ 0.000000] Stack : 9800000005dfbf00 ffffffff8178e950 0000000000000000 0000000000000000
+[ 0.000000] 0000000000000000 ffffffff81970000 000000000000003f ffffffff810a6528
+[ 0.000000] 0000000000000001 9800000005dfbe80 9800000005dfbf00 ffffffff81980000
+[ 0.000000] ffffffff810a6450 ffffffff81afb6c0 0000000000000000 ffffffff810a2258
+[ 0.000000] ffffffff81d82ec8 ffffffff8198d010 ffffffff81b67e80 ffffffff8197dd98
+[ 0.000000] ffffffff81d81c80 ffffffff81930000 0000000000000040 0000000000000000
+[ 0.000000] 0000000000000000 0000000000000000 0000000000000000 0000000000000000
+[ 0.000000] 0000000000000000 000000000000009e ffffffff9fc01000 0000000000000000
+[ 0.000000] 0000000000000000 0000000000000000 0000000000000000 0000000000000000
+[ 0.000000] 0000000000000000 ffffffff81ae86dc ffffffff81b3c741 0000000000000002
+[ 0.000000] ...
+[ 0.000000] Call Trace:
+[ 0.000000] [<ffffffff81afada8>] init_idle+0x130/0x270
+[ 0.000000] [<ffffffff81afb6c0>] sched_init+0x5c8/0x6c0
+[ 0.000000] [<ffffffff81ae86dc>] start_kernel+0x27c/0x7a8
+
+This bug has been reported to LLVM[2] and affects version from (at
+least) 18 to 21. Let's work around this by using inline assembly to
+assign $gp before a fix is widely available.
+
+Cc: stable@vger.kernel.org
+Link: https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Global-Register-Variables.html # [1]
+Link: https://github.com/llvm/llvm-project/issues/176546 # [2]
+Signed-off-by: Yao Zi <me@ziyao.cc>
+Acked-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/kernel/relocate.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/mips/kernel/relocate.c
++++ b/arch/mips/kernel/relocate.c
+@@ -420,7 +420,20 @@ void *__init relocate_kernel(void)
+ goto out;
+
+ /* The current thread is now within the relocated image */
++#ifndef CONFIG_CC_IS_CLANG
+ __current_thread_info = RELOCATED(&init_thread_union);
++#else
++ /*
++ * LLVM may wrongly restore $gp ($28) in epilog even if it's
++ * intentionally modified. Work around this by using inline
++ * assembly to assign $gp. $gp couldn't be listed as output or
++ * clobber, or LLVM will still restore its original value.
++ * See also LLVM upstream issue
++ * https://github.com/llvm/llvm-project/issues/176546
++ */
++ asm volatile("move $28, %0" : :
++ "r" (RELOCATED(&init_thread_union)));
++#endif
+
+ /* Return the new kernel's entry point */
+ kernel_entry = RELOCATED(start_kernel);
x86-hyperv-fix-error-pointer-dereference.patch
asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch
drm-amd-display-use-same-max-plane-scaling-limits-fo.patch
+mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch
+ext4-don-t-cache-extent-during-splitting-extent.patch
+ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch
+ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch
+ata-pata_ftide010-fix-some-dma-timings.patch
+ata-libata-scsi-refactor-ata_scsi_translate.patch
+ata-libata-scsi-avoid-non-ncq-command-starvation.patch
+sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch
+sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch
+asoc-dt-bindings-asahi-kasei-ak4458-set-unevaluatedproperties-false.patch
+asoc-dt-bindings-asahi-kasei-ak4458-fix-the-supply-names.patch
+asoc-dt-bindings-asahi-kasei-ak5558-fix-the-supply-names.patch
--- /dev/null
+From 3e6397b056335cc56ef0e9da36c95946a19f5118 Mon Sep 17 00:00:00 2001
+From: Chuck Lever <chuck.lever@oracle.com>
+Date: Fri, 26 Dec 2025 10:15:32 -0500
+Subject: SUNRPC: auth_gss: fix memory leaks in XDR decoding error paths
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+commit 3e6397b056335cc56ef0e9da36c95946a19f5118 upstream.
+
+The gssx_dec_ctx(), gssx_dec_status(), and gssx_dec_name()
+functions allocate memory via gssx_dec_buffer(), which calls
+kmemdup(). When a subsequent decode operation fails, these
+functions return immediately without freeing previously
+allocated buffers, causing memory leaks.
+
+The leak in gssx_dec_ctx() is particularly relevant because
+the caller (gssp_accept_sec_context_upcall) initializes several
+buffer length fields to non-zero values, resulting in memory
+allocation:
+
+ struct gssx_ctx rctxh = {
+ .exported_context_token.len = GSSX_max_output_handle_sz,
+ .mech.len = GSS_OID_MAX_LEN,
+ .src_name.display_name.len = GSSX_max_princ_sz,
+ .targ_name.display_name.len = GSSX_max_princ_sz
+ };
+
+If, for example, gssx_dec_name() succeeds for src_name but
+fails for targ_name, the memory allocated for
+exported_context_token, mech, and src_name.display_name
+remains unreferenced and cannot be reclaimed.
+
+Add error handling with goto-based cleanup to free any
+previously allocated buffers before returning an error.
+
+Reported-by: Xingjing Deng <micro6947@gmail.com>
+Closes: https://lore.kernel.org/linux-nfs/CAK+ZN9qttsFDu6h1FoqGadXjMx1QXqPMoYQ=6O9RY4SxVTvKng@mail.gmail.com/
+Fixes: 1d658336b05f ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth")
+Cc: stable@vger.kernel.org
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sunrpc/auth_gss/gss_rpc_xdr.c | 82 +++++++++++++++++++++++++++++---------
+ 1 file changed, 64 insertions(+), 18 deletions(-)
+
+--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
++++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
+@@ -320,29 +320,47 @@ static int gssx_dec_status(struct xdr_st
+
+ /* status->minor_status */
+ p = xdr_inline_decode(xdr, 8);
+- if (unlikely(p == NULL))
+- return -ENOSPC;
++ if (unlikely(p == NULL)) {
++ err = -ENOSPC;
++ goto out_free_mech;
++ }
+ p = xdr_decode_hyper(p, &status->minor_status);
+
+ /* status->major_status_string */
+ err = gssx_dec_buffer(xdr, &status->major_status_string);
+ if (err)
+- return err;
++ goto out_free_mech;
+
+ /* status->minor_status_string */
+ err = gssx_dec_buffer(xdr, &status->minor_status_string);
+ if (err)
+- return err;
++ goto out_free_major_status_string;
+
+ /* status->server_ctx */
+ err = gssx_dec_buffer(xdr, &status->server_ctx);
+ if (err)
+- return err;
++ goto out_free_minor_status_string;
+
+ /* we assume we have no options for now, so simply consume them */
+ /* status->options */
+ err = dummy_dec_opt_array(xdr, &status->options);
++ if (err)
++ goto out_free_server_ctx;
+
++ return 0;
++
++out_free_server_ctx:
++ kfree(status->server_ctx.data);
++ status->server_ctx.data = NULL;
++out_free_minor_status_string:
++ kfree(status->minor_status_string.data);
++ status->minor_status_string.data = NULL;
++out_free_major_status_string:
++ kfree(status->major_status_string.data);
++ status->major_status_string.data = NULL;
++out_free_mech:
++ kfree(status->mech.data);
++ status->mech.data = NULL;
+ return err;
+ }
+
+@@ -505,28 +523,35 @@ static int gssx_dec_name(struct xdr_stre
+ /* name->name_type */
+ err = gssx_dec_buffer(xdr, &dummy_netobj);
+ if (err)
+- return err;
++ goto out_free_display_name;
+
+ /* name->exported_name */
+ err = gssx_dec_buffer(xdr, &dummy_netobj);
+ if (err)
+- return err;
++ goto out_free_display_name;
+
+ /* name->exported_composite_name */
+ err = gssx_dec_buffer(xdr, &dummy_netobj);
+ if (err)
+- return err;
++ goto out_free_display_name;
+
+ /* we assume we have no attributes for now, so simply consume them */
+ /* name->name_attributes */
+ err = dummy_dec_nameattr_array(xdr, &dummy_name_attr_array);
+ if (err)
+- return err;
++ goto out_free_display_name;
+
+ /* we assume we have no options for now, so simply consume them */
+ /* name->extensions */
+ err = dummy_dec_opt_array(xdr, &dummy_option_array);
++ if (err)
++ goto out_free_display_name;
+
++ return 0;
++
++out_free_display_name:
++ kfree(name->display_name.data);
++ name->display_name.data = NULL;
+ return err;
+ }
+
+@@ -649,32 +674,34 @@ static int gssx_dec_ctx(struct xdr_strea
+ /* ctx->state */
+ err = gssx_dec_buffer(xdr, &ctx->state);
+ if (err)
+- return err;
++ goto out_free_exported_context_token;
+
+ /* ctx->need_release */
+ err = gssx_dec_bool(xdr, &ctx->need_release);
+ if (err)
+- return err;
++ goto out_free_state;
+
+ /* ctx->mech */
+ err = gssx_dec_buffer(xdr, &ctx->mech);
+ if (err)
+- return err;
++ goto out_free_state;
+
+ /* ctx->src_name */
+ err = gssx_dec_name(xdr, &ctx->src_name);
+ if (err)
+- return err;
++ goto out_free_mech;
+
+ /* ctx->targ_name */
+ err = gssx_dec_name(xdr, &ctx->targ_name);
+ if (err)
+- return err;
++ goto out_free_src_name;
+
+ /* ctx->lifetime */
+ p = xdr_inline_decode(xdr, 8+8);
+- if (unlikely(p == NULL))
+- return -ENOSPC;
++ if (unlikely(p == NULL)) {
++ err = -ENOSPC;
++ goto out_free_targ_name;
++ }
+ p = xdr_decode_hyper(p, &ctx->lifetime);
+
+ /* ctx->ctx_flags */
+@@ -683,17 +710,36 @@ static int gssx_dec_ctx(struct xdr_strea
+ /* ctx->locally_initiated */
+ err = gssx_dec_bool(xdr, &ctx->locally_initiated);
+ if (err)
+- return err;
++ goto out_free_targ_name;
+
+ /* ctx->open */
+ err = gssx_dec_bool(xdr, &ctx->open);
+ if (err)
+- return err;
++ goto out_free_targ_name;
+
+ /* we assume we have no options for now, so simply consume them */
+ /* ctx->options */
+ err = dummy_dec_opt_array(xdr, &ctx->options);
++ if (err)
++ goto out_free_targ_name;
++
++ return 0;
+
++out_free_targ_name:
++ kfree(ctx->targ_name.display_name.data);
++ ctx->targ_name.display_name.data = NULL;
++out_free_src_name:
++ kfree(ctx->src_name.display_name.data);
++ ctx->src_name.display_name.data = NULL;
++out_free_mech:
++ kfree(ctx->mech.data);
++ ctx->mech.data = NULL;
++out_free_state:
++ kfree(ctx->state.data);
++ ctx->state.data = NULL;
++out_free_exported_context_token:
++ kfree(ctx->exported_context_token.data);
++ ctx->exported_context_token.data = NULL;
+ return err;
+ }
+
--- /dev/null
+From dd2fdc3504592d85e549c523b054898a036a6afe Mon Sep 17 00:00:00 2001
+From: Daniel Hodges <git@danielhodges.dev>
+Date: Fri, 6 Feb 2026 15:41:46 -0500
+Subject: SUNRPC: fix gss_auth kref leak in gss_alloc_msg error path
+
+From: Daniel Hodges <git@danielhodges.dev>
+
+commit dd2fdc3504592d85e549c523b054898a036a6afe upstream.
+
+Commit 5940d1cf9f42 ("SUNRPC: Rebalance a kref in auth_gss.c") added
+a kref_get(&gss_auth->kref) call to balance the gss_put_auth() done
+in gss_release_msg(), but forgot to add a corresponding kref_put()
+on the error path when kstrdup_const() fails.
+
+If service_name is non-NULL and kstrdup_const() fails, the function
+jumps to err_put_pipe_version which calls put_pipe_version() and
+kfree(gss_msg), but never releases the gss_auth reference. This leads
+to a kref leak where the gss_auth structure is never freed.
+
+Add a forward declaration for gss_free_callback() and call kref_put()
+in the err_put_pipe_version error path to properly release the
+reference taken earlier.
+
+Fixes: 5940d1cf9f42 ("SUNRPC: Rebalance a kref in auth_gss.c")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Hodges <git@danielhodges.dev>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sunrpc/auth_gss/auth_gss.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -39,6 +39,8 @@ static const struct rpc_authops authgss_
+ static const struct rpc_credops gss_credops;
+ static const struct rpc_credops gss_nullops;
+
++static void gss_free_callback(struct kref *kref);
++
+ #define GSS_RETRY_EXPIRED 5
+ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
+
+@@ -551,6 +553,7 @@ gss_alloc_msg(struct gss_auth *gss_auth,
+ }
+ return gss_msg;
+ err_put_pipe_version:
++ kref_put(&gss_auth->kref, gss_free_callback);
+ put_pipe_version(gss_auth->net);
+ err_free_msg:
+ kfree(gss_msg);