Patch "vfio/pds: Fix possible sleep while in atomic context" has been added to the 6.6-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

    vfio/pds: Fix possible sleep while in atomic context

to the 6.6-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:
     vfio-pds-fix-possible-sleep-while-in-atomic-context.patch
and it can be found in the queue-6.6 subdirectory.

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



commit d223bcc6cae7ee99296be2d5e969b2d07e92f00c
Author: Brett Creeley <brett.creeley@xxxxxxx>
Date:   Wed Nov 22 11:25:32 2023 -0800

    vfio/pds: Fix possible sleep while in atomic context
    
    [ Upstream commit ae2667cd8a479bb5abd6e24c12fcc9ef5bc06d75 ]
    
    The driver could possibly sleep while in atomic context resulting
    in the following call trace while CONFIG_DEBUG_ATOMIC_SLEEP=y is
    set:
    
    BUG: sleeping function called from invalid context at kernel/locking/mutex.c:283
    in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2817, name: bash
    preempt_count: 1, expected: 0
    RCU nest depth: 0, expected: 0
    Call Trace:
     <TASK>
     dump_stack_lvl+0x36/0x50
     __might_resched+0x123/0x170
     mutex_lock+0x1e/0x50
     pds_vfio_put_lm_file+0x1e/0xa0 [pds_vfio_pci]
     pds_vfio_put_save_file+0x19/0x30 [pds_vfio_pci]
     pds_vfio_state_mutex_unlock+0x2e/0x80 [pds_vfio_pci]
     pci_reset_function+0x4b/0x70
     reset_store+0x5b/0xa0
     kernfs_fop_write_iter+0x137/0x1d0
     vfs_write+0x2de/0x410
     ksys_write+0x5d/0xd0
     do_syscall_64+0x3b/0x90
     entry_SYSCALL_64_after_hwframe+0x6e/0xd8
    
    This can happen if pds_vfio_put_restore_file() and/or
    pds_vfio_put_save_file() grab the mutex_lock(&lm_file->lock)
    while the spin_lock(&pds_vfio->reset_lock) is held, which can
    happen during while calling pds_vfio_state_mutex_unlock().
    
    Fix this by changing the reset_lock to reset_mutex so there are no such
    conerns. Also, make sure to destroy the reset_mutex in the driver specific
    VFIO device release function.
    
    This also fixes a spinlock bad magic BUG that was caused
    by not calling spinlock_init() on the reset_lock. Since, the lock is
    being changed to a mutex, make sure to call mutex_init() on it.
    
    Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>
    Closes: https://lore.kernel.org/kvm/1f9bc27b-3de9-4891-9687-ba2820c1b390@moroto.mountain/
    Fixes: bb500dbe2ac6 ("vfio/pds: Add VFIO live migration support")
    Signed-off-by: Brett Creeley <brett.creeley@xxxxxxx>
    Reviewed-by: Shannon Nelson <shannon.nelson@xxxxxxx>
    Link: https://lore.kernel.org/r/20231122192532.25791-3-brett.creeley@xxxxxxx
    Signed-off-by: Alex Williamson <alex.williamson@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/vfio/pci/pds/pci_drv.c b/drivers/vfio/pci/pds/pci_drv.c
index ab4b5958e4131..caffa1a2cf591 100644
--- a/drivers/vfio/pci/pds/pci_drv.c
+++ b/drivers/vfio/pci/pds/pci_drv.c
@@ -55,10 +55,10 @@ static void pds_vfio_recovery(struct pds_vfio_pci_device *pds_vfio)
 	 * VFIO_DEVICE_STATE_RUNNING.
 	 */
 	if (deferred_reset_needed) {
-		spin_lock(&pds_vfio->reset_lock);
+		mutex_lock(&pds_vfio->reset_mutex);
 		pds_vfio->deferred_reset = true;
 		pds_vfio->deferred_reset_state = VFIO_DEVICE_STATE_ERROR;
-		spin_unlock(&pds_vfio->reset_lock);
+		mutex_unlock(&pds_vfio->reset_mutex);
 	}
 }
 
