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

msm_fence.c (2485B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2013-2016 Red Hat
      4 * Author: Rob Clark <robdclark@gmail.com>
      5 */
      6
      7#include <linux/dma-fence.h>
      8
      9#include "msm_drv.h"
     10#include "msm_fence.h"
     11
     12
     13struct msm_fence_context *
     14msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr,
     15		const char *name)
     16{
     17	struct msm_fence_context *fctx;
     18	static int index = 0;
     19
     20	fctx = kzalloc(sizeof(*fctx), GFP_KERNEL);
     21	if (!fctx)
     22		return ERR_PTR(-ENOMEM);
     23
     24	fctx->dev = dev;
     25	strncpy(fctx->name, name, sizeof(fctx->name));
     26	fctx->context = dma_fence_context_alloc(1);
     27	fctx->index = index++;
     28	fctx->fenceptr = fenceptr;
     29	spin_lock_init(&fctx->spinlock);
     30
     31	return fctx;
     32}
     33
     34void msm_fence_context_free(struct msm_fence_context *fctx)
     35{
     36	kfree(fctx);
     37}
     38
     39bool msm_fence_completed(struct msm_fence_context *fctx, uint32_t fence)
     40{
     41	/*
     42	 * Note: Check completed_fence first, as fenceptr is in a write-combine
     43	 * mapping, so it will be more expensive to read.
     44	 */
     45	return (int32_t)(fctx->completed_fence - fence) >= 0 ||
     46		(int32_t)(*fctx->fenceptr - fence) >= 0;
     47}
     48
     49/* called from irq handler and workqueue (in recover path) */
     50void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence)
     51{
     52	unsigned long flags;
     53
     54	spin_lock_irqsave(&fctx->spinlock, flags);
     55	fctx->completed_fence = max(fence, fctx->completed_fence);
     56	spin_unlock_irqrestore(&fctx->spinlock, flags);
     57}
     58
     59struct msm_fence {
     60	struct dma_fence base;
     61	struct msm_fence_context *fctx;
     62};
     63
     64static inline struct msm_fence *to_msm_fence(struct dma_fence *fence)
     65{
     66	return container_of(fence, struct msm_fence, base);
     67}
     68
     69static const char *msm_fence_get_driver_name(struct dma_fence *fence)
     70{
     71	return "msm";
     72}
     73
     74static const char *msm_fence_get_timeline_name(struct dma_fence *fence)
     75{
     76	struct msm_fence *f = to_msm_fence(fence);
     77	return f->fctx->name;
     78}
     79
     80static bool msm_fence_signaled(struct dma_fence *fence)
     81{
     82	struct msm_fence *f = to_msm_fence(fence);
     83	return msm_fence_completed(f->fctx, f->base.seqno);
     84}
     85
     86static const struct dma_fence_ops msm_fence_ops = {
     87	.get_driver_name = msm_fence_get_driver_name,
     88	.get_timeline_name = msm_fence_get_timeline_name,
     89	.signaled = msm_fence_signaled,
     90};
     91
     92struct dma_fence *
     93msm_fence_alloc(struct msm_fence_context *fctx)
     94{
     95	struct msm_fence *f;
     96
     97	f = kzalloc(sizeof(*f), GFP_KERNEL);
     98	if (!f)
     99		return ERR_PTR(-ENOMEM);
    100
    101	f->fctx = fctx;
    102
    103	dma_fence_init(&f->base, &msm_fence_ops, &fctx->spinlock,
    104		       fctx->context, ++fctx->last_fence);
    105
    106	return &f->base;
    107}