diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2022-07-27 06:57:07 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2022-07-27 06:57:07 +0000 |
commit | dd5a9892bb6377c2621287d46d6744fe2f5676c3 (patch) | |
tree | 405fb11eed78cc11ffc28aa749bd9c0b6618a58d | |
parent | 61c49133f941a91cc4f419840963e490ce73297a (diff) |
fix llist_for_each_entry*
enabling more of __notify_execute_cb() and running the intel xorg driver
on broadwell would fault in __notify_execute_cb() on
movq 0x38(%rsi),%r12
offsetof(struct execute_cb, work.node.llist) 0x38
llist_entry(NULL must not return NULL, it needs to wrap around
and return NULL minus the offset
the iterators stop when the offset added back to the result of
llist_entry() is NULL
they test that the first node is not NULL or that the next pointer
stored in a previous iteration of the loop is not NULL
-rw-r--r-- | sys/dev/pci/drm/include/linux/llist.h | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/sys/dev/pci/drm/include/linux/llist.h b/sys/dev/pci/drm/include/linux/llist.h index 8c0b37da123..2e518eb5941 100644 --- a/sys/dev/pci/drm/include/linux/llist.h +++ b/sys/dev/pci/drm/include/linux/llist.h @@ -13,8 +13,7 @@ struct llist_head { struct llist_node *first; }; -#define llist_entry(ptr, type, member) \ - ((ptr) ? container_of(ptr, type, member) : NULL) +#define llist_entry(ptr, type, member) container_of(ptr, type, member) static inline struct llist_node * llist_del_all(struct llist_head *head) @@ -82,13 +81,13 @@ llist_empty(struct llist_head *head) #define llist_for_each_entry_safe(pos, n, node, member) \ for (pos = llist_entry((node), __typeof(*pos), member); \ - pos != NULL && \ + ((char *)(pos) + offsetof(typeof(*(pos)), member)) != NULL && \ (n = llist_entry(pos->member.next, __typeof(*pos), member), pos); \ pos = n) #define llist_for_each_entry(pos, node, member) \ for ((pos) = llist_entry((node), __typeof(*(pos)), member); \ - (pos) != NULL; \ + ((char *)(pos) + offsetof(typeof(*(pos)), member)) != NULL; \ (pos) = llist_entry((pos)->member.next, __typeof(*(pos)), member)) #endif |