I am at a dead end of trying to figure out why copy_from_user() fails on
me. Any help or pointers will be greatly appreciated!
I made new system call which is simplified copy of sys_socketcall() system
call with basically copy_from_user() in it, but it results in system Ooops
when called from user space using syscall().
When adding a new system call I edited arch/i386/kernel/entry.S and
increasing the number of system calls to 191. I also edited
include/asm/unistd.h. The new system call is being called.
The new system call is as follows:
asmlinkage int sys_qsocketcall(int call, unsigned long *args)
{
unsigned long a[6];
unsigned long a0,a1;
struct request filter_req;
struct request class_req;
printk( "sys_qsocketcall(): inside. \n");
if(call<1||call>SYS_RECVMSG)
return -EINVAL;
/* copy_from_user should be SMP safe. */
if (copy_from_user(a, args, nargs[call])) // nargs[..]=12
return -EFAULT;
printk( "sys_qsocketcall(): copy_from_user() done. [a0=%X, a1=%X]\n",
a[0], a[1] );
printk( "sys_qsocketcall(): returning.\n" );
return -EINVAL;
}
I am calling this from user space as follows:
....
char *lng_args;
lng_args = (char*)malloc( 3*sizeof(struct request) ); // allocates ~8 KB
memset( lng_args, 3, 3*sizeof(struct request) );
printf( "calling syscall()....\n" );
res = syscall( SYS_qsocketcall, 1, lng_args );
printf( "after syscall()....\n" );
....
There is basically no difference that I can see between my code and how
sys_socketcall() system call works. sys_socketcall() doesn't use any
locks before doing copy so I thought I don't have to either. I just
allocate much bigger chunk of memory, but inside of system call I can't
even read first 12 Bytes under light loads (having ~5 clients call new
system call at the same time).
And here is what I see in a log file:
Jun 24 16:56:36 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:36 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:36 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:37 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:56:38 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:56:38 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:57:06 thinker kernel: sys_qsocketcall(): inside. (call=1, args=080499c8)
Jun 24 16:57:06 thinker kernel: sys_qsocketcall(): doing first copy_from_user()....
Jun 24 16:57:06 thinker kernel: sys_qsocketcall(): copy_from_user() done. [a0=D0C0B0A, a1=A100F0E]
Jun 24 16:57:06 thinker kernel: sys_qsocketcall(): returning.
Jun 24 16:57:07 thinker kernel: Unable to handle kernel NULL pointer dereference at virtual address 00000276
Jun 24 16:57:07 thinker kernel: current->tss.cr3 = 0304f000, %cr3 = 0304f000
Jun 24 16:57:07 thinker kernel: *pde = 00000000
Jun 24 16:57:07 thinker kernel: Oops: 0000
Jun 24 16:57:07 thinker kernel: CPU: 0
Any suggestions? What am I missing?
Thanks,
Gregory
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/