static int validate_ctr_version()

in kernel/perf_cpum_cf.c [262:321]


static int validate_ctr_version(const struct hw_perf_event *hwc,
				enum cpumf_ctr_set set)
{
	struct cpu_cf_events *cpuhw;
	int err = 0;
	u16 mtdiag_ctl;

	cpuhw = &get_cpu_var(cpu_cf_events);

	/* check required version for counter sets */
	switch (set) {
	case CPUMF_CTR_SET_BASIC:
	case CPUMF_CTR_SET_USER:
		if (cpuhw->info.cfvn < 1)
			err = -EOPNOTSUPP;
		break;
	case CPUMF_CTR_SET_CRYPTO:
		if ((cpuhw->info.csvn >= 1 && cpuhw->info.csvn <= 5 &&
		     hwc->config > 79) ||
		    (cpuhw->info.csvn >= 6 && hwc->config > 83))
			err = -EOPNOTSUPP;
		break;
	case CPUMF_CTR_SET_EXT:
		if (cpuhw->info.csvn < 1)
			err = -EOPNOTSUPP;
		if ((cpuhw->info.csvn == 1 && hwc->config > 159) ||
		    (cpuhw->info.csvn == 2 && hwc->config > 175) ||
		    (cpuhw->info.csvn >= 3 && cpuhw->info.csvn <= 5
		     && hwc->config > 255) ||
		    (cpuhw->info.csvn >= 6 && hwc->config > 287))
			err = -EOPNOTSUPP;
		break;
	case CPUMF_CTR_SET_MT_DIAG:
		if (cpuhw->info.csvn <= 3)
			err = -EOPNOTSUPP;
		/*
		 * MT-diagnostic counters are read-only.  The counter set
		 * is automatically enabled and activated on all CPUs with
		 * multithreading (SMT).  Deactivation of multithreading
		 * also disables the counter set.  State changes are ignored
		 * by lcctl().	Because Linux controls SMT enablement through
		 * a kernel parameter only, the counter set is either disabled
		 * or enabled and active.
		 *
		 * Thus, the counters can only be used if SMT is on and the
		 * counter set is enabled and active.
		 */
		mtdiag_ctl = cpumf_ctr_ctl[CPUMF_CTR_SET_MT_DIAG];
		if (!((cpuhw->info.auth_ctl & mtdiag_ctl) &&
		      (cpuhw->info.enable_ctl & mtdiag_ctl) &&
		      (cpuhw->info.act_ctl & mtdiag_ctl)))
			err = -EOPNOTSUPP;
		break;
	case CPUMF_CTR_SET_MAX:
		err = -EOPNOTSUPP;
	}

	put_cpu_var(cpu_cf_events);
	return err;
}