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

vector.c (6882B)


      1/*
      2 * Copyright 2012-15 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include <linux/slab.h>
     27
     28#include "dm_services.h"
     29#include "include/vector.h"
     30
     31bool dal_vector_construct(
     32	struct vector *vector,
     33	struct dc_context *ctx,
     34	uint32_t capacity,
     35	uint32_t struct_size)
     36{
     37	vector->container = NULL;
     38
     39	if (!struct_size || !capacity) {
     40		/* Container must be non-zero size*/
     41		BREAK_TO_DEBUGGER();
     42		return false;
     43	}
     44
     45	vector->container = kcalloc(capacity, struct_size, GFP_KERNEL);
     46	if (vector->container == NULL)
     47		return false;
     48	vector->capacity = capacity;
     49	vector->struct_size = struct_size;
     50	vector->count = 0;
     51	vector->ctx = ctx;
     52	return true;
     53}
     54
     55static bool dal_vector_presized_costruct(
     56	struct vector *vector,
     57	struct dc_context *ctx,
     58	uint32_t count,
     59	void *initial_value,
     60	uint32_t struct_size)
     61{
     62	uint32_t i;
     63
     64	vector->container = NULL;
     65
     66	if (!struct_size || !count) {
     67		/* Container must be non-zero size*/
     68		BREAK_TO_DEBUGGER();
     69		return false;
     70	}
     71
     72	vector->container = kcalloc(count, struct_size, GFP_KERNEL);
     73
     74	if (vector->container == NULL)
     75		return false;
     76
     77	/* If caller didn't supply initial value then the default
     78	 * of all zeros is expected, which is exactly what dal_alloc()
     79	 * initialises the memory to. */
     80	if (NULL != initial_value) {
     81		for (i = 0; i < count; ++i)
     82			memmove(
     83				vector->container + i * struct_size,
     84				initial_value,
     85				struct_size);
     86	}
     87
     88	vector->capacity = count;
     89	vector->struct_size = struct_size;
     90	vector->count = count;
     91	return true;
     92}
     93
     94struct vector *dal_vector_presized_create(
     95	struct dc_context *ctx,
     96	uint32_t size,
     97	void *initial_value,
     98	uint32_t struct_size)
     99{
    100	struct vector *vector = kzalloc(sizeof(struct vector), GFP_KERNEL);
    101
    102	if (vector == NULL)
    103		return NULL;
    104
    105	if (dal_vector_presized_costruct(
    106		vector, ctx, size, initial_value, struct_size))
    107		return vector;
    108
    109	BREAK_TO_DEBUGGER();
    110	kfree(vector);
    111	return NULL;
    112}
    113
    114struct vector *dal_vector_create(
    115	struct dc_context *ctx,
    116	uint32_t capacity,
    117	uint32_t struct_size)
    118{
    119	struct vector *vector = kzalloc(sizeof(struct vector), GFP_KERNEL);
    120
    121	if (vector == NULL)
    122		return NULL;
    123
    124	if (dal_vector_construct(vector, ctx, capacity, struct_size))
    125		return vector;
    126
    127	BREAK_TO_DEBUGGER();
    128	kfree(vector);
    129	return NULL;
    130}
    131
    132void dal_vector_destruct(
    133	struct vector *vector)
    134{
    135	kfree(vector->container);
    136	vector->count = 0;
    137	vector->capacity = 0;
    138}
    139
    140void dal_vector_destroy(
    141	struct vector **vector)
    142{
    143	if (vector == NULL || *vector == NULL)
    144		return;
    145	dal_vector_destruct(*vector);
    146	kfree(*vector);
    147	*vector = NULL;
    148}
    149
    150uint32_t dal_vector_get_count(
    151	const struct vector *vector)
    152{
    153	return vector->count;
    154}
    155
    156void *dal_vector_at_index(
    157	const struct vector *vector,
    158	uint32_t index)
    159{
    160	if (vector->container == NULL || index >= vector->count)
    161		return NULL;
    162	return vector->container + (index * vector->struct_size);
    163}
    164
    165bool dal_vector_remove_at_index(
    166	struct vector *vector,
    167	uint32_t index)
    168{
    169	if (index >= vector->count)
    170		return false;
    171
    172	if (index != vector->count - 1)
    173		memmove(
    174			vector->container + (index * vector->struct_size),
    175			vector->container + ((index + 1) * vector->struct_size),
    176			(vector->count - index - 1) * vector->struct_size);
    177	vector->count -= 1;
    178
    179	return true;
    180}
    181
    182void dal_vector_set_at_index(
    183	const struct vector *vector,
    184	const void *what,
    185	uint32_t index)
    186{
    187	void *where = dal_vector_at_index(vector, index);
    188
    189	if (!where) {
    190		BREAK_TO_DEBUGGER();
    191		return;
    192	}
    193	memmove(
    194		where,
    195		what,
    196		vector->struct_size);
    197}
    198
    199static inline uint32_t calc_increased_capacity(
    200	uint32_t old_capacity)
    201{
    202	return old_capacity * 2;
    203}
    204
    205bool dal_vector_insert_at(
    206	struct vector *vector,
    207	const void *what,
    208	uint32_t position)
    209{
    210	uint8_t *insert_address;
    211
    212	if (vector->count == vector->capacity) {
    213		if (!dal_vector_reserve(
    214			vector,
    215			calc_increased_capacity(vector->capacity)))
    216			return false;
    217	}
    218
    219	insert_address = vector->container + (vector->struct_size * position);
    220
    221	if (vector->count && position < vector->count)
    222		memmove(
    223			insert_address + vector->struct_size,
    224			insert_address,
    225			vector->struct_size * (vector->count - position));
    226
    227	memmove(
    228		insert_address,
    229		what,
    230		vector->struct_size);
    231
    232	vector->count++;
    233
    234	return true;
    235}
    236
    237bool dal_vector_append(
    238	struct vector *vector,
    239	const void *item)
    240{
    241	return dal_vector_insert_at(vector, item, vector->count);
    242}
    243
    244struct vector *dal_vector_clone(
    245	const struct vector *vector)
    246{
    247	struct vector *vec_cloned;
    248	uint32_t count;
    249
    250	/* create new vector */
    251	count = dal_vector_get_count(vector);
    252
    253	if (count == 0)
    254		/* when count is 0 we still want to create clone of the vector
    255		 */
    256		vec_cloned = dal_vector_create(
    257			vector->ctx,
    258			vector->capacity,
    259			vector->struct_size);
    260	else
    261		/* Call "presized create" version, independently of how the
    262		 * original vector was created.
    263		 * The owner of original vector must know how to treat the new
    264		 * vector - as "presized" or as "regular".
    265		 * But from vector point of view it doesn't matter. */
    266		vec_cloned = dal_vector_presized_create(vector->ctx, count,
    267			NULL,/* no initial value */
    268			vector->struct_size);
    269
    270	if (NULL == vec_cloned) {
    271		BREAK_TO_DEBUGGER();
    272		return NULL;
    273	}
    274
    275	/* copy vector's data */
    276	memmove(vec_cloned->container, vector->container,
    277			vec_cloned->struct_size * vec_cloned->capacity);
    278
    279	return vec_cloned;
    280}
    281
    282uint32_t dal_vector_capacity(const struct vector *vector)
    283{
    284	return vector->capacity;
    285}
    286
    287bool dal_vector_reserve(struct vector *vector, uint32_t capacity)
    288{
    289	void *new_container;
    290
    291	if (capacity <= vector->capacity)
    292		return true;
    293
    294	new_container = krealloc(vector->container,
    295				 capacity * vector->struct_size, GFP_KERNEL);
    296
    297	if (new_container) {
    298		vector->container = new_container;
    299		vector->capacity = capacity;
    300		return true;
    301	}
    302
    303	return false;
    304}
    305
    306void dal_vector_clear(struct vector *vector)
    307{
    308	vector->count = 0;
    309}