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

selftest_ring.c (2401B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright © 2020 Intel Corporation
      4 */
      5
      6static struct intel_ring *mock_ring(unsigned long sz)
      7{
      8	struct intel_ring *ring;
      9
     10	ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
     11	if (!ring)
     12		return NULL;
     13
     14	kref_init(&ring->ref);
     15	ring->size = sz;
     16	ring->wrap = BITS_PER_TYPE(ring->size) - ilog2(sz);
     17	ring->effective_size = sz;
     18	ring->vaddr = (void *)(ring + 1);
     19	atomic_set(&ring->pin_count, 1);
     20
     21	intel_ring_update_space(ring);
     22
     23	return ring;
     24}
     25
     26static void mock_ring_free(struct intel_ring *ring)
     27{
     28	kfree(ring);
     29}
     30
     31static int check_ring_direction(struct intel_ring *ring,
     32				u32 next, u32 prev,
     33				int expected)
     34{
     35	int result;
     36
     37	result = intel_ring_direction(ring, next, prev);
     38	if (result < 0)
     39		result = -1;
     40	else if (result > 0)
     41		result = 1;
     42
     43	if (result != expected) {
     44		pr_err("intel_ring_direction(%u, %u):%d != %d\n",
     45		       next, prev, result, expected);
     46		return -EINVAL;
     47	}
     48
     49	return 0;
     50}
     51
     52static int check_ring_step(struct intel_ring *ring, u32 x, u32 step)
     53{
     54	u32 prev = x, next = intel_ring_wrap(ring, x + step);
     55	int err = 0;
     56
     57	err |= check_ring_direction(ring, next, next,  0);
     58	err |= check_ring_direction(ring, prev, prev,  0);
     59	err |= check_ring_direction(ring, next, prev,  1);
     60	err |= check_ring_direction(ring, prev, next, -1);
     61
     62	return err;
     63}
     64
     65static int check_ring_offset(struct intel_ring *ring, u32 x, u32 step)
     66{
     67	int err = 0;
     68
     69	err |= check_ring_step(ring, x, step);
     70	err |= check_ring_step(ring, intel_ring_wrap(ring, x + 1), step);
     71	err |= check_ring_step(ring, intel_ring_wrap(ring, x - 1), step);
     72
     73	return err;
     74}
     75
     76static int igt_ring_direction(void *dummy)
     77{
     78	struct intel_ring *ring;
     79	unsigned int half = 2048;
     80	int step, err = 0;
     81
     82	ring = mock_ring(2 * half);
     83	if (!ring)
     84		return -ENOMEM;
     85
     86	GEM_BUG_ON(ring->size != 2 * half);
     87
     88	/* Precision of wrap detection is limited to ring->size / 2 */
     89	for (step = 1; step < half; step <<= 1) {
     90		err |= check_ring_offset(ring, 0, step);
     91		err |= check_ring_offset(ring, half, step);
     92	}
     93	err |= check_ring_step(ring, 0, half - 64);
     94
     95	/* And check unwrapped handling for good measure */
     96	err |= check_ring_offset(ring, 0, 2 * half + 64);
     97	err |= check_ring_offset(ring, 3 * half, 1);
     98
     99	mock_ring_free(ring);
    100	return err;
    101}
    102
    103int intel_ring_mock_selftests(void)
    104{
    105	static const struct i915_subtest tests[] = {
    106		SUBTEST(igt_ring_direction),
    107	};
    108
    109	return i915_subtests(tests, NULL);
    110}