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

st-dma-fence-unwrap.c (4526B)


      1// SPDX-License-Identifier: MIT
      2
      3/*
      4 * Copyright (C) 2022 Advanced Micro Devices, Inc.
      5 */
      6
      7#include <linux/dma-fence-unwrap.h>
      8#if 0
      9#include <linux/kernel.h>
     10#include <linux/kthread.h>
     11#include <linux/mm.h>
     12#include <linux/sched/signal.h>
     13#include <linux/slab.h>
     14#include <linux/spinlock.h>
     15#include <linux/random.h>
     16#endif
     17
     18#include "selftest.h"
     19
     20#define CHAIN_SZ (4 << 10)
     21
     22static inline struct mock_fence {
     23	struct dma_fence base;
     24	spinlock_t lock;
     25} *to_mock_fence(struct dma_fence *f) {
     26	return container_of(f, struct mock_fence, base);
     27}
     28
     29static const char *mock_name(struct dma_fence *f)
     30{
     31	return "mock";
     32}
     33
     34static const struct dma_fence_ops mock_ops = {
     35	.get_driver_name = mock_name,
     36	.get_timeline_name = mock_name,
     37};
     38
     39static struct dma_fence *mock_fence(void)
     40{
     41	struct mock_fence *f;
     42
     43	f = kmalloc(sizeof(*f), GFP_KERNEL);
     44	if (!f)
     45		return NULL;
     46
     47	spin_lock_init(&f->lock);
     48	dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0);
     49
     50	return &f->base;
     51}
     52
     53static struct dma_fence *mock_array(unsigned int num_fences, ...)
     54{
     55	struct dma_fence_array *array;
     56	struct dma_fence **fences;
     57	va_list valist;
     58	int i;
     59
     60	fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
     61	if (!fences)
     62		return NULL;
     63
     64	va_start(valist, num_fences);
     65	for (i = 0; i < num_fences; ++i)
     66		fences[i] = va_arg(valist, typeof(*fences));
     67	va_end(valist);
     68
     69	array = dma_fence_array_create(num_fences, fences,
     70				       dma_fence_context_alloc(1),
     71				       1, false);
     72	if (!array)
     73		goto cleanup;
     74	return &array->base;
     75
     76cleanup:
     77	for (i = 0; i < num_fences; ++i)
     78		dma_fence_put(fences[i]);
     79	kfree(fences);
     80	return NULL;
     81}
     82
     83static struct dma_fence *mock_chain(struct dma_fence *prev,
     84				    struct dma_fence *fence)
     85{
     86	struct dma_fence_chain *f;
     87
     88	f = dma_fence_chain_alloc();
     89	if (!f) {
     90		dma_fence_put(prev);
     91		dma_fence_put(fence);
     92		return NULL;
     93	}
     94
     95	dma_fence_chain_init(f, prev, fence, 1);
     96	return &f->base;
     97}
     98
     99static int sanitycheck(void *arg)
    100{
    101	struct dma_fence *f, *chain, *array;
    102	int err = 0;
    103
    104	f = mock_fence();
    105	if (!f)
    106		return -ENOMEM;
    107
    108	array = mock_array(1, f);
    109	if (!array)
    110		return -ENOMEM;
    111
    112	chain = mock_chain(NULL, array);
    113	if (!chain)
    114		return -ENOMEM;
    115
    116	dma_fence_signal(f);
    117	dma_fence_put(chain);
    118	return err;
    119}
    120
    121static int unwrap_array(void *arg)
    122{
    123	struct dma_fence *fence, *f1, *f2, *array;
    124	struct dma_fence_unwrap iter;
    125	int err = 0;
    126
    127	f1 = mock_fence();
    128	if (!f1)
    129		return -ENOMEM;
    130
    131	f2 = mock_fence();
    132	if (!f2) {
    133		dma_fence_put(f1);
    134		return -ENOMEM;
    135	}
    136
    137	array = mock_array(2, f1, f2);
    138	if (!array)
    139		return -ENOMEM;
    140
    141	dma_fence_unwrap_for_each(fence, &iter, array) {
    142		if (fence == f1) {
    143			f1 = NULL;
    144		} else if (fence == f2) {
    145			f2 = NULL;
    146		} else {
    147			pr_err("Unexpected fence!\n");
    148			err = -EINVAL;
    149		}
    150	}
    151
    152	if (f1 || f2) {
    153		pr_err("Not all fences seen!\n");
    154		err = -EINVAL;
    155	}
    156
    157	dma_fence_signal(f1);
    158	dma_fence_signal(f2);
    159	dma_fence_put(array);
    160	return 0;
    161}
    162
    163static int unwrap_chain(void *arg)
    164{
    165	struct dma_fence *fence, *f1, *f2, *chain;
    166	struct dma_fence_unwrap iter;
    167	int err = 0;
    168
    169	f1 = mock_fence();
    170	if (!f1)
    171		return -ENOMEM;
    172
    173	f2 = mock_fence();
    174	if (!f2) {
    175		dma_fence_put(f1);
    176		return -ENOMEM;
    177	}
    178
    179	chain = mock_chain(f1, f2);
    180	if (!chain)
    181		return -ENOMEM;
    182
    183	dma_fence_unwrap_for_each(fence, &iter, chain) {
    184		if (fence == f1) {
    185			f1 = NULL;
    186		} else if (fence == f2) {
    187			f2 = NULL;
    188		} else {
    189			pr_err("Unexpected fence!\n");
    190			err = -EINVAL;
    191		}
    192	}
    193
    194	if (f1 || f2) {
    195		pr_err("Not all fences seen!\n");
    196		err = -EINVAL;
    197	}
    198
    199	dma_fence_signal(f1);
    200	dma_fence_signal(f2);
    201	dma_fence_put(chain);
    202	return 0;
    203}
    204
    205static int unwrap_chain_array(void *arg)
    206{
    207	struct dma_fence *fence, *f1, *f2, *array, *chain;
    208	struct dma_fence_unwrap iter;
    209	int err = 0;
    210
    211	f1 = mock_fence();
    212	if (!f1)
    213		return -ENOMEM;
    214
    215	f2 = mock_fence();
    216	if (!f2) {
    217		dma_fence_put(f1);
    218		return -ENOMEM;
    219	}
    220
    221	array = mock_array(2, f1, f2);
    222	if (!array)
    223		return -ENOMEM;
    224
    225	chain = mock_chain(NULL, array);
    226	if (!chain)
    227		return -ENOMEM;
    228
    229	dma_fence_unwrap_for_each(fence, &iter, chain) {
    230		if (fence == f1) {
    231			f1 = NULL;
    232		} else if (fence == f2) {
    233			f2 = NULL;
    234		} else {
    235			pr_err("Unexpected fence!\n");
    236			err = -EINVAL;
    237		}
    238	}
    239
    240	if (f1 || f2) {
    241		pr_err("Not all fences seen!\n");
    242		err = -EINVAL;
    243	}
    244
    245	dma_fence_signal(f1);
    246	dma_fence_signal(f2);
    247	dma_fence_put(chain);
    248	return 0;
    249}
    250
    251int dma_fence_unwrap(void)
    252{
    253	static const struct subtest tests[] = {
    254		SUBTEST(sanitycheck),
    255		SUBTEST(unwrap_array),
    256		SUBTEST(unwrap_chain),
    257		SUBTEST(unwrap_chain_array),
    258	};
    259
    260	return subtests(tests, NULL);
    261}