xref: /linux/arch/arm64/kvm/hyp/nvhe/list_debug.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2022 - Google LLC
4  * Author: Keir Fraser <keirf@google.com>
5  */
6 
7 #include <linux/list.h>
8 #include <linux/bug.h>
9 
10 static inline __must_check bool nvhe_check_data_corruption(bool v)
11 {
12 	return v;
13 }
14 
15 #define NVHE_CHECK_DATA_CORRUPTION(condition)				 \
16 	nvhe_check_data_corruption(({					 \
17 		bool corruption = unlikely(condition);			 \
18 		if (corruption) {					 \
19 			if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \
20 				BUG_ON(1);				 \
21 			} else						 \
22 				WARN_ON(1);				 \
23 		}							 \
24 		corruption;						 \
25 	}))
26 
27 /* The predicates checked here are taken from lib/list_debug.c. */
28 
29 __list_valid_slowpath
30 bool __list_add_valid_or_report(struct list_head *new, struct list_head *prev,
31 				struct list_head *next)
32 {
33 	if (NVHE_CHECK_DATA_CORRUPTION(next->prev != prev) ||
34 	    NVHE_CHECK_DATA_CORRUPTION(prev->next != next) ||
35 	    NVHE_CHECK_DATA_CORRUPTION(new == prev || new == next))
36 		return false;
37 
38 	return true;
39 }
40 
41 __list_valid_slowpath
42 bool __list_del_entry_valid_or_report(struct list_head *entry)
43 {
44 	struct list_head *prev, *next;
45 
46 	prev = entry->prev;
47 	next = entry->next;
48 
49 	if (NVHE_CHECK_DATA_CORRUPTION(next == LIST_POISON1) ||
50 	    NVHE_CHECK_DATA_CORRUPTION(prev == LIST_POISON2) ||
51 	    NVHE_CHECK_DATA_CORRUPTION(prev->next != entry) ||
52 	    NVHE_CHECK_DATA_CORRUPTION(next->prev != entry))
53 		return false;
54 
55 	return true;
56 }
57