URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 3469
[ Назад ]

Исходное сообщение
"получение памяти из модуля ядра, так чтобы она была из user space."

Отправлено TeCTeP , 12-Окт-04 02:47 
Т.е. надо из основного модуля вызвать ioctl функцию другого модуля(вспомогательного), но в качестве последнего параметра ioctl идёт переменная с адресом из user space. kmalloc выделяет память замаппеную как своё кернельное пространство, поэтому её использование отпадает. Можно из user space программы передать моему основному модулю переменную, а её уже подкидывать вспомогательному, но если user space программа закончит своё выполнение раньше передачи параметра вспомогательному модулю, то всё падает, ибо передаётся уже неправильный указатель (такой переменной нет, так как user space прога сделала free...). Вот посему и возник такой вопрос. Или как просто замапить адрес возвращаемый kmalloc-ом так чтобы получился адрес из user space? Надеюсь что хоть кто-нибудь что-то понял из вышенаписанного :)

Содержание

Сообщения в этом обсуждении
"получение памяти из модуля ядра, так чтобы она была из user ..."
Отправлено Murr , 12-Окт-04 12:34 
Бррр...
Давайте подробнее что и как у вас там передается...
а)Нить вызывает иоктл, в который передает указатель
б)ваш модуль вызывает иоктл, который в компетенции другого модуля
в)другой модуль что-то делает с полученным указателем

Несколько комментариев.

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

Во-вторых, если речь все же не про иоктл, а про то, как асинхронно ковырять из модуля данные по пользовательским адресам - то тут вам подойдет get_user_pages.


"получение памяти из модуля ядра, так чтобы она была из user ..."
Отправлено TeCTeP , 12-Окт-04 15:14 
>Давайте подробнее что и как у вас там передается...
>а)Нить вызывает иоктл, в который передает указатель

ну да, выглядит это так: ioctl(snp, SNPSTTY, ttypath), где
ttypath это указатель на строку (char*).

>б)ваш модуль вызывает иоктл, который в компетенции другого модуля

Примерно так:
tty_filp->f_op->ioctl ( tty_filp->f_dentry->d_inode, tty_filp, TIOCSETD,
(int)line_disc_num )
ну это ioctl вызов для установки на терминале новой line_discipline,
с номером line_disc_num. Дык вот последний параметр должен быть
из user_space. Можно туда засунуть и ttypath (предваритель в неё записав
нужный ldic_num), но бывает, что прога,
которая делала первый ioctl уже завершилась, и это не прокатывает.
Ещё как выяснилось этот ioctl юзает функцию tty_set_ldisc, которую можно
юзать, только после того как заэкспортируешь её через EXPORT_SYMBOL. Но
этого не  хочется делать, нужно чтоб эта лабуда работала везде без
перекомпиляции ядра...

>в)другой модуль что-то делает с полученным указателем

ну даже не модуль, а терминал устанавливает у себя новую ldisc.

>Несколько комментариев.
>
>Во-первых, если вы вызываете иоктл, то тот модуль точно так же как
>и ваш
>должен воспринимать указатель переданный параметром как указатель из процесса и эрго проверять
>его.

ну да, но вот если процесс сдыхает, то уже проверки не срабатывают и
всё вылетает с ошибками :(

>Во-вторых, если речь все же не про иоктл, а про то, как
>асинхронно ковырять из модуля данные по пользовательским адресам - то тут
>вам подойдет get_user_pages.

возможно, щас почитаю :) Просто хотелось что-нибудь попроще, в одну
функцию...


"получение памяти из модуля ядра, так чтобы она была из user ..."
Отправлено Murr , 13-Окт-04 12:23 
Тьфу, наконец я понял о чем речь.
Вам нужны set_fs(KERNEL_DS);

"получение памяти из модуля ядра, так чтобы она была из user ..."
Отправлено TeCTeP , 13-Окт-04 13:46 
>Вам нужны set_fs(KERNEL_DS);

как я понял, она устанавливает адресное пространство треда(нити). Но я не
совсем понимаю куда мне её засунуть-то нужно, можно чуть-чуть поподробнее?



"получение памяти из модуля ядра, так чтобы она была из user ..."
Отправлено Murr , 13-Окт-04 15:52 
Как я понял:
вам нужно передать ядреный указатель, так чтобы он был принят функцией,
ожидающей userspace указатель. При обращении к userspace данным обычно
проводится проверка на addr_limit текущего процесса (например, в copy_from_user). Вы можете "расширить" адресное пр-во процесса на время выполнения этой функции с целью передачи подобного указателя.

set_fs(KERNEL_DS);
...->ioctl(...);
set_fs(USER_DS);


"получение памяти из модуля ядра, так чтобы она была из user ..."
Отправлено TeCTeP , 13-Окт-04 23:37 
Спасибо, всё заработало как надо.