Skip to content

Commit d93d4ce

Browse files
committed
Merge tag 'sound-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "The amount of the changes isn't as quite small as wished, nevertheless they are straight fixes that deserve merging to 4.14 final. Most of fixes are about ALSA core bugs spotted by fuzzer: a follow-up fix for the previous nested rwsem patch, a fix to avoid the resource hogs due to too many concurrent ALSA timer invocations, and a fix for a crash with SYSEX MIDI transfer over OSS sequencer emulation that is used by none but fuzzer. The rest are usual HD-audio and USB-audio device-specific quirks, which are safe to apply" * tag 'sound-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - fix headset mic problem for Dell machines with alc274 ALSA: seq: Fix OSS sysex delivery in OSS emulation ALSA: seq: Avoid invalid lockdep class warning ALSA: timer: Limit max instances per timer ALSA: usb-audio: support new Amanero Combo384 firmware version
2 parents d1041cd + 75ee94b commit d93d4ce

File tree

9 files changed

+97
-17
lines changed

9 files changed

+97
-17
lines changed

include/sound/seq_kernel.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ typedef union snd_seq_timestamp snd_seq_timestamp_t;
4949
#define SNDRV_SEQ_DEFAULT_CLIENT_EVENTS 200
5050

5151
/* max delivery path length */
52-
#define SNDRV_SEQ_MAX_HOPS 10
52+
/* NOTE: this shouldn't be greater than MAX_LOCKDEP_SUBCLASSES */
53+
#define SNDRV_SEQ_MAX_HOPS 8
5354

5455
/* max size of event size */
5556
#define SNDRV_SEQ_MAX_EVENT_LEN 0x3fffffff

include/sound/timer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ struct snd_timer {
9090
struct list_head ack_list_head;
9191
struct list_head sack_list_head; /* slow ack list head */
9292
struct tasklet_struct task_queue;
93+
int max_instances; /* upper limit of timer instances */
94+
int num_instances; /* current number of timer instances */
9395
};
9496

9597
struct snd_timer_instance {

sound/core/hrtimer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ static int __init snd_hrtimer_init(void)
159159
timer->hw = hrtimer_hw;
160160
timer->hw.resolution = resolution;
161161
timer->hw.ticks = NANO_SEC / resolution;
162+
timer->max_instances = 100; /* lower the limit */
162163

163164
err = snd_timer_global_register(timer);
164165
if (err < 0) {

sound/core/seq/oss/seq_oss_midi.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,9 +612,7 @@ send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq
612612
if (!dp->timer->running)
613613
len = snd_seq_oss_timer_start(dp->timer);
614614
if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
615-
if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
616-
snd_seq_oss_readq_puts(dp->readq, mdev->seq_device,
617-
ev->data.ext.ptr, ev->data.ext.len);
615+
snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev);
618616
} else {
619617
len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);
620618
if (len > 0)

sound/core/seq/oss/seq_oss_readq.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,35 @@ snd_seq_oss_readq_puts(struct seq_oss_readq *q, int dev, unsigned char *data, in
117117
return 0;
118118
}
119119

