2012-03-29 7 views
4

Я собираю некоторую память io для vmalloced области в драйвере. Я также разделяю эту область с пользовательскими процессами, используя флаг (PAGE_SHARED в ioremap_page_range).системные вызовы, не соответствующие iomapped памяти в Linux.

Теперь я могу получить доступ к этой общей памяти в пространстве пользователя. Я могу писать и читать эту память. Однако, если я передаю эту память в качестве буфера для системных вызовов, например recv или send, тогда сбой вызовов происходит с плохой памятью (Memory not mapped into user process).

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

код драйвера:

shared_buf = __get_vm_area(size, VM_IOREMAP, VMALLOCS_START, VMALLOC_END); 
ioremap_page_range(shared_buf->addr, size, phy_addr_of_io, PAGE_SHARED);  

После того, что я делаю вызов IOCTL и передать этот shared_buf-> адр в приложение пользовательского пространства.
Я пишу и читаю, используя этот addr. Тогда я

ret = recv(sockfd, shared_buf->area, 0) and I get an error "bad addr". 

Вместо того, что если я попытаюсь

ret = recv(sockfd, local_buf, size, 0); 
memcpy(shared_buf->addr, local_buf, size); Then it goes without issues. 

(Отказ от ответственности:.. Я использую shared_buf->area в потоках, которые не сделали IOCTL Однако это тот же процесс)

Может ли кто-нибудь увидеть ошибку?

+0

Показать код. –

+0

обновил сообщение. –

+0

Возможно, вы захотите обновить это снова, чтобы дать вашему запросу 'recv' достаточно аргументов. – Nemo

ответ

3

Системные вызовы все проверяют, что указанный указатель находится в пользовательской части адресного пространства. пространство vmalloc не находится в этой пользовательской части; следовательно, вы не можете использовать его для системных вызовов. Что еще более важно, не предоставляйте пользовательским процессам прямой доступ к памяти в адресном пространстве vmalloc. Это просто просит неприятностей. И, вероятно, ужасно неуверенно - могут ли другие процессы получить доступ к этому тоже? Напишите an mmapable file instead.

+0

@bdolan: У меня вроде было заминок, что должна быть проверка, чтобы увидеть, находится ли addr в пользовательском пространстве. Тем не менее, мне также было интересно, почему проверка не выполняется над битом супервизора в таблице страниц. Может быть, разработчики ядра не ожидают, что программисты будут использовать буфер ядра. (Я знаю, что mmap - это обряд для этого.) Я использовал этот ужасный метод обмена mem, так как хотел что-то быстро проверить и наткнулся на эту проблему. Благодарю. –

+0

@ agent.smith, фактически поиск страницы в таблице страниц - _slow_. Ядро просто проверяет, находится ли он в области пользовательского пространства, а затем напрямую обращается к нему (даже в кольце 0 ЦП будет соблюдать не настоящие или защищенные от записи биты). Единственным исключением являются некоторые очень ранние модели 386 процессоров, в которых ядро ​​действительно проверяет таблицу страниц, но опять же, это довольно медленно. – bdonlan

Смежные вопросы