Branch data Line data Source code
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 <kay.sievers@vrfy.org>
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/export.h>
15 : : #include <linux/init.h>
16 : : #include <linux/kexec.h>
17 : : #include <linux/profile.h>
18 : : #include <linux/stat.h>
19 : : #include <linux/sched.h>
20 : : #include <linux/capability.h>
21 : :
22 : : #define KERNEL_ATTR_RO(_name) \
23 : : static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
24 : :
25 : : #define KERNEL_ATTR_RW(_name) \
26 : : static struct kobj_attribute _name##_attr = \
27 : : __ATTR(_name, 0644, _name##_show, _name##_store)
28 : :
29 : : /* current uevent sequence number */
30 : 0 : static ssize_t uevent_seqnum_show(struct kobject *kobj,
31 : : struct kobj_attribute *attr, char *buf)
32 : : {
33 : 0 : 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 : 0 : static ssize_t uevent_helper_show(struct kobject *kobj,
39 : : struct kobj_attribute *attr, char *buf)
40 : : {
41 : 0 : return sprintf(buf, "%s\n", uevent_helper);
42 : : }
43 : 0 : static ssize_t uevent_helper_store(struct kobject *kobj,
44 : : struct kobj_attribute *attr,
45 : : const char *buf, size_t count)
46 : : {
47 [ # # ]: 0 : if (count+1 > UEVENT_HELPER_PATH_LEN)
48 : : return -ENOENT;
49 : 0 : memcpy(uevent_helper, buf, count);
50 : 0 : uevent_helper[count] = '\0';
51 [ # # ][ # # ]: 0 : if (count && uevent_helper[count-1] == '\n')
52 : 0 : uevent_helper[count-1] = '\0';
53 : 0 : return count;
54 : : }
55 : : KERNEL_ATTR_RW(uevent_helper);
56 : :
57 : :
58 : : #ifdef CONFIG_PROFILING
59 : 0 : static ssize_t profiling_show(struct kobject *kobj,
60 : : struct kobj_attribute *attr, char *buf)
61 : : {
62 : 0 : return sprintf(buf, "%d\n", prof_on);
63 : : }
64 : 0 : 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 [ # # ]: 0 : 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 : 0 : profile_setup((char *)buf);
78 : 0 : ret = profile_init();
79 [ # # ]: 0 : if (ret)
80 : : return ret;
81 : 0 : ret = create_proc_profile();
82 [ # # ]: 0 : if (ret)
83 : : return ret;
84 : 0 : 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 (kstrtoul(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)sizeof(vmcoreinfo_note));
130 : : }
131 : : KERNEL_ATTR_RO(vmcoreinfo);
132 : :
133 : : #endif /* CONFIG_KEXEC */
134 : :
135 : : /* whether file capabilities are enabled */
136 : 0 : static ssize_t fscaps_show(struct kobject *kobj,
137 : : struct kobj_attribute *attr, char *buf)
138 : : {
139 : 0 : return sprintf(buf, "%d\n", file_caps_enabled);
140 : : }
141 : : KERNEL_ATTR_RO(fscaps);
142 : :
143 : : int rcu_expedited;
144 : 0 : static ssize_t rcu_expedited_show(struct kobject *kobj,
145 : : struct kobj_attribute *attr, char *buf)
146 : : {
147 : 0 : return sprintf(buf, "%d\n", rcu_expedited);
148 : : }
149 : 0 : static ssize_t rcu_expedited_store(struct kobject *kobj,
150 : : struct kobj_attribute *attr,
151 : : const char *buf, size_t count)
152 : : {
153 [ # # ]: 0 : if (kstrtoint(buf, 0, &rcu_expedited))
154 : : return -EINVAL;
155 : :
156 : 0 : return count;
157 : : }
158 : : KERNEL_ATTR_RW(rcu_expedited);
159 : :
160 : : /*
161 : : * Make /sys/kernel/notes give the raw contents of our kernel .notes section.
162 : : */
163 : : extern const void __start_notes __attribute__((weak));
164 : : extern const void __stop_notes __attribute__((weak));
165 : : #define notes_size (&__stop_notes - &__start_notes)
166 : :
167 : 0 : static ssize_t notes_read(struct file *filp, struct kobject *kobj,
168 : : struct bin_attribute *bin_attr,
169 : : char *buf, loff_t off, size_t count)
170 : : {
171 : 0 : memcpy(buf, &__start_notes + off, count);
172 : 0 : return count;
173 : : }
174 : :
175 : : static struct bin_attribute notes_attr = {
176 : : .attr = {
177 : : .name = "notes",
178 : : .mode = S_IRUGO,
179 : : },
180 : : .read = ¬es_read,
181 : : };
182 : :
183 : : struct kobject *kernel_kobj;
184 : : EXPORT_SYMBOL_GPL(kernel_kobj);
185 : :
186 : : static struct attribute * kernel_attrs[] = {
187 : : &fscaps_attr.attr,
188 : : &uevent_seqnum_attr.attr,
189 : : &uevent_helper_attr.attr,
190 : : #ifdef CONFIG_PROFILING
191 : : &profiling_attr.attr,
192 : : #endif
193 : : #ifdef CONFIG_KEXEC
194 : : &kexec_loaded_attr.attr,
195 : : &kexec_crash_loaded_attr.attr,
196 : : &kexec_crash_size_attr.attr,
197 : : &vmcoreinfo_attr.attr,
198 : : #endif
199 : : &rcu_expedited_attr.attr,
200 : : NULL
201 : : };
202 : :
203 : : static struct attribute_group kernel_attr_group = {
204 : : .attrs = kernel_attrs,
205 : : };
206 : :
207 : 0 : static int __init ksysfs_init(void)
208 : : {
209 : : int error;
210 : :
211 : 0 : kernel_kobj = kobject_create_and_add("kernel", NULL);
212 [ # # ]: 0 : if (!kernel_kobj) {
213 : : error = -ENOMEM;
214 : : goto exit;
215 : : }
216 : 0 : error = sysfs_create_group(kernel_kobj, &kernel_attr_group);
217 [ # # ]: 0 : if (error)
218 : : goto kset_exit;
219 : :
220 [ # # ]: 0 : if (notes_size > 0) {
221 : 0 : notes_attr.size = notes_size;
222 : 0 : error = sysfs_create_bin_file(kernel_kobj, ¬es_attr);
223 [ # # ]: 0 : if (error)
224 : : goto group_exit;
225 : : }
226 : :
227 : : return 0;
228 : :
229 : : group_exit:
230 : 0 : sysfs_remove_group(kernel_kobj, &kernel_attr_group);
231 : : kset_exit:
232 : 0 : kobject_put(kernel_kobj);
233 : : exit:
234 : 0 : return error;
235 : : }
236 : :
237 : : core_initcall(ksysfs_init);
|