.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * ALSA sequencer Memory Manager |
---|
3 | 4 | * Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl> |
---|
4 | 5 | * Jaroslav Kysela <perex@perex.cz> |
---|
5 | 6 | * 2000 by Takashi Iwai <tiwai@suse.de> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License as published by |
---|
9 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
10 | | - * (at your option) any later version. |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope that it will be useful, |
---|
13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 | | - * GNU General Public License for more details. |
---|
16 | | - * |
---|
17 | | - * You should have received a copy of the GNU General Public License |
---|
18 | | - * along with this program; if not, write to the Free Software |
---|
19 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
20 | | - * |
---|
21 | 7 | */ |
---|
22 | 8 | |
---|
23 | 9 | #include <linux/init.h> |
---|
24 | 10 | #include <linux/export.h> |
---|
25 | 11 | #include <linux/slab.h> |
---|
26 | 12 | #include <linux/sched/signal.h> |
---|
27 | | -#include <linux/vmalloc.h> |
---|
| 13 | +#include <linux/mm.h> |
---|
28 | 14 | #include <sound/core.h> |
---|
29 | 15 | |
---|
30 | 16 | #include <sound/seq_kernel.h> |
---|
.. | .. |
---|
126 | 112 | * expand the variable length event to linear buffer space. |
---|
127 | 113 | */ |
---|
128 | 114 | |
---|
129 | | -static int seq_copy_in_kernel(char **bufptr, const void *src, int size) |
---|
| 115 | +static int seq_copy_in_kernel(void *ptr, void *src, int size) |
---|
130 | 116 | { |
---|
| 117 | + char **bufptr = ptr; |
---|
| 118 | + |
---|
131 | 119 | memcpy(*bufptr, src, size); |
---|
132 | 120 | *bufptr += size; |
---|
133 | 121 | return 0; |
---|
134 | 122 | } |
---|
135 | 123 | |
---|
136 | | -static int seq_copy_in_user(char __user **bufptr, const void *src, int size) |
---|
| 124 | +static int seq_copy_in_user(void *ptr, void *src, int size) |
---|
137 | 125 | { |
---|
| 126 | + char __user **bufptr = ptr; |
---|
| 127 | + |
---|
138 | 128 | if (copy_to_user(*bufptr, src, size)) |
---|
139 | 129 | return -EFAULT; |
---|
140 | 130 | *bufptr += size; |
---|
.. | .. |
---|
163 | 153 | return newlen; |
---|
164 | 154 | } |
---|
165 | 155 | err = snd_seq_dump_var_event(event, |
---|
166 | | - in_kernel ? (snd_seq_dump_func_t)seq_copy_in_kernel : |
---|
167 | | - (snd_seq_dump_func_t)seq_copy_in_user, |
---|
| 156 | + in_kernel ? seq_copy_in_kernel : seq_copy_in_user, |
---|
168 | 157 | &buf); |
---|
169 | 158 | return err < 0 ? err : newlen; |
---|
170 | 159 | } |
---|
.. | .. |
---|
244 | 233 | |
---|
245 | 234 | set_current_state(TASK_INTERRUPTIBLE); |
---|
246 | 235 | add_wait_queue(&pool->output_sleep, &wait); |
---|
247 | | - spin_unlock_irq(&pool->lock); |
---|
| 236 | + spin_unlock_irqrestore(&pool->lock, flags); |
---|
248 | 237 | if (mutexp) |
---|
249 | 238 | mutex_unlock(mutexp); |
---|
250 | 239 | schedule(); |
---|
251 | 240 | if (mutexp) |
---|
252 | 241 | mutex_lock(mutexp); |
---|
253 | | - spin_lock_irq(&pool->lock); |
---|
| 242 | + spin_lock_irqsave(&pool->lock, flags); |
---|
254 | 243 | remove_wait_queue(&pool->output_sleep, &wait); |
---|
255 | 244 | /* interrupted? */ |
---|
256 | 245 | if (signal_pending(current)) { |
---|
.. | .. |
---|
384 | 373 | { |
---|
385 | 374 | int cell; |
---|
386 | 375 | struct snd_seq_event_cell *cellptr; |
---|
387 | | - unsigned long flags; |
---|
388 | 376 | |
---|
389 | 377 | if (snd_BUG_ON(!pool)) |
---|
390 | 378 | return -EINVAL; |
---|
391 | 379 | |
---|
392 | | - cellptr = vmalloc(array_size(sizeof(struct snd_seq_event_cell), |
---|
393 | | - pool->size)); |
---|
| 380 | + cellptr = kvmalloc_array(sizeof(struct snd_seq_event_cell), pool->size, |
---|
| 381 | + GFP_KERNEL); |
---|
394 | 382 | if (!cellptr) |
---|
395 | 383 | return -ENOMEM; |
---|
396 | 384 | |
---|
397 | 385 | /* add new cells to the free cell list */ |
---|
398 | | - spin_lock_irqsave(&pool->lock, flags); |
---|
| 386 | + spin_lock_irq(&pool->lock); |
---|
399 | 387 | if (pool->ptr) { |
---|
400 | | - spin_unlock_irqrestore(&pool->lock, flags); |
---|
401 | | - vfree(cellptr); |
---|
| 388 | + spin_unlock_irq(&pool->lock); |
---|
| 389 | + kvfree(cellptr); |
---|
402 | 390 | return 0; |
---|
403 | 391 | } |
---|
404 | 392 | |
---|
.. | .. |
---|
416 | 404 | /* init statistics */ |
---|
417 | 405 | pool->max_used = 0; |
---|
418 | 406 | pool->total_elements = pool->size; |
---|
419 | | - spin_unlock_irqrestore(&pool->lock, flags); |
---|
| 407 | + spin_unlock_irq(&pool->lock); |
---|
420 | 408 | return 0; |
---|
421 | 409 | } |
---|
422 | 410 | |
---|
.. | .. |
---|
435 | 423 | /* remove events */ |
---|
436 | 424 | int snd_seq_pool_done(struct snd_seq_pool *pool) |
---|
437 | 425 | { |
---|
438 | | - unsigned long flags; |
---|
439 | 426 | struct snd_seq_event_cell *ptr; |
---|
440 | 427 | |
---|
441 | 428 | if (snd_BUG_ON(!pool)) |
---|
.. | .. |
---|
449 | 436 | schedule_timeout_uninterruptible(1); |
---|
450 | 437 | |
---|
451 | 438 | /* release all resources */ |
---|
452 | | - spin_lock_irqsave(&pool->lock, flags); |
---|
| 439 | + spin_lock_irq(&pool->lock); |
---|
453 | 440 | ptr = pool->ptr; |
---|
454 | 441 | pool->ptr = NULL; |
---|
455 | 442 | pool->free = NULL; |
---|
456 | 443 | pool->total_elements = 0; |
---|
457 | | - spin_unlock_irqrestore(&pool->lock, flags); |
---|
| 444 | + spin_unlock_irq(&pool->lock); |
---|
458 | 445 | |
---|
459 | | - vfree(ptr); |
---|
| 446 | + kvfree(ptr); |
---|
460 | 447 | |
---|
461 | | - spin_lock_irqsave(&pool->lock, flags); |
---|
| 448 | + spin_lock_irq(&pool->lock); |
---|
462 | 449 | pool->closing = 0; |
---|
463 | | - spin_unlock_irqrestore(&pool->lock, flags); |
---|
| 450 | + spin_unlock_irq(&pool->lock); |
---|
464 | 451 | |
---|
465 | 452 | return 0; |
---|
466 | 453 | } |
---|