Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : #include <linux/export.h> 3 : #include <linux/types.h> 4 : #include <linux/bits.h> 5 : #include "probe.h" 6 : 7 : static umode_t 8 8 : not_visible(struct kobject *kobj, struct attribute *attr, int i) 9 : { 10 8 : return 0; 11 : } 12 : 13 : /* 14 : * Accepts msr[] array with non populated entries as long as either 15 : * msr[i].msr is 0 or msr[i].grp is NULL. Note that the default sysfs 16 : * visibility is visible when group->is_visible callback is set. 17 : */ 18 : unsigned long 19 1 : perf_msr_probe(struct perf_msr *msr, int cnt, bool zero, void *data) 20 : { 21 1 : unsigned long avail = 0; 22 1 : unsigned int bit; 23 1 : u64 val; 24 : 25 1 : if (cnt >= BITS_PER_LONG) 26 : return 0; 27 : 28 9 : for (bit = 0; bit < cnt; bit++) { 29 8 : if (!msr[bit].no_check) { 30 7 : struct attribute_group *grp = msr[bit].grp; 31 7 : u64 mask; 32 : 33 : /* skip entry with no group */ 34 7 : if (!grp) 35 0 : continue; 36 : 37 7 : grp->is_visible = not_visible; 38 : 39 : /* skip unpopulated entry */ 40 7 : if (!msr[bit].msr) 41 0 : continue; 42 : 43 7 : if (msr[bit].test && !msr[bit].test(bit, data)) 44 6 : continue; 45 : /* Virt sucks; you cannot tell if a R/O MSR is present :/ */ 46 1 : if (rdmsrl_safe(msr[bit].msr, &val)) 47 0 : continue; 48 : 49 1 : mask = msr[bit].mask; 50 1 : if (!mask) 51 1 : mask = ~0ULL; 52 : /* Disable zero counters if requested. */ 53 1 : if (!zero && !(val & mask)) 54 0 : continue; 55 : 56 1 : grp->is_visible = NULL; 57 : } 58 2 : avail |= BIT(bit); 59 : } 60 : 61 : return avail; 62 : } 63 : EXPORT_SYMBOL_GPL(perf_msr_probe);