Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: gadget: dummy_hcd: execute hrtimer callback in softirq context

Commit a7f3813e589f ("usb: gadget: dummy_hcd: Switch to hrtimer transfer
scheduler") switched dummy_hcd to use hrtimer and made the timer's
callback be executed in the hardirq context.

With that change, __usb_hcd_giveback_urb now gets executed in the hardirq
context, which causes problems for KCOV and KMSAN.

One problem is that KCOV now is unable to collect coverage from
the USB code that gets executed from the dummy_hcd's timer callback,
as KCOV cannot collect coverage in the hardirq context.

Another problem is that the dummy_hcd hrtimer might get triggered in the
middle of a softirq with KCOV remote coverage collection enabled, and that
causes a WARNING in KCOV, as reported by syzbot. (I sent a separate patch
to shut down this WARNING, but that doesn't fix the other two issues.)

Finally, KMSAN appears to ignore tracking memory copying operations
that happen in the hardirq context, which causes false positive
kernel-infoleaks, as reported by syzbot.

Change the hrtimer in dummy_hcd to execute the callback in the softirq
context.

Reported-by: syzbot+2388cdaeb6b10f0c13ac@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=2388cdaeb6b10f0c13ac
Reported-by: syzbot+17ca2339e34a1d863aad@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=17ca2339e34a1d863aad
Reported-by: syzbot+c793a7eca38803212c61@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c793a7eca38803212c61
Reported-by: syzbot+1e6e0b916b211bee1bd6@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1e6e0b916b211bee1bd6
Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202406141323.413a90d2-lkp@intel.com
Fixes: a7f3813e589f ("usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler")
Cc: stable@vger.kernel.org
Acked-by: Marcello Sylvester Bauer <sylv@sylv.io>
Signed-off-by: Andrey Konovalov <andreyknvl@gmail.com>
Reported-by: syzbot+edd9fe0d3a65b14588d5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=edd9fe0d3a65b14588d5
Link: https://lore.kernel.org/r/20240904013051.4409-1-andrey.konovalov@linux.dev
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Andrey Konovalov and committed by
Greg Kroah-Hartman
9313d139 d40ae4cd

+8 -6
+8 -6
drivers/usb/gadget/udc/dummy_hcd.c
··· 1304 1304 1305 1305 /* kick the scheduler, it'll do the rest */ 1306 1306 if (!hrtimer_active(&dum_hcd->timer)) 1307 - hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), HRTIMER_MODE_REL); 1307 + hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), 1308 + HRTIMER_MODE_REL_SOFT); 1308 1309 1309 1310 done: 1310 1311 spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); ··· 1326 1325 rc = usb_hcd_check_unlink_urb(hcd, urb, status); 1327 1326 if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING && 1328 1327 !list_empty(&dum_hcd->urbp_list)) 1329 - hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL); 1328 + hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); 1330 1329 1331 1330 spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); 1332 1331 return rc; ··· 1996 1995 dum_hcd->udev = NULL; 1997 1996 } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { 1998 1997 /* want a 1 msec delay here */ 1999 - hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), HRTIMER_MODE_REL); 1998 + hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), 1999 + HRTIMER_MODE_REL_SOFT); 2000 2000 } 2001 2001 2002 2002 spin_unlock_irqrestore(&dum->lock, flags); ··· 2391 2389 dum_hcd->rh_state = DUMMY_RH_RUNNING; 2392 2390 set_link_state(dum_hcd); 2393 2391 if (!list_empty(&dum_hcd->urbp_list)) 2394 - hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL); 2392 + hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); 2395 2393 hcd->state = HC_STATE_RUNNING; 2396 2394 } 2397 2395 spin_unlock_irq(&dum_hcd->dum->lock); ··· 2469 2467 2470 2468 static int dummy_start_ss(struct dummy_hcd *dum_hcd) 2471 2469 { 2472 - hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 2470 + hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); 2473 2471 dum_hcd->timer.function = dummy_timer; 2474 2472 dum_hcd->rh_state = DUMMY_RH_RUNNING; 2475 2473 dum_hcd->stream_en_ep = 0; ··· 2499 2497 return dummy_start_ss(dum_hcd); 2500 2498 2501 2499 spin_lock_init(&dum_hcd->dum->lock); 2502 - hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 2500 + hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); 2503 2501 dum_hcd->timer.function = dummy_timer; 2504 2502 dum_hcd->rh_state = DUMMY_RH_RUNNING; 2505 2503