120+
/*
121+
* put MIDI sysex bytes; the event buffer may be chained, thus it has
122+
* to be expanded via snd_seq_dump_var_event().
123+
*/
124+
struct readq_sysex_ctx {
125+
struct seq_oss_readq *readq;
126+
int dev;
127+
};
128+
129+
static int readq_dump_sysex(void *ptr, void *buf, int count)
130+
{
131+
struct readq_sysex_ctx *ctx = ptr;
132+
133+
return snd_seq_oss_readq_puts(ctx->readq, ctx->dev, buf, count);
134+
}
135+
136+
int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
137+
struct snd_seq_event *ev)
138+
{
139+
struct readq_sysex_ctx ctx = {
140+
.readq = q,
141+
.dev = dev
142+
};
143+
144+
if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
145+
return 0;
146+
return snd_seq_dump_var_event(ev, readq_dump_sysex, &ctx);
147+
}
148+
120149
/*
121150
* copy an event to input queue:
122151
* return zero if enqueued

sound/core/seq/oss/seq_oss_readq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ void snd_seq_oss_readq_delete(struct seq_oss_readq *q);
4444
void snd_seq_oss_readq_clear(struct seq_oss_readq *readq);
4545
unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait);
4646
int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len);
47+
int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
48+
struct snd_seq_event *ev);
4749
int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev);
4850
int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode);
4951
int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec);

sound/core/timer.c

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ static void snd_timer_request(struct snd_timer_id *tid)
180180
*
181181
* call this with register_mutex down.
182182
*/
183-
static void snd_timer_check_slave(struct snd_timer_instance *slave)
183+
static int snd_timer_check_slave(struct snd_timer_instance *slave)
184184
{
185185
struct snd_timer *timer;
186186
struct snd_timer_instance *master;
@@ -190,16 +190,21 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
190190
list_for_each_entry(master, &timer->open_list_head, open_list) {
191191
if (slave->slave_class == master->slave_class &&
192192
slave->slave_id == master->slave_id) {
193+
if (master->timer->num_instances >=
194+
master->timer->max_instances)
195+
return -EBUSY;
193196
list_move_tail(&slave->open_list,
194197
&master->slave_list_head);
198+
master->timer->num_instances++;
195199
spin_lock_irq(&slave_active_lock);
196200
slave->master = master;
197201
slave->timer = master->timer;
198202
spin_unlock_irq(&slave_active_lock);
199-
return;
203+
return 0;
200204
}
201205
}
202206
}
207+
return 0;
203208
}
204209

205210
/*
@@ -208,15 +213,19 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
208213
*
209214
* call this with register_mutex down.
210215
*/
211-
static void snd_timer_check_master(struct snd_timer_instance *master)
216+
static int snd_timer_check_master(struct snd_timer_instance *master)
212217
{
213218
struct snd_timer_instance *slave, *tmp;
214219

215220
/* check all pending slaves */
216221
list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) {
217222
if (slave->slave_class == master->slave_class &&
218223
slave->slave_id == master->slave_id) {
224+
if (master->timer->num_instances >=
225+
master->timer->max_instances)
226+
return -EBUSY;
219227
list_move_tail(&slave->open_list, &master->slave_list_head);
228+
master->timer->num_instances++;
220229
spin_lock_irq(&slave_active_lock);
221230
spin_lock(&master->timer->lock);
222231
slave->master = master;
@@ -228,8 +237,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
228237
spin_unlock_irq(&slave_active_lock);
229238
}
230239
}
240+
return 0;
231241
}
232242

243+
static int snd_timer_close_locked(struct snd_timer_instance *timeri);
244+
233245
/*
234246
* open a timer instance
235247
* when opening a master, the slave id must be here given.
@@ -240,6 +252,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
240252
{
241253
struct snd_timer *timer;
242254
struct snd_timer_instance *timeri = NULL;
255+
int err;
243256

244257
if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
245258
/* open a slave instance */
@@ -259,10 +272,14 @@ int snd_timer_open(struct snd_timer_instance **ti,
259272
timeri->slave_id = tid->device;
260273
timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
261274
list_add_tail(&timeri->open_list, &snd_timer_slave_list);
262-
snd_timer_check_slave(timeri);
275+
err = snd_timer_check_slave(timeri);
276+
if (err < 0) {
277+
snd_timer_close_locked(timeri);
278+
timeri = NULL;
279+
}
263280
mutex_unlock(&register_mutex);
264281
*ti = timeri;
265-
return 0;
282+
return err;
266283
}
267284

