pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
unsigned long value, reset_pmds;
unsigned int cnum, reg_flags, flags;
- int i;
- int ret = -EINVAL;
+ int is_monitor, is_counting;
+ int i, ret = -EINVAL;
+#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
/* we don't quite support this right now */
if (task != current) return -EINVAL;
reset_pmds = tmp.reg_reset_pmds[0];
flags = 0;
+ is_counting = PMC_IS_COUNTING(cnum);
+ is_monitor = PMC_IS_MONITOR(cnum);
+
/*
* we reject all non implemented PMC as well
* as attempts to modify PMC[0-3] which are used
goto error;
}
/*
- * A PMC used to configure monitors must be:
- * - system-wide session: privileged monitor
- * - per-task : user monitor
- * any other configuration is rejected.
+ * If the PMC is a monitor, then if the value is not the default:
+ * - system-wide session: PMCx.pm=1 (privileged monitor)
+ * - per-task : PMCx.pm=0 (user monitor)
*/
- if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) {
- DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, value)));
-
- if (ctx->ctx_fl_system ^ PMC_PM(cnum, value)) {
- DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, value), ctx->ctx_fl_system));
- goto error;
- }
+ if ((is_monitor || is_counting) && value != PMC_DFL_VAL(i) && PFM_CHECK_PMC_PM(ctx, cnum, value)) {
+ DBprintk(("pmc%u pmc_pm=%ld fl_system=%d\n",
+ cnum,
+ PMC_PM(cnum, value),
+ ctx->ctx_fl_system));
+ goto error;
}
- if (PMC_IS_COUNTING(cnum)) {
+ if (is_counting) {
pfm_monitor_t *p = (pfm_monitor_t *)&value;
/*
* enforce generation of overflow interrupt. Necessary on all
*/
ctx->ctx_soft_pmds[cnum].flags = flags;
- if (PMC_IS_COUNTING(cnum)) {
+ if (is_counting) {
ctx->ctx_soft_pmds[cnum].reset_pmds[0] = reset_pmds;
/* mark all PMDS to be accessed as used */
unsigned int cnum, reg_flags = 0;
int i, ret = 0;
-#if __GNUC__ < 3
- int foo;
-#endif
-
if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
/*
for (i = 0; i < count; i++, req++) {
int me;
-#if __GNUC__ < 3
- foo = __get_user(cnum, &req->reg_num);
- if (foo) return -EFAULT;
- foo = __get_user(reg_flags, &req->reg_flags);
- if (foo) return -EFAULT;
-#else
+
if (__get_user(cnum, &req->reg_num)) return -EFAULT;
if (__get_user(reg_flags, &req->reg_flags)) return -EFAULT;
-#endif
lval = 0UL;
if (!PMD_IS_IMPL(cnum)) goto abort_mission;