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

iteration_check_2.c (1670B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * iteration_check_2.c: Check that deleting a tagged entry doesn't cause
      4 * an RCU walker to finish early.
      5 * Copyright (c) 2020 Oracle
      6 * Author: Matthew Wilcox <willy@infradead.org>
      7 */
      8#include <pthread.h>
      9#include "test.h"
     10
     11static volatile bool test_complete;
     12
     13static void *iterator(void *arg)
     14{
     15	XA_STATE(xas, arg, 0);
     16	void *entry;
     17
     18	rcu_register_thread();
     19
     20	while (!test_complete) {
     21		xas_set(&xas, 0);
     22		rcu_read_lock();
     23		xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0)
     24			;
     25		rcu_read_unlock();
     26		assert(xas.xa_index >= 100);
     27	}
     28
     29	rcu_unregister_thread();
     30	return NULL;
     31}
     32
     33static void *throbber(void *arg)
     34{
     35	struct xarray *xa = arg;
     36
     37	rcu_register_thread();
     38
     39	while (!test_complete) {
     40		int i;
     41
     42		for (i = 0; i < 100; i++) {
     43			xa_store(xa, i, xa_mk_value(i), GFP_KERNEL);
     44			xa_set_mark(xa, i, XA_MARK_0);
     45		}
     46		for (i = 0; i < 100; i++)
     47			xa_erase(xa, i);
     48	}
     49
     50	rcu_unregister_thread();
     51	return NULL;
     52}
     53
     54void iteration_test2(unsigned test_duration)
     55{
     56	pthread_t threads[2];
     57	DEFINE_XARRAY(array);
     58	int i;
     59
     60	printv(1, "Running iteration test 2 for %d seconds\n", test_duration);
     61
     62	test_complete = false;
     63
     64	xa_store(&array, 100, xa_mk_value(100), GFP_KERNEL);
     65	xa_set_mark(&array, 100, XA_MARK_0);
     66
     67	if (pthread_create(&threads[0], NULL, iterator, &array)) {
     68		perror("create iterator thread");
     69		exit(1);
     70	}
     71	if (pthread_create(&threads[1], NULL, throbber, &array)) {
     72		perror("create throbber thread");
     73		exit(1);
     74	}
     75
     76	sleep(test_duration);
     77	test_complete = true;
     78
     79	for (i = 0; i < 2; i++) {
     80		if (pthread_join(threads[i], NULL)) {
     81			perror("pthread_join");
     82			exit(1);
     83		}
     84	}
     85
     86	xa_destroy(&array);
     87}