aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorAaro Koskinen <aaro.koskinen@nsn.com>2014-07-22 14:51:08 +0300
committerBen Hutchings <ben@decadent.org.uk>2014-09-13 23:41:46 +0100
commita17245332e650651e3d70aa94013d806d61a40cb (patch)
tree9f546830b4ffe36724fb4b8861c7ae004381fcc7 /arch/mips
parente0d0f5bb569ae0d3d28cbce48259459b5615fcb4 (diff)
downloadkernel_samsung_smdk4412-a17245332e650651e3d70aa94013d806d61a40cb.zip
kernel_samsung_smdk4412-a17245332e650651e3d70aa94013d806d61a40cb.tar.gz
kernel_samsung_smdk4412-a17245332e650651e3d70aa94013d806d61a40cb.tar.bz2
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: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/cavium-octeon/setup.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 2d9028f..3c5f61c 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -266,6 +266,18 @@ static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id)
}
#endif
+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);
+
/**
* Return a string representing the system type
*
@@ -273,11 +285,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)