diff options
author | Aaro Koskinen <aaro.koskinen@nsn.com> | 2014-07-22 07:51:08 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-08-25 20:18:57 -0400 |
commit | 33d9a530d4a87c5d645cfc82f23108ca8d89aa78 (patch) | |
tree | c526f119bb038cb920999356635f7fbd085c62e3 /arch/mips | |
parent | 56d2960958f81db9cfd488e530d2206edede5f8f (diff) |
MIPS: OCTEON: make get_system_type() thread-safe
get_system_type() is not thread-safe on OCTEON. It uses static data,
also more dangerous issue is that it's calling cvmx_fuse_read_byte()
every time without any synchronization. Currently it's possible to get
processes stuck looping forever in kernel simply by launching multiple
readers of /proc/cpuinfo:
(while true; do cat /proc/cpuinfo > /dev/null; done) &
(while true; do cat /proc/cpuinfo > /dev/null; done) &
...
Fix by initializing the system type string only once during the early
boot.
Signed-off-by: Aaro Koskinen <aaro.koskinen@nsn.com>
Cc: stable@vger.kernel.org
Reviewed-by: Markos Chandras <markos.chandras@imgtec.com>
Patchwork: http://patchwork.linux-mips.org/patch/7437/
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/cavium-octeon/setup.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index dba7cf7656c7..38f4c32e2816 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c | |||
@@ -457,6 +457,18 @@ static void octeon_halt(void) | |||
457 | octeon_kill_core(NULL); | 457 | octeon_kill_core(NULL); |
458 | } | 458 | } |
459 | 459 | ||
460 | static char __read_mostly octeon_system_type[80]; | ||
461 | |||
462 | static int __init init_octeon_system_type(void) | ||
463 | { | ||
464 | snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)", | ||
465 | cvmx_board_type_to_string(octeon_bootinfo->board_type), | ||
466 | octeon_model_get_string(read_c0_prid())); | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | early_initcall(init_octeon_system_type); | ||
471 | |||
460 | /** | 472 | /** |
461 | * Return a string representing the system type | 473 | * Return a string representing the system type |
462 | * | 474 | * |
@@ -464,11 +476,7 @@ static void octeon_halt(void) | |||
464 | */ | 476 | */ |
465 | const char *octeon_board_type_string(void) | 477 | const char *octeon_board_type_string(void) |
466 | { | 478 | { |
467 | static char name[80]; | 479 | return octeon_system_type; |
468 | sprintf(name, "%s (%s)", | ||
469 | cvmx_board_type_to_string(octeon_bootinfo->board_type), | ||
470 | octeon_model_get_string(read_c0_prid())); | ||
471 | return name; | ||
472 | } | 480 | } |
473 | 481 | ||
474 | const char *get_system_type(void) | 482 | const char *get_system_type(void) |