免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3527 | 回复: 3
打印 上一主题 下一主题

[求助]关于在内核代码中使用copy_to_user向用户空间复制数据的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-23 08:41 |只看该作者 |倒序浏览
我使用do_mmap在用户空间指定地址addr处建立了一块匿名映射区间,大小0x1000,flag指定为MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,函数正常返回我指定的addr。接着我使用kernel_read从文件中读取了0x1000的数据到内核中,然后我想使用copy_to_user将这些数据复制到addr处,结果通过printk打印调试信息发现,似乎copy_to_user会出现错误,该函数并没有返回。

附上代码:
map_addr = do_mmap(NULL, addr, 0x1000, prot|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0);
printk("map_addr: 0x%x\n", map_addr);    // map_addr = addr

ptmp = (char*)kmalloc(0x1000, GFP_KERNEL);
retval = kernel_read(pfile, 0, ptmp, 0x1000);
printk("kernel_read is done! first char: %x\n", *ptmp);    //打印出的first char正确

printk("1\n");
copy_to_user((char*)map_addr, ptmp, 0x1000);
printk("2\n");

结果只打印出了1,却没有打印2,而且模块从现在开始就无法用rmmod卸载了,提示busy。

请问大家我是不是忽略了什么细节?还是这种方法本身就有问题?为什么copy_to_user函数会不返回呢?

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
2 [报告]
发表于 2010-08-24 02:54 |只看该作者
do_mmap还没有未申请的虚拟地址建立映射.
copy_to_user访问用户空间的时候发生缺页异常.ismod进程被杀死.
给do_mmap加个标志,MAP_LOCKED

论坛徽章:
0
3 [报告]
发表于 2010-08-24 17:31 |只看该作者
回复 2# smalloc


    do_mmap还没有未申请的虚拟地址建立映射
请问这个是如何判断出来?

论坛徽章:
0
4 [报告]
发表于 2010-08-25 16:57 |只看该作者
感谢大家的回答,现在这个问题已经解决。

经过仔细排查发现是临界区的问题,我在这段代码之前使用了down_write(&current->mm->mmap_sem)操作,应该是它导致了copy_to_user的等待,可能copy_to_user中也down了这个锁,所以就无法返回了。

当把down_write去掉之后一切正常。

其实我是因为do_mmap必须要求offset页对齐,但是手头的项目不得不使用非页对齐的文件offset,所以才曲线救国使用了这个方法,先匿名映射,再直接从文件读取数据后copy过去。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP