Patch "firmware: arm_scmi: Fix chan_free cleanup on SMC" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    firmware: arm_scmi: Fix chan_free cleanup on SMC

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     firmware-arm_scmi-fix-chan_free-cleanup-on-smc.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit f1b056a8d31eb954469e2cd4c66a7f428a0f6c17
Author: Cristian Marussi <cristian.marussi@xxxxxxx>
Date:   Wed Jul 19 18:35:33 2023 +0100

    firmware: arm_scmi: Fix chan_free cleanup on SMC
    
    [ Upstream commit d1ff11d7ad8704f8d615f6446041c221b2d2ec4d ]
    
    SCMI transport based on SMC can optionally use an additional IRQ to
    signal message completion. The associated interrupt handler is currently
    allocated using devres but on shutdown the core SCMI stack will call
    .chan_free() well before any managed cleanup is invoked by devres.
    As a consequence, the arrival of a late reply to an in-flight pending
    transaction could still trigger the interrupt handler well after the
    SCMI core has cleaned up the channels, with unpleasant results.
    
    Inhibit further message processing on the IRQ path by explicitly freeing
    the IRQ inside .chan_free() callback itself.
    
    Fixes: dd820ee21d5e ("firmware: arm_scmi: Augment SMC/HVC to allow optional interrupt")
    Reported-by: Bjorn Andersson <andersson@xxxxxxxxxx>
    Signed-off-by: Cristian Marussi <cristian.marussi@xxxxxxx>
    Link: https://lore.kernel.org/r/20230719173533.2739319-1-cristian.marussi@xxxxxxx
    Signed-off-by: Sudeep Holla <sudeep.holla@xxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index 4effecc3bb463..f529004f1922e 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -21,6 +21,7 @@
 /**
  * struct scmi_smc - Structure representing a SCMI smc transport
  *
+ * @irq: An optional IRQ for completion
  * @cinfo: SCMI channel info
  * @shmem: Transmit/Receive shared memory area
  * @shmem_lock: Lock to protect access to Tx/Rx shared memory area
@@ -30,6 +31,7 @@
  */
 
 struct scmi_smc {
+	int irq;
 	struct scmi_chan_info *cinfo;
 	struct scmi_shared_mem __iomem *shmem;
 	struct mutex shmem_lock;
@@ -66,7 +68,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 	struct resource res;
 	struct device_node *np;
 	u32 func_id;
-	int ret, irq;
+	int ret;
 
 	if (!tx)
 		return -ENODEV;
@@ -102,11 +104,10 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 	 * completion of a message is signaled by an interrupt rather than by
 	 * the return of the SMC call.
 	 */
-	irq = of_irq_get_byname(cdev->of_node, "a2p");
-	if (irq > 0) {
-		ret = devm_request_irq(dev, irq, smc_msg_done_isr,
-				       IRQF_NO_SUSPEND,
-				       dev_name(dev), scmi_info);
+	scmi_info->irq = of_irq_get_byname(cdev->of_node, "a2p");
+	if (scmi_info->irq > 0) {
+		ret = request_irq(scmi_info->irq, smc_msg_done_isr,
+				  IRQF_NO_SUSPEND, dev_name(dev), scmi_info);
 		if (ret) {
 			dev_err(dev, "failed to setup SCMI smc irq\n");
 			return ret;
@@ -128,6 +129,10 @@ static int smc_chan_free(int id, void *p, void *data)
 	struct scmi_chan_info *cinfo = p;
 	struct scmi_smc *scmi_info = cinfo->transport_info;
 
+	/* Ignore any possible further reception on the IRQ path */
+	if (scmi_info->irq > 0)
+		free_irq(scmi_info->irq, scmi_info);
+
 	cinfo->transport_info = NULL;
 	scmi_info->cinfo = NULL;
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux