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

mock_dmabuf.c (2723B)


      1/*
      2 * SPDX-License-Identifier: MIT
      3 *
      4 * Copyright © 2016 Intel Corporation
      5 */
      6
      7#include "mock_dmabuf.h"
      8
      9static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
     10					 enum dma_data_direction dir)
     11{
     12	struct mock_dmabuf *mock = to_mock(attachment->dmabuf);
     13	struct sg_table *st;
     14	struct scatterlist *sg;
     15	int i, err;
     16
     17	st = kmalloc(sizeof(*st), GFP_KERNEL);
     18	if (!st)
     19		return ERR_PTR(-ENOMEM);
     20
     21	err = sg_alloc_table(st, mock->npages, GFP_KERNEL);
     22	if (err)
     23		goto err_free;
     24
     25	sg = st->sgl;
     26	for (i = 0; i < mock->npages; i++) {
     27		sg_set_page(sg, mock->pages[i], PAGE_SIZE, 0);
     28		sg = sg_next(sg);
     29	}
     30
     31	err = dma_map_sgtable(attachment->dev, st, dir, 0);
     32	if (err)
     33		goto err_st;
     34
     35	return st;
     36
     37err_st:
     38	sg_free_table(st);
     39err_free:
     40	kfree(st);
     41	return ERR_PTR(err);
     42}
     43
     44static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
     45			       struct sg_table *st,
     46			       enum dma_data_direction dir)
     47{
     48	dma_unmap_sgtable(attachment->dev, st, dir, 0);
     49	sg_free_table(st);
     50	kfree(st);
     51}
     52
     53static void mock_dmabuf_release(struct dma_buf *dma_buf)
     54{
     55	struct mock_dmabuf *mock = to_mock(dma_buf);
     56	int i;
     57
     58	for (i = 0; i < mock->npages; i++)
     59		put_page(mock->pages[i]);
     60
     61	kfree(mock);
     62}
     63
     64static int mock_dmabuf_vmap(struct dma_buf *dma_buf, struct iosys_map *map)
     65{
     66	struct mock_dmabuf *mock = to_mock(dma_buf);
     67	void *vaddr;
     68
     69	vaddr = vm_map_ram(mock->pages, mock->npages, 0);
     70	if (!vaddr)
     71		return -ENOMEM;
     72	iosys_map_set_vaddr(map, vaddr);
     73
     74	return 0;
     75}
     76
     77static void mock_dmabuf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map)
     78{
     79	struct mock_dmabuf *mock = to_mock(dma_buf);
     80
     81	vm_unmap_ram(map->vaddr, mock->npages);
     82}
     83
     84static int mock_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
     85{
     86	return -ENODEV;
     87}
     88
     89static const struct dma_buf_ops mock_dmabuf_ops =  {
     90	.map_dma_buf = mock_map_dma_buf,
     91	.unmap_dma_buf = mock_unmap_dma_buf,
     92	.release = mock_dmabuf_release,
     93	.mmap = mock_dmabuf_mmap,
     94	.vmap = mock_dmabuf_vmap,
     95	.vunmap = mock_dmabuf_vunmap,
     96};
     97
     98static struct dma_buf *mock_dmabuf(int npages)
     99{
    100	struct mock_dmabuf *mock;
    101	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
    102	struct dma_buf *dmabuf;
    103	int i;
    104
    105	mock = kmalloc(sizeof(*mock) + npages * sizeof(struct page *),
    106		       GFP_KERNEL);
    107	if (!mock)
    108		return ERR_PTR(-ENOMEM);
    109
    110	mock->npages = npages;
    111	for (i = 0; i < npages; i++) {
    112		mock->pages[i] = alloc_page(GFP_KERNEL);
    113		if (!mock->pages[i])
    114			goto err;
    115	}
    116
    117	exp_info.ops = &mock_dmabuf_ops;
    118	exp_info.size = npages * PAGE_SIZE;
    119	exp_info.flags = O_CLOEXEC;
    120	exp_info.priv = mock;
    121
    122	dmabuf = dma_buf_export(&exp_info);
    123	if (IS_ERR(dmabuf))
    124		goto err;
    125
    126	return dmabuf;
    127
    128err:
    129	while (i--)
    130		put_page(mock->pages[i]);
    131	kfree(mock);
    132	return ERR_PTR(-ENOMEM);
    133}