xref: /openbmc/linux/arch/arm64/kvm/hyp/nvhe/list_debug.c (revision aebc7b0d)
14c68d6c0SKeir Fraser // SPDX-License-Identifier: GPL-2.0-only
24c68d6c0SKeir Fraser /*
34c68d6c0SKeir Fraser  * Copyright (C) 2022 - Google LLC
44c68d6c0SKeir Fraser  * Author: Keir Fraser <keirf@google.com>
54c68d6c0SKeir Fraser  */
64c68d6c0SKeir Fraser 
74c68d6c0SKeir Fraser #include <linux/list.h>
84c68d6c0SKeir Fraser #include <linux/bug.h>
94c68d6c0SKeir Fraser 
nvhe_check_data_corruption(bool v)104c68d6c0SKeir Fraser static inline __must_check bool nvhe_check_data_corruption(bool v)
114c68d6c0SKeir Fraser {
124c68d6c0SKeir Fraser 	return v;
134c68d6c0SKeir Fraser }
144c68d6c0SKeir Fraser 
154c68d6c0SKeir Fraser #define NVHE_CHECK_DATA_CORRUPTION(condition)				 \
164c68d6c0SKeir Fraser 	nvhe_check_data_corruption(({					 \
174c68d6c0SKeir Fraser 		bool corruption = unlikely(condition);			 \
184c68d6c0SKeir Fraser 		if (corruption) {					 \
194c68d6c0SKeir Fraser 			if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \
204c68d6c0SKeir Fraser 				BUG_ON(1);				 \
214c68d6c0SKeir Fraser 			} else						 \
224c68d6c0SKeir Fraser 				WARN_ON(1);				 \
234c68d6c0SKeir Fraser 		}							 \
244c68d6c0SKeir Fraser 		corruption;						 \
254c68d6c0SKeir Fraser 	}))
264c68d6c0SKeir Fraser 
274c68d6c0SKeir Fraser /* The predicates checked here are taken from lib/list_debug.c. */
284c68d6c0SKeir Fraser 
29*aebc7b0dSMarco Elver __list_valid_slowpath
__list_add_valid_or_report(struct list_head * new,struct list_head * prev,struct list_head * next)30b16c42c8SMarco Elver bool __list_add_valid_or_report(struct list_head *new, struct list_head *prev,
314c68d6c0SKeir Fraser 				struct list_head *next)
324c68d6c0SKeir Fraser {
334c68d6c0SKeir Fraser 	if (NVHE_CHECK_DATA_CORRUPTION(next->prev != prev) ||
344c68d6c0SKeir Fraser 	    NVHE_CHECK_DATA_CORRUPTION(prev->next != next) ||
354c68d6c0SKeir Fraser 	    NVHE_CHECK_DATA_CORRUPTION(new == prev || new == next))
364c68d6c0SKeir Fraser 		return false;
374c68d6c0SKeir Fraser 
384c68d6c0SKeir Fraser 	return true;
394c68d6c0SKeir Fraser }
404c68d6c0SKeir Fraser 
41*aebc7b0dSMarco Elver __list_valid_slowpath
__list_del_entry_valid_or_report(struct list_head * entry)42b16c42c8SMarco Elver bool __list_del_entry_valid_or_report(struct list_head *entry)
434c68d6c0SKeir Fraser {
444c68d6c0SKeir Fraser 	struct list_head *prev, *next;
454c68d6c0SKeir Fraser 
464c68d6c0SKeir Fraser 	prev = entry->prev;
474c68d6c0SKeir Fraser 	next = entry->next;
484c68d6c0SKeir Fraser 
494c68d6c0SKeir Fraser 	if (NVHE_CHECK_DATA_CORRUPTION(next == LIST_POISON1) ||
504c68d6c0SKeir Fraser 	    NVHE_CHECK_DATA_CORRUPTION(prev == LIST_POISON2) ||
514c68d6c0SKeir Fraser 	    NVHE_CHECK_DATA_CORRUPTION(prev->next != entry) ||
524c68d6c0SKeir Fraser 	    NVHE_CHECK_DATA_CORRUPTION(next->prev != entry))
534c68d6c0SKeir Fraser 		return false;
544c68d6c0SKeir Fraser 
554c68d6c0SKeir Fraser 	return true;
564c68d6c0SKeir Fraser }
57