How does “get_user_pages” work (For linux driver)

落爺英雄遲暮 提交于 2021-02-18 22:37:28

问题


Working on a Linux PCI driver, now I'm trying to write codes for DMA using scatter/gather.

For now, I've learned that to access to DMA datas directly from User space, we need to pin user space pages to kernel space.

And to do this, we have get_user_pages, its full definition is like:

int get_user_pages(struct task_struct * tsk,  
    struct mm_struct * mm,  
    unsigned long start,  
    int nr_pages,  
    int write,  
    int force,  
    struct page ** pages,  
    struct vm_area_struct ** vmas);

My first question is about the struct page ** pages. Here do we need to allocate memory(using kcalloc for ex.) for the pages before calling the get_user_pages?

My second question is about the unsigned long start, on the man page, it says "starting user address", does it mean that, if I declare a pointer in user space like int *p, the "starting user address" I should pass to kernel space is p?

My third question is also about the unsigned long start, if I understand correctly in the second question, then how can we make sure that this address begins exactly at the beginning of a page?

So three questions, thanks for advance.


回答1:


My first question is about the struct page ** pages. Here do we need to allocate memory(using kcalloc for ex.) for the pages before calling the get_user_pages?

You can, but it's not mandatory, an array is sufficent (its size depends on nr_pages)

If you want to pin 4 pages, struct page *pages[4]; is enough.

My second question is about the unsigned long start, on the man page, it says "starting user address", does it mean that, if I declare a pointer like int *p, the "starting user address" I should pass to kernel space is p?

This parameter should points to memory owned by your user process (like after a malloc).

My third question is also about the unsigned long start, if I understand correctly in the second question, then how can we make sure that this address begins exactly at the beginning of a page?

I think you can do it with getpagesize function.

I think this blog entry: "get_user_pages example" may help you.



来源:https://stackoverflow.com/questions/36337942/how-does-get-user-pages-work-for-linux-driver

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