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

base.c (3318B)


      1/*
      2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
      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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     20 * DEALINGS IN THE SOFTWARE.
     21 */
     22#include "priv.h"
     23
     24#include <core/firmware.h>
     25#include <subdev/top.h>
     26
     27static void
     28nvkm_sec2_recv(struct work_struct *work)
     29{
     30	struct nvkm_sec2 *sec2 = container_of(work, typeof(*sec2), work);
     31
     32	if (!sec2->initmsg_received) {
     33		int ret = sec2->func->initmsg(sec2);
     34		if (ret) {
     35			nvkm_error(&sec2->engine.subdev,
     36				   "error parsing init message: %d\n", ret);
     37			return;
     38		}
     39
     40		sec2->initmsg_received = true;
     41	}
     42
     43	nvkm_falcon_msgq_recv(sec2->msgq);
     44}
     45
     46static void
     47nvkm_sec2_intr(struct nvkm_engine *engine)
     48{
     49	struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
     50	sec2->func->intr(sec2);
     51}
     52
     53static int
     54nvkm_sec2_fini(struct nvkm_engine *engine, bool suspend)
     55{
     56	struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
     57
     58	flush_work(&sec2->work);
     59
     60	if (suspend) {
     61		nvkm_falcon_cmdq_fini(sec2->cmdq);
     62		sec2->initmsg_received = false;
     63	}
     64
     65	return 0;
     66}
     67
     68static void *
     69nvkm_sec2_dtor(struct nvkm_engine *engine)
     70{
     71	struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
     72	nvkm_falcon_msgq_del(&sec2->msgq);
     73	nvkm_falcon_cmdq_del(&sec2->cmdq);
     74	nvkm_falcon_qmgr_del(&sec2->qmgr);
     75	nvkm_falcon_dtor(&sec2->falcon);
     76	return sec2;
     77}
     78
     79static const struct nvkm_engine_func
     80nvkm_sec2 = {
     81	.dtor = nvkm_sec2_dtor,
     82	.fini = nvkm_sec2_fini,
     83	.intr = nvkm_sec2_intr,
     84};
     85
     86int
     87nvkm_sec2_new_(const struct nvkm_sec2_fwif *fwif, struct nvkm_device *device,
     88	       enum nvkm_subdev_type type, int inst, u32 addr, struct nvkm_sec2 **psec2)
     89{
     90	struct nvkm_sec2 *sec2;
     91	int ret;
     92
     93	if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL)))
     94		return -ENOMEM;
     95
     96	ret = nvkm_engine_ctor(&nvkm_sec2, device, type, inst, true, &sec2->engine);
     97	if (ret)
     98		return ret;
     99
    100	fwif = nvkm_firmware_load(&sec2->engine.subdev, fwif, "Sec2", sec2);
    101	if (IS_ERR(fwif))
    102		return PTR_ERR(fwif);
    103
    104	sec2->func = fwif->func;
    105
    106	ret = nvkm_falcon_ctor(sec2->func->flcn, &sec2->engine.subdev,
    107			       sec2->engine.subdev.name, addr, &sec2->falcon);
    108	if (ret)
    109		return ret;
    110
    111	if ((ret = nvkm_falcon_qmgr_new(&sec2->falcon, &sec2->qmgr)) ||
    112	    (ret = nvkm_falcon_cmdq_new(sec2->qmgr, "cmdq", &sec2->cmdq)) ||
    113	    (ret = nvkm_falcon_msgq_new(sec2->qmgr, "msgq", &sec2->msgq)))
    114		return ret;
    115
    116	INIT_WORK(&sec2->work, nvkm_sec2_recv);
    117	return 0;
    118};