Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: scache: Fix scache init with invalid line size.

In current scache init cache line_size is determined from
cpu config register, however if there there no scache
then mips_sc_probe_cm3 function populates a invalid line_size of 2.

The invalid line_size can cause a NULL pointer deference
during r4k_dma_cache_inv as r4k_blast_scache is populated
based on line_size. Scache line_size of 2 is invalid option in
r4k_blast_scache_setup.

This issue was faced during a MIPS I6400 based virtual platform bring up
where scache was not available in virtual platform model.

Signed-off-by: Govindraj Raja <Govindraj.Raja@imgtec.com>
Fixes: 7d53e9c4cd21("MIPS: CM3: Add support for CM3 L2 cache.")
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: James Hartley <James.Hartley@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: stable@vger.kernel.org # v4.2+
Patchwork: https://patchwork.linux-mips.org/patch/12710/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Govindraj Raja and committed by
Ralf Baechle
56fa81fc 51ff5d77

+9 -4
+9 -4
arch/mips/mm/sc-mips.c
··· 164 164 165 165 sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK; 166 166 sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF; 167 - c->scache.sets = 64 << sets; 167 + if (sets) 168 + c->scache.sets = 64 << sets; 168 169 169 170 line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK; 170 171 line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF; 171 - c->scache.linesz = 2 << line_sz; 172 + if (line_sz) 173 + c->scache.linesz = 2 << line_sz; 172 174 173 175 assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK; 174 176 assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF; ··· 178 176 c->scache.waysize = c->scache.sets * c->scache.linesz; 179 177 c->scache.waybit = __ffs(c->scache.waysize); 180 178 181 - c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 179 + if (c->scache.linesz) { 180 + c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 181 + return 1; 182 + } 182 183 183 - return 1; 184 + return 0; 184 185 } 185 186 186 187 static inline int __init mips_sc_probe(void)