Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/kernel/ksysfs.c
10814 views
1
/*
2
* kernel/ksysfs.c - sysfs attributes in /sys/kernel, which
3
* are not related to any other subsystem
4
*
5
* Copyright (C) 2004 Kay Sievers <[email protected]>
6
*
7
* This file is release under the GPLv2
8
*
9
*/
10
11
#include <linux/kobject.h>
12
#include <linux/string.h>
13
#include <linux/sysfs.h>
14
#include <linux/module.h>
15
#include <linux/init.h>
16
#include <linux/kexec.h>
17
#include <linux/profile.h>
18
#include <linux/sched.h>
19
#include <linux/capability.h>
20
21
#define KERNEL_ATTR_RO(_name) \
22
static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
23
24
#define KERNEL_ATTR_RW(_name) \
25
static struct kobj_attribute _name##_attr = \
26
__ATTR(_name, 0644, _name##_show, _name##_store)
27
28
#if defined(CONFIG_HOTPLUG)
29
/* current uevent sequence number */
30
static ssize_t uevent_seqnum_show(struct kobject *kobj,
31
struct kobj_attribute *attr, char *buf)
32
{
33
return sprintf(buf, "%llu\n", (unsigned long long)uevent_seqnum);
34
}
35
KERNEL_ATTR_RO(uevent_seqnum);
36
37
/* uevent helper program, used during early boot */
38
static ssize_t uevent_helper_show(struct kobject *kobj,
39
struct kobj_attribute *attr, char *buf)
40
{
41
return sprintf(buf, "%s\n", uevent_helper);
42
}
43
static ssize_t uevent_helper_store(struct kobject *kobj,
44
struct kobj_attribute *attr,
45
const char *buf, size_t count)
46
{
47
if (count+1 > UEVENT_HELPER_PATH_LEN)
48
return -ENOENT;
49
memcpy(uevent_helper, buf, count);
50
uevent_helper[count] = '\0';
51
if (count && uevent_helper[count-1] == '\n')
52
uevent_helper[count-1] = '\0';
53
return count;
54
}
55
KERNEL_ATTR_RW(uevent_helper);
56
#endif
57
58
#ifdef CONFIG_PROFILING
59
static ssize_t profiling_show(struct kobject *kobj,
60
struct kobj_attribute *attr, char *buf)
61
{
62
return sprintf(buf, "%d\n", prof_on);
63
}
64
static ssize_t profiling_store(struct kobject *kobj,
65
struct kobj_attribute *attr,
66
const char *buf, size_t count)
67
{
68
int ret;
69
70
if (prof_on)
71
return -EEXIST;
72
/*
73
* This eventually calls into get_option() which
74
* has a ton of callers and is not const. It is
75
* easiest to cast it away here.
76
*/
77
profile_setup((char *)buf);
78
ret = profile_init();
79
if (ret)
80
return ret;
81
ret = create_proc_profile();
82
if (ret)
83
return ret;
84
return count;
85
}
86
KERNEL_ATTR_RW(profiling);
87
#endif
88
89
#ifdef CONFIG_KEXEC
90
static ssize_t kexec_loaded_show(struct kobject *kobj,
91
struct kobj_attribute *attr, char *buf)
92
{
93
return sprintf(buf, "%d\n", !!kexec_image);
94
}
95
KERNEL_ATTR_RO(kexec_loaded);
96
97
static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
98
struct kobj_attribute *attr, char *buf)
99
{
100
return sprintf(buf, "%d\n", !!kexec_crash_image);
101
}
102
KERNEL_ATTR_RO(kexec_crash_loaded);
103
104
static ssize_t kexec_crash_size_show(struct kobject *kobj,
105
struct kobj_attribute *attr, char *buf)
106
{
107
return sprintf(buf, "%zu\n", crash_get_memory_size());
108
}
109
static ssize_t kexec_crash_size_store(struct kobject *kobj,
110
struct kobj_attribute *attr,
111
const char *buf, size_t count)
112
{
113
unsigned long cnt;
114
int ret;
115
116
if (strict_strtoul(buf, 0, &cnt))
117
return -EINVAL;
118
119
ret = crash_shrink_memory(cnt);
120
return ret < 0 ? ret : count;
121
}
122
KERNEL_ATTR_RW(kexec_crash_size);
123
124
static ssize_t vmcoreinfo_show(struct kobject *kobj,
125
struct kobj_attribute *attr, char *buf)
126
{
127
return sprintf(buf, "%lx %x\n",
128
paddr_vmcoreinfo_note(),
129
(unsigned int)vmcoreinfo_max_size);
130
}
131
KERNEL_ATTR_RO(vmcoreinfo);
132
133
#endif /* CONFIG_KEXEC */
134
135
/* whether file capabilities are enabled */
136
static ssize_t fscaps_show(struct kobject *kobj,
137
struct kobj_attribute *attr, char *buf)
138
{
139
return sprintf(buf, "%d\n", file_caps_enabled);
140
}
141
KERNEL_ATTR_RO(fscaps);
142
143
/*
144
* Make /sys/kernel/notes give the raw contents of our kernel .notes section.
145
*/
146
extern const void __start_notes __attribute__((weak));
147
extern const void __stop_notes __attribute__((weak));
148
#define notes_size (&__stop_notes - &__start_notes)
149
150
static ssize_t notes_read(struct file *filp, struct kobject *kobj,
151
struct bin_attribute *bin_attr,
152
char *buf, loff_t off, size_t count)
153
{
154
memcpy(buf, &__start_notes + off, count);
155
return count;
156
}
157
158
static struct bin_attribute notes_attr = {
159
.attr = {
160
.name = "notes",
161
.mode = S_IRUGO,
162
},
163
.read = &notes_read,
164
};
165
166
struct kobject *kernel_kobj;
167
EXPORT_SYMBOL_GPL(kernel_kobj);
168
169
static struct attribute * kernel_attrs[] = {
170
&fscaps_attr.attr,
171
#if defined(CONFIG_HOTPLUG)
172
&uevent_seqnum_attr.attr,
173
&uevent_helper_attr.attr,
174
#endif
175
#ifdef CONFIG_PROFILING
176
&profiling_attr.attr,
177
#endif
178
#ifdef CONFIG_KEXEC
179
&kexec_loaded_attr.attr,
180
&kexec_crash_loaded_attr.attr,
181
&kexec_crash_size_attr.attr,
182
&vmcoreinfo_attr.attr,
183
#endif
184
NULL
185
};
186
187
static struct attribute_group kernel_attr_group = {
188
.attrs = kernel_attrs,
189
};
190
191
static int __init ksysfs_init(void)
192
{
193
int error;
194
195
kernel_kobj = kobject_create_and_add("kernel", NULL);
196
if (!kernel_kobj) {
197
error = -ENOMEM;
198
goto exit;
199
}
200
error = sysfs_create_group(kernel_kobj, &kernel_attr_group);
201
if (error)
202
goto kset_exit;
203
204
if (notes_size > 0) {
205
notes_attr.size = notes_size;
206
error = sysfs_create_bin_file(kernel_kobj, &notes_attr);
207
if (error)
208
goto group_exit;
209
}
210
211
return 0;
212
213
group_exit:
214
sysfs_remove_group(kernel_kobj, &kernel_attr_group);
215
kset_exit:
216
kobject_put(kernel_kobj);
217
exit:
218
return error;
219
}
220
221
core_initcall(ksysfs_init);
222
223