Доступ к пользовательскому пространству из пространства ядра - get_user_pages - PullRequest
3 голосов
/ 07 декабря 2009

Я бы хотел передать указатель из памяти пространства пользователя в функцию в моем модуле ядра. Я не хочу использовать copy_from_user. Я прочитал, что я должен использовать функцию get_user_pages.

Например, одна страница.

struct page **pages;
pages = kmalloc(1 * sizeof(*pages), GFP_KERNEL);

down_read(&current->mm->mmap_sem);
get_user_pages(current,current->mm,uaddr, 1, 1, 0,pages,NULL);
up_read(&current->mm->mmap_sem);

uaddr - это адрес в пространстве пользователя.

  1. После этого я могу привести и передать uaddr в мой модуль модуля ядра? Или, может быть, я должен каким-то образом использовать эти struct pages
  2. Почему я должен использовать чтение вниз / вверх?
  3. После всего мне нужно использовать функции SetPageDirty() и page_cache_release()?

Ответы [ 4 ]

2 голосов
/ 08 декабря 2009

Пользовательские страницы можно использовать только для действий типа страницы, например, для настройки Scatter / Gather DMA в пользовательской памяти. Вы не можете использовать его для прямого доступа к пользовательскому пространству из кода режима ядра. Следовательно, функции copy_to / from существуют по этой причине. Если вы не перемещаете большие объемы данных, почему бы не использовать эти функции?

2 голосов
/ 03 марта 2011
  1. Нет, вы не можете напрямую получить доступ к страницам пользовательского пространства через uaddr. Страницы структуры заполняются, чтобы позволить ядру получить доступ к физическим страницам, которые соответствуют страницам пользовательского пространства. Также обратите внимание, что они вряд ли будут смежными, поэтому необходимо использовать правильный индекс страницы в массиве с начала uaddr.
  2. Вы изменяете структуры отображения страниц для этого процесса, поэтому необходимо защищать их при настройке отображения страниц в ядре.
  3. Когда вы закончите с отображениями, которые были установлены get_user_pages (), вы должны «освободить» их с помощью указанных функций.
2 голосов
/ 08 декабря 2009

Это не то, для чего get_user_pages (и нет - тогда вы не можете просто привести и передать uaddr в функцию модуля ядра).

Если вы не хотите вызывать copy_from_user в вызывающей функции, просто передайте void __user * функции вашего модуля и наберите it do copy_from_user.

0 голосов
/ 21 июня 2013

Как только вы получите действительный адрес пространства пользователя, используйте get_user_pages, чтобы получить указатель на структуру страницы. как только получен указатель struct page, для доступа к нему в режиме ядра вы должны сопоставить его с виртуальным адресом ядра с помощью kmap. надеюсь, что это поможет

...