From 05510f2b4819398a25ef432d72efa9e95419768a Mon Sep 17 00:00:00 2001 From: Marcin Nowakowski Date: Tue, 7 Mar 2017 14:19:56 +0100 Subject: MIPS: Enable GENERIC_CPU_AUTOPROBE Add missing macros and methods that are required by CONFIG_GENERIC_CPU_AUTOPROBE: MAX_CPU_FEATURES, cpu_have_feature(), cpu_feature(). Also set a default elf platform as currently it is not set for most MIPS platforms resulting in incorrectly specified modalias values in cpu autoprobe ("cpu:type:(null):feature:..."). Export 'elf_hwcap' symbol so that it can be accessed from modules that use module_cpu_feature_match() Signed-off-by: Marcin Nowakowski Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/15395/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 12422fd4af23..e57e6850f4dd 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -34,6 +34,7 @@ /* Hardware capabilities */ unsigned int elf_hwcap __read_mostly; +EXPORT_SYMBOL_GPL(elf_hwcap); /* * Get the FPU Implementation/Revision. @@ -1946,6 +1947,12 @@ void cpu_probe(void) struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int cpu = smp_processor_id(); + /* + * Set a default elf platform, cpu probe may later + * overwrite it with a more precise value + */ + set_elf_platform(cpu, "mips"); + c->processor_id = PRID_IMP_UNKNOWN; c->fpu_id = FPIR_IMP_NONE; c->cputype = CPU_UNKNOWN; -- cgit From 5bba7aa4958e271c3ffceb70d47d3206524cf489 Mon Sep 17 00:00:00 2001 From: Leonid Yegoshin Date: Mon, 13 Mar 2017 16:36:35 +0100 Subject: MIPS: r2-on-r6-emu: Fix BLEZL and BGTZL identification Fix the problem of inaccurate identification of instructions BLEZL and BGTZL in R2 emulation code by making sure all necessary encoding specifications are met. Previously, certain R6 instructions could be identified as BLEZL or BGTZL. R2 emulation routine didn't take into account that both BLEZL and BGTZL instructions require their rt field (bits 20 to 16 of instruction encoding) to be 0, and that, at same time, if the value in that field is not 0, the encoding may represent a legitimate MIPS R6 instruction. This means that a problem could occur after emulation optimization, when emulation routine tried to pipeline emulation, picked up a next candidate, and subsequently misrecognized an R6 instruction as BLEZL or BGTZL. It should be said that for single pass strategy, the problem does not happen because CPU doesn't trap on branch-compacts which share opcode space with BLEZL/BGTZL (but have rt field != 0, of course). Signed-off-by: Leonid Yegoshin Signed-off-by: Miodrag Dinic Signed-off-by: Aleksandar Markovic Reported-by: Douglas Leung Reviewed-by: Paul Burton Cc: james.hogan@imgtec.com Cc: petar.jovanovic@imgtec.com Cc: goran.ferenc@imgtec.com Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/15456/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/mips-r2-to-r6-emul.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index d8f1cf1ec370..50558b30a809 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -1096,10 +1096,20 @@ repeat: } break; - case beql_op: - case bnel_op: case blezl_op: case bgtzl_op: + /* + * For BLEZL and BGTZL, rt field must be set to 0. If this + * is not the case, this may be an encoding of a MIPS R6 + * instruction, so return to CPU execution if this occurs + */ + if (MIPSInst_RT(inst)) { + err = SIGILL; + break; + } + /* fall through */ + case beql_op: + case bnel_op: if (delay_slot(regs)) { err = SIGILL; break; -- cgit From 411dac79cc2ed80f7e348ccc23eb4d8b0ba9f6d5 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Mon, 13 Mar 2017 16:36:36 +0100 Subject: MIPS: r2-on-r6-emu: Clear BLTZALL and BGEZALL debugfs counters Add missing clearing of BLTZALL and BGEZALL emulation counters in function mipsr2_stats_clear_show(). Previously, it was not possible to reset BLTZALL and BGEZALL emulation counters - their value remained the same even after explicit request via debugfs. As far as other related counters are concerned, they all seem to be properly cleared. This change affects debugfs operation only, core R2 emulation functionality is not affected. Signed-off-by: Aleksandar Markovic Reviewed-by: Paul Burton Cc: james.hogan@imgtec.com Cc: leonid.yegoshin@imgtec.com Cc: douglas.leung@imgtec.com Cc: petar.jovanovic@imgtec.com Cc: miodrag.dinic@imgtec.com Cc: goran.ferenc@imgtec.com Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/15517/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/mips-r2-to-r6-emul.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index 50558b30a809..e1416f1d2477 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -2339,6 +2339,8 @@ static int mipsr2_stats_clear_show(struct seq_file *s, void *unused) __this_cpu_write((mipsr2bremustats).bgezl, 0); __this_cpu_write((mipsr2bremustats).bltzll, 0); __this_cpu_write((mipsr2bremustats).bgezll, 0); + __this_cpu_write((mipsr2bremustats).bltzall, 0); + __this_cpu_write((mipsr2bremustats).bgezall, 0); __this_cpu_write((mipsr2bremustats).bltzal, 0); __this_cpu_write((mipsr2bremustats).bgezal, 0); __this_cpu_write((mipsr2bremustats).beql, 0); -- cgit From 1f83f5e42b5b17f844955b49e986c3f1f187dd54 Mon Sep 17 00:00:00 2001 From: Marcin Nowakowski Date: Fri, 7 Apr 2017 13:40:28 +0200 Subject: MIPS: Use common outgoing-CPU-notification code Replace the open-coded CPU-offline notification with common code. In particular avoid calling scheduler code using RCU from an offline CPU that RCU is ignoring. Signed-off-by: Marcin Nowakowski Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/15921/ Patchwork: https://patchwork.linux-mips.org/patch/15953/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-cps.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 6d45f05538c8..306b4a64cb8f 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -8,6 +8,7 @@ * option) any later version. */ +#include #include #include #include @@ -408,7 +409,6 @@ static int cps_cpu_disable(void) return 0; } -static DECLARE_COMPLETION(cpu_death_chosen); static unsigned cpu_death_sibling; static enum { CPU_DEATH_HALT, @@ -444,7 +444,7 @@ void play_dead(void) } /* This CPU has chosen its way out */ - complete(&cpu_death_chosen); + (void)cpu_report_death(); if (cpu_death == CPU_DEATH_HALT) { vpe_id = cpu_vpe_id(&cpu_data[cpu]); @@ -493,8 +493,7 @@ static void cps_cpu_die(unsigned int cpu) int err; /* Wait for the cpu to choose its way out */ - if (!wait_for_completion_timeout(&cpu_death_chosen, - msecs_to_jiffies(5000))) { + if (!cpu_wait_death(cpu, 5)) { pr_err("CPU%u: didn't offline\n", cpu); return; } -- cgit From 828d1e4e98654e2284496e2fd7f9605ba04ef02a Mon Sep 17 00:00:00 2001 From: Matt Redfearn Date: Thu, 6 Apr 2017 11:29:06 +0100 Subject: MIPS: Remove dead define of ST_OFF Commit 1a3d59579b9f ("MIPS: Tidy up FPU context switching") removed the last usage of the macro ST_OFF. Remove the dead code. Signed-off-by: Matt Redfearn Cc: James Hogan Cc: Paul Burton Cc: trivial@kernel.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/15898/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/r4k_switch.S | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 758577861523..7b386d54fd65 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -25,12 +25,6 @@ /* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ #undef fp -/* - * Offset to the current process status flags, the first 32 bytes of the - * stack are not used. - */ -#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS) - #ifndef USE_ALTERNATE_RESUME_IMPL /* * task_struct *resume(task_struct *prev, task_struct *next, -- cgit From f9c4e3a6dae1a3a15055ea478438cdc0352e1af2 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Fri, 31 Mar 2017 17:09:58 +0100 Subject: MIPS: Opt into HAVE_COPY_THREAD_TLS This the mips version of commit c1bd55f922a2d ("x86: opt into HAVE_COPY_THREAD_TLS, for both 32-bit and 64-bit"). Simply use the tls system call argument instead of extracting the tls argument by magic from the pt_regs structure. See commit 3033f14ab78c3 ("clone: support passing tls argument via C rather than pt_regs magic") for more background. Signed-off-by: James Cowgill Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/15855/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/process.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index b68e10fc453d..918d4c73e951 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -114,8 +114,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) /* * Copy architecture-specific thread state */ -int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long kthread_arg, struct task_struct *p) +int copy_thread_tls(unsigned long clone_flags, unsigned long usp, + unsigned long kthread_arg, struct task_struct *p, unsigned long tls) { struct thread_info *ti = task_thread_info(p); struct pt_regs *childregs, *regs = current_pt_regs(); @@ -176,7 +176,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, atomic_set(&p->thread.bd_emu_frame, BD_EMUFRAME_NONE); if (clone_flags & CLONE_SETTLS) - ti->tp_value = regs->regs[7]; + ti->tp_value = tls; return 0; } -- cgit From 1eed40043579608e16509c43eeeb3a53a8a42378 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 30 Mar 2017 12:06:12 -0700 Subject: MIPS: smp-mt: Use CPU interrupt controller IPI IRQ domain support Remove the smp-mt IPI code that supported single-core multithreaded systems and instead make use of the IPI IRQ domain support provided by the MIPS CPU interrupt controller driver. This removes some less than nice code, the horrible split between arch & board code and the duplication that led to within board code. The lantiq portion of this patch has only been compile tested. Malta has been tested & is functional. Signed-off-by: Paul Burton Cc: Thomas Gleixner Cc: Jason Cooper Cc: Marc Zyngier Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/15837/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-mt.c | 49 ++++------------------------------------------- 1 file changed, 4 insertions(+), 45 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index e398cbc3d776..ed6b4df583ea 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -83,6 +83,8 @@ static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0, if (tc != 0) smvp_copy_vpe_config(); + cpu_data[ncpu].vpe_id = tc; + return ncpu; } @@ -114,49 +116,6 @@ static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0) write_tc_c0_tchalt(TCHALT_H); } -static void vsmp_send_ipi_single(int cpu, unsigned int action) -{ - int i; - unsigned long flags; - int vpflags; - -#ifdef CONFIG_MIPS_GIC - if (gic_present) { - mips_smp_send_ipi_single(cpu, action); - return; - } -#endif - local_irq_save(flags); - - vpflags = dvpe(); /* can't access the other CPU's registers whilst MVPE enabled */ - - switch (action) { - case SMP_CALL_FUNCTION: - i = C_SW1; - break; - - case SMP_RESCHEDULE_YOURSELF: - default: - i = C_SW0; - break; - } - - /* 1:1 mapping of vpe and tc... */ - settc(cpu); - write_vpe_c0_cause(read_vpe_c0_cause() | i); - evpe(vpflags); - - local_irq_restore(flags); -} - -static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action) -{ - unsigned int i; - - for_each_cpu(i, mask) - vsmp_send_ipi_single(i, action); -} - static void vsmp_init_secondary(void) { #ifdef CONFIG_MIPS_GIC @@ -281,8 +240,8 @@ static void __init vsmp_prepare_cpus(unsigned int max_cpus) } struct plat_smp_ops vsmp_smp_ops = { - .send_ipi_single = vsmp_send_ipi_single, - .send_ipi_mask = vsmp_send_ipi_mask, + .send_ipi_single = mips_smp_send_ipi_single, + .send_ipi_mask = mips_smp_send_ipi_mask, .init_secondary = vsmp_init_secondary, .smp_finish = vsmp_smp_finish, .boot_secondary = vsmp_boot_secondary, -- cgit From e64889823d58305a5ddb2828ae0a988c59e87d7e Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 30 Mar 2017 12:06:13 -0700 Subject: MIPS: Stengthen IPI IRQ domain sanity check Commit fbde2d7d8290 ("MIPS: Add generic SMP IPI support") introduced a sanity check that an IPI IRQ domain can be found during boot, in order to ensure that IPIs are able to be set up in systems using such domains. However it was added at a point where systems may have used an IPI IRQ domain in some situations but not others, and we could not know which were the case until runtime, so commit 578bffc82ec5 ("MIPS: Don't BUG_ON when no IPI domain is found") made that check simply skip IPI init if no domain were found in order to fix the boot for systems such as QEMU Malta. We now use IPI IRQ domains for the MIPS CPU interrupt controller, which means systems which make use of IPI IRQ domains will always do so when running on multiple CPUs. As a result we now strengthen the sanity check to ensure that an IPI IRQ domain is found when multiple CPUs are present in the system. Signed-off-by: Paul Burton Cc: Thomas Gleixner Cc: Jason Cooper Cc: Marc Zyngier Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/15838/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 6e71130549ea..aba1afb64b62 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -261,16 +261,20 @@ int mips_smp_ipi_allocate(const struct cpumask *mask) ipidomain = irq_find_matching_host(NULL, DOMAIN_BUS_IPI); /* - * There are systems which only use IPI domains some of the time, - * depending upon configuration we don't know until runtime. An - * example is Malta where we may compile in support for GIC & the - * MT ASE, but run on a system which has multiple VPEs in a single - * core and doesn't include a GIC. Until all IPI implementations - * have been converted to use IPI domains the best we can do here - * is to return & hope some other code sets up the IPIs. + * There are systems which use IPI IRQ domains, but only have one + * registered when some runtime condition is met. For example a Malta + * kernel may include support for GIC & CPU interrupt controller IPI + * IRQ domains, but if run on a system with no GIC & no MT ASE then + * neither will be supported or registered. + * + * We only have a problem if we're actually using multiple CPUs so fail + * loudly if that is the case. Otherwise simply return, skipping IPI + * setup, if we're running with only a single CPU. */ - if (!ipidomain) + if (!ipidomain) { + BUG_ON(num_present_cpus() > 1); return 0; + } virq = irq_reserve_ipi(ipidomain, mask); BUG_ON(!virq); -- cgit