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

pmsg.c (1965B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2014  Google, Inc.
      4 */
      5
      6#include <linux/cdev.h>
      7#include <linux/device.h>
      8#include <linux/fs.h>
      9#include <linux/uaccess.h>
     10#include "internal.h"
     11
     12static DEFINE_MUTEX(pmsg_lock);
     13
     14static ssize_t write_pmsg(struct file *file, const char __user *buf,
     15			  size_t count, loff_t *ppos)
     16{
     17	struct pstore_record record;
     18	int ret;
     19
     20	if (!count)
     21		return 0;
     22
     23	pstore_record_init(&record, psinfo);
     24	record.type = PSTORE_TYPE_PMSG;
     25	record.size = count;
     26
     27	/* check outside lock, page in any data. write_user also checks */
     28	if (!access_ok(buf, count))
     29		return -EFAULT;
     30
     31	mutex_lock(&pmsg_lock);
     32	ret = psinfo->write_user(&record, buf);
     33	mutex_unlock(&pmsg_lock);
     34	return ret ? ret : count;
     35}
     36
     37static const struct file_operations pmsg_fops = {
     38	.owner		= THIS_MODULE,
     39	.llseek		= noop_llseek,
     40	.write		= write_pmsg,
     41};
     42
     43static struct class *pmsg_class;
     44static int pmsg_major;
     45#define PMSG_NAME "pmsg"
     46#undef pr_fmt
     47#define pr_fmt(fmt) PMSG_NAME ": " fmt
     48
     49static char *pmsg_devnode(struct device *dev, umode_t *mode)
     50{
     51	if (mode)
     52		*mode = 0220;
     53	return NULL;
     54}
     55
     56void pstore_register_pmsg(void)
     57{
     58	struct device *pmsg_device;
     59
     60	pmsg_major = register_chrdev(0, PMSG_NAME, &pmsg_fops);
     61	if (pmsg_major < 0) {
     62		pr_err("register_chrdev failed\n");
     63		goto err;
     64	}
     65
     66	pmsg_class = class_create(THIS_MODULE, PMSG_NAME);
     67	if (IS_ERR(pmsg_class)) {
     68		pr_err("device class file already in use\n");
     69		goto err_class;
     70	}
     71	pmsg_class->devnode = pmsg_devnode;
     72
     73	pmsg_device = device_create(pmsg_class, NULL, MKDEV(pmsg_major, 0),
     74					NULL, "%s%d", PMSG_NAME, 0);
     75	if (IS_ERR(pmsg_device)) {
     76		pr_err("failed to create device\n");
     77		goto err_device;
     78	}
     79	return;
     80
     81err_device:
     82	class_destroy(pmsg_class);
     83err_class:
     84	unregister_chrdev(pmsg_major, PMSG_NAME);
     85err:
     86	return;
     87}
     88
     89void pstore_unregister_pmsg(void)
     90{
     91	device_destroy(pmsg_class, MKDEV(pmsg_major, 0));
     92	class_destroy(pmsg_class);
     93	unregister_chrdev(pmsg_major, PMSG_NAME);
     94}