How to map pages using the page fault handler?

泪湿孤枕 提交于 2019-12-08 05:53:50

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/27318607/how-to-map-pages-using-the-page-fault-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!