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
10static 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
30bool __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
42bool __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