我在Linux内核(h.w)中有一个相当大的项目。
部分需要使用copy_to_user函数, 由于某种原因,无论缓冲区大小是多少,它都会返回缓冲区大小(而不是0)。
你可以帮忙吗?这是我的代码的一部分:
asmlinkage int sys_receive_mpi_message(int rank, char *message, ssize_t message_size)
{
int reader_rank =-10;
struct task_struct* p = NULL;
struct my_message_list* tmp;
struct list_head *pos, *q;
struct blabla* tmp1;
int bufSize = 0;
int res =0;
int i=0;
if ((rank < 0) || (rank > counter))
{
return -ESRCH;
}
list_for_each(pos, &(my_api_list->list))
{
tmp1 = list_entry(pos, struct blabla, list);
if (tmp1->pid == (current->pid))
{
reader_rank = tmp1->place;
p = tmp1->task_struct_p;
break;
}
}
if (reader_rank == -10)
{
return -ESRCH;
}
list_for_each_safe(pos,q, &(p->message_list->list))
{
tmp=list_entry(pos, struct my_message_list, list);
if (tmp->sender_rank == rank)
{
if (message_size > (tmp->meesage_size))
{
bufSize = tmp->meesage_size;
}
else
{
bufSize = message_size;
}
res = copy_to_user(message,tmp->message,bufSize);
if(res != 0)
{
return -EFAULT;
}
kfree(tmp->message);
list_del(pos);
kfree(tmp);
return (bufSize);
}
return -EFAULT;
}
return -EFAULT;
}
另外,我有这个结构:
struct my_message_list{
char* message;
int meesage_size;
int sender_rank;
struct list_head list;
};
更新 - 我发现我正在向用户发送的消息始终指向0! 这是否告诉我问题出在包装函数中? 这是我的说唱歌手功能(相关部分):
#include <errno.h>
int receive_mpi_message(int rank, char* message, int message_size)
{
int res;
__asm__
(
"pushl %%eax;"
"pushl %%ebx;"
"pushl %%ecx;"
"pushl %%edx;"
"movl $245, %%eax;"
"movl %1, %%ebx;"
"int $0x80;"
"movl %%eax,%0;"
"popl %%edx;"
"popl %%ecx;"
"popl %%ebx;"
"popl %%eax;"
: "=m" (res)
:"m"(rank),"m"(message),"m"(message_size)
);
if (res >= (unsigned long)(-125))
{
errno = -res;
res = -1;
}
return (int) res;
}
答案 0 :(得分:1)
您使用什么用户空间界面进行通信?无论您使用什么用户空间接口(chardev,ioctl,...),您挂钩的函数定义的签名都应该具有__user
属性。
例如:fs.h
struct file_operations {
...
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
...
}
因此char *message
变量应为char __user *message
,只需查看您使用的用户空间界面即可。
另一件事可能是你在错误的地方调用该方法。据我所知,copy_*_user
函数仅允许从用户空间调用。如果我错了,请有人纠正我。
答案 1 :(得分:0)
无论如何,无法复制您要复制的日期,例如,您无法读取源或写入目标。它在arch / x86 / lib / usercopy_32.c中解释:
/*
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*/
答案 2 :(得分:0)
我的说唱歌手功能有问题, 忘了将数据存储到所有寄存器:
int receive_mpi_message(int rank, char* message, int message_size)
{
int res;
__asm__
(
"pushl %%eax;"
"pushl %%ebx;"
"pushl %%ecx;"
"pushl %%edx;"
"movl $245, %%eax;"
"movl %1, %%ebx;"
"movl %2, %%ecx;"
"movl %3, %%edx;"
"int $0x80;"
"movl %%eax,%0;"
"popl %%edx;"
"popl %%ecx;"
"popl %%ebx;"
"popl %%eax;"
: "=m" (res)
:"m"(rank),"m"(message),"m"(message_size)
);
if (res >= (unsigned long)(-125))
{
errno = -res;
res = -1;
}
return (int) res;
}