Commit 72006112 authored by Stéphane Eranian's avatar Stéphane Eranian Committed by David Mosberger

[PATCH] ia64: fix NULL pointer dereferences in perfmon

This patch fixes some NULL pointer
problems in perfmon.

 - fixes NULL pointer derefence in perfmon_mckinley.h when context is not
   loaded
 - fixes typo in pfm_write_pmcs()
parent 803bf599
......@@ -3060,7 +3060,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/* verify validity of reset_pmds */
if ((reset_pmds & pmu_conf.impl_pmds[0]) != reset_pmds) {
DPRINT(("invalid reset_pmds 0x%lx for pmc%u\n", smpl_pmds, cnum));
DPRINT(("invalid reset_pmds 0x%lx for pmc%u\n", reset_pmds, cnum));
goto error;
}
} else {
......@@ -3075,7 +3075,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* execute write checker, if any
*/
if (PMC_WR_FUNC(cnum)) {
ret = PMC_WR_FUNC(cnum)(ctx->ctx_task, NULL, cnum, &value, regs);
ret = PMC_WR_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &value, regs);
if (ret) goto error;
ret = -EINVAL;
}
......@@ -3254,7 +3254,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
if (PMD_WR_FUNC(cnum)) {
unsigned long v = value;
ret = PMD_WR_FUNC(cnum)(ctx->ctx_task, NULL, cnum, &v, regs);
ret = PMD_WR_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &v, regs);
if (ret) goto abort_mission;
value = v;
......@@ -3496,7 +3496,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/
if (PMD_RD_FUNC(cnum)) {
unsigned long v = val;
ret = PMD_RD_FUNC(cnum)(ctx->ctx_task, NULL, cnum, &v, regs);
ret = PMD_RD_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &v, regs);
if (ret) goto error;
val = v;
ret = -EINVAL;
......
......@@ -93,16 +93,21 @@ pfm_mck_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs)
return 0;
}
/*
* task can be NULL if the context is unloaded
*/
static int
pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
{
int ret = 0, check_case1 = 0;
struct thread_struct *th = &task->thread;
unsigned long val8 = 0, val14 = 0, val13 = 0;
/* first preserve the reserved fields */
pfm_mck_reserved(cnum, val, regs);
/* sanitfy check */
if (ctx == NULL) return -EINVAL;
/*
* we must clear the debug registers if any pmc13.ena_dbrpX bit is enabled
* before they are written (fl_using_dbreg==0) to avoid picking up stale information.
......@@ -141,17 +146,17 @@ pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnu
case 4: *val |= 1UL << 23; /* force power enable bit */
break;
case 8: val8 = *val;
val13 = th->pmcs[13];
val14 = th->pmcs[14];
val13 = ctx->ctx_pmcs[13];
val14 = ctx->ctx_pmcs[14];
check_case1 = 1;
break;
case 13: val8 = th->pmcs[8];
case 13: val8 = ctx->ctx_pmcs[8];
val13 = *val;
val14 = th->pmcs[14];
val14 = ctx->ctx_pmcs[14];
check_case1 = 1;
break;
case 14: val8 = th->pmcs[13];
val13 = th->pmcs[13];
case 14: val8 = ctx->ctx_pmcs[13];
val13 = ctx->ctx_pmcs[13];
val14 = *val;
check_case1 = 1;
break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment