Hi Jan & Cyril, On 07/14/2014 03:45 PM, [email protected] wrote: >> just trying to understand why it's not working now. Shouldn't >> __LONG_LONG_PAIR >> take care of endian issues?
Partly. I'll explain further down... Jan wrote in the other mail: > In email from Apr 18, you said "Yes, works for me (hppa arch, 32bit userspace, > 64bit kernel)." - has anything changed since then? Nothing changed, but I did some further testing and noticed, that the same testcase (same binary executable!) was broken on a 32bit kernel. As you see above I tested earlier this year only on a 64bit kernel where it worked. So, the main important thing is, that the same binary needs to work on 32bit and 64bit kernel. Otherwise something is wrong in the compat layer of a 64bit kernel. > I've talked about this on linux-api mailing list and been told that > it's not only about endianity but also about packing of the arguments[0]. > [0] http://marc.info/?l=linux-api&m=140016971909948&w=2 Exactly! Please read my explanation in the patch which I submitted upstream yesterday: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ab8a261ba5e2dd9206da640de5870cc31d568a7c My initial analysis started with a thread on LKML (it has a wrong patch!): https://lkml.org/lkml/2014/7/4/340 So, in summary: In the Linux kernel we have two implementations of fanotify_mark(). See in fs/notify/fanotify/fanotify_user.c SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags, __u64, mask, int, dfd, const char __user *, pathname) -> this one is used for native 32bit and native 64bit kernels. COMPAT_SYSCALL_DEFINE6(fanotify_mark, int, fanotify_fd, unsigned int, flags, __u32, mask0, __u32, mask1, int, dfd, const char __user *, pathname) -> this one is only used for 32bit-userspace on 64bit kernel (compat) As you can see, both differ in that the first one uses "__u64" for the mask parameter, while the second one uses two "__32" for mask0 and mask1. Because the second one used 2 __u32 I initially sent the old patch to LTP, which used __LONG_LONG_PAIR() and which seemed ok. But when I compiled a 32bit kernel, suddenly the syscall now had __u64 (because the first function above is used) and the endianess became wrong (because it used "native" __u64 instead of what __LONG_LONG_PAIR() hands over). So, I had to fix the kernel for both cases which is what this patch does: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ab8a261ba5e2dd9206da640de5870cc31d568a7c During the testing I noticed another bad thing: On hppa calling syscall(__NR_fanotify_mark, ...) and fanotify_mark() from glibc will not create the same code. The additional 32bit value (__NR_fanotify_mark) changes the number of arguments and the compiler will thus insert a padding parameter to keep the __u64 argument aligned to the architectural calling design. This is explained in my kernel patch too. > I've also been hinted that there are scripts that can generate correct > code to call syscalls with 64 bit arguments from syscall descriptions in > klibc[1] and that it's resonably easy to reuse these but haven't yet had > time to look into that. > [1] http://git.kernel.org/cgit/libs/klibc/klibc.git/ I think this is a good idea. Especially, as described above, it's better to rely on the glibc or klibc function calls instead of trying to get the native syscall()-syntax correct for each architecture. Helge ------------------------------------------------------------------------------ Want fast and easy access to all the code in your enterprise? Index and search up to 200,000 lines of code with a free copy of Black Duck® Code Sight™ - the same software that powers the world's largest code search on Ohloh, the Black Duck Open Hub! Try it now. http://p.sf.net/sfu/bds _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
