aboutsummaryrefslogtreecommitdiff
path: root/core/opal.c
diff options
context:
space:
mode:
authorVaibhav Jain <vaibhav@linux.ibm.com>2018-09-11 20:50:52 +0530
committerStewart Smith <stewart@linux.ibm.com>2018-09-17 21:39:02 -0500
commit5f728c53d42c664234b45a33218ba522a6e8f216 (patch)
treee33325981f67886413195a5be22962bb809688b0 /core/opal.c
parent9d5b516f287096df429d4637a4f2dc8b7f933721 (diff)
downloadskiboot-5f728c53d42c664234b45a33218ba522a6e8f216.zip
skiboot-5f728c53d42c664234b45a33218ba522a6e8f216.tar.gz
skiboot-5f728c53d42c664234b45a33218ba522a6e8f216.tar.bz2
opal: use for_each_safe to iterate over opal_syncers
Presently a fault will happen in opal_sync_host_reboot if a callback tries to remove itself from the opal_syncers list by calling opal_del_host_sync_notifier. This happens as iteration over opal_syncers is done using the list_for_each() which doesn't preserve list_node->next. So when the current opal_syncers callback removes itself from the list, current node contents are lost and current_node->next pointer is rendered invalid. To fix this we simply switch from list_for_each() to list_for_each_safe() which keeps the current_node->next cached hence even if the current node is freed, iteration over subsequent nodes can still continue. Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com> Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'core/opal.c')
-rw-r--r--core/opal.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/core/opal.c b/core/opal.c
index 7ffca9c..63a0851 100644
--- a/core/opal.c
+++ b/core/opal.c
@@ -692,10 +692,10 @@ void opal_del_host_sync_notifier(bool (*notify)(void *data))
*/
static int64_t opal_sync_host_reboot(void)
{
- struct opal_sync_entry *ent;
+ struct opal_sync_entry *ent, *nxt;
bool ret = true;
- list_for_each(&opal_syncers, ent, link)
+ list_for_each_safe(&opal_syncers, ent, nxt, link)
ret &= ent->notify(ent->data);
if (ret)