Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/acpi/custom_method.c
15111 views
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
15
ACPI_MODULE_NAME("custom_method");
16
MODULE_LICENSE("GPL");
17
18
static struct dentry *cm_dentry;
19
20
/* /sys/kernel/debug/acpi/custom_method */
21
22
static 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
75
static const struct file_operations cm_fops = {
76
.write = cm_write,
77
.llseek = default_llseek,
78
};
79
80
static 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
93
static void __exit acpi_custom_method_exit(void)
94
{
95
if (cm_dentry)
96
debugfs_remove(cm_dentry);
97
}
98
99
module_init(acpi_custom_method_init);
100
module_exit(acpi_custom_method_exit);
101
102