aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_native.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r--sound/core/pcm_native.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index d35c6614fdab..9ade0c8b54a3 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3376,10 +3376,29 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
3376 area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; 3376 area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
3377 return 0; 3377 return 0;
3378} 3378}
3379
3380static bool pcm_status_mmap_allowed(struct snd_pcm_file *pcm_file)
3381{
3382 if (pcm_file->no_compat_mmap)
3383 return false;
3384 /* Disallow the status/control mmap when SYNC_APPLPTR flag is set;
3385 * it enforces the user-space to fall back to snd_pcm_sync_ptr(),
3386 * thus it effectively assures the manual update of appl_ptr.
3387 * In theory, it should be enough to disallow only PCM control mmap,
3388 * but since the current alsa-lib implementation requires both status
3389 * and control mmaps always paired, we have to disable both of them.
3390 */
3391 if (pcm_file->substream->runtime->hw.info & SNDRV_PCM_INFO_SYNC_APPLPTR)
3392 return false;
3393 return true;
3394}
3395
3379#else /* ! coherent mmap */ 3396#else /* ! coherent mmap */
3380/* 3397/*
3381 * don't support mmap for status and control records. 3398 * don't support mmap for status and control records.
3382 */ 3399 */
3400#define pcm_status_mmap_allowed(pcm_file) false
3401
3383static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file, 3402static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
3384 struct vm_area_struct *area) 3403 struct vm_area_struct *area)
3385{ 3404{
@@ -3563,11 +3582,11 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
3563 offset = area->vm_pgoff << PAGE_SHIFT; 3582 offset = area->vm_pgoff << PAGE_SHIFT;
3564 switch (offset) { 3583 switch (offset) {
3565 case SNDRV_PCM_MMAP_OFFSET_STATUS: 3584 case SNDRV_PCM_MMAP_OFFSET_STATUS:
3566 if (pcm_file->no_compat_mmap) 3585 if (!pcm_status_mmap_allowed(pcm_file))
3567 return -ENXIO; 3586 return -ENXIO;
3568 return snd_pcm_mmap_status(substream, file, area); 3587 return snd_pcm_mmap_status(substream, file, area);
3569 case SNDRV_PCM_MMAP_OFFSET_CONTROL: 3588 case SNDRV_PCM_MMAP_OFFSET_CONTROL:
3570 if (pcm_file->no_compat_mmap) 3589 if (!pcm_status_mmap_allowed(pcm_file))
3571 return -ENXIO; 3590 return -ENXIO;
3572 return snd_pcm_mmap_control(substream, file, area); 3591 return snd_pcm_mmap_control(substream, file, area);
3573 default: 3592 default: