Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does "get_user_pages" work (For linux driver)

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.

like image 521
Cong Li Avatar asked Mar 31 '16 15:03

Cong Li


1 Answers

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.

like image 146
Mathieu Avatar answered Sep 20 '22 11:09

Mathieu