[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250915012914.361334-1-lizhi.xu@windriver.com>
Date: Mon, 15 Sep 2025 09:29:13 +0800
From: Lizhi Xu <lizhi.xu@...driver.com>
To: <syzbot+205ef33a3b636b4181fb@...kaller.appspotmail.com>
CC: <gregkh@...uxfoundation.org>, <linux-kernel@...r.kernel.org>,
<linux-usb@...r.kernel.org>, <syzkaller-bugs@...glegroups.com>
Subject: [PATCH] usb: mon: Make mon_bus::lock a raw spinlock
Interrupts are disabled before entering usb_hcd_giveback_urb().
A spinlock_t becomes a sleeping lock on PREEMPT_RT, so it cannot be
acquired with disabled interrupts.
Make mon_bus::lock a raw spinlock so it can be used with interrupts disabled.
syz reported:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
CPU: 1 UID: 0 PID: 45 Comm: kworker/1:1 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
Workqueue: usb_hub_wq hub_event
Call Trace:
<TASK>
dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
__might_resched+0x44b/0x5d0 kernel/sched/core.c:8957
rt_spin_lock+0xc7/0x2c0 kernel/locking/spinlock_rt.c:57
spin_lock include/linux/spinlock_rt.h:44 [inline]
mon_bus_complete drivers/usb/mon/mon_main.c:134 [inline]
mon_complete+0x5c/0x200 drivers/usb/mon/mon_main.c:147
usbmon_urb_complete include/linux/usb/hcd.h:738 [inline]
__usb_hcd_giveback_urb+0x254/0x5e0 drivers/usb/core/hcd.c:1647
vhci_urb_enqueue+0xb4f/0xe70 drivers/usb/usbip/vhci_hcd.c:818
Reported-by: syzbot+205ef33a3b636b4181fb@...kaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=205ef33a3b636b4181fb
Signed-off-by: Lizhi Xu <lizhi.xu@...driver.com>
---
drivers/usb/mon/mon_main.c | 24 +++++++++---------------
drivers/usb/mon/mon_text.c | 6 +++---
drivers/usb/mon/usb_mon.h | 2 +-
3 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index af852d53aac6..83d19b769d84 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -38,7 +38,7 @@ void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r)
unsigned long flags;
struct list_head *p;
- spin_lock_irqsave(&mbus->lock, flags);
+ raw_spin_lock_irqsave(&mbus->lock, flags);
if (mbus->nreaders == 0) {
if (mbus == &mon_bus0) {
list_for_each (p, &mon_buses) {
@@ -52,7 +52,7 @@ void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r)
}
mbus->nreaders++;
list_add_tail(&r->r_link, &mbus->r_list);
- spin_unlock_irqrestore(&mbus->lock, flags);
+ raw_spin_unlock_irqrestore(&mbus->lock, flags);
kref_get(&mbus->ref);
}
@@ -66,12 +66,12 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r)
{
unsigned long flags;
- spin_lock_irqsave(&mbus->lock, flags);
+ raw_spin_lock_irqsave(&mbus->lock, flags);
list_del(&r->r_link);
--mbus->nreaders;
if (mbus->nreaders == 0)
mon_stop(mbus);
- spin_unlock_irqrestore(&mbus->lock, flags);
+ raw_spin_unlock_irqrestore(&mbus->lock, flags);
kref_put(&mbus->ref, mon_bus_drop);
}
@@ -80,14 +80,12 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r)
*/
static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb)
{
- unsigned long flags;
struct mon_reader *r;
- spin_lock_irqsave(&mbus->lock, flags);
+ guard(raw_spinlock_irqsave)(&mbus->lock);
mbus->cnt_events++;
list_for_each_entry(r, &mbus->r_list, r_link)
r->rnf_submit(r->r_data, urb);
- spin_unlock_irqrestore(&mbus->lock, flags);
}
static void mon_submit(struct usb_bus *ubus, struct urb *urb)
@@ -104,14 +102,12 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb)
*/
static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int error)
{
- unsigned long flags;
struct mon_reader *r;
- spin_lock_irqsave(&mbus->lock, flags);
+ guard(raw_spinlock_irqsave)(&mbus->lock);
mbus->cnt_events++;
list_for_each_entry(r, &mbus->r_list, r_link)
r->rnf_error(r->r_data, urb, error);
- spin_unlock_irqrestore(&mbus->lock, flags);
}
static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
@@ -128,14 +124,12 @@ static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
*/
static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb, int status)
{
- unsigned long flags;
struct mon_reader *r;
- spin_lock_irqsave(&mbus->lock, flags);
+ guard(raw_spinlock_irqsave)(&mbus->lock);
mbus->cnt_events++;
list_for_each_entry(r, &mbus->r_list, r_link)
r->rnf_complete(r->r_data, urb, status);
- spin_unlock_irqrestore(&mbus->lock, flags);
}
static void mon_complete(struct usb_bus *ubus, struct urb *urb, int status)
@@ -277,7 +271,7 @@ static void mon_bus_init(struct usb_bus *ubus)
if (mbus == NULL)
goto err_alloc;
kref_init(&mbus->ref);
- spin_lock_init(&mbus->lock);
+ raw_spin_lock_init(&mbus->lock);
INIT_LIST_HEAD(&mbus->r_list);
/*
@@ -304,7 +298,7 @@ static void mon_bus0_init(void)
struct mon_bus *mbus = &mon_bus0;
kref_init(&mbus->ref);
- spin_lock_init(&mbus->lock);
+ raw_spin_lock_init(&mbus->lock);
INIT_LIST_HEAD(&mbus->r_list);
mbus->text_inited = mon_text_add(mbus, NULL);
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 68b9b2b41189..b482c610dad1 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -307,15 +307,15 @@ static struct mon_event_text *mon_text_fetch(struct mon_reader_text *rp,
struct list_head *p;
unsigned long flags;
- spin_lock_irqsave(&mbus->lock, flags);
+ raw_spin_lock_irqsave(&mbus->lock, flags);
if (list_empty(&rp->e_list)) {
- spin_unlock_irqrestore(&mbus->lock, flags);
+ raw_spin_unlock_irqrestore(&mbus->lock, flags);
return NULL;
}
p = rp->e_list.next;
list_del(p);
--rp->nevents;
- spin_unlock_irqrestore(&mbus->lock, flags);
+ raw_spin_unlock_irqrestore(&mbus->lock, flags);
return list_entry(p, struct mon_event_text, e_link);
}
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
index aa64efaba366..d2a342feaad3 100644
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -17,7 +17,7 @@
struct mon_bus {
struct list_head bus_link;
- spinlock_t lock;
+ raw_spinlock_t lock;
struct usb_bus *u_bus;
int text_inited;
--
2.43.0
Powered by blists - more mailing lists