Monday, January 31, 2022

[SOLVED] How to acquire the "mm semaphore" in C?

Issue

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.


Solution

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.



Answered By - Craig Estey
Answer Checked By - Gilberto Lyons (WPSolving Admin)