From: Mikael Pettersson ppc32 fix and cleanups: - If check_ireset() fails, clear state->cstatus to undo any settings check_control() may have left there. - Eliminate power-of-two sizeof assumption in access_regs(). - Merge check_ireset() and setup_imode_start_values(). Signed-off-by: Mikael Pettersson Signed-off-by: Andrew Morton --- 25-akpm/drivers/perfctr/ppc.c | 27 ++++++++------------------- 1 files changed, 8 insertions(+), 19 deletions(-) diff -puN drivers/perfctr/ppc.c~perfctr-ppc32-fix-and-cleanups drivers/perfctr/ppc.c --- 25/drivers/perfctr/ppc.c~perfctr-ppc32-fix-and-cleanups 2005-03-23 01:36:51.000000000 -0800 +++ 25-akpm/drivers/perfctr/ppc.c 2005-03-23 01:36:51.000000000 -0800 @@ -573,7 +573,7 @@ unsigned int perfctr_cpu_identify_overfl return pmc_mask; } -static inline int check_ireset(const struct perfctr_cpu_state *state) +static inline int check_ireset(struct perfctr_cpu_state *state) { unsigned int nrctrs, i; @@ -583,27 +583,15 @@ static inline int check_ireset(const str unsigned int pmc = state->pmc[i].map; if ((int)state->control.ireset[pmc] < 0) /* PPC-specific */ return -EINVAL; - } - return 0; -} - -static inline void setup_imode_start_values(struct perfctr_cpu_state *state) -{ - unsigned int cstatus, nrctrs, i; - - cstatus = state->cstatus; - nrctrs = perfctr_cstatus_nrctrs(cstatus); - for(i = perfctr_cstatus_nractrs(cstatus); i < nrctrs; ++i) { - unsigned int pmc = state->pmc[i].map; state->pmc[i].start = state->control.ireset[pmc]; } + return 0; } #else /* CONFIG_PERFCTR_INTERRUPT_SUPPORT */ static inline void perfctr_cpu_isuspend(struct perfctr_cpu_state *state) { } static inline void perfctr_cpu_iresume(const struct perfctr_cpu_state *state) { } -static inline int check_ireset(const struct perfctr_cpu_state *state) { return 0; } -static inline void setup_imode_start_values(struct perfctr_cpu_state *state) { } +static inline int check_ireset(struct perfctr_cpu_state *state) { return 0; } #endif /* CONFIG_PERFCTR_INTERRUPT_SUPPORT */ static int check_control(struct perfctr_cpu_state *state) @@ -627,12 +615,13 @@ int perfctr_cpu_update_control(struct pe if (err < 0) return err; err = check_ireset(state); - if (err < 0) + if (err < 0) { + state->cstatus = 0; return err; + } state->cstatus |= perfctr_mk_cstatus(state->control.header.tsc_on, state->control.header.nractrs, state->control.header.nrictrs); - setup_imode_start_values(state); return 0; } @@ -672,10 +661,10 @@ static int access_regs(struct perfctr_cp unsigned int i, nr_regs, *where; int offset; - if (argbytes & (sizeof(struct perfctr_cpu_reg) - 1)) + nr_regs = argbytes / sizeof(struct perfctr_cpu_reg); + if (nr_regs * sizeof(struct perfctr_cpu_reg) != argbytes) return -EINVAL; regs = (struct perfctr_cpu_reg*)argp; - nr_regs = argbytes / sizeof(struct perfctr_cpu_reg); for(i = 0; i < nr_regs; ++i) { offset = get_reg_offset(regs[i].nr); _