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

snic_trc.c (3877B)


      1/*
      2 * Copyright 2014 Cisco Systems, Inc.  All rights reserved.
      3 *
      4 * This program is free software; you may redistribute it and/or modify
      5 * it under the terms of the GNU General Public License as published by
      6 * the Free Software Foundation; version 2 of the License.
      7 *
      8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     15 * SOFTWARE.
     16 */
     17
     18#include <linux/module.h>
     19#include <linux/mempool.h>
     20#include <linux/errno.h>
     21#include <linux/vmalloc.h>
     22
     23#include "snic_io.h"
     24#include "snic.h"
     25
     26/*
     27 * snic_get_trc_buf : Allocates a trace record and returns.
     28 */
     29struct snic_trc_data *
     30snic_get_trc_buf(void)
     31{
     32	struct snic_trc *trc = &snic_glob->trc;
     33	struct snic_trc_data *td = NULL;
     34	unsigned long flags;
     35
     36	spin_lock_irqsave(&trc->lock, flags);
     37	td = &trc->buf[trc->wr_idx];
     38	trc->wr_idx++;
     39
     40	if (trc->wr_idx == trc->max_idx)
     41		trc->wr_idx = 0;
     42
     43	if (trc->wr_idx != trc->rd_idx) {
     44		spin_unlock_irqrestore(&trc->lock, flags);
     45
     46		goto end;
     47	}
     48
     49	trc->rd_idx++;
     50	if (trc->rd_idx == trc->max_idx)
     51		trc->rd_idx = 0;
     52
     53	td->ts = 0;	/* Marker for checking the record, for complete data*/
     54	spin_unlock_irqrestore(&trc->lock, flags);
     55
     56end:
     57
     58	return td;
     59} /* end of snic_get_trc_buf */
     60
     61/*
     62 * snic_fmt_trc_data : Formats trace data for printing.
     63 */
     64static int
     65snic_fmt_trc_data(struct snic_trc_data *td, char *buf, int buf_sz)
     66{
     67	int len = 0;
     68	struct timespec64 tmspec;
     69
     70	jiffies_to_timespec64(td->ts, &tmspec);
     71
     72	len += snprintf(buf, buf_sz,
     73			"%llu.%09lu %-25s %3d %4x %16llx %16llx %16llx %16llx %16llx\n",
     74			tmspec.tv_sec,
     75			tmspec.tv_nsec,
     76			td->fn,
     77			td->hno,
     78			td->tag,
     79			td->data[0], td->data[1], td->data[2], td->data[3],
     80			td->data[4]);
     81
     82	return len;
     83} /* end of snic_fmt_trc_data */
     84
     85/*
     86 * snic_get_trc_data : Returns a formatted trace buffer.
     87 */
     88int
     89snic_get_trc_data(char *buf, int buf_sz)
     90{
     91	struct snic_trc_data *td = NULL;
     92	struct snic_trc *trc = &snic_glob->trc;
     93	unsigned long flags;
     94
     95	spin_lock_irqsave(&trc->lock, flags);
     96	if (trc->rd_idx == trc->wr_idx) {
     97		spin_unlock_irqrestore(&trc->lock, flags);
     98
     99		return -1;
    100	}
    101	td = &trc->buf[trc->rd_idx];
    102
    103	if (td->ts == 0) {
    104		/* write in progress. */
    105		spin_unlock_irqrestore(&trc->lock, flags);
    106
    107		return -1;
    108	}
    109
    110	trc->rd_idx++;
    111	if (trc->rd_idx == trc->max_idx)
    112		trc->rd_idx = 0;
    113	spin_unlock_irqrestore(&trc->lock, flags);
    114
    115	return snic_fmt_trc_data(td, buf, buf_sz);
    116} /* end of snic_get_trc_data */
    117
    118/*
    119 * snic_trc_init() : Configures Trace Functionality for snic.
    120 */
    121int
    122snic_trc_init(void)
    123{
    124	struct snic_trc *trc = &snic_glob->trc;
    125	void *tbuf = NULL;
    126	int tbuf_sz = 0, ret;
    127
    128	tbuf_sz = (snic_trace_max_pages * PAGE_SIZE);
    129	tbuf = vzalloc(tbuf_sz);
    130	if (!tbuf) {
    131		SNIC_ERR("Failed to Allocate Trace Buffer Size. %d\n", tbuf_sz);
    132		SNIC_ERR("Trace Facility not enabled.\n");
    133		ret = -ENOMEM;
    134
    135		return ret;
    136	}
    137
    138	trc->buf = (struct snic_trc_data *) tbuf;
    139	spin_lock_init(&trc->lock);
    140
    141	snic_trc_debugfs_init();
    142
    143	trc->max_idx = (tbuf_sz / SNIC_TRC_ENTRY_SZ);
    144	trc->rd_idx = trc->wr_idx = 0;
    145	trc->enable = true;
    146	SNIC_INFO("Trace Facility Enabled.\n Trace Buffer SZ %lu Pages.\n",
    147		  tbuf_sz / PAGE_SIZE);
    148	ret = 0;
    149
    150	return ret;
    151} /* end of snic_trc_init */
    152
    153/*
    154 * snic_trc_free : Releases the trace buffer and disables the tracing.
    155 */
    156void
    157snic_trc_free(void)
    158{
    159	struct snic_trc *trc = &snic_glob->trc;
    160
    161	trc->enable = false;
    162	snic_trc_debugfs_term();
    163
    164	if (trc->buf) {
    165		vfree(trc->buf);
    166		trc->buf = NULL;
    167	}
    168
    169	SNIC_INFO("Trace Facility Disabled.\n");
    170} /* end of snic_trc_free */