cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

test_static_keys.c (5731B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Kernel module for testing static keys.
      4 *
      5 * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
      6 *
      7 * Authors:
      8 *      Jason Baron       <jbaron@akamai.com>
      9 */
     10
     11#include <linux/module.h>
     12#include <linux/jump_label.h>
     13
     14/* old keys */
     15struct static_key old_true_key	= STATIC_KEY_INIT_TRUE;
     16struct static_key old_false_key	= STATIC_KEY_INIT_FALSE;
     17
     18/* new api */
     19DEFINE_STATIC_KEY_TRUE(true_key);
     20DEFINE_STATIC_KEY_FALSE(false_key);
     21
     22/* external */
     23extern struct static_key base_old_true_key;
     24extern struct static_key base_inv_old_true_key;
     25extern struct static_key base_old_false_key;
     26extern struct static_key base_inv_old_false_key;
     27
     28/* new api */
     29extern struct static_key_true base_true_key;
     30extern struct static_key_true base_inv_true_key;
     31extern struct static_key_false base_false_key;
     32extern struct static_key_false base_inv_false_key;
     33
     34
     35struct test_key {
     36	bool			init_state;
     37	struct static_key	*key;
     38	bool			(*test_key)(void);
     39};
     40
     41#define test_key_func(key, branch)	\
     42static bool key ## _ ## branch(void)	\
     43{					\
     44	return branch(&key);		\
     45}
     46
     47static void invert_key(struct static_key *key)
     48{
     49	if (static_key_enabled(key))
     50		static_key_disable(key);
     51	else
     52		static_key_enable(key);
     53}
     54
     55static void invert_keys(struct test_key *keys, int size)
     56{
     57	struct static_key *previous = NULL;
     58	int i;
     59
     60	for (i = 0; i < size; i++) {
     61		if (previous != keys[i].key) {
     62			invert_key(keys[i].key);
     63			previous = keys[i].key;
     64		}
     65	}
     66}
     67
     68static int verify_keys(struct test_key *keys, int size, bool invert)
     69{
     70	int i;
     71	bool ret, init;
     72
     73	for (i = 0; i < size; i++) {
     74		ret = static_key_enabled(keys[i].key);
     75		init = keys[i].init_state;
     76		if (ret != (invert ? !init : init))
     77			return -EINVAL;
     78		ret = keys[i].test_key();
     79		if (static_key_enabled(keys[i].key)) {
     80			if (!ret)
     81				return -EINVAL;
     82		} else {
     83			if (ret)
     84				return -EINVAL;
     85		}
     86	}
     87	return 0;
     88}
     89
     90test_key_func(old_true_key, static_key_true)
     91test_key_func(old_false_key, static_key_false)
     92test_key_func(true_key, static_branch_likely)
     93test_key_func(true_key, static_branch_unlikely)
     94test_key_func(false_key, static_branch_likely)
     95test_key_func(false_key, static_branch_unlikely)
     96test_key_func(base_old_true_key, static_key_true)
     97test_key_func(base_inv_old_true_key, static_key_true)
     98test_key_func(base_old_false_key, static_key_false)
     99test_key_func(base_inv_old_false_key, static_key_false)
    100test_key_func(base_true_key, static_branch_likely)
    101test_key_func(base_true_key, static_branch_unlikely)
    102test_key_func(base_inv_true_key, static_branch_likely)
    103test_key_func(base_inv_true_key, static_branch_unlikely)
    104test_key_func(base_false_key, static_branch_likely)
    105test_key_func(base_false_key, static_branch_unlikely)
    106test_key_func(base_inv_false_key, static_branch_likely)
    107test_key_func(base_inv_false_key, static_branch_unlikely)
    108
    109static int __init test_static_key_init(void)
    110{
    111	int ret;
    112	int size;
    113
    114	struct test_key static_key_tests[] = {
    115		/* internal keys - old keys */
    116		{
    117			.init_state	= true,
    118			.key		= &old_true_key,
    119			.test_key	= &old_true_key_static_key_true,
    120		},
    121		{
    122			.init_state	= false,
    123			.key		= &old_false_key,
    124			.test_key	= &old_false_key_static_key_false,
    125		},
    126		/* internal keys - new keys */
    127		{
    128			.init_state	= true,
    129			.key		= &true_key.key,
    130			.test_key	= &true_key_static_branch_likely,
    131		},
    132		{
    133			.init_state	= true,
    134			.key		= &true_key.key,
    135			.test_key	= &true_key_static_branch_unlikely,
    136		},
    137		{
    138			.init_state	= false,
    139			.key		= &false_key.key,
    140			.test_key	= &false_key_static_branch_likely,
    141		},
    142		{
    143			.init_state	= false,
    144			.key		= &false_key.key,
    145			.test_key	= &false_key_static_branch_unlikely,
    146		},
    147		/* external keys - old keys */
    148		{
    149			.init_state	= true,
    150			.key		= &base_old_true_key,
    151			.test_key	= &base_old_true_key_static_key_true,
    152		},
    153		{
    154			.init_state	= false,
    155			.key		= &base_inv_old_true_key,
    156			.test_key	= &base_inv_old_true_key_static_key_true,
    157		},
    158		{
    159			.init_state	= false,
    160			.key		= &base_old_false_key,
    161			.test_key	= &base_old_false_key_static_key_false,
    162		},
    163		{
    164			.init_state	= true,
    165			.key		= &base_inv_old_false_key,
    166			.test_key	= &base_inv_old_false_key_static_key_false,
    167		},
    168		/* external keys - new keys */
    169		{
    170			.init_state	= true,
    171			.key		= &base_true_key.key,
    172			.test_key	= &base_true_key_static_branch_likely,
    173		},
    174		{
    175			.init_state	= true,
    176			.key		= &base_true_key.key,
    177			.test_key	= &base_true_key_static_branch_unlikely,
    178		},
    179		{
    180			.init_state	= false,
    181			.key		= &base_inv_true_key.key,
    182			.test_key	= &base_inv_true_key_static_branch_likely,
    183		},
    184		{
    185			.init_state	= false,
    186			.key		= &base_inv_true_key.key,
    187			.test_key	= &base_inv_true_key_static_branch_unlikely,
    188		},
    189		{
    190			.init_state	= false,
    191			.key		= &base_false_key.key,
    192			.test_key	= &base_false_key_static_branch_likely,
    193		},
    194		{
    195			.init_state	= false,
    196			.key		= &base_false_key.key,
    197			.test_key	= &base_false_key_static_branch_unlikely,
    198		},
    199		{
    200			.init_state	= true,
    201			.key		= &base_inv_false_key.key,
    202			.test_key	= &base_inv_false_key_static_branch_likely,
    203		},
    204		{
    205			.init_state	= true,
    206			.key		= &base_inv_false_key.key,
    207			.test_key	= &base_inv_false_key_static_branch_unlikely,
    208		},
    209	};
    210
    211	size = ARRAY_SIZE(static_key_tests);
    212
    213	ret = verify_keys(static_key_tests, size, false);
    214	if (ret)
    215		goto out;
    216
    217	invert_keys(static_key_tests, size);
    218	ret = verify_keys(static_key_tests, size, true);
    219	if (ret)
    220		goto out;
    221
    222	invert_keys(static_key_tests, size);
    223	ret = verify_keys(static_key_tests, size, false);
    224	if (ret)
    225		goto out;
    226	return 0;
    227out:
    228	return ret;
    229}
    230
    231static void __exit test_static_key_exit(void)
    232{
    233}
    234
    235module_init(test_static_key_init);
    236module_exit(test_static_key_exit);
    237
    238MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
    239MODULE_LICENSE("GPL");