LINUX.ORG.RU

сделать страницы в адресном пространстве ядра writeable


0

0

Внимание, вопрос. Ядро - 2.6.31. Имеются некоторые адреса в адресном пространстве ядра, по коим желательно бы записать некоторые данные. Но «ой, вот ведь незадача» - эти страницы памяти помечены как read-only, а прекрасную функцию change_page_attr давным-давно из ядра убрали. Попробовал я set_memory_rw и set_pages_rw - даже то, что они не экспортируются, меня не остановило, взял адреса из kallsyms. Не работает - при попытке записать данные все так же возвращается Oops. Что же делать, господа? Посоветуйте, прошу, больше конкретных решений, хороших и разных.


спасибо, разобрался и так. если кому-то вдруг интересно:

/*
 * set_page_addr_rw()
 * установка режима read-write для страницы, содержащей адрес
 *  address - заданный адрес
 */
int set_page_addr_rw(unsigned long address)
{
   pgd_t *pgd;
   pmd_t *pmd;
   pud_t *pud;
   pte_t *ptep, pte;
 
   // получим PGD
   pgd = pgd_offset(current->mm, address);
   if (pgd_none(*pgd) || pgd_bad(*pgd))
      return -1;

   // получим PUD
   pud = pud_offset(pgd, address);
   if (pud_none(*pud) || pud_bad(*pud))
      return -1;

   // получим PMD
   pmd = pmd_offset(pud, address);
   if (pmd_none(*pmd) || pmd_bad(*pmd))
      return -1;

   // получим текущий PTE (Page Table Entry)
   ptep = pte_offset_kernel(pmd, address);
   if (!ptep)
      return -1;
   
   pte = *ptep;

   // добавим _PAGE_RW флаг в PTE
   pte = pte_mkwrite(pte);

   // запишем обновленный PTE
   ptep_modify_prot_start (current->mm, address, ptep);
   ptep_modify_prot_commit(current->mm, address, ptep, pte);

   return 0;
}
xdiman
() автор топика
Ответ на: комментарий от xdiman

sys_mprotect((long)addr, PAGE_SIZE, 3), вызванный из ядра, тоже работает :)

mv ★★★★★
()

> функцию change_page_attr давным-давно из ядра убрали.

как это убрали? см arch/x86/mm/pageattr.c

переделали/переименовали - да, и static да.

set_pages_rw - даже то, что они не экспортируются,


хмм... arch/x86/mm/pageattr.c:

EXPORT_SYMBOL_GPL(set_memory_rw)

ЗЫ: не забудьте, это все для init_mm, может потому у
вас и не работает.

idle ★★★★★
()
Ответ на: комментарий от pradd

> 3 бессонных ночи провел пока не нашел это сообщение!

боюсь, использование этой функции может подарить вам гораздо
больше бессонных ночей ;) она настолько неправильна, что я
даже не знаю, с чего начать.

ну... если уж ptep_modify_prot_start/commit, то код должен
быть

pte = ptep_modify_prot_start(...);
pte = pte_mkwrite(...);
ptep_modify_prot_commit();

но это ерунда. как насчет tlb flush? races? vma/page associated
с этим address? да много чего.

я не говорю, что это _никогда_ не будет работать, но это в
любом случае какой-то хак с очень нетривиальными side effects.

вы бы лучше рассказали, ЗАЧЕМ это нужно???

idle ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.