diff options
author | Carl Love <cel@us.ibm.com> | 2008-10-29 01:06:45 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-10-31 01:13:51 -0400 |
commit | 210434d7633d477aa503454d68511fa2904e418e (patch) | |
tree | 8f06b51f5dc03f35fd7cb54329d0a61c88db9cd2 /arch/powerpc | |
parent | 3c10c9c45e290022ca7d2aa1ad33a0b6ed767520 (diff) |
powerpc/cell/OProfile: Fix on-stack array size in activate spu profiling function
The size of the pm_signal_local array should be equal to the
number of SPUs being configured in the array. Currently, the
array is of size 4 (NR_PHYS_CTRS) but being indexed by a for
loop from 0 to 7 (NUM_SPUS_PER_NODE). This could potentially
cause an oops or random memory corruption since the pm_signal_local
array is on the stack. This fixes it.
Signed-off-by: Carl Love <carll@us.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/oprofile/op_model_cell.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 35141a8bc3d9..25a4ec2514a3 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c | |||
@@ -582,6 +582,13 @@ static int cell_reg_setup(struct op_counter_config *ctr, | |||
582 | 582 | ||
583 | num_counters = num_ctrs; | 583 | num_counters = num_ctrs; |
584 | 584 | ||
585 | if (unlikely(num_ctrs > NR_PHYS_CTRS)) { | ||
586 | printk(KERN_ERR | ||
587 | "%s: Oprofile, number of specified events " \ | ||
588 | "exceeds number of physical counters\n", | ||
589 | __func__); | ||
590 | return -EIO; | ||
591 | } | ||
585 | pm_regs.group_control = 0; | 592 | pm_regs.group_control = 0; |
586 | pm_regs.debug_bus_control = 0; | 593 | pm_regs.debug_bus_control = 0; |
587 | 594 | ||
@@ -830,13 +837,13 @@ static int calculate_lfsr(int n) | |||
830 | static int pm_rtas_activate_spu_profiling(u32 node) | 837 | static int pm_rtas_activate_spu_profiling(u32 node) |
831 | { | 838 | { |
832 | int ret, i; | 839 | int ret, i; |
833 | struct pm_signal pm_signal_local[NR_PHYS_CTRS]; | 840 | struct pm_signal pm_signal_local[NUM_SPUS_PER_NODE]; |
834 | 841 | ||
835 | /* | 842 | /* |
836 | * Set up the rtas call to configure the debug bus to | 843 | * Set up the rtas call to configure the debug bus to |
837 | * route the SPU PCs. Setup the pm_signal for each SPU | 844 | * route the SPU PCs. Setup the pm_signal for each SPU |
838 | */ | 845 | */ |
839 | for (i = 0; i < NUM_SPUS_PER_NODE; i++) { | 846 | for (i = 0; i < ARRAY_SIZE(pm_signal_local); i++) { |
840 | pm_signal_local[i].cpu = node; | 847 | pm_signal_local[i].cpu = node; |
841 | pm_signal_local[i].signal_group = 41; | 848 | pm_signal_local[i].signal_group = 41; |
842 | /* spu i on word (i/2) */ | 849 | /* spu i on word (i/2) */ |
@@ -848,7 +855,7 @@ static int pm_rtas_activate_spu_profiling(u32 node) | |||
848 | 855 | ||
849 | ret = rtas_ibm_cbe_perftools(SUBFUNC_ACTIVATE, | 856 | ret = rtas_ibm_cbe_perftools(SUBFUNC_ACTIVATE, |
850 | PASSTHRU_ENABLE, pm_signal_local, | 857 | PASSTHRU_ENABLE, pm_signal_local, |
851 | (NUM_SPUS_PER_NODE | 858 | (ARRAY_SIZE(pm_signal_local) |
852 | * sizeof(struct pm_signal))); | 859 | * sizeof(struct pm_signal))); |
853 | 860 | ||
854 | if (unlikely(ret)) { | 861 | if (unlikely(ret)) { |