Я получаю сбой в результате звонка kmap
, и я не знаю, почему. Я надеюсь, что кто-то с большим количеством знаний о ядре, чем я могу помочь с этим. Вот код:Чтение содержимого страницы пользовательского пространства из ядра
pgd_t *pgd = pgd_offset(vma->vm_mm, userspace_addr);
pud_t *pud = pud_offset(pgd, userspace_addr);
pmd_t *pmd = pmd_offset(pud, userspace_addr);
pte_t *pte = pte_offset_map(pmd, userspace_addr);
if (pte_present_user(*pte)) {
void *p = NULL;
struct page *page = pte_page(*pte);
get_page(page);
p = kmap(page); /* CRASH HERE??? */
/* Read from 'p' */
kunmap(p);
put_page(page);
}
Я изолирован, что вызов kmap
является виновником, так как без него код работает нормально. Насколько я могу судить, все указатели действительны.
Я уверен, если pte_offset_map
должен быть использован в сочетании с kmap
...
Код выше запускается с mm->mmap_sem
и vma->vm_mm->page_table_lock
запертой и на kthread
в контексте ядра.
Вы выполнили 'access_ok()' на 'userspage_addr' –
@Miline: я добавил чек, и у меня есть доступ к странице. Я также попытался заменить вызов 'kmap()' 'page_address()', но NULL был возвращен. Я не уверен, что это значит. – MarkP
Что произойдет, если вы удалите kmap()? Я думаю, что pte_offset_map() делает kmap_atomic() внутренне –