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-19 12:24:42 -0400 |
| commit | 608308682addfdc7b8e2aee88f0e028331d88e4d (patch) | |
| tree | dbf68401067b7d6582d55705afb23ab374c57329 | |
| parent | 6521d9a436a62e83ce57d6be6e5484e1098c1380 (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>
| -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) |
