Merge tag 'block-6.1-2022-11-18' of git://git.kernel.dk/linux
[linux-block.git] / kernel / ksysfs.c
CommitLineData
468e15fd 1// SPDX-License-Identifier: GPL-2.0-only
1da177e4
LT
2/*
3 * kernel/ksysfs.c - sysfs attributes in /sys/kernel, which
4 * are not related to any other subsystem
5 *
6 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
1da177e4
LT
7 */
8
1da177e4
LT
9#include <linux/kobject.h>
10#include <linux/string.h>
11#include <linux/sysfs.h>
9984de1a 12#include <linux/export.h>
1da177e4 13#include <linux/init.h>
c330dda9 14#include <linux/kexec.h>
22b8ce94 15#include <linux/profile.h>
1596425f 16#include <linux/stat.h>
5cb350ba 17#include <linux/sched.h>
088ab0b4 18#include <linux/capability.h>
52f5684c 19#include <linux/compiler.h>
1da177e4 20
5a9be7c6 21#include <linux/rcupdate.h> /* rcu_expedited and rcu_normal */
7a754743 22
1da177e4 23#define KERNEL_ATTR_RO(_name) \
386f275f 24static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
1da177e4
LT
25
26#define KERNEL_ATTR_RW(_name) \
a7cd9a53 27static struct kobj_attribute _name##_attr = __ATTR_RW(_name)
1da177e4 28
0f76e5ac 29/* current uevent sequence number */
386f275f
KS
30static ssize_t uevent_seqnum_show(struct kobject *kobj,
31 struct kobj_attribute *attr, char *buf)
1da177e4 32{
386f275f 33 return sprintf(buf, "%llu\n", (unsigned long long)uevent_seqnum);
1da177e4 34}
0f76e5ac
KS
35KERNEL_ATTR_RO(uevent_seqnum);
36
86d56134 37#ifdef CONFIG_UEVENT_HELPER
af665852 38/* uevent helper program, used during early boot */
386f275f
KS
39static ssize_t uevent_helper_show(struct kobject *kobj,
40 struct kobj_attribute *attr, char *buf)
0f76e5ac 41{
386f275f 42 return sprintf(buf, "%s\n", uevent_helper);
0f76e5ac 43}
386f275f
KS
44static ssize_t uevent_helper_store(struct kobject *kobj,
45 struct kobj_attribute *attr,
46 const char *buf, size_t count)
0f76e5ac 47{
312c004d 48 if (count+1 > UEVENT_HELPER_PATH_LEN)
0f76e5ac 49 return -ENOENT;
386f275f 50 memcpy(uevent_helper, buf, count);
312c004d
KS
51 uevent_helper[count] = '\0';
52 if (count && uevent_helper[count-1] == '\n')
53 uevent_helper[count-1] = '\0';
0f76e5ac
KS
54 return count;
55}
56KERNEL_ATTR_RW(uevent_helper);
86d56134 57#endif
1da177e4 58
22b8ce94
DH
59#ifdef CONFIG_PROFILING
60static ssize_t profiling_show(struct kobject *kobj,
61 struct kobj_attribute *attr, char *buf)
62{
63 return sprintf(buf, "%d\n", prof_on);
64}
65static ssize_t profiling_store(struct kobject *kobj,
66 struct kobj_attribute *attr,
67 const char *buf, size_t count)
68{
69 int ret;
70
71 if (prof_on)
72 return -EEXIST;
73 /*
74 * This eventually calls into get_option() which
75 * has a ton of callers and is not const. It is
76 * easiest to cast it away here.
77 */
78 profile_setup((char *)buf);
79 ret = profile_init();
80 if (ret)
81 return ret;
82 ret = create_proc_profile();
83 if (ret)
84 return ret;
85 return count;
86}
87KERNEL_ATTR_RW(profiling);
88#endif
89
2965faa5 90#ifdef CONFIG_KEXEC_CORE
386f275f
KS
91static ssize_t kexec_loaded_show(struct kobject *kobj,
92 struct kobj_attribute *attr, char *buf)
c330dda9 93{
386f275f 94 return sprintf(buf, "%d\n", !!kexec_image);
c330dda9
JM
95}
96KERNEL_ATTR_RO(kexec_loaded);
97
386f275f
KS
98static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
99 struct kobj_attribute *attr, char *buf)
c330dda9 100{
21db79e8 101 return sprintf(buf, "%d\n", kexec_crash_loaded());
c330dda9
JM
102}
103KERNEL_ATTR_RO(kexec_crash_loaded);
fd59d231 104
06a7f711
AW
105static ssize_t kexec_crash_size_show(struct kobject *kobj,
106 struct kobj_attribute *attr, char *buf)
107{
7bb5da0d
VS
108 ssize_t size = crash_get_memory_size();
109
110 if (size < 0)
111 return size;
112
113 return sprintf(buf, "%zd\n", size);
06a7f711
AW
114}
115static ssize_t kexec_crash_size_store(struct kobject *kobj,
116 struct kobj_attribute *attr,
117 const char *buf, size_t count)
118{
119 unsigned long cnt;
120 int ret;
121
6072ddc8 122 if (kstrtoul(buf, 0, &cnt))
06a7f711
AW
123 return -EINVAL;
124
125 ret = crash_shrink_memory(cnt);
126 return ret < 0 ? ret : count;
127}
128KERNEL_ATTR_RW(kexec_crash_size);
129
692f66f2
HB
130#endif /* CONFIG_KEXEC_CORE */
131
132#ifdef CONFIG_CRASH_CORE
133
386f275f
KS
134static ssize_t vmcoreinfo_show(struct kobject *kobj,
135 struct kobj_attribute *attr, char *buf)
fd59d231 136{
dae28018
RK
137 phys_addr_t vmcore_base = paddr_vmcoreinfo_note();
138 return sprintf(buf, "%pa %x\n", &vmcore_base,
203e9e41 139 (unsigned int)VMCOREINFO_NOTE_SIZE);
fd59d231
KO
140}
141KERNEL_ATTR_RO(vmcoreinfo);
142
692f66f2 143#endif /* CONFIG_CRASH_CORE */
c330dda9 144
088ab0b4
LN
145/* whether file capabilities are enabled */
146static ssize_t fscaps_show(struct kobject *kobj,
147 struct kobj_attribute *attr, char *buf)
148{
149 return sprintf(buf, "%d\n", file_caps_enabled);
150}
151KERNEL_ATTR_RO(fscaps);
152
79cfea02 153#ifndef CONFIG_TINY_RCU
3705b88d
AM
154int rcu_expedited;
155static ssize_t rcu_expedited_show(struct kobject *kobj,
156 struct kobj_attribute *attr, char *buf)
157{
5a9be7c6 158 return sprintf(buf, "%d\n", READ_ONCE(rcu_expedited));
3705b88d
AM
159}
160static ssize_t rcu_expedited_store(struct kobject *kobj,
161 struct kobj_attribute *attr,
162 const char *buf, size_t count)
163{
164 if (kstrtoint(buf, 0, &rcu_expedited))
165 return -EINVAL;
166
167 return count;
168}
169KERNEL_ATTR_RW(rcu_expedited);
170
5a9be7c6
PM
171int rcu_normal;
172static ssize_t rcu_normal_show(struct kobject *kobj,
173 struct kobj_attribute *attr, char *buf)
174{
175 return sprintf(buf, "%d\n", READ_ONCE(rcu_normal));
176}
177static ssize_t rcu_normal_store(struct kobject *kobj,
178 struct kobj_attribute *attr,
179 const char *buf, size_t count)
180{
181 if (kstrtoint(buf, 0, &rcu_normal))
182 return -EINVAL;
183
184 return count;
185}
186KERNEL_ATTR_RW(rcu_normal);
79cfea02 187#endif /* #ifndef CONFIG_TINY_RCU */
5a9be7c6 188
da1a679c
RM
189/*
190 * Make /sys/kernel/notes give the raw contents of our kernel .notes section.
191 */
52f5684c
GID
192extern const void __start_notes __weak;
193extern const void __stop_notes __weak;
da1a679c
RM
194#define notes_size (&__stop_notes - &__start_notes)
195
2c3c8bea
CW
196static ssize_t notes_read(struct file *filp, struct kobject *kobj,
197 struct bin_attribute *bin_attr,
da1a679c
RM
198 char *buf, loff_t off, size_t count)
199{
200 memcpy(buf, &__start_notes + off, count);
201 return count;
202}
203
738bc38d 204static struct bin_attribute notes_attr __ro_after_init = {
da1a679c
RM
205 .attr = {
206 .name = "notes",
207 .mode = S_IRUGO,
208 },
209 .read = &notes_read,
210};
211
0ff21e46
GKH
212struct kobject *kernel_kobj;
213EXPORT_SYMBOL_GPL(kernel_kobj);
1da177e4
LT
214
215static struct attribute * kernel_attrs[] = {
088ab0b4 216 &fscaps_attr.attr,
0f76e5ac 217 &uevent_seqnum_attr.attr,
86d56134 218#ifdef CONFIG_UEVENT_HELPER
0f76e5ac 219 &uevent_helper_attr.attr,
86d56134 220#endif
22b8ce94
DH
221#ifdef CONFIG_PROFILING
222 &profiling_attr.attr,
223#endif
2965faa5 224#ifdef CONFIG_KEXEC_CORE
c330dda9
JM
225 &kexec_loaded_attr.attr,
226 &kexec_crash_loaded_attr.attr,
06a7f711 227 &kexec_crash_size_attr.attr,
692f66f2
HB
228#endif
229#ifdef CONFIG_CRASH_CORE
fd59d231 230 &vmcoreinfo_attr.attr,
1da177e4 231#endif
79cfea02 232#ifndef CONFIG_TINY_RCU
3705b88d 233 &rcu_expedited_attr.attr,
5a9be7c6 234 &rcu_normal_attr.attr,
79cfea02 235#endif
1da177e4
LT
236 NULL
237};
238
9dcdcea1 239static const struct attribute_group kernel_attr_group = {
1da177e4
LT
240 .attrs = kernel_attrs,
241};
242
243static int __init ksysfs_init(void)
244{
bd35b93d 245 int error;
1da177e4 246
0ff21e46
GKH
247 kernel_kobj = kobject_create_and_add("kernel", NULL);
248 if (!kernel_kobj) {
bd35b93d
GKH
249 error = -ENOMEM;
250 goto exit;
251 }
0ff21e46 252 error = sysfs_create_group(kernel_kobj, &kernel_attr_group);
bd35b93d
GKH
253 if (error)
254 goto kset_exit;
255
256 if (notes_size > 0) {
da1a679c 257 notes_attr.size = notes_size;
0ff21e46 258 error = sysfs_create_bin_file(kernel_kobj, &notes_attr);
bd35b93d
GKH
259 if (error)
260 goto group_exit;
da1a679c
RM
261 }
262
bd35b93d
GKH
263 return 0;
264
bd35b93d 265group_exit:
0ff21e46 266 sysfs_remove_group(kernel_kobj, &kernel_attr_group);
bd35b93d 267kset_exit:
78a2d906 268 kobject_put(kernel_kobj);
bd35b93d 269exit:
1da177e4
LT
270 return error;
271}
272
273core_initcall(ksysfs_init);