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