forked from luck/tmp_suning_uos_patched
4c953f8794
This patch modifies perf_probe_msr() by allowing passing of struct perf_msr array where some entries are not populated, i.e., they have either an msr address of 0 or no attribute_group pointer. This helps with certain call paths, e.g., RAPL. In case the grp is NULL, the default sysfs visibility rule applies which is to make the group visible. Without the patch, you would get a kernel crash with a NULL group. Signed-off-by: Stephane Eranian <eranian@google.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200527224659.206129-5-eranian@google.com
59 lines
1.2 KiB
C
59 lines
1.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <linux/export.h>
|
|
#include <linux/types.h>
|
|
#include <linux/bits.h>
|
|
#include "probe.h"
|
|
|
|
static umode_t
|
|
not_visible(struct kobject *kobj, struct attribute *attr, int i)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Accepts msr[] array with non populated entries as long as either
|
|
* msr[i].msr is 0 or msr[i].grp is NULL. Note that the default sysfs
|
|
* visibility is visible when group->is_visible callback is set.
|
|
*/
|
|
unsigned long
|
|
perf_msr_probe(struct perf_msr *msr, int cnt, bool zero, void *data)
|
|
{
|
|
unsigned long avail = 0;
|
|
unsigned int bit;
|
|
u64 val;
|
|
|
|
if (cnt >= BITS_PER_LONG)
|
|
return 0;
|
|
|
|
for (bit = 0; bit < cnt; bit++) {
|
|
if (!msr[bit].no_check) {
|
|
struct attribute_group *grp = msr[bit].grp;
|
|
|
|
/* skip entry with no group */
|
|
if (!grp)
|
|
continue;
|
|
|
|
grp->is_visible = not_visible;
|
|
|
|
/* skip unpopulated entry */
|
|
if (!msr[bit].msr)
|
|
continue;
|
|
|
|
if (msr[bit].test && !msr[bit].test(bit, data))
|
|
continue;
|
|
/* Virt sucks; you cannot tell if a R/O MSR is present :/ */
|
|
if (rdmsrl_safe(msr[bit].msr, &val))
|
|
continue;
|
|
/* Disable zero counters if requested. */
|
|
if (!zero && !val)
|
|
continue;
|
|
|
|
grp->is_visible = NULL;
|
|
}
|
|
avail |= BIT(bit);
|
|
}
|
|
|
|
return avail;
|
|
}
|
|
EXPORT_SYMBOL_GPL(perf_msr_probe);
|