Re: [PATCH v4 12/38] ALSA: pcm: use vm_insert_page() to map PCM status page
From: Suren Baghdasaryan
Date: Sun Oct 04 2026 - 13:32:14 EST
On Sat, Oct 3, 2026 at 6:37 PM Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx> wrote:
>
> There's no need to keep a fault handler around for this, instead map on
> mmap.
>
> While we're here, rename area to vma to be consistent.
>
> This correctly makes the mapping a mixed map mapping.
>
> This works towards establishing the invariant that only PFN mapped or mixed
> map mappings may clear the VM_MAYWRITE flag. The status page mapping clears
> VM_MAYWRITE, so it must not be mm-managed; the control page mapping remains
> writable and is left fault-based.
>
> The assumption is made that the struct pcm_mmap_status structure is at most
> a page in size, which is asserted as a build bug.
>
> This is safe to assume, as the size of the structure is 56 bytes at most.
>
> Acked-by: Takashi Iwai <tiwai@xxxxxxx>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
Reviewed-by: Suren Baghdasaryan <surenb@xxxxxxxxxx>
> ---
> sound/core/pcm_native.c | 38 +++++++++++++-------------------------
> 1 file changed, 13 insertions(+), 25 deletions(-)
>
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index 62324282fcae..c98fb3df14f3 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -3760,39 +3760,27 @@ static __poll_t snd_pcm_poll(struct file *file, poll_table *wait)
> /*
> * mmap status record
> */
> -static vm_fault_t snd_pcm_mmap_status_fault(struct vm_fault *vmf)
> +static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
> + struct vm_area_struct *vma)
> {
> - struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
> + const unsigned long size = vma->vm_end - vma->vm_start;
> struct snd_pcm_runtime *runtime;
> -
> - if (substream == NULL)
> - return VM_FAULT_SIGBUS;
> - runtime = substream->runtime;
> - vmf->page = virt_to_page(runtime->status);
> - get_page(vmf->page);
> - return 0;
> -}
> + struct page *page;
>
> -static const struct vm_operations_struct snd_pcm_vm_ops_status =
> -{
> - .fault = snd_pcm_mmap_status_fault,
> -};
> + BUILD_BUG_ON(sizeof(struct snd_pcm_mmap_status) > PAGE_SIZE);
>
> -static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
> - struct vm_area_struct *area)
> -{
> - long size;
> - if (!(area->vm_flags & VM_READ))
> + if (!(vma->vm_flags & VM_READ))
> return -EINVAL;
> - size = area->vm_end - area->vm_start;
> - if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)))
> + if (size != PAGE_SIZE)
> return -EINVAL;
> - area->vm_ops = &snd_pcm_vm_ops_status;
> - area->vm_private_data = substream;
> - vm_flags_mod(area, VM_DONTEXPAND | VM_DONTDUMP,
> +
> + vm_flags_mod(vma, VM_DONTEXPAND | VM_DONTDUMP,
> VM_WRITE | VM_MAYWRITE);
> + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
>
> - return 0;
> + runtime = substream->runtime;
> + page = virt_to_page(runtime->status);
> + return vm_insert_page(vma, vma->vm_start, page);
> }
>
> /*
>
> --
> 2.55.0
>