简体   繁体   中英

How to map pages using the page fault handler?

I want to use the pagefault handler of my struct vm_area_struct * to map a physical page to user space.

Here is how I proceed:

  • I globally allocate a page using alloc_page(GFP_USER) during the module initialization (I tried various GFP).
  • I create a struct vm_area_struct , set a custom pagefault handler, and attach the vma to current->mm .

When a page fault occurs:

  • I set vmf->page to the page I previously allocated and return 0.

The result is that every virtual page in the vma should be mapped to the same physical page after a page fault.

But here is what I noticed:

  • When I write to the page from my kernel module, it's reflected in my user-space program.
  • When I write to the page from my user-space, I don't see it from my kernel module.
  • When I'm using get_user_pages in my kernel module to get the page (instead of using my global variable), I get a different physical address than the global page variable. I print the address using page_to_phys(page) . Writing to this page is reflected in my user-space program.

All of this is done in the page fault handler by the way.

How can this curious behavior be explained?

To access the page from kernel space, I'm using kmap_atomic and kunmap_atomic .

This is due to the copy-on-write mechanism. After your page fault handler runs, the page you returned in vmf->page is copied to a newly allocated page. This is why your changes in user-space are not reflected in your kernel module. The page you were trying to read from in the kernel is not the one that was really mapped in your user-space process.

You can refer to the do_cow_fault function in mm/memory.c .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM