Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * kernel/ksysfs.c - sysfs attributes in /sys/kernel, which
0004  *           are not related to any other subsystem
0005  *
0006  * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
0007  */
0008 
0009 #include <linux/kobject.h>
0010 #include <linux/string.h>
0011 #include <linux/sysfs.h>
0012 #include <linux/export.h>
0013 #include <linux/init.h>
0014 #include <linux/kexec.h>
0015 #include <linux/profile.h>
0016 #include <linux/stat.h>
0017 #include <linux/sched.h>
0018 #include <linux/capability.h>
0019 #include <linux/compiler.h>
0020 
0021 #include <linux/rcupdate.h> /* rcu_expedited and rcu_normal */
0022 
0023 #define KERNEL_ATTR_RO(_name) \
0024 static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
0025 
0026 #define KERNEL_ATTR_RW(_name) \
0027 static struct kobj_attribute _name##_attr = __ATTR_RW(_name)
0028 
0029 /* current uevent sequence number */
0030 static ssize_t uevent_seqnum_show(struct kobject *kobj,
0031                   struct kobj_attribute *attr, char *buf)
0032 {
0033     return sprintf(buf, "%llu\n", (unsigned long long)uevent_seqnum);
0034 }
0035 KERNEL_ATTR_RO(uevent_seqnum);
0036 
0037 #ifdef CONFIG_UEVENT_HELPER
0038 /* uevent helper program, used during early boot */
0039 static ssize_t uevent_helper_show(struct kobject *kobj,
0040                   struct kobj_attribute *attr, char *buf)
0041 {
0042     return sprintf(buf, "%s\n", uevent_helper);
0043 }
0044 static ssize_t uevent_helper_store(struct kobject *kobj,
0045                    struct kobj_attribute *attr,
0046                    const char *buf, size_t count)
0047 {
0048     if (count+1 > UEVENT_HELPER_PATH_LEN)
0049         return -ENOENT;
0050     memcpy(uevent_helper, buf, count);
0051     uevent_helper[count] = '\0';
0052     if (count && uevent_helper[count-1] == '\n')
0053         uevent_helper[count-1] = '\0';
0054     return count;
0055 }
0056 KERNEL_ATTR_RW(uevent_helper);
0057 #endif
0058 
0059 #ifdef CONFIG_PROFILING
0060 static ssize_t profiling_show(struct kobject *kobj,
0061                   struct kobj_attribute *attr, char *buf)
0062 {
0063     return sprintf(buf, "%d\n", prof_on);
0064 }
0065 static ssize_t profiling_store(struct kobject *kobj,
0066                    struct kobj_attribute *attr,
0067                    const char *buf, size_t count)
0068 {
0069     int ret;
0070 
0071     if (prof_on)
0072         return -EEXIST;
0073     /*
0074      * This eventually calls into get_option() which
0075      * has a ton of callers and is not const.  It is
0076      * easiest to cast it away here.
0077      */
0078     profile_setup((char *)buf);
0079     ret = profile_init();
0080     if (ret)
0081         return ret;
0082     ret = create_proc_profile();
0083     if (ret)
0084         return ret;
0085     return count;
0086 }
0087 KERNEL_ATTR_RW(profiling);
0088 #endif
0089 
0090 #ifdef CONFIG_KEXEC_CORE
0091 static ssize_t kexec_loaded_show(struct kobject *kobj,
0092                  struct kobj_attribute *attr, char *buf)
0093 {
0094     return sprintf(buf, "%d\n", !!kexec_image);
0095 }
0096 KERNEL_ATTR_RO(kexec_loaded);
0097 
0098 static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
0099                        struct kobj_attribute *attr, char *buf)
0100 {
0101     return sprintf(buf, "%d\n", kexec_crash_loaded());
0102 }
0103 KERNEL_ATTR_RO(kexec_crash_loaded);
0104 
0105 static ssize_t kexec_crash_size_show(struct kobject *kobj,
0106                        struct kobj_attribute *attr, char *buf)
0107 {
0108     return sprintf(buf, "%zu\n", crash_get_memory_size());
0109 }
0110 static ssize_t kexec_crash_size_store(struct kobject *kobj,
0111                    struct kobj_attribute *attr,
0112                    const char *buf, size_t count)
0113 {
0114     unsigned long cnt;
0115     int ret;
0116 
0117     if (kstrtoul(buf, 0, &cnt))
0118         return -EINVAL;
0119 
0120     ret = crash_shrink_memory(cnt);
0121     return ret < 0 ? ret : count;
0122 }
0123 KERNEL_ATTR_RW(kexec_crash_size);
0124 
0125 #endif /* CONFIG_KEXEC_CORE */
0126 
0127 #ifdef CONFIG_CRASH_CORE
0128 
0129 static ssize_t vmcoreinfo_show(struct kobject *kobj,
0130                    struct kobj_attribute *attr, char *buf)
0131 {
0132     phys_addr_t vmcore_base = paddr_vmcoreinfo_note();
0133     return sprintf(buf, "%pa %x\n", &vmcore_base,
0134             (unsigned int)VMCOREINFO_NOTE_SIZE);
0135 }
0136 KERNEL_ATTR_RO(vmcoreinfo);
0137 
0138 #endif /* CONFIG_CRASH_CORE */
0139 
0140 /* whether file capabilities are enabled */
0141 static ssize_t fscaps_show(struct kobject *kobj,
0142                   struct kobj_attribute *attr, char *buf)
0143 {
0144     return sprintf(buf, "%d\n", file_caps_enabled);
0145 }
0146 KERNEL_ATTR_RO(fscaps);
0147 
0148 #ifndef CONFIG_TINY_RCU
0149 int rcu_expedited;
0150 static ssize_t rcu_expedited_show(struct kobject *kobj,
0151                   struct kobj_attribute *attr, char *buf)
0152 {
0153     return sprintf(buf, "%d\n", READ_ONCE(rcu_expedited));
0154 }
0155 static ssize_t rcu_expedited_store(struct kobject *kobj,
0156                    struct kobj_attribute *attr,
0157                    const char *buf, size_t count)
0158 {
0159     if (kstrtoint(buf, 0, &rcu_expedited))
0160         return -EINVAL;
0161 
0162     return count;
0163 }
0164 KERNEL_ATTR_RW(rcu_expedited);
0165 
0166 int rcu_normal;
0167 static ssize_t rcu_normal_show(struct kobject *kobj,
0168                    struct kobj_attribute *attr, char *buf)
0169 {
0170     return sprintf(buf, "%d\n", READ_ONCE(rcu_normal));
0171 }
0172 static ssize_t rcu_normal_store(struct kobject *kobj,
0173                 struct kobj_attribute *attr,
0174                 const char *buf, size_t count)
0175 {
0176     if (kstrtoint(buf, 0, &rcu_normal))
0177         return -EINVAL;
0178 
0179     return count;
0180 }
0181 KERNEL_ATTR_RW(rcu_normal);
0182 #endif /* #ifndef CONFIG_TINY_RCU */
0183 
0184 /*
0185  * Make /sys/kernel/notes give the raw contents of our kernel .notes section.
0186  */
0187 extern const void __start_notes __weak;
0188 extern const void __stop_notes __weak;
0189 #define notes_size (&__stop_notes - &__start_notes)
0190 
0191 static ssize_t notes_read(struct file *filp, struct kobject *kobj,
0192               struct bin_attribute *bin_attr,
0193               char *buf, loff_t off, size_t count)
0194 {
0195     memcpy(buf, &__start_notes + off, count);
0196     return count;
0197 }
0198 
0199 static struct bin_attribute notes_attr __ro_after_init  = {
0200     .attr = {
0201         .name = "notes",
0202         .mode = S_IRUGO,
0203     },
0204     .read = &notes_read,
0205 };
0206 
0207 struct kobject *kernel_kobj;
0208 EXPORT_SYMBOL_GPL(kernel_kobj);
0209 
0210 static struct attribute * kernel_attrs[] = {
0211     &fscaps_attr.attr,
0212     &uevent_seqnum_attr.attr,
0213 #ifdef CONFIG_UEVENT_HELPER
0214     &uevent_helper_attr.attr,
0215 #endif
0216 #ifdef CONFIG_PROFILING
0217     &profiling_attr.attr,
0218 #endif
0219 #ifdef CONFIG_KEXEC_CORE
0220     &kexec_loaded_attr.attr,
0221     &kexec_crash_loaded_attr.attr,
0222     &kexec_crash_size_attr.attr,
0223 #endif
0224 #ifdef CONFIG_CRASH_CORE
0225     &vmcoreinfo_attr.attr,
0226 #endif
0227 #ifndef CONFIG_TINY_RCU
0228     &rcu_expedited_attr.attr,
0229     &rcu_normal_attr.attr,
0230 #endif
0231     NULL
0232 };
0233 
0234 static const struct attribute_group kernel_attr_group = {
0235     .attrs = kernel_attrs,
0236 };
0237 
0238 static int __init ksysfs_init(void)
0239 {
0240     int error;
0241 
0242     kernel_kobj = kobject_create_and_add("kernel", NULL);
0243     if (!kernel_kobj) {
0244         error = -ENOMEM;
0245         goto exit;
0246     }
0247     error = sysfs_create_group(kernel_kobj, &kernel_attr_group);
0248     if (error)
0249         goto kset_exit;
0250 
0251     if (notes_size > 0) {
0252         notes_attr.size = notes_size;
0253         error = sysfs_create_bin_file(kernel_kobj, &notes_attr);
0254         if (error)
0255             goto group_exit;
0256     }
0257 
0258     return 0;
0259 
0260 group_exit:
0261     sysfs_remove_group(kernel_kobj, &kernel_attr_group);
0262 kset_exit:
0263     kobject_put(kernel_kobj);
0264 exit:
0265     return error;
0266 }
0267 
0268 core_initcall(ksysfs_init);