[PATCH 12/39] ALSA: pcm: use vm_insert_page() to map PCM status page
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
Date: 2026-09-08 20:08:10
Also in:
bpf, dri-devel, fuse-devel, kvm, kvm-riscv, kvmarm, linux-arch, linux-doc, linux-fbdev, linux-fsdevel, linux-mm, linux-perf-users, linux-s390, linux-scsi, linux-sound, linux-trace-kernel, linux-usb, linuxppc-dev, lkml, selinux, sparclinux
Subsystem:
sound, the rest · Maintainers:
Jaroslav Kysela, Takashi Iwai, Linus Torvalds
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 be kernel-owned; 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.
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
---
sound/core/pcm_native.c | 37 ++++++++++++-------------------------
1 file changed, 12 insertions(+), 25 deletions(-)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 62324282fcae..37a157d55832 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3760,39 +3760,26 @@ 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);
- return 0;
+ runtime = substream->runtime;
+ page = virt_to_page(runtime->status);
+ return vm_insert_page(vma, vma->vm_start, page);
}
/*
--
2.55.0