If you want to use the remap_pfn_range
function within a custom kernel driver implementing mmap, you know that you have to acquire the 'mm semaphore'. But it's not clear how to do so from the examples that I can find publicly available. I think it would benefit the community to edit the examples that are available, and I'm willing to do so, but I don't know where to start.
As per the documentation: this is only safe if the mm semaphore is held when called.
It helps to look at the actual source [for remap_pfn_range
]. That's in the mm
subdirectory, specifically in mm/memory.c
There you'll see struct mm_struct *mm = vma->vm_mm;
so that's the mm
you want. Note that is also [probably] current->mm
If you look around in a few more files there [notably mm/mmap.c
], you'll see down_write(&mm->mmap_sem)
and up_write(&mm->mmap_sem)
[which are the kernel's semaphore primitives]. Note that if you only needed to read from the area, there are down_read
and up_read
So, to put it all together:
void
myfnc(...)
{
struct vm_area_struct *vma = ...;
struct mm_struct *mm = vma->vm_mm;
...
down_write(&mm->mmap_sem);
remap_pfn_range(vma,...);
up_write(&mm->mmap_sem);
...
}
Documentation aside, one of the best ways to find these things is the look through the source itself. I've been writing linux kernel/driver code for 20+ years and it's what I do when I need to find something that I don't know about.