OSDN Git Service

usb: gadget: ffs: ffs_aio_cancel(): Save/restore IRQ flags
authorLars-Peter Clausen <lars@metafoo.de>
Thu, 16 Jan 2020 13:29:01 +0000 (15:29 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 11 Mar 2020 13:14:49 +0000 (14:14 +0100)
[ Upstream commit 43d565727a3a6fd24e37c7c2116475106af71806 ]

ffs_aio_cancel() can be called from both interrupt and thread context. Make
sure that the current IRQ state is saved and restored by using
spin_{un,}lock_irq{save,restore}().

Otherwise undefined behavior might occur.

Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/usb/gadget/function/f_fs.c

index 2050993..a923945 100644 (file)
@@ -1077,18 +1077,19 @@ static int ffs_aio_cancel(struct kiocb *kiocb)
 {
        struct ffs_io_data *io_data = kiocb->private;
        struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
+       unsigned long flags;
        int value;
 
        ENTER();
 
-       spin_lock_irq(&epfile->ffs->eps_lock);
+       spin_lock_irqsave(&epfile->ffs->eps_lock, flags);
 
        if (likely(io_data && io_data->ep && io_data->req))
                value = usb_ep_dequeue(io_data->ep, io_data->req);
        else
                value = -EINVAL;
 
-       spin_unlock_irq(&epfile->ffs->eps_lock);
+       spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);
 
        return value;
 }