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

rtlx-cmp.c (2693B)


      1/*
      2 * This file is subject to the terms and conditions of the GNU General Public
      3 * License.  See the file "COPYING" in the main directory of this archive
      4 * for more details.
      5 *
      6 * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
      7 * Copyright (C) 2013 Imagination Technologies Ltd.
      8 */
      9#include <linux/device.h>
     10#include <linux/fs.h>
     11#include <linux/err.h>
     12#include <linux/wait.h>
     13#include <linux/sched.h>
     14#include <linux/smp.h>
     15
     16#include <asm/mips_mt.h>
     17#include <asm/vpe.h>
     18#include <asm/rtlx.h>
     19
     20static int major;
     21
     22static void rtlx_interrupt(void)
     23{
     24	int i;
     25	struct rtlx_info *info;
     26	struct rtlx_info **p = vpe_get_shared(aprp_cpu_index());
     27
     28	if (p == NULL || *p == NULL)
     29		return;
     30
     31	info = *p;
     32
     33	if (info->ap_int_pending == 1 && smp_processor_id() == 0) {
     34		for (i = 0; i < RTLX_CHANNELS; i++) {
     35			wake_up(&channel_wqs[i].lx_queue);
     36			wake_up(&channel_wqs[i].rt_queue);
     37		}
     38		info->ap_int_pending = 0;
     39	}
     40}
     41
     42void _interrupt_sp(void)
     43{
     44	smp_send_reschedule(aprp_cpu_index());
     45}
     46
     47int __init rtlx_module_init(void)
     48{
     49	struct device *dev;
     50	int i, err;
     51
     52	if (!cpu_has_mipsmt) {
     53		pr_warn("VPE loader: not a MIPS MT capable processor\n");
     54		return -ENODEV;
     55	}
     56
     57	if (num_possible_cpus() - aprp_cpu_index() < 1) {
     58		pr_warn("No TCs reserved for AP/SP, not initializing RTLX.\n"
     59			"Pass maxcpus=<n> argument as kernel argument\n");
     60
     61		return -ENODEV;
     62	}
     63
     64	major = register_chrdev(0, RTLX_MODULE_NAME, &rtlx_fops);
     65	if (major < 0) {
     66		pr_err("rtlx_module_init: unable to register device\n");
     67		return major;
     68	}
     69
     70	/* initialise the wait queues */
     71	for (i = 0; i < RTLX_CHANNELS; i++) {
     72		init_waitqueue_head(&channel_wqs[i].rt_queue);
     73		init_waitqueue_head(&channel_wqs[i].lx_queue);
     74		atomic_set(&channel_wqs[i].in_open, 0);
     75		mutex_init(&channel_wqs[i].mutex);
     76
     77		dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
     78				    "%s%d", RTLX_MODULE_NAME, i);
     79		if (IS_ERR(dev)) {
     80			while (i--)
     81				device_destroy(mt_class, MKDEV(major, i));
     82
     83			err = PTR_ERR(dev);
     84			goto out_chrdev;
     85		}
     86	}
     87
     88	/* set up notifiers */
     89	rtlx_notify.start = rtlx_starting;
     90	rtlx_notify.stop = rtlx_stopping;
     91	vpe_notify(aprp_cpu_index(), &rtlx_notify);
     92
     93	if (cpu_has_vint) {
     94		aprp_hook = rtlx_interrupt;
     95	} else {
     96		pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
     97		err = -ENODEV;
     98		goto out_class;
     99	}
    100
    101	return 0;
    102
    103out_class:
    104	for (i = 0; i < RTLX_CHANNELS; i++)
    105		device_destroy(mt_class, MKDEV(major, i));
    106out_chrdev:
    107	unregister_chrdev(major, RTLX_MODULE_NAME);
    108
    109	return err;
    110}
    111
    112void __exit rtlx_module_exit(void)
    113{
    114	int i;
    115
    116	for (i = 0; i < RTLX_CHANNELS; i++)
    117		device_destroy(mt_class, MKDEV(major, i));
    118
    119	unregister_chrdev(major, RTLX_MODULE_NAME);
    120
    121	aprp_hook = NULL;
    122}