title: mmap: mapping in user space a kernel buffer allocated with kmalloc
body: <p>Which is the correct way to map in an user space process a buffer allocated with kmalloc? Maybe i didn't understand memory mapping yet...I write a kernel module that allocs this buffer (for example 120 bytes) and i would read and write it in a user-space process. Obviously i created a char device and implemented a <code>mmap</code> method in the <code>file_operations</code> struct. My method is:</p>
  
  <pre><code>static int my_mmap(struct file *filp, struct vm_area_struct *vma)
  {
    //printk(KERN_INFO "Allocated virtual memory length = %d", vma-&gt;vm_end - vma-&gt;vm_start);
  
    long unsigned int size = vma-&gt;vm_end - vma-&gt;vm_start;
  
    if (remap_pfn_range(vma, vma-&gt;vm_start,
                        __pa(mem_area) &gt;&gt; PAGE_SHIFT,  //what about vma-&gt;vm_pgoff?
                        size,
                        vma-&gt;vm_page_prot) &lt; 0)
      return -EAGAIN;
  
    vma-&gt;vm_flags |= VM_LOCKED;
    vma-&gt;vm_ops = &amp;vmops;
    vma-&gt;vm_flags |= VM_RESERVED;
  
    my_vm_open(vma);
  
    return 0;
  }
  </code></pre>
  
  <p>where <code>mem_area</code> points at a memory area allocated with <code>kmalloc</code> at module init. The area is filled with the same value (for example 0x10). All works but i think there is something wrong in this code:</p>
  
  <ol>
  <li><p><code>kmalloc</code> could return a pointer that isn't page aligned and, in that case, i don't think is correct the value of the third parameter of <code>remap_pfn_range</code> in fact in user space i read the wrong value. Instead all works if i use <code>__get_free_page</code> (because the the function always returns a pointer that is page aligned) or when <code>kmalloc</code> returns a page aligned pointer. Memory mapping works with memory regions that are multple of <code>PAGE_SIZE</code> so, should i allocate an entire page instead of using <code>kmalloc</code>?</p></li>
  <li><p>When <code>my_mmap</code> is called, the kernel has allocated some pages yet? I ask this because i found some implementations of custom <code>mmap</code> method that call <code>remap_pfn_range</code> with <code>vma-&gt;vm_pgoff</code> as third parameter...how could be useful this? Is this the page frame of the first new allocated page? If i pass as third parameter a page frame like i do in <code>my_mmap</code>, i should free pages starting from page in <code>vma-&gt;vm_pgoff</code>?</p></li>
  <li><p>However i found an implementation of <code>mmap</code> method that maps a buffer allocated with <code>kmalloc</code>. To correctly map the buffer an operation (that i don't undestand for now) is performed before <code>remap_pfn_range</code>. Suppose that <code>mem</code> is the pointer returned by <code>kmalloc</code>, <code>mem_area</code> is initialized in this manner:</p>
  
  <pre><code>mem_area=(int *)(((unsigned long)mem + PAGE_SIZE - 1) &amp; PAGE_MASK);
  </code></pre></li>
  </ol>
  
  <p>So <code>mem_area</code> contains the same value of <code>mem</code> only if <code>mem</code> is page aligned otherwise is should contain the pointer at the beginning of the next page. However, with this operation if i pass as third param of <code>remap_pfn_range</code> the value <code>__pa(mem_area) &gt;&gt; PAGE_SHIFT</code> mapping works well. Why?</p>
  
  <p>Thank you all!</p>