Skip to contentSkip to conversation

x86: fls64() exported to user space but not fls()?

DISCUSSION H. Peter Anvin 2 participants 2 messages Dec 15, 2011

Subsystems (2)
lore
Share & tools
lore

H. Peter Anvin

author reviewer
#0 lore raw

I'm trying to grok why fls64() seems to be exported to user space in <asm/bitops.h> on x86 by unconditional inclusion of <asm-generic/bitops/fls64.h>:

...
#endif /* __KERNEL__ */

#include <asm-generic/bitops/fls64.h>

#ifdef __KERNEL__
...

whereas fls() isn't (although __fls() is!)

This is even more bizarre since <asm-generic/bitops/fls64.h> contains:

...
#if BITS_PER_LONG == 32
static __always_inline int fls64(__u64 x)

{
        __u32 h = x >> 32;
        if (h)
                return fls(h) + 32;
        return fls(x);
}
#elif BITS_PER_LONG == 64
static __always_inline int fls64(__u64 x)
{
        if (x == 0)
                return 0;
        return __fls(x) + 1;
}

#else
#error BITS_PER_LONG not 32 or 64
#endif
...

Both BITS_PER_LONG and fls() are non-user-visible symbols, so this code should fail on user space. Finally, <asm-generic/bitops/*> are non-exported headers; they are not installed by make headers_install.

Is the #endif..#ifdef in <asm/bitops.h> a bug, plain and simple?

-hpa

#1 lore raw

[tip:x86/asm] x86, bitops: Move fls64.h inside __KERNEL__

Commit-ID:  83d99df7c4bf37176d8c7b199e3b129a51fa04c8
Gitweb:     http://git.kernel.org/tip/83d99df7c4bf37176d8c7b199e3b129a51fa04c8
Author:     H. Peter Anvin <[email protected]>
AuthorDate: Thu, 15 Dec 2011 14:55:53 -0800
Committer:  H. Peter Anvin <[email protected]>
CommitDate: Thu, 15 Dec 2011 15:04:07 -0800

x86, bitops: Move fls64.h inside __KERNEL__

We would include <asm-generic/bitops/fls64.h> even without __KERNEL__, but that doesn't make sense, as:

1. That file provides fls64(), but the corresponding function fls() is not exported to user space.
2. The implementation of fls64.h uses kernel-only symbols.
3. fls64.h is not exported to user space.

This appears to have been a bug introduced in checkin:

d57594c203b1 bitops: use __fls for fls64 on 64-bit archs

---
 arch/x86/include/asm/bitops.h |   11 ++---------
 1 files changed, 2 insertions(+), 9 deletions(-)
arch/x86/include/asm/bitops.h +2 -9
index 1775d6e..4a6235b 100644
@@ -380,6 +380,8 @@ static inline unsigned long __fls(unsigned long word)
 	return word;
 }
 
+#undef ADDR
+
 #ifdef __KERNEL__
 /**
  * ffs - find first set bit in word
@@ -434,11 +436,6 @@ static inline int fls(int x)
 #endif
 	return r + 1;
 }
-#endif /* __KERNEL__ */
-
-#undef ADDR
-
-#ifdef __KERNEL__
 
 #include <asm-generic/bitops/find.h>
 
@@ -450,12 +447,8 @@ static inline int fls(int x)
 
 #include <asm-generic/bitops/const_hweight.h>
 
-#endif /* __KERNEL__ */
-
 #include <asm-generic/bitops/fls64.h>
 
-#ifdef __KERNEL__
-
 #include <asm-generic/bitops/le.h>
 
 #include <asm-generic/bitops/ext2-atomic-setbit.h>