[systemd-devel] [PATCH] Fix broken syscall(__NR_fanotify_mark... on 32bit mips.

Eric Paris eparis at redhat.com
Wed Apr 20 09:14:21 PDT 2011


On Wed, 2011-04-20 at 12:16 +0200, Aurelien Jarno wrote:
> On Wed, Apr 20, 2011 at 03:22:08AM +0200, Lennart Poettering wrote:
> > On Wed, 20.04.11 09:15, fykcee1 at gmail.com (fykcee1 at gmail.com) wrote:
> > 
> > > 
> > > 2011/4/20 Lennart Poettering <lennart at poettering.net>
> > > >
> > > > On Thu, 14.04.11 17:34, fykcee1 at gmail.com (fykcee1 at gmail.com) wrote:
> > > >
> > > > > diff --git a/src/missing.h b/src/missing.h
> > > > > index 35e209f..b367831 100644
> > > > > --- a/src/missing.h
> > > > > +++ b/src/missing.h
> > > > > @@ -125,7 +125,12 @@ static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags)
> > > > >
> > > > >  static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask,
> > > > >                                  int dfd, const char *pathname) {
> > > > > -        return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dfd, pathname);
> > > > > +        if (sizeof(void *) == 4)
> > > > > +                return syscall(__NR_fanotify_mark, fanotify_fd, flags,
> > > > > +                               *((uint32_t *) &mask), *((uint32_t *) &mask + 1),
> > > > > +                               dfd, pathname);
> > > > > +        else /* 64bit */
> > > > > +                return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dfd, pathname);
> > > > >  }
> > > > >
> > > > >  #ifndef BTRFS_IOCTL_MAGIC
> > > >
> > > > Hmm, wouldn't this break x86-32?
> > > It works fine on my asus laptop with a 32bit CPU Pentium-M.
> > > 
> > > We pass two 32bit arguments instead of one 64bit argument. syscall()
> > > doesn't know the prototype, I guess it will only fetch 9 native-width
> > > arguments(1 syscall number + 8 parameters) from the stack. Aurelien,
> > > am I right?
> > 
> > Hmm, I am not sure I understand this? How is it possible that both ways
> > work on x86? There must be quite a difference between passing 6 or 7
> > arguments to syscall.
> 
> syscall(64_bit_arg) actually pass the 64-bit argument in two different
> registers (or on two different 32-bit stack entries). Then the GNU libc
> copies the registers while converting from the userspace ABI to the
> kernel ABI (usually passing more values into registers).
> 
> On a lot of 32-bit cpus which needs alignment, a 64-bit arguments have 
> to be stack aligned, or register aligned. That's why due to the userspace
> ABI, one register or one stack entry has to be empty. This later break
> when this empty register arrives at the kernel level.
> 
> > Or are you suggesting that the current invocation is broken even on x86,
> > just doesn't become visible since only the lower 32 bit of "mask" are
> > used?
> > 
> 
> No, on x86 it just work "by chance", as x86 is very flexible with
> alignement.

When I implemented the kernel interface I remember someone brought up
64-bit alignment and it was suggest I go with the ordering I have.  I
understood that fanotify_fd would be the first 32 bits, flags be the
second and then mask should be 64-bit aligned as the 3rd/4th?

I am pretty arch stupid, and I have no idea at all if it is related, but
I'm looking at kernel commit 5e844b31c2ace282ab8bea630b63e0212d9532d4
which wires up the fanotify syscalls for mips.  I see that it used a u64
for a3 and a4 when these are only going to be 32 values.  Does that
matter?  I also see that some prototype such as sys32_readahead()
explicitly added a pad into the 32 helper.  Should we be doing that?  I
also notice that the naming of arguments seems wrong (although it
shouldn't matter)

SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags,
                u64, a3, u64, a4, int, dfd, const char  __user *, pathname)

I would have thought equivalently:
  fanotify_fd == a0
  flags == a1
  'a3' == a2
  'a4' == a3
  dfd == a4

etc.....

Anyway, no idea if it is related, but I thought I designed the
systemcall with this padding in mind.....

-Eric



More information about the systemd-devel mailing list