powerpc/perfctr: Check oprofile_cpu_type for NULL before using it
PATCH 1/1 powerpc/perfctr: Check oprofile_cpu_type for NULL before using it
If the current CPU doesn't support performance counters, cur_cpu_spec->oprofile_cpu_type can be NULL. The current perfctr modules don't test for that case and would thus crash.
Bug reported by David Woodhouse
--- arch/powerpc/kernel/mpc7450-pmu.c | 3 ++- arch/powerpc/kernel/power4-pmu.c | 3 ++- arch/powerpc/kernel/power5+-pmu.c | 5 +++-- arch/powerpc/kernel/power5-pmu.c | 3 ++- arch/powerpc/kernel/power6-pmu.c | 3 ++- arch/powerpc/kernel/power7-pmu.c | 3 ++- arch/powerpc/kernel/ppc970-pmu.c | 5 +++-- 7 files changed, 16 insertions(+), 9 deletions(-)
arch/powerpc/kernel/mpc7450-pmu.c +2 -1
@@ -407,7 +407,8 @@ struct power_pmu mpc7450_pmu = {static int init_mpc7450_pmu (void ) { -if (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc/7450" )) +if (!cur_cpu_spec->oprofile_cpu_type || +strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc/7450" ))return -ENODEV ;return register_power_pmu (&mpc7450_pmu);
arch/powerpc/kernel/power4-pmu.c +2 -1
@@ -606,7 +606,8 @@ static struct power_pmu power4_pmu = {static int init_power4_pmu (void ) { -if (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power4" )) +if (!cur_cpu_spec->oprofile_cpu_type || +strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power4" ))return -ENODEV ;return register_power_pmu (&power4_pmu);
arch/powerpc/kernel/power5+-pmu.c +3 -2
@@ -678,8 +678,9 @@ static struct power_pmu power5p_pmu = {static int init_power5p_pmu (void ) { -if (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power5+" ) - &&strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power5++" )) +if (!cur_cpu_spec->oprofile_cpu_type || + (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power5+" ) + &&strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power5++" )))return -ENODEV ;return register_power_pmu (&power5p_pmu);
arch/powerpc/kernel/power5-pmu.c +2 -1
@@ -618,7 +618,8 @@ static struct power_pmu power5_pmu = {static int init_power5_pmu (void ) { -if (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power5" )) +if (!cur_cpu_spec->oprofile_cpu_type || +strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power5" ))return -ENODEV ;return register_power_pmu (&power5_pmu);
arch/powerpc/kernel/power6-pmu.c +2 -1
@@ -537,7 +537,8 @@ static struct power_pmu power6_pmu = {static int init_power6_pmu (void ) { -if (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power6" )) +if (!cur_cpu_spec->oprofile_cpu_type || +strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power6" ))return -ENODEV ;return register_power_pmu (&power6_pmu);
arch/powerpc/kernel/power7-pmu.c +2 -1
@@ -366,7 +366,8 @@ static struct power_pmu power7_pmu = {static int init_power7_pmu (void ) { -if (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power7" )) +if (!cur_cpu_spec->oprofile_cpu_type || +strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/power7" ))return -ENODEV ;return register_power_pmu (&power7_pmu);
arch/powerpc/kernel/ppc970-pmu.c +3 -2
@@ -488,8 +488,9 @@ static struct power_pmu ppc970_pmu = {static int init_ppc970_pmu (void ) { -if (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/970" ) - &&strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/970MP" )) +if (!cur_cpu_spec->oprofile_cpu_type || + (strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/970" ) + &&strcmp (cur_cpu_spec->oprofile_cpu_type,"ppc64/970MP" )))return -ENODEV ;return register_power_pmu (&ppc970_pmu);
Signature · 1 line
1.6.0.4
Quoted 4 lines · Benjamin Herrenschmidt
If the current CPU doesn't support performance counters,
cur_cpu_spec->oprofile_cpu_typecan be NULL. The current perfctr modules don't test for that case and would thus crash.
It can't actually be NULL on a 64-bit CPU; all 64-bit CPUs in the table have ->oprofile_cpu_type set.
Of course, adding the check probably makes sense anyway.
Signature · 2 lines
David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
Quoted 8 lines · David Woodhouse
Quoted 4 lines · Benjamin Herrenschmidt
If the current CPU doesn't support performance counters,
cur_cpu_spec->oprofile_cpu_typecan be NULL. The current perfctr modules don't test for that case and would thus crash.It can't actually be NULL on a 64-bit CPU; all 64-bit CPUs in the table have ->oprofile_cpu_type set.
.... today :-)
Quoted 1 line
Of course, adding the check probably makes sense anyway.
Yup, better safe.
Cheers,
Ben.
Quoted 6 lines · Benjamin Herrenschmidt
If the current CPU doesn't support performance counters,
cur_cpu_spec->oprofile_cpu_typecan be NULL. The current perfctr modules don't test for that case and would thus crash.(quoted diff) +1
-0+ if (!cur_cpu_spec->oprofile_cpu_type ||
..
Quoted 1 line
(quoted diff) +1
-0+ if (!cur_cpu_spec->oprofile_cpu_type ||
..
Quoted 1 line
(quoted diff) +1
-0+ if (!cur_cpu_spec->oprofile_cpu_type ||
..
Quoted 1 line
(quoted diff) +1
-0+ if (!cur_cpu_spec->oprofile_cpu_type ||
..
Quoted 1 line
(quoted diff) +1
-0+ if (!cur_cpu_spec->oprofile_cpu_type ||
..
Quoted 1 line
(quoted diff) +1
-0+ if (!cur_cpu_spec->oprofile_cpu_type ||
..
Review
Quoted 1 line
(quoted diff) +1
-0+ if (!cur_cpu_spec->oprofile_cpu_type ||
Typing it seven times didn't make you think "how about a helper?" :)
Perhaps:
arch/powerpc/include/asm/cputable.h +5 -0
@@ -123,6 +123,11 @@ struct cpu_spec {extern struct cpu_spec *cur_cpu_spec; +static inline int oprofile_cpu_type_matches (const char *s) +{ +return s && (strcmp (cur_cpu_spec->oprofile_cpu_type, s) ==0 ); +} +extern unsigned int __start___ftr_fixup, __stop___ftr_fixup;extern struct cpu_spec *identify_cpu (unsigned long offset,unsigned int pvr);
And then callsites become:
static int init_mpc7450_pmu(void)
{
if (!oprofile_cpu_type_matches("ppc/7450"))
return -ENODEV;cheers
Quoted 2 lines · Michael Ellerman
Typing it seven times didn't make you think "how about a helper?" :)
Copy/paste works fine :-) Seriously, I did think about it, but a couple of cases test more than one string so a totally trivial helper wouldn't do and I couldn't be bothered doing anything more complicated while under influenza :-) You are welcome to do something nicer for .32.
BTW. While at it, I think we should move that stuff to a separate subdir too.
Cheers,
Ben.