]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.45/alsa-line6-toneport-fix-broken-usage-of-timer-for-delayed-execution.patch
Linux 4.19.45
[thirdparty/kernel/stable-queue.git] / releases / 4.19.45 / alsa-line6-toneport-fix-broken-usage-of-timer-for-delayed-execution.patch
1 From 7f84ff68be05ec7a5d2acf8fdc734fe5897af48f Mon Sep 17 00:00:00 2001
2 From: Takashi Iwai <tiwai@suse.de>
3 Date: Wed, 8 May 2019 15:01:24 +0200
4 Subject: ALSA: line6: toneport: Fix broken usage of timer for delayed execution
5
6 From: Takashi Iwai <tiwai@suse.de>
7
8 commit 7f84ff68be05ec7a5d2acf8fdc734fe5897af48f upstream.
9
10 The line6 toneport driver has code for some delayed initialization,
11 and this hits the kernel Oops because mutex and other sleepable
12 functions are used in the timer callback. Fix the abuse by a delayed
13 work instead so that everything works gracefully.
14
15 Reported-by: syzbot+a07d0142e74fdd595cfb@syzkaller.appspotmail.com
16 Cc: <stable@vger.kernel.org>
17 Signed-off-by: Takashi Iwai <tiwai@suse.de>
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
19
20 ---
21 sound/usb/line6/toneport.c | 16 +++++++++-------
22 1 file changed, 9 insertions(+), 7 deletions(-)
23
24 --- a/sound/usb/line6/toneport.c
25 +++ b/sound/usb/line6/toneport.c
26 @@ -54,8 +54,8 @@ struct usb_line6_toneport {
27 /* Firmware version (x 100) */
28 u8 firmware_version;
29
30 - /* Timer for delayed PCM startup */
31 - struct timer_list timer;
32 + /* Work for delayed PCM startup */
33 + struct delayed_work pcm_work;
34
35 /* Device type */
36 enum line6_device_type type;
37 @@ -241,9 +241,10 @@ static int snd_toneport_source_put(struc
38 return 1;
39 }
40
41 -static void toneport_start_pcm(struct timer_list *t)
42 +static void toneport_start_pcm(struct work_struct *work)
43 {
44 - struct usb_line6_toneport *toneport = from_timer(toneport, t, timer);
45 + struct usb_line6_toneport *toneport =
46 + container_of(work, struct usb_line6_toneport, pcm_work.work);
47 struct usb_line6 *line6 = &toneport->line6;
48
49 line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR, true);
50 @@ -393,7 +394,8 @@ static int toneport_setup(struct usb_lin
51 if (toneport_has_led(toneport))
52 toneport_update_led(toneport);
53
54 - mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
55 + schedule_delayed_work(&toneport->pcm_work,
56 + msecs_to_jiffies(TONEPORT_PCM_DELAY * 1000));
57 return 0;
58 }
59
60 @@ -405,7 +407,7 @@ static void line6_toneport_disconnect(st
61 struct usb_line6_toneport *toneport =
62 (struct usb_line6_toneport *)line6;
63
64 - del_timer_sync(&toneport->timer);
65 + cancel_delayed_work_sync(&toneport->pcm_work);
66
67 if (toneport_has_led(toneport))
68 toneport_remove_leds(toneport);
69 @@ -422,7 +424,7 @@ static int toneport_init(struct usb_line
70 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6;
71
72 toneport->type = id->driver_info;
73 - timer_setup(&toneport->timer, toneport_start_pcm, 0);
74 + INIT_DELAYED_WORK(&toneport->pcm_work, toneport_start_pcm);
75
76 line6->disconnect = line6_toneport_disconnect;
77