All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Florian Fainelli" <f.fainelli@gmail.com>
Cc: "open list:COMMON CLK FRAMEWORK" <linux-clk@vger.kernel.org>
Subject: Re: [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support
Date: Tue, 10 Nov 2026 05:10:57 +0000	[thread overview]
Message-ID: <sashiko-outbox-206263@kernel.org> (raw)
In-Reply-To: <20261110043131.1985993-3-f.fainelli@gmail.com>

Thank you for your contribution! Sashiko AI review found 6 potential
issues to consider:
- [High] MIPS: idle: check_wait() selects xburst_wait_irqoff() on UP
  XBurst SoCs
- [High] MIPS: Ingenic: boot BUG_ON in mips_smp_ipi_allocate() on
  generic kernel
- [High] MIPS: Ingenic: missing set_cpu_present() and hotplug callbacks
  in xburst_smp_ops
- [High] MIPS: Ingenic: missing cpu_set_core() suppresses cache IPIs
  under MIPS_CPS
- [Medium] MIPS: Ingenic: invalid wait context in
  xburst_boot_secondary()
- [Low] MIPS: Ingenic: 64-bit generic kernel build failure in
  ingenic-smp
--

commit 84aca91e29a4f9f60b4d407205a2e5c0ec8d50c1
Author: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>

MIPS: Ingenic: Add XBurst SMP support

This commit adds SMP support for the second XBurst core on the Ingenic
JZ4780 using CP0 mailboxes for inter-processor interrupts, and flushes
the private data cache before entering WAIT on SMP builds.

Link: https://lkml.iu.edu/hypermail/linux/kernel/2005.2/03488.html
Link: https://lists.openwall.net/linux-kernel/2020/05/13/1482
Link: https://lists.openwall.net/linux-kernel/2020/05/19/1099

> diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c
> index 1d712eac16171..38f294887c17a 100644
> --- a/arch/mips/generic/init.c
> +++ b/arch/mips/generic/init.c
> @@ -13,6 +13,7 @@
>  
>  #include <asm/bootinfo.h>
>  #include <asm/fw/fw.h>
> +#include <asm/ingenic-smp.h>
>  #include <asm/irq_cpu.h>
>  #include <asm/machine.h>
>  #include <asm/mips-cps.h>
> @@ -113,6 +114,8 @@ void __init device_tree_init(void)
>  	unflatten_and_copy_device_tree();
>  	mips_cpc_probe();
>  
> +	if (!register_ingenic_smp_ops())
> +		return;
>  	if (!register_cps_smp_ops())
>  		return;
>  	if (!register_vsmp_smp_ops())

[Severity: High]
Does registering xburst_smp_ops on a generic MIPS kernel trigger the
BUG_ON() in mips_smp_ipi_allocate() during boot on JZ4780?

CONFIG_MIPS_GENERIC_KERNEL selects CONFIG_MIPS_GIC and
CONFIG_SYS_SUPPORTS_MULTITHREADING, which enable CONFIG_GENERIC_IRQ_IPI
when CONFIG_SMP is enabled.  During early initcalls, mips_smp_ipi_init()
calls mips_smp_ipi_allocate() whenever num_possible_cpus() > 1, but
JZ4780 uses CP0 mailbox interrupts instead of registering a
DOMAIN_BUS_IPI irq_domain:

arch/mips/kernel/smp.c:mips_smp_ipi_allocate() {
    ...
	if (!ipidomain) {
		BUG_ON(num_present_cpus() > 1);
		return 0;
	}
    ...
}

> diff --git a/arch/mips/ingenic/ingenic-smp-entry.S b/arch/mips/ingenic/ingenic-smp-entry.S
> new file mode 100644
> index 0000000000000..250a0c89c9556
> --- /dev/null
> +++ b/arch/mips/ingenic/ingenic-smp-entry.S
> @@ -0,0 +1,54 @@
[ ... ]
> +	/* Invalidate both private caches before entering cached code. */
> +	li	t0, KSEG0
> +	ori	t1, t0, CACHE_SIZE
> +	mtc0	zero, CP0_TAGLO
> +	ehb
> +1:	cache	Index_Store_Tag_I, 0(t0)
> +	cache	Index_Store_Tag_D, 0(t0)
> +	addiu	t0, t0, CACHE_LINESIZE
> +	bne	t0, t1, 1b
> +	 nop
> +
> +	mfc0	t0, CP0_CONFIG
> +	li	t1, ~CONF_CM_CMASK
> +	and	t0, t0, t1
> +	ori	t0, t0, CONF_CM_CACHABLE_NONCOHERENT
> +	mtc0	t0, CP0_CONFIG
> +	mtc0	zero, CP0_PAGEMASK
> +	ehb
> +
> +	/* CPU0 publishes these in RAM before releasing CPU1 from reset. */
> +	la	t0, xburst_cpu_entry_sp
> +	lw	sp, 0(t0)
> +	la	t0, xburst_cpu_entry_gp
> +	lw	gp, 0(t0)
> +
> +	la	t0, smp_bootstrap
> +	jr	t0
> +	 nop
> +END(xburst_secondary_cpu_entry)

[Severity: Low]
Does this break 64-bit generic kernel builds when CONFIG_BOARD_INGENIC
and CONFIG_SMP are enabled?

CONFIG_BOARD_INGENIC has no dependency on CONFIG_32BIT and selects
CONFIG_MACH_JZ4780, so a 64-bit CONFIG_MIPS_GENERIC_KERNEL build compiles
arch/mips/ingenic/.  Under CONFIG_64BIT, KSEG0 (used here) and KSEG1ADDR
(used in xburst_smp_setup()) are not defined in <asm/addrspace.h>, and
xburst_secondary_cpu_entry uses 32-bit la and lw instructions to load the
unsigned long globals xburst_cpu_entry_sp and xburst_cpu_entry_gp.

> diff --git a/arch/mips/ingenic/ingenic-smp.c b/arch/mips/ingenic/ingenic-smp.c
> new file mode 100644
> index 0000000000000..3cdb953c7a871
> --- /dev/null
> +++ b/arch/mips/ingenic/ingenic-smp.c
> @@ -0,0 +1,247 @@
[ ... ]
> +static void __init xburst_smp_setup(void)
> +{
> +	struct device_node *np;
> +	u32 entry, reim;
> +	unsigned int cpu = 0;
> +	u64 hwid;
> +
> +	for_each_of_cpu_node(np) {
> +		hwid = of_get_cpu_hwid(np, 0);
> +		if (!of_device_is_available(np) ||
> +		    hwid >= ARRAY_SIZE(__cpu_number_map))
> +			continue;
> +		if (cpu >= nr_cpu_ids) {
> +			of_node_put(np);
> +			break;
> +		}
> +		__cpu_number_map[hwid] = cpu;
> +		__cpu_logical_map[cpu] = hwid;
> +		set_cpu_possible(cpu, true);
> +		cpu++;
> +	}

[Severity: High]
Does omitting cpu_set_core() leave cpu_foreign_map empty when
CONFIG_MIPS_CPS is enabled (such as in generic_defconfig)?

decode_configs() only populates the core ID from EBase.CPUNum when
CONFIG_MIPS_CPS is disabled:

arch/mips/kernel/cpu-probe.c:decode_configs() {
    ...
#ifndef CONFIG_MIPS_CPS
	if (cpu_has_mips_r2_r6) {
		unsigned int core;

		core = get_ebase_cpunum();
		if (cpu_has_mipsmt)
			core >>= fls(core_nvpes()) - 1;
		cpu_set_core(c, core);
	}
#endif
}

Because neither xburst_smp_setup() nor xburst_init_secondary() calls
cpu_set_core(), both CPUs keep core ID 0 under CONFIG_MIPS_CPS.
calculate_cpu_foreign_map() then treats CPU0 and CPU1 as SMT siblings
sharing L1 caches and leaves cpu_foreign_map empty, so
r4k_op_needs_ipi() returns false and cross-CPU cache flushes never send
IPIs to the other core's private L1 caches.

[ ... ]

> +static int xburst_boot_secondary(int cpu, struct task_struct *idle)
> +{
> +	unsigned long flags;
> +	u32 ctrl;
> +	int ret;
> +
> +	if (cpu_logical_map(cpu) != 1 || IS_ERR_OR_NULL(cpu1_clock))
> +		return -ENODEV;
> +
> +	raw_spin_lock_irqsave(&smp_lock, flags);
> +	ctrl = read_c0_corectrl() | CORECTRL_SWRST(1) | CORECTRL_RPC(1);
> +	write_c0_corectrl(ctrl);
> +	back_to_back_c0_hazard();
> +
> +	ret = clk_enable(cpu1_clock);
> +	if (ret)
> +		goto unlock;

[Severity: Medium]
Does calling clk_enable() while holding the raw spinlock smp_lock trigger
an invalid wait context warning under lockdep?

clk_enable() acquires the non-raw spinlock_t enable_lock in
clk_enable_lock() and cgu->lock in jz4780_core1_enable(), nesting
spinlock_t inside raw_spinlock_t and holding smp_lock with interrupts
disabled across the register polling loop in jz4780_core1_enable().

[ ... ]

> +static const struct plat_smp_ops xburst_smp_ops = {
> +	.send_ipi_single = xburst_send_ipi_single,
> +	.send_ipi_mask = xburst_send_ipi_mask,
> +	.init_secondary = xburst_init_secondary,
> +	.smp_finish = xburst_smp_finish,
> +	.boot_secondary = xburst_boot_secondary,
> +	.smp_setup = xburst_smp_setup,
> +	.prepare_cpus = xburst_prepare_cpus,
> +};

[Severity: High]
What happens when CONFIG_HOTPLUG_CPU is enabled (for example in a
CONFIG_MIPS_GENERIC_KERNEL build where CONFIG_MIPS_CPS selects
CONFIG_SYS_SUPPORTS_HOTPLUG_CPU)?

smp_prepare_cpus() only initializes cpu_present_mask from
cpu_possible_mask when CONFIG_HOTPLUG_CPU is disabled:

arch/mips/kernel/smp.c:smp_prepare_cpus() {
    ...
#ifndef CONFIG_HOTPLUG_CPU
	init_cpu_present(cpu_possible_mask);
#endif
}

Because neither xburst_smp_setup() nor xburst_prepare_cpus() calls
set_cpu_present(cpu, true), CPU1 is never marked present and is never
brought online during boot when CONFIG_HOTPLUG_CPU is enabled.  In
addition, xburst_smp_ops leaves .cpu_disable and .cpu_die NULL, while
__cpu_disable() and __cpu_die() in <asm/smp.h> dereference them
unconditionally.

> diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
> index 80e8a04a642e0..46526997a4c64 100644
> --- a/arch/mips/kernel/idle.c
> +++ b/arch/mips/kernel/idle.c
[ ... ]
> @@ -156,10 +174,16 @@ void __init check_wait(void)
>  	case CPU_CAVIUM_OCTEON_PLUS:
>  	case CPU_CAVIUM_OCTEON2:
>  	case CPU_CAVIUM_OCTEON3:
> -	case CPU_XBURST:
>  	case CPU_LOONGSON32:
>  		cpu_wait = r4k_wait;
>  		break;
> +	case CPU_XBURST:
> +		if (IS_ENABLED(CONFIG_MACH_JZ4780) &&
> +		    IS_ENABLED(CONFIG_SMP))
> +			cpu_wait = xburst_wait_irqoff;
> +		else
> +			cpu_wait = r4k_wait;
> +		break;

[Severity: High]
Does this compile-time check cause single-core XBurst SoCs to use
xburst_wait_irqoff() when booted with a shared Ingenic kernel?

CONFIG_MACH_INGENIC_GENERIC unconditionally selects CONFIG_MACH_JZ4780
alongside single-core XBurst SoCs such as JZ4740, JZ4725B, JZ4770, X1000
and X1830, and all of them report CPU_XBURST.  When CONFIG_SMP is enabled
in a multi-SoC kernel, booting on any single-core XBurst SoC selects
xburst_wait_irqoff() instead of r4k_wait().  That blasts the entire L1
data cache on every idle entry and executes WAIT with local interrupts
disabled (CP0_Status.IE == 0) and without the r4k_wait rollback handler,
which prevents interrupts from waking MIPS32r1 XBurst cores such as
JZ4740 and JZ4725B from idle.  Checking num_possible_cpus() > 1 at
runtime would restrict xburst_wait_irqoff() to SMP systems.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261110043131.1985993-1-f.fainelli@gmail.com?part=2

  reply	other threads:[~2026-11-10  5:10 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10  4:31 [PATCH v2 0/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli
2026-11-10  4:31 ` [PATCH v2 1/3] clk: ingenic: Poll JZ4780 CPU1 power status atomically Florian Fainelli
2026-11-11 18:41   ` Brian Masney
2026-11-11 19:21     ` Florian Fainelli
2026-11-10  4:31 ` [PATCH v2 2/3] MIPS: Ingenic: Add XBurst SMP support Florian Fainelli
2026-11-10  5:10   ` sashiko-bot [this message]
2026-11-10 15:30   ` Paul Cercueil
2026-11-10  4:31 ` [PATCH v2 3/3] MIPS: CI20: Enable SMP with two CPUs Florian Fainelli
2026-11-10  5:32   ` sashiko-bot
2026-11-10 15:31   ` Paul Cercueil
2026-11-10 15:44 ` [PATCH v2 0/3] " Paul Cercueil
2026-11-10 17:14   ` Florian Fainelli
2026-11-10 18:11     ` Paul Cercueil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-206263@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=linux-clk@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.