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

cpqphp_sysfs.c (4866B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Compaq Hot Plug Controller Driver
      4 *
      5 * Copyright (C) 1995,2001 Compaq Computer Corporation
      6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
      7 * Copyright (C) 2001 IBM Corp.
      8 *
      9 * All rights reserved.
     10 *
     11 * Send feedback to <greg@kroah.com>
     12 *
     13 */
     14
     15#include <linux/module.h>
     16#include <linux/kernel.h>
     17#include <linux/slab.h>
     18#include <linux/types.h>
     19#include <linux/proc_fs.h>
     20#include <linux/workqueue.h>
     21#include <linux/pci.h>
     22#include <linux/pci_hotplug.h>
     23#include <linux/mutex.h>
     24#include <linux/debugfs.h>
     25#include "cpqphp.h"
     26
     27static DEFINE_MUTEX(cpqphp_mutex);
     28static int show_ctrl(struct controller *ctrl, char *buf)
     29{
     30	char *out = buf;
     31	int index;
     32	struct pci_resource *res;
     33
     34	out += sprintf(buf, "Free resources: memory\n");
     35	index = 11;
     36	res = ctrl->mem_head;
     37	while (res && index--) {
     38		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
     39		res = res->next;
     40	}
     41	out += sprintf(out, "Free resources: prefetchable memory\n");
     42	index = 11;
     43	res = ctrl->p_mem_head;
     44	while (res && index--) {
     45		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
     46		res = res->next;
     47	}
     48	out += sprintf(out, "Free resources: IO\n");
     49	index = 11;
     50	res = ctrl->io_head;
     51	while (res && index--) {
     52		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
     53		res = res->next;
     54	}
     55	out += sprintf(out, "Free resources: bus numbers\n");
     56	index = 11;
     57	res = ctrl->bus_head;
     58	while (res && index--) {
     59		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
     60		res = res->next;
     61	}
     62
     63	return out - buf;
     64}
     65
     66static int show_dev(struct controller *ctrl, char *buf)
     67{
     68	char *out = buf;
     69	int index;
     70	struct pci_resource *res;
     71	struct pci_func *new_slot;
     72	struct slot *slot;
     73
     74	slot = ctrl->slot;
     75
     76	while (slot) {
     77		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
     78		if (!new_slot)
     79			break;
     80		out += sprintf(out, "assigned resources: memory\n");
     81		index = 11;
     82		res = new_slot->mem_head;
     83		while (res && index--) {
     84			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
     85			res = res->next;
     86		}
     87		out += sprintf(out, "assigned resources: prefetchable memory\n");
     88		index = 11;
     89		res = new_slot->p_mem_head;
     90		while (res && index--) {
     91			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
     92			res = res->next;
     93		}
     94		out += sprintf(out, "assigned resources: IO\n");
     95		index = 11;
     96		res = new_slot->io_head;
     97		while (res && index--) {
     98			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
     99			res = res->next;
    100		}
    101		out += sprintf(out, "assigned resources: bus numbers\n");
    102		index = 11;
    103		res = new_slot->bus_head;
    104		while (res && index--) {
    105			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
    106			res = res->next;
    107		}
    108		slot = slot->next;
    109	}
    110
    111	return out - buf;
    112}
    113
    114static int spew_debug_info(struct controller *ctrl, char *data, int size)
    115{
    116	int used;
    117
    118	used = size - show_ctrl(ctrl, data);
    119	used = (size - used) - show_dev(ctrl, &data[used]);
    120	return used;
    121}
    122
    123struct ctrl_dbg {
    124	int size;
    125	char *data;
    126	struct controller *ctrl;
    127};
    128
    129#define MAX_OUTPUT	(4*PAGE_SIZE)
    130
    131static int open(struct inode *inode, struct file *file)
    132{
    133	struct controller *ctrl = inode->i_private;
    134	struct ctrl_dbg *dbg;
    135	int retval = -ENOMEM;
    136
    137	mutex_lock(&cpqphp_mutex);
    138	dbg = kmalloc(sizeof(*dbg), GFP_KERNEL);
    139	if (!dbg)
    140		goto exit;
    141	dbg->data = kmalloc(MAX_OUTPUT, GFP_KERNEL);
    142	if (!dbg->data) {
    143		kfree(dbg);
    144		goto exit;
    145	}
    146	dbg->size = spew_debug_info(ctrl, dbg->data, MAX_OUTPUT);
    147	file->private_data = dbg;
    148	retval = 0;
    149exit:
    150	mutex_unlock(&cpqphp_mutex);
    151	return retval;
    152}
    153
    154static loff_t lseek(struct file *file, loff_t off, int whence)
    155{
    156	struct ctrl_dbg *dbg = file->private_data;
    157	return fixed_size_llseek(file, off, whence, dbg->size);
    158}
    159
    160static ssize_t read(struct file *file, char __user *buf,
    161		    size_t nbytes, loff_t *ppos)
    162{
    163	struct ctrl_dbg *dbg = file->private_data;
    164	return simple_read_from_buffer(buf, nbytes, ppos, dbg->data, dbg->size);
    165}
    166
    167static int release(struct inode *inode, struct file *file)
    168{
    169	struct ctrl_dbg *dbg = file->private_data;
    170
    171	kfree(dbg->data);
    172	kfree(dbg);
    173	return 0;
    174}
    175
    176static const struct file_operations debug_ops = {
    177	.owner = THIS_MODULE,
    178	.open = open,
    179	.llseek = lseek,
    180	.read = read,
    181	.release = release,
    182};
    183
    184static struct dentry *root;
    185
    186void cpqhp_initialize_debugfs(void)
    187{
    188	if (!root)
    189		root = debugfs_create_dir("cpqhp", NULL);
    190}
    191
    192void cpqhp_shutdown_debugfs(void)
    193{
    194	debugfs_remove(root);
    195}
    196
    197void cpqhp_create_debugfs_files(struct controller *ctrl)
    198{
    199	ctrl->dentry = debugfs_create_file(dev_name(&ctrl->pci_dev->dev),
    200					   S_IRUGO, root, ctrl, &debug_ops);
    201}
    202
    203void cpqhp_remove_debugfs_files(struct controller *ctrl)
    204{
    205	debugfs_remove(ctrl->dentry);
    206	ctrl->dentry = NULL;
    207}
    208