From: Markos Chandras Date: Wed, 3 Feb 2016 03:15:23 +0000 (+0000) Subject: MIPS: pm-cps: Avoid offset overflow on MIPSr6 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=0f2a1484487407390196ca5b3c3a07bee6df15ad;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git MIPS: pm-cps: Avoid offset overflow on MIPSr6 This is similar to commit 934c79231c1b ("MIPS: asm: r4kcache: Add MIPS R6 cache unroll functions"). The CACHE instruction has been redefined for MIPSr6 and it reduced its offset field to 8 bits. This leads to micro-assembler field overflow warnings when booting SMP MIPSr6 cores like the following one: Call Trace: [] show_stack+0x68/0x88 [] dump_stack+0x68/0x88 [] warn_slowpath_common+0x8c/0xc8 [] warn_slowpath_fmt+0x38/0x48 [] build_insn+0x514/0x5c0 [] cps_gen_cache_routine.isra.3+0xe0/0x1b8 [] cps_pm_init+0x364/0x9ec [] do_one_initcall+0x90/0x1a8 [] kernel_init_freeable+0x160/0x21c [] kernel_init+0x10/0xf8 [] ret_from_kernel_thread+0x14/0x1c We fix this by incrementing the base register on every loop. Signed-off-by: Markos Chandras Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/12329/ Signed-off-by: Ralf Baechle --- diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index fa3f9ebad8f4..adda3ffb9b78 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -224,11 +224,18 @@ static void __init cps_gen_cache_routine(u32 **pp, struct uasm_label **pl, uasm_build_label(pl, *pp, lbl); /* Generate the cache ops */ - for (i = 0; i < unroll_lines; i++) - uasm_i_cache(pp, op, i * cache->linesz, t0); + for (i = 0; i < unroll_lines; i++) { + if (cpu_has_mips_r6) { + uasm_i_cache(pp, op, 0, t0); + uasm_i_addiu(pp, t0, t0, cache->linesz); + } else { + uasm_i_cache(pp, op, i * cache->linesz, t0); + } + } - /* Update the base address */ - uasm_i_addiu(pp, t0, t0, unroll_lines * cache->linesz); + if (!cpu_has_mips_r6) + /* Update the base address */ + uasm_i_addiu(pp, t0, t0, unroll_lines * cache->linesz); /* Loop if we haven't reached the end address yet */ uasm_il_bne(pp, pr, t0, t1, lbl);