On Monday 07 May 2012 13:58:53 Luck, Tony wrote: > the disassembly of the sched_getcpu() code at runtime looks like: > 0x2000000000203940 <+0>: [MMI] alloc r32=ar.pfs,9,1,0 > 0x2000000000203941 <+1>: adds r14=8,r13 > 0x2000000000203942 <+2>: mov r33=r12;; > 0x2000000000203950 <+16>: [MMI] ld8 r14=[r14] > 0x2000000000203951 <+17>: nop.m 0x0 > 0x2000000000203952 <+18>: mov r15=1304 > 0x2000000000203960 <+32>: [MII] mov r35=r0 <<<<<<<<<<<<<<<<<<< > 0x2000000000203961 <+33>: mov r34=r0;;<<<<<<<<<<<<<<<<<<< > 0x2000000000203962 <+34>: mov b7=r14;; > 0x2000000000203970 <+48>: [MIB] nop.m 0x0 > 0x2000000000203971 <+49>: nop.i 0x0 > 0x2000000000203972 <+50>: br.call.sptk.many b6=b7;; > > When the "br.call" is executed, we flip to the new register > frame and r34/r35 in the sched_getcpu() frame become r32/r33 > in the new frame. > > So you get -EFAULT because the VDSO tries to dereference a NULL > pointer for each of the *cpu and *node arguments. oh, i think i see. the funcs implemented via the ia64 vdso are not the normal kernel funcs. instead they're hand coded assembly. in this case, fsys_getcpu in arch/ia64/kernel/fsys.S is lacking handling for NULL cpu/node arguments and if either is NULL, it incorrectly fails. EX(.fail_efault, probe.w.fault r32, 3) // M This takes 5 cycles EX(.fail_efault, probe.w.fault r33, 3) // M This takes 5 cycles i guess that needs to load some p reg with a NULL pointer test and then do the loads/stores based on that. calling getcpu(NULL, NULL, NULL) from userspace shouldn't trigger EFAULT. -mike
Attachment:
signature.asc
Description: This is a digitally signed message part.