From 75a9d582dab09c68dd5c13290c15f09bd3f36393 Mon Sep 17 00:00:00 2001 From: jsg Date: Wed, 27 Jul 2022 06:57:06 +0000 Subject: [PATCH] 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 --- sys/dev/pci/drm/include/linux/llist.h | 7 +++---- 1 file 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 -- 2.20.1