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

linux.c (2052B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <stdlib.h>
      3#include <string.h>
      4#include <malloc.h>
      5#include <pthread.h>
      6#include <unistd.h>
      7#include <assert.h>
      8
      9#include <linux/gfp.h>
     10#include <linux/poison.h>
     11#include <linux/slab.h>
     12#include <linux/radix-tree.h>
     13#include <urcu/uatomic.h>
     14
     15int nr_allocated;
     16int preempt_count;
     17int test_verbose;
     18
     19struct kmem_cache {
     20	pthread_mutex_t lock;
     21	unsigned int size;
     22	unsigned int align;
     23	int nr_objs;
     24	void *objs;
     25	void (*ctor)(void *);
     26};
     27
     28void *kmem_cache_alloc_lru(struct kmem_cache *cachep, struct list_lru *lru,
     29		int gfp)
     30{
     31	void *p;
     32
     33	if (!(gfp & __GFP_DIRECT_RECLAIM))
     34		return NULL;
     35
     36	pthread_mutex_lock(&cachep->lock);
     37	if (cachep->nr_objs) {
     38		struct radix_tree_node *node = cachep->objs;
     39		cachep->nr_objs--;
     40		cachep->objs = node->parent;
     41		pthread_mutex_unlock(&cachep->lock);
     42		node->parent = NULL;
     43		p = node;
     44	} else {
     45		pthread_mutex_unlock(&cachep->lock);
     46		if (cachep->align)
     47			posix_memalign(&p, cachep->align, cachep->size);
     48		else
     49			p = malloc(cachep->size);
     50		if (cachep->ctor)
     51			cachep->ctor(p);
     52		else if (gfp & __GFP_ZERO)
     53			memset(p, 0, cachep->size);
     54	}
     55
     56	uatomic_inc(&nr_allocated);
     57	if (kmalloc_verbose)
     58		printf("Allocating %p from slab\n", p);
     59	return p;
     60}
     61
     62void kmem_cache_free(struct kmem_cache *cachep, void *objp)
     63{
     64	assert(objp);
     65	uatomic_dec(&nr_allocated);
     66	if (kmalloc_verbose)
     67		printf("Freeing %p to slab\n", objp);
     68	pthread_mutex_lock(&cachep->lock);
     69	if (cachep->nr_objs > 10 || cachep->align) {
     70		memset(objp, POISON_FREE, cachep->size);
     71		free(objp);
     72	} else {
     73		struct radix_tree_node *node = objp;
     74		cachep->nr_objs++;
     75		node->parent = cachep->objs;
     76		cachep->objs = node;
     77	}
     78	pthread_mutex_unlock(&cachep->lock);
     79}
     80
     81struct kmem_cache *
     82kmem_cache_create(const char *name, unsigned int size, unsigned int align,
     83		unsigned int flags, void (*ctor)(void *))
     84{
     85	struct kmem_cache *ret = malloc(sizeof(*ret));
     86
     87	pthread_mutex_init(&ret->lock, NULL);
     88	ret->size = size;
     89	ret->align = align;
     90	ret->nr_objs = 0;
     91	ret->objs = NULL;
     92	ret->ctor = ctor;
     93	return ret;
     94}