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

topology.c (5164B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * driver/base/topology.c - Populate sysfs with cpu topology information
      4 *
      5 * Written by: Zhang Yanmin, Intel Corporation
      6 *
      7 * Copyright (C) 2006, Intel Corp.
      8 *
      9 * All rights reserved.
     10 */
     11#include <linux/mm.h>
     12#include <linux/cpu.h>
     13#include <linux/module.h>
     14#include <linux/hardirq.h>
     15#include <linux/topology.h>
     16
     17#define define_id_show_func(name, fmt)					\
     18static ssize_t name##_show(struct device *dev,				\
     19			   struct device_attribute *attr, char *buf)	\
     20{									\
     21	return sysfs_emit(buf, fmt "\n", topology_##name(dev->id));	\
     22}
     23
     24#define define_siblings_read_func(name, mask)					\
     25static ssize_t name##_read(struct file *file, struct kobject *kobj,		\
     26			   struct bin_attribute *attr, char *buf,		\
     27			   loff_t off, size_t count)				\
     28{										\
     29	struct device *dev = kobj_to_dev(kobj);                                 \
     30										\
     31	return cpumap_print_bitmask_to_buf(buf, topology_##mask(dev->id),	\
     32					   off, count);                         \
     33}										\
     34										\
     35static ssize_t name##_list_read(struct file *file, struct kobject *kobj,	\
     36				struct bin_attribute *attr, char *buf,		\
     37				loff_t off, size_t count)			\
     38{										\
     39	struct device *dev = kobj_to_dev(kobj);					\
     40										\
     41	return cpumap_print_list_to_buf(buf, topology_##mask(dev->id),		\
     42					off, count);				\
     43}
     44
     45define_id_show_func(physical_package_id, "%d");
     46static DEVICE_ATTR_RO(physical_package_id);
     47
     48#ifdef TOPOLOGY_DIE_SYSFS
     49define_id_show_func(die_id, "%d");
     50static DEVICE_ATTR_RO(die_id);
     51#endif
     52
     53#ifdef TOPOLOGY_CLUSTER_SYSFS
     54define_id_show_func(cluster_id, "%d");
     55static DEVICE_ATTR_RO(cluster_id);
     56#endif
     57
     58define_id_show_func(core_id, "%d");
     59static DEVICE_ATTR_RO(core_id);
     60
     61define_id_show_func(ppin, "0x%llx");
     62static DEVICE_ATTR_ADMIN_RO(ppin);
     63
     64define_siblings_read_func(thread_siblings, sibling_cpumask);
     65static BIN_ATTR_RO(thread_siblings, 0);
     66static BIN_ATTR_RO(thread_siblings_list, 0);
     67
     68define_siblings_read_func(core_cpus, sibling_cpumask);
     69static BIN_ATTR_RO(core_cpus, 0);
     70static BIN_ATTR_RO(core_cpus_list, 0);
     71
     72define_siblings_read_func(core_siblings, core_cpumask);
     73static BIN_ATTR_RO(core_siblings, 0);
     74static BIN_ATTR_RO(core_siblings_list, 0);
     75
     76#ifdef TOPOLOGY_CLUSTER_SYSFS
     77define_siblings_read_func(cluster_cpus, cluster_cpumask);
     78static BIN_ATTR_RO(cluster_cpus, 0);
     79static BIN_ATTR_RO(cluster_cpus_list, 0);
     80#endif
     81
     82#ifdef TOPOLOGY_DIE_SYSFS
     83define_siblings_read_func(die_cpus, die_cpumask);
     84static BIN_ATTR_RO(die_cpus, 0);
     85static BIN_ATTR_RO(die_cpus_list, 0);
     86#endif
     87
     88define_siblings_read_func(package_cpus, core_cpumask);
     89static BIN_ATTR_RO(package_cpus, 0);
     90static BIN_ATTR_RO(package_cpus_list, 0);
     91
     92#ifdef TOPOLOGY_BOOK_SYSFS
     93define_id_show_func(book_id, "%d");
     94static DEVICE_ATTR_RO(book_id);
     95define_siblings_read_func(book_siblings, book_cpumask);
     96static BIN_ATTR_RO(book_siblings, 0);
     97static BIN_ATTR_RO(book_siblings_list, 0);
     98#endif
     99
    100#ifdef TOPOLOGY_DRAWER_SYSFS
    101define_id_show_func(drawer_id, "%d");
    102static DEVICE_ATTR_RO(drawer_id);
    103define_siblings_read_func(drawer_siblings, drawer_cpumask);
    104static BIN_ATTR_RO(drawer_siblings, 0);
    105static BIN_ATTR_RO(drawer_siblings_list, 0);
    106#endif
    107
    108static struct bin_attribute *bin_attrs[] = {
    109	&bin_attr_core_cpus,
    110	&bin_attr_core_cpus_list,
    111	&bin_attr_thread_siblings,
    112	&bin_attr_thread_siblings_list,
    113	&bin_attr_core_siblings,
    114	&bin_attr_core_siblings_list,
    115#ifdef TOPOLOGY_CLUSTER_SYSFS
    116	&bin_attr_cluster_cpus,
    117	&bin_attr_cluster_cpus_list,
    118#endif
    119#ifdef TOPOLOGY_DIE_SYSFS
    120	&bin_attr_die_cpus,
    121	&bin_attr_die_cpus_list,
    122#endif
    123	&bin_attr_package_cpus,
    124	&bin_attr_package_cpus_list,
    125#ifdef TOPOLOGY_BOOK_SYSFS
    126	&bin_attr_book_siblings,
    127	&bin_attr_book_siblings_list,
    128#endif
    129#ifdef TOPOLOGY_DRAWER_SYSFS
    130	&bin_attr_drawer_siblings,
    131	&bin_attr_drawer_siblings_list,
    132#endif
    133	NULL
    134};
    135
    136static struct attribute *default_attrs[] = {
    137	&dev_attr_physical_package_id.attr,
    138#ifdef TOPOLOGY_DIE_SYSFS
    139	&dev_attr_die_id.attr,
    140#endif
    141#ifdef TOPOLOGY_CLUSTER_SYSFS
    142	&dev_attr_cluster_id.attr,
    143#endif
    144	&dev_attr_core_id.attr,
    145#ifdef TOPOLOGY_BOOK_SYSFS
    146	&dev_attr_book_id.attr,
    147#endif
    148#ifdef TOPOLOGY_DRAWER_SYSFS
    149	&dev_attr_drawer_id.attr,
    150#endif
    151	&dev_attr_ppin.attr,
    152	NULL
    153};
    154
    155static umode_t topology_is_visible(struct kobject *kobj,
    156				   struct attribute *attr, int unused)
    157{
    158	if (attr == &dev_attr_ppin.attr && !topology_ppin(kobj_to_dev(kobj)->id))
    159		return 0;
    160
    161	return attr->mode;
    162}
    163
    164static const struct attribute_group topology_attr_group = {
    165	.attrs = default_attrs,
    166	.bin_attrs = bin_attrs,
    167	.is_visible = topology_is_visible,
    168	.name = "topology"
    169};
    170
    171/* Add/Remove cpu_topology interface for CPU device */
    172static int topology_add_dev(unsigned int cpu)
    173{
    174	struct device *dev = get_cpu_device(cpu);
    175
    176	return sysfs_create_group(&dev->kobj, &topology_attr_group);
    177}
    178
    179static int topology_remove_dev(unsigned int cpu)
    180{
    181	struct device *dev = get_cpu_device(cpu);
    182
    183	sysfs_remove_group(&dev->kobj, &topology_attr_group);
    184	return 0;
    185}
    186
    187static int __init topology_sysfs_init(void)
    188{
    189	return cpuhp_setup_state(CPUHP_TOPOLOGY_PREPARE,
    190				 "base/topology:prepare", topology_add_dev,
    191				 topology_remove_dev);
    192}
    193
    194device_initcall(topology_sysfs_init);