Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/export.h>
0003 #include <linux/types.h>
0004 #include <linux/bits.h>
0005 #include "probe.h"
0006 
0007 static umode_t
0008 not_visible(struct kobject *kobj, struct attribute *attr, int i)
0009 {
0010     return 0;
0011 }
0012 
0013 /*
0014  * Accepts msr[] array with non populated entries as long as either
0015  * msr[i].msr is 0 or msr[i].grp is NULL. Note that the default sysfs
0016  * visibility is visible when group->is_visible callback is set.
0017  */
0018 unsigned long
0019 perf_msr_probe(struct perf_msr *msr, int cnt, bool zero, void *data)
0020 {
0021     unsigned long avail = 0;
0022     unsigned int bit;
0023     u64 val;
0024 
0025     if (cnt >= BITS_PER_LONG)
0026         return 0;
0027 
0028     for (bit = 0; bit < cnt; bit++) {
0029         if (!msr[bit].no_check) {
0030             struct attribute_group *grp = msr[bit].grp;
0031             u64 mask;
0032 
0033             /* skip entry with no group */
0034             if (!grp)
0035                 continue;
0036 
0037             grp->is_visible = not_visible;
0038 
0039             /* skip unpopulated entry */
0040             if (!msr[bit].msr)
0041                 continue;
0042 
0043             if (msr[bit].test && !msr[bit].test(bit, data))
0044                 continue;
0045             /* Virt sucks; you cannot tell if a R/O MSR is present :/ */
0046             if (rdmsrl_safe(msr[bit].msr, &val))
0047                 continue;
0048 
0049             mask = msr[bit].mask;
0050             if (!mask)
0051                 mask = ~0ULL;
0052             /* Disable zero counters if requested. */
0053             if (!zero && !(val & mask))
0054                 continue;
0055 
0056             grp->is_visible = NULL;
0057         }
0058         avail |= BIT(bit);
0059     }
0060 
0061     return avail;
0062 }
0063 EXPORT_SYMBOL_GPL(perf_msr_probe);