[lkml]   [2018]   [Apr]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
SubjectRe: [GIT PULL] x86/build changes for v4.17
On Thu, Apr 5, 2018 at 3:08 AM Peter Zijlstra <> wrote:

> On Wed, Apr 04, 2018 at 10:21:05PM +0000, James Y Knight wrote:
> > But allowing random pointer arithmetic, and pointer arithmetic
> > is still different than asserting that an object _field access_ can
> > overflow. Clang does not believe that can happen -- it assumes that an
> > object will still be contiguous. And that's why the llist stuff used to
> > broken, before it was corrected to do simply do math on a uintptr_t
> > is a nice and simple and sane fix!).

> That 'fix' wasn't anything simple, I recently ran into that
> member_address_is_nonnull() trainwreck and had to think real hard wtf it
> was about.

I agree the comment there could be clearer. You could replace it with
something like this (apologies: this patch is likely going to be mangled by
gmail's plaintext mode hard-wrapping it.)

diff --git a/include/linux/llist.h b/include/linux/llist.h
index 85abc2915e8d..04e972a0bbe8 100644
--- a/include/linux/llist.h
+++ b/include/linux/llist.h
@@ -99,12 +99,15 @@ static inline void init_llist_head(struct llist_head
* This macro is conceptually the same as
* &ptr->member != NULL
- * but it works around the fact that compilers can decide that taking a
- * address is never a NULL pointer.
- *
- * Real objects that start at a high address and have a member at NULL are
- * unlikely to exist, but such pointers may be returned e.g. by the
- * container_of() macro.
+ * except that it uses addition on a uintptr_t instead of member
+ * access syntax. This avoids running into a compiler assumption that
+ * objects must be contiguous in memory, and therefore that member
+ * address lookup cannot wrap, and therefore that a field with a
+ * positive offset within an object can never be at address 0.
+ *
+ * Real objects which start at a high address and have a member at
+ * NULL do not exist, but such a pointer is the result of applying
+ * container_of() to NULL, which llist_for_each_entry does.
#define member_address_is_nonnull(ptr, member) \
((uintptr_t)(ptr) + offsetof(typeof(*(ptr)), member) != 0)
 \ /
  Last update: 2018-04-05 18:22    [W:0.068 / U:0.272 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site