cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ksysfs.c (6410B)


      1// SPDX-License-Identifier: GPL-2.0-only
      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>
      7 */
      8
      9#include <linux/kobject.h>
     10#include <linux/string.h>
     11#include <linux/sysfs.h>
     12#include <linux/export.h>
     13#include <linux/init.h>
     14#include <linux/kexec.h>
     15#include <linux/profile.h>
     16#include <linux/stat.h>
     17#include <linux/sched.h>
     18#include <linux/capability.h>
     19#include <linux/compiler.h>
     20
     21#include <linux/rcupdate.h>	/* rcu_expedited and rcu_normal */
     22
     23#define KERNEL_ATTR_RO(_name) \
     24static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
     25
     26#define KERNEL_ATTR_RW(_name) \
     27static struct kobj_attribute _name##_attr = __ATTR_RW(_name)
     28
     29/* current uevent sequence number */
     30static 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}
     35KERNEL_ATTR_RO(uevent_seqnum);
     36
     37#ifdef CONFIG_UEVENT_HELPER
     38/* uevent helper program, used during early boot */
     39static ssize_t uevent_helper_show(struct kobject *kobj,
     40				  struct kobj_attribute *attr, char *buf)
     41{
     42	return sprintf(buf, "%s\n", uevent_helper);
     43}
     44static ssize_t uevent_helper_store(struct kobject *kobj,
     45				   struct kobj_attribute *attr,
     46				   const char *buf, size_t count)
     47{
     48	if (count+1 > UEVENT_HELPER_PATH_LEN)
     49		return -ENOENT;
     50	memcpy(uevent_helper, buf, count);
     51	uevent_helper[count] = '\0';
     52	if (count && uevent_helper[count-1] == '\n')
     53		uevent_helper[count-1] = '\0';
     54	return count;
     55}
     56KERNEL_ATTR_RW(uevent_helper);
     57#endif
     58
     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
     90#ifdef CONFIG_KEXEC_CORE
     91static ssize_t kexec_loaded_show(struct kobject *kobj,
     92				 struct kobj_attribute *attr, char *buf)
     93{
     94	return sprintf(buf, "%d\n", !!kexec_image);
     95}
     96KERNEL_ATTR_RO(kexec_loaded);
     97
     98static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
     99				       struct kobj_attribute *attr, char *buf)
    100{
    101	return sprintf(buf, "%d\n", kexec_crash_loaded());
    102}
    103KERNEL_ATTR_RO(kexec_crash_loaded);
    104
    105static ssize_t kexec_crash_size_show(struct kobject *kobj,
    106				       struct kobj_attribute *attr, char *buf)
    107{
    108	return sprintf(buf, "%zu\n", crash_get_memory_size());
    109}
    110static ssize_t kexec_crash_size_store(struct kobject *kobj,
    111				   struct kobj_attribute *attr,
    112				   const char *buf, size_t count)
    113{
    114	unsigned long cnt;
    115	int ret;
    116
    117	if (kstrtoul(buf, 0, &cnt))
    118		return -EINVAL;
    119
    120	ret = crash_shrink_memory(cnt);
    121	return ret < 0 ? ret : count;
    122}
    123KERNEL_ATTR_RW(kexec_crash_size);
    124
    125#endif /* CONFIG_KEXEC_CORE */
    126
    127#ifdef CONFIG_CRASH_CORE
    128
    129static ssize_t vmcoreinfo_show(struct kobject *kobj,
    130			       struct kobj_attribute *attr, char *buf)
    131{
    132	phys_addr_t vmcore_base = paddr_vmcoreinfo_note();
    133	return sprintf(buf, "%pa %x\n", &vmcore_base,
    134			(unsigned int)VMCOREINFO_NOTE_SIZE);
    135}
    136KERNEL_ATTR_RO(vmcoreinfo);
    137
    138#endif /* CONFIG_CRASH_CORE */
    139
    140/* whether file capabilities are enabled */
    141static ssize_t fscaps_show(struct kobject *kobj,
    142				  struct kobj_attribute *attr, char *buf)
    143{
    144	return sprintf(buf, "%d\n", file_caps_enabled);
    145}
    146KERNEL_ATTR_RO(fscaps);
    147
    148#ifndef CONFIG_TINY_RCU
    149int rcu_expedited;
    150static ssize_t rcu_expedited_show(struct kobject *kobj,
    151				  struct kobj_attribute *attr, char *buf)
    152{
    153	return sprintf(buf, "%d\n", READ_ONCE(rcu_expedited));
    154}
    155static ssize_t rcu_expedited_store(struct kobject *kobj,
    156				   struct kobj_attribute *attr,
    157				   const char *buf, size_t count)
    158{
    159	if (kstrtoint(buf, 0, &rcu_expedited))
    160		return -EINVAL;
    161
    162	return count;
    163}
    164KERNEL_ATTR_RW(rcu_expedited);
    165
    166int rcu_normal;
    167static ssize_t rcu_normal_show(struct kobject *kobj,
    168			       struct kobj_attribute *attr, char *buf)
    169{
    170	return sprintf(buf, "%d\n", READ_ONCE(rcu_normal));
    171}
    172static ssize_t rcu_normal_store(struct kobject *kobj,
    173				struct kobj_attribute *attr,
    174				const char *buf, size_t count)
    175{
    176	if (kstrtoint(buf, 0, &rcu_normal))
    177		return -EINVAL;
    178
    179	return count;
    180}
    181KERNEL_ATTR_RW(rcu_normal);
    182#endif /* #ifndef CONFIG_TINY_RCU */
    183
    184/*
    185 * Make /sys/kernel/notes give the raw contents of our kernel .notes section.
    186 */
    187extern const void __start_notes __weak;
    188extern const void __stop_notes __weak;
    189#define	notes_size (&__stop_notes - &__start_notes)
    190
    191static ssize_t notes_read(struct file *filp, struct kobject *kobj,
    192			  struct bin_attribute *bin_attr,
    193			  char *buf, loff_t off, size_t count)
    194{
    195	memcpy(buf, &__start_notes + off, count);
    196	return count;
    197}
    198
    199static struct bin_attribute notes_attr __ro_after_init  = {
    200	.attr = {
    201		.name = "notes",
    202		.mode = S_IRUGO,
    203	},
    204	.read = &notes_read,
    205};
    206
    207struct kobject *kernel_kobj;
    208EXPORT_SYMBOL_GPL(kernel_kobj);
    209
    210static struct attribute * kernel_attrs[] = {
    211	&fscaps_attr.attr,
    212	&uevent_seqnum_attr.attr,
    213#ifdef CONFIG_UEVENT_HELPER
    214	&uevent_helper_attr.attr,
    215#endif
    216#ifdef CONFIG_PROFILING
    217	&profiling_attr.attr,
    218#endif
    219#ifdef CONFIG_KEXEC_CORE
    220	&kexec_loaded_attr.attr,
    221	&kexec_crash_loaded_attr.attr,
    222	&kexec_crash_size_attr.attr,
    223#endif
    224#ifdef CONFIG_CRASH_CORE
    225	&vmcoreinfo_attr.attr,
    226#endif
    227#ifndef CONFIG_TINY_RCU
    228	&rcu_expedited_attr.attr,
    229	&rcu_normal_attr.attr,
    230#endif
    231	NULL
    232};
    233
    234static const struct attribute_group kernel_attr_group = {
    235	.attrs = kernel_attrs,
    236};
    237
    238static int __init ksysfs_init(void)
    239{
    240	int error;
    241
    242	kernel_kobj = kobject_create_and_add("kernel", NULL);
    243	if (!kernel_kobj) {
    244		error = -ENOMEM;
    245		goto exit;
    246	}
    247	error = sysfs_create_group(kernel_kobj, &kernel_attr_group);
    248	if (error)
    249		goto kset_exit;
    250
    251	if (notes_size > 0) {
    252		notes_attr.size = notes_size;
    253		error = sysfs_create_bin_file(kernel_kobj, &notes_attr);
    254		if (error)
    255			goto group_exit;
    256	}
    257
    258	return 0;
    259
    260group_exit:
    261	sysfs_remove_group(kernel_kobj, &kernel_attr_group);
    262kset_exit:
    263	kobject_put(kernel_kobj);
    264exit:
    265	return error;
    266}
    267
    268core_initcall(ksysfs_init);