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) ...@@ -3060,7 +3060,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/* verify validity of reset_pmds */ /* verify validity of reset_pmds */
if ((reset_pmds & pmu_conf.impl_pmds[0]) != 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; goto error;
} }
} else { } else {
...@@ -3075,7 +3075,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) ...@@ -3075,7 +3075,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* execute write checker, if any * execute write checker, if any
*/ */
if (PMC_WR_FUNC(cnum)) { 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; if (ret) goto error;
ret = -EINVAL; ret = -EINVAL;
} }
...@@ -3254,7 +3254,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) ...@@ -3254,7 +3254,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
if (PMD_WR_FUNC(cnum)) { if (PMD_WR_FUNC(cnum)) {
unsigned long v = value; 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; if (ret) goto abort_mission;
value = v; value = v;
...@@ -3496,7 +3496,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) ...@@ -3496,7 +3496,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/ */
if (PMD_RD_FUNC(cnum)) { if (PMD_RD_FUNC(cnum)) {
unsigned long v = val; 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; if (ret) goto error;
val = v; val = v;
ret = -EINVAL; ret = -EINVAL;
......
...@@ -93,16 +93,21 @@ pfm_mck_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs) ...@@ -93,16 +93,21 @@ pfm_mck_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs)
return 0; return 0;
} }
/*
* task can be NULL if the context is unloaded
*/
static int static int
pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs) 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; int ret = 0, check_case1 = 0;
struct thread_struct *th = &task->thread;
unsigned long val8 = 0, val14 = 0, val13 = 0; unsigned long val8 = 0, val14 = 0, val13 = 0;
/* first preserve the reserved fields */ /* first preserve the reserved fields */
pfm_mck_reserved(cnum, val, regs); 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 * 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. * 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 ...@@ -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 */ case 4: *val |= 1UL << 23; /* force power enable bit */
break; break;
case 8: val8 = *val; case 8: val8 = *val;
val13 = th->pmcs[13]; val13 = ctx->ctx_pmcs[13];
val14 = th->pmcs[14]; val14 = ctx->ctx_pmcs[14];
check_case1 = 1; check_case1 = 1;
break; break;
case 13: val8 = th->pmcs[8]; case 13: val8 = ctx->ctx_pmcs[8];
val13 = *val; val13 = *val;
val14 = th->pmcs[14]; val14 = ctx->ctx_pmcs[14];
check_case1 = 1; check_case1 = 1;
break; break;
case 14: val8 = th->pmcs[13]; case 14: val8 = ctx->ctx_pmcs[13];
val13 = th->pmcs[13]; val13 = ctx->ctx_pmcs[13];
val14 = *val; val14 = *val;
check_case1 = 1; check_case1 = 1;
break; 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