Т.е. надо из основного модуля вызвать ioctl функцию другого модуля(вспомогательного), но в качестве последнего параметра ioctl идёт переменная с адресом из user space. kmalloc выделяет память замаппеную как своё кернельное пространство, поэтому её использование отпадает. Можно из user space программы передать моему основному модулю переменную, а её уже подкидывать вспомогательному, но если user space программа закончит своё выполнение раньше передачи параметра вспомогательному модулю, то всё падает, ибо передаётся уже неправильный указатель (такой переменной нет, так как user space прога сделала free...). Вот посему и возник такой вопрос. Или как просто замапить адрес возвращаемый kmalloc-ом так чтобы получился адрес из user space? Надеюсь что хоть кто-нибудь что-то понял из вышенаписанного :)
Бррр...
Давайте подробнее что и как у вас там передается...
а)Нить вызывает иоктл, в который передает указатель
б)ваш модуль вызывает иоктл, который в компетенции другого модуля
в)другой модуль что-то делает с полученным указателемНесколько комментариев.
Во-первых, если вы вызываете иоктл, то тот модуль точно так же как и ваш
должен воспринимать указатель переданный параметром как указатель из процесса и эрго проверять его.Во-вторых, если речь все же не про иоктл, а про то, как асинхронно ковырять из модуля данные по пользовательским адресам - то тут вам подойдет get_user_pages.
>Давайте подробнее что и как у вас там передается...
>а)Нить вызывает иоктл, в который передает указатель
ну да, выглядит это так: 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.возможно, щас почитаю :) Просто хотелось что-нибудь попроще, в одну
функцию...
Тьфу, наконец я понял о чем речь.
Вам нужны set_fs(KERNEL_DS);
>Вам нужны set_fs(KERNEL_DS);как я понял, она устанавливает адресное пространство треда(нити). Но я не
совсем понимаю куда мне её засунуть-то нужно, можно чуть-чуть поподробнее?
Как я понял:
вам нужно передать ядреный указатель, так чтобы он был принят функцией,
ожидающей userspace указатель. При обращении к userspace данным обычно
проводится проверка на addr_limit текущего процесса (например, в copy_from_user). Вы можете "расширить" адресное пр-во процесса на время выполнения этой функции с целью передачи подобного указателя.set_fs(KERNEL_DS);
...->ioctl(...);
set_fs(USER_DS);
Спасибо, всё заработало как надо.