// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2022 - Google LLC * Author: Keir Fraser */ #include #include static inline __must_check bool nvhe_check_data_corruption(bool v) { return v; } #define NVHE_CHECK_DATA_CORRUPTION(condition) \ nvhe_check_data_corruption(({ \ bool corruption = unlikely(condition); \ if (corruption) { \ if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \ BUG_ON(1); \ } else \ WARN_ON(1); \ } \ corruption; \ })) /* The predicates checked here are taken from lib/list_debug.c. */ __list_valid_slowpath bool __list_add_valid_or_report(struct list_head *new, struct list_head *prev, struct list_head *next) { if (NVHE_CHECK_DATA_CORRUPTION(next->prev != prev) || NVHE_CHECK_DATA_CORRUPTION(prev->next != next) || NVHE_CHECK_DATA_CORRUPTION(new == prev || new == next)) return false; return true; } __list_valid_slowpath bool __list_del_entry_valid_or_report(struct list_head *entry) { struct list_head *prev, *next; prev = entry->prev; next = entry->next; if (NVHE_CHECK_DATA_CORRUPTION(next == LIST_POISON1) || NVHE_CHECK_DATA_CORRUPTION(prev == LIST_POISON2) || NVHE_CHECK_DATA_CORRUPTION(prev->next != entry) || NVHE_CHECK_DATA_CORRUPTION(next->prev != entry)) return false; return true; }