diff --git a/drivers/vfio/pci/pds/vfio_dev.c b/drivers/vfio/pci/pds/vfio_dev.c
index 8c9fb87b13e1d..4c351c59d05a9 100644
--- a/drivers/vfio/pci/pds/vfio_dev.c
+++ b/drivers/vfio/pci/pds/vfio_dev.c
@@ -29,7 +29,7 @@ struct pds_vfio_pci_device *pds_vfio_pci_drvdata(struct pci_dev *pdev)
 void pds_vfio_state_mutex_unlock(struct pds_vfio_pci_device *pds_vfio)
 {
 again:
-	spin_lock(&pds_vfio->reset_lock);
+	mutex_lock(&pds_vfio->reset_mutex);
 	if (pds_vfio->deferred_reset) {
 		pds_vfio->deferred_reset = false;
 		if (pds_vfio->state == VFIO_DEVICE_STATE_ERROR) {
@@ -39,23 +39,23 @@ void pds_vfio_state_mutex_unlock(struct pds_vfio_pci_device *pds_vfio)
 		}
 		pds_vfio->state = pds_vfio->deferred_reset_state;
 		pds_vfio->deferred_reset_state = VFIO_DEVICE_STATE_RUNNING;
-		spin_unlock(&pds_vfio->reset_lock);
+		mutex_unlock(&pds_vfio->reset_mutex);
 		goto again;
 	}
 	mutex_unlock(&pds_vfio->state_mutex);
-	spin_unlock(&pds_vfio->reset_lock);
+	mutex_unlock(&pds_vfio->reset_mutex);
 }
 
 void pds_vfio_reset(struct pds_vfio_pci_device *pds_vfio)
 {
-	spin_lock(&pds_vfio->reset_lock);
+	mutex_lock(&pds_vfio->reset_mutex);
 	pds_vfio->deferred_reset = true;
 	pds_vfio->deferred_reset_state = VFIO_DEVICE_STATE_RUNNING;
 	if (!mutex_trylock(&pds_vfio->state_mutex)) {
-		spin_unlock(&pds_vfio->reset_lock);
+		mutex_unlock(&pds_vfio->reset_mutex);
 		return;
 	}
-	spin_unlock(&pds_vfio->reset_lock);
+	mutex_unlock(&pds_vfio->reset_mutex);
 	pds_vfio_state_mutex_unlock(pds_vfio);
 }
 
@@ -156,6 +156,7 @@ static int pds_vfio_init_device(struct vfio_device *vdev)
 	pds_vfio->vf_id = vf_id;
 
 	mutex_init(&pds_vfio->state_mutex);
+	mutex_init(&pds_vfio->reset_mutex);
 
 	vdev->migration_flags = VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_P2P;
 	vdev->mig_ops = &pds_vfio_lm_ops;
@@ -177,6 +178,7 @@ static void pds_vfio_release_device(struct vfio_device *vdev)
 			     vfio_coredev.vdev);
 
 	mutex_destroy(&pds_vfio->state_mutex);
+	mutex_destroy(&pds_vfio->reset_mutex);
 	vfio_pci_core_release_dev(vdev);
 }
 
diff --git a/drivers/vfio/pci/pds/vfio_dev.h b/drivers/vfio/pci/pds/vfio_dev.h
index b8f2d667608f3..e7b01080a1ec3 100644
--- a/drivers/vfio/pci/pds/vfio_dev.h
+++ b/drivers/vfio/pci/pds/vfio_dev.h
@@ -18,7 +18,7 @@ struct pds_vfio_pci_device {
 	struct pds_vfio_dirty dirty;
 	struct mutex state_mutex; /* protect migration state */
 	enum vfio_device_mig_state state;
-	spinlock_t reset_lock; /* protect reset_done flow */
+	struct mutex reset_mutex; /* protect reset_done flow */
 	u8 deferred_reset;
 	enum vfio_device_mig_state deferred_reset_state;
 	struct notifier_block nb;



[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