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

devsynth.c (2113B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/errno.h>
      3#include <linux/miscdevice.h>	/* for misc_register, and MISC_DYNAMIC_MINOR */
      4#include <linux/types.h>
      5#include <linux/uaccess.h>
      6
      7#include "speakup.h"
      8#include "spk_priv.h"
      9
     10static int misc_registered;
     11static int dev_opened;
     12
     13static ssize_t speakup_file_write(struct file *fp, const char __user *buffer,
     14				  size_t nbytes, loff_t *ppos)
     15{
     16	size_t count = nbytes;
     17	const char __user *ptr = buffer;
     18	size_t bytes;
     19	unsigned long flags;
     20	u_char buf[256];
     21
     22	if (!synth)
     23		return -ENODEV;
     24	while (count > 0) {
     25		bytes = min(count, sizeof(buf));
     26		if (copy_from_user(buf, ptr, bytes))
     27			return -EFAULT;
     28		count -= bytes;
     29		ptr += bytes;
     30		spin_lock_irqsave(&speakup_info.spinlock, flags);
     31		synth_write(buf, bytes);
     32		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
     33	}
     34	return (ssize_t)nbytes;
     35}
     36
     37static ssize_t speakup_file_read(struct file *fp, char __user *buf,
     38				 size_t nbytes, loff_t *ppos)
     39{
     40	return 0;
     41}
     42
     43static int speakup_file_open(struct inode *ip, struct file *fp)
     44{
     45	if (!synth)
     46		return -ENODEV;
     47	if (xchg(&dev_opened, 1))
     48		return -EBUSY;
     49	return 0;
     50}
     51
     52static int speakup_file_release(struct inode *ip, struct file *fp)
     53{
     54	dev_opened = 0;
     55	return 0;
     56}
     57
     58static const struct file_operations synth_fops = {
     59	.read = speakup_file_read,
     60	.write = speakup_file_write,
     61	.open = speakup_file_open,
     62	.release = speakup_file_release,
     63};
     64
     65static struct miscdevice synth_device = {
     66	.minor = MISC_DYNAMIC_MINOR,
     67	.name = "synth",
     68	.fops = &synth_fops,
     69};
     70
     71void speakup_register_devsynth(void)
     72{
     73	if (misc_registered != 0)
     74		return;
     75/* zero it so if register fails, deregister will not ref invalid ptrs */
     76	if (misc_register(&synth_device)) {
     77		pr_warn("Couldn't initialize miscdevice /dev/synth.\n");
     78	} else {
     79		pr_info("initialized device: /dev/synth, node (MAJOR %d, MINOR %d)\n",
     80			MISC_MAJOR, synth_device.minor);
     81		misc_registered = 1;
     82	}
     83}
     84
     85void speakup_unregister_devsynth(void)
     86{
     87	if (!misc_registered)
     88		return;
     89	pr_info("speakup: unregistering synth device /dev/synth\n");
     90	misc_deregister(&synth_device);
     91	misc_registered = 0;
     92}