Chinaunix

标题: [求助]关于在内核代码中使用copy_to_user向用户空间复制数据的问题 [打印本页]

作者: 暗影吉他手    时间: 2010-08-23 08:41
标题: [求助]关于在内核代码中使用copy_to_user向用户空间复制数据的问题
我使用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函数会不返回呢?
作者: smalloc    时间: 2010-08-24 02:54
do_mmap还没有未申请的虚拟地址建立映射.
copy_to_user访问用户空间的时候发生缺页异常.ismod进程被杀死.
给do_mmap加个标志,MAP_LOCKED
作者: klanet    时间: 2010-08-24 17:31
回复 2# smalloc


    do_mmap还没有未申请的虚拟地址建立映射
请问这个是如何判断出来?
作者: 暗影吉他手    时间: 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过去。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2