268285
/* open a master instance */
@@ -288,6 +305,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
288305
return -EBUSY;
289306
}
290307
}
308+
if (timer->num_instances >= timer->max_instances) {
309+
mutex_unlock(&register_mutex);
310+
return -EBUSY;
311+
}
291312
timeri = snd_timer_instance_new(owner, timer);
292313
if (!timeri) {
293314
mutex_unlock(&register_mutex);
@@ -314,32 +335,35 @@ int snd_timer_open(struct snd_timer_instance **ti,
314335
}
315336

316337
list_add_tail(&timeri->open_list, &timer->open_list_head);
317-
snd_timer_check_master(timeri);
338+
timer->num_instances++;
339+
err = snd_timer_check_master(timeri);
340+
if (err < 0) {
341+
snd_timer_close_locked(timeri);
342+
timeri = NULL;
343+
}
318344
mutex_unlock(&register_mutex);
319345
*ti = timeri;
320-
return 0;
346+
return err;
321347
}
322348
EXPORT_SYMBOL(snd_timer_open);
323349

324350
/*
325351
* close a timer instance
352+
* call this with register_mutex down.
326353
*/
327-
int snd_timer_close(struct snd_timer_instance *timeri)
354+
static int snd_timer_close_locked(struct snd_timer_instance *timeri)
328355
{
329356
struct snd_timer *timer = NULL;
330357
struct snd_timer_instance *slave, *tmp;
331358

332-
if (snd_BUG_ON(!timeri))
333-
return -ENXIO;
334-
335-
mutex_lock(&register_mutex);
336359
list_del(&timeri->open_list);
337360

338361
/* force to stop the timer */
339362
snd_timer_stop(timeri);
340363

341364
timer = timeri->timer;
342365
if (timer) {
366+
timer->num_instances--;
343367
/* wait, until the active callback is finished */
344368
spin_lock_irq(&timer->lock);
345369
while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
@@ -355,6 +379,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
355379
list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
356380
open_list) {
357381
list_move_tail(&slave->open_list, &snd_timer_slave_list);
382+
timer->num_instances--;
358383
slave->master = NULL;
359384
slave->timer = NULL;
360385
list_del_init(&slave->ack_list);
@@ -382,9 +407,24 @@ int snd_timer_close(struct snd_timer_instance *timeri)
382407
module_put(timer->module);
383408
}
384409

385-
mutex_unlock(&register_mutex);
386410
return 0;
387411
}
412+
413+
/*
414+
* close a timer instance
415+
*/
416+
int snd_timer_close(struct snd_timer_instance *timeri)
417+
{
418+
int err;
419+
420+
if (snd_BUG_ON(!timeri))
421+
return -ENXIO;
422+
423+
mutex_lock(&register_mutex);
424+
err = snd_timer_close_locked(timeri);
425+
mutex_unlock(&register_mutex);
426+
return err;
427+
}
388428
EXPORT_SYMBOL(snd_timer_close);
389429

390430
unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
@@ -856,6 +896,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
856896
spin_lock_init(&timer->lock);
857897
tasklet_init(&timer->task_queue, snd_timer_tasklet,
858898
(unsigned long)timer);
899+
timer->max_instances = 1000; /* default limit per timer */
859900
if (card != NULL) {
860901
timer->module = card->module;
861902
err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);

sound/pci/hda/patch_realtek.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6544,6 +6544,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
65446544
{0x14, 0x90170110},
65456545
{0x1b, 0x90a70130},
65466546
{0x21, 0x03211020}),
6547+
SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6548+
{0x12, 0xb7a60130},
6549+
{0x13, 0xb8a61140},
6550+
{0x16, 0x90170110},
6551+
{0x21, 0x04211020}),
65476552
SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
65486553
{0x12, 0x90a60130},
65496554
{0x14, 0x90170110},

sound/usb/quirks.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
13751375
case 0x199:
13761376
return SNDRV_PCM_FMTBIT_DSD_U32_LE;
13771377
case 0x19b:
1378+
case 0x203:
13781379
return SNDRV_PCM_FMTBIT_DSD_U32_BE;
13791380
default:
13801381
break;

0 commit comments

Comments
 (0)