Linux Audio

Check our new training course

Loading...
v3.1
 
  1/*
  2 * debugfs.c - ACPI debugfs interface to userspace.
  3 */
  4
  5#include <linux/init.h>
  6#include <linux/module.h>
  7#include <linux/kernel.h>
  8#include <linux/uaccess.h>
  9#include <linux/debugfs.h>
 10#include <acpi/acpi_drivers.h>
 
 11
 12#include "internal.h"
 13
 14#define _COMPONENT		ACPI_SYSTEM_COMPONENT
 15ACPI_MODULE_NAME("custom_method");
 16MODULE_LICENSE("GPL");
 17
 18static struct dentry *cm_dentry;
 19
 20/* /sys/kernel/debug/acpi/custom_method */
 21
 22static ssize_t cm_write(struct file *file, const char __user * user_buf,
 23			size_t count, loff_t *ppos)
 24{
 25	static char *buf;
 26	static u32 max_size;
 27	static u32 uncopied_bytes;
 28
 29	struct acpi_table_header table;
 30	acpi_status status;
 
 
 
 
 
 31
 32	if (!(*ppos)) {
 33		/* parse the table header to get the table length */
 34		if (count <= sizeof(struct acpi_table_header))
 35			return -EINVAL;
 36		if (copy_from_user(&table, user_buf,
 37				   sizeof(struct acpi_table_header)))
 38			return -EFAULT;
 39		uncopied_bytes = max_size = table.length;
 40		buf = kzalloc(max_size, GFP_KERNEL);
 41		if (!buf)
 42			return -ENOMEM;
 43	}
 44
 45	if (buf == NULL)
 46		return -EINVAL;
 47
 48	if ((*ppos > max_size) ||
 49	    (*ppos + count > max_size) ||
 50	    (*ppos + count < count) ||
 51	    (count > uncopied_bytes))
 
 52		return -EINVAL;
 
 53
 54	if (copy_from_user(buf + (*ppos), user_buf, count)) {
 55		kfree(buf);
 56		buf = NULL;
 57		return -EFAULT;
 58	}
 59
 60	uncopied_bytes -= count;
 61	*ppos += count;
 62
 63	if (!uncopied_bytes) {
 64		status = acpi_install_method(buf);
 65		kfree(buf);
 66		buf = NULL;
 67		if (ACPI_FAILURE(status))
 68			return -EINVAL;
 69		add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
 70	}
 71
 
 72	return count;
 73}
 74
 75static const struct file_operations cm_fops = {
 76	.write = cm_write,
 77	.llseek = default_llseek,
 78};
 79
 80static int __init acpi_custom_method_init(void)
 81{
 82	if (acpi_debugfs_dir == NULL)
 83		return -ENOENT;
 84
 85	cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
 86					acpi_debugfs_dir, NULL, &cm_fops);
 87	if (cm_dentry == NULL)
 88		return -ENODEV;
 89
 90	return 0;
 91}
 92
 93static void __exit acpi_custom_method_exit(void)
 94{
 95	if (cm_dentry)
 96		debugfs_remove(cm_dentry);
 97 }
 98
 99module_init(acpi_custom_method_init);
100module_exit(acpi_custom_method_exit);
v5.9
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * custom_method.c - debugfs interface for customizing ACPI control method
  4 */
  5
  6#include <linux/init.h>
  7#include <linux/module.h>
  8#include <linux/kernel.h>
  9#include <linux/uaccess.h>
 10#include <linux/debugfs.h>
 11#include <linux/acpi.h>
 12#include <linux/security.h>
 13
 14#include "internal.h"
 15
 16#define _COMPONENT		ACPI_SYSTEM_COMPONENT
 17ACPI_MODULE_NAME("custom_method");
 18MODULE_LICENSE("GPL");
 19
 20static struct dentry *cm_dentry;
 21
 22/* /sys/kernel/debug/acpi/custom_method */
 23
 24static ssize_t cm_write(struct file *file, const char __user * user_buf,
 25			size_t count, loff_t *ppos)
 26{
 27	static char *buf;
 28	static u32 max_size;
 29	static u32 uncopied_bytes;
 30
 31	struct acpi_table_header table;
 32	acpi_status status;
 33	int ret;
 34
 35	ret = security_locked_down(LOCKDOWN_ACPI_TABLES);
 36	if (ret)
 37		return ret;
 38
 39	if (!(*ppos)) {
 40		/* parse the table header to get the table length */
 41		if (count <= sizeof(struct acpi_table_header))
 42			return -EINVAL;
 43		if (copy_from_user(&table, user_buf,
 44				   sizeof(struct acpi_table_header)))
 45			return -EFAULT;
 46		uncopied_bytes = max_size = table.length;
 47		buf = kzalloc(max_size, GFP_KERNEL);
 48		if (!buf)
 49			return -ENOMEM;
 50	}
 51
 52	if (buf == NULL)
 53		return -EINVAL;
 54
 55	if ((*ppos > max_size) ||
 56	    (*ppos + count > max_size) ||
 57	    (*ppos + count < count) ||
 58	    (count > uncopied_bytes)) {
 59		kfree(buf);
 60		return -EINVAL;
 61	}
 62
 63	if (copy_from_user(buf + (*ppos), user_buf, count)) {
 64		kfree(buf);
 65		buf = NULL;
 66		return -EFAULT;
 67	}
 68
 69	uncopied_bytes -= count;
 70	*ppos += count;
 71
 72	if (!uncopied_bytes) {
 73		status = acpi_install_method(buf);
 74		kfree(buf);
 75		buf = NULL;
 76		if (ACPI_FAILURE(status))
 77			return -EINVAL;
 78		add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
 79	}
 80
 81	kfree(buf);
 82	return count;
 83}
 84
 85static const struct file_operations cm_fops = {
 86	.write = cm_write,
 87	.llseek = default_llseek,
 88};
 89
 90static int __init acpi_custom_method_init(void)
 91{
 
 
 
 92	cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
 93					acpi_debugfs_dir, NULL, &cm_fops);
 
 
 
 94	return 0;
 95}
 96
 97static void __exit acpi_custom_method_exit(void)
 98{
 99	debugfs_remove(cm_dentry);
100}
 
101
102module_init(acpi_custom_method_init);
103module_exit(acpi_custom_method_exit);