| .. | .. |
|---|
| 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 | } |
|---|