diff options
author | Aaro Koskinen <aaro.koskinen@nsn.com> | 2014-07-22 14:51:08 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-09-17 09:03:58 -0700 |
commit | d2a3ec399f0429d595ca3b14849b001ebb091f78 (patch) | |
tree | 697f43acccb8072da13d91d1b966853f5f172e20 /arch/mips | |
parent | 4fc5ea5e141b9874db74af31befd6a953972b7c0 (diff) | |
download | linux-3.10-d2a3ec399f0429d595ca3b14849b001ebb091f78.tar.gz linux-3.10-d2a3ec399f0429d595ca3b14849b001ebb091f78.tar.bz2 linux-3.10-d2a3ec399f0429d595ca3b14849b001ebb091f78.zip |
MIPS: OCTEON: make get_system_type() thread-safe
commit 608308682addfdc7b8e2aee88f0e028331d88e4d upstream.
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>
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 2a75ff249e7..6430e7acb1e 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -463,6 +463,18 @@ static void octeon_halt(void) octeon_kill_core(NULL); } +static char __read_mostly octeon_system_type[80]; + +static int __init init_octeon_system_type(void) +{ + snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)", + cvmx_board_type_to_string(octeon_bootinfo->board_type), + octeon_model_get_string(read_c0_prid())); + + return 0; +} +early_initcall(init_octeon_system_type); + /** * Handle all the error condition interrupts that might occur. * @@ -482,11 +494,7 @@ static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id) */ const char *octeon_board_type_string(void) { - static char name[80]; - sprintf(name, "%s (%s)", - cvmx_board_type_to_string(octeon_bootinfo->board_type), - octeon_model_get_string(read_c0_prid())); - return name; + return octeon_system_type; } const char *get_system_type(void) |