lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1438022532-14576-1-git-send-email-eric@anholt.net>
Date:	Mon, 27 Jul 2015 11:42:12 -0700
From:	Eric Anholt <eric@...olt.net>
To:	linux-arm-kernel@...ts.infradead.org
Cc:	linux-rpi-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
	Stephen Warren <swarren@...dotorg.org>,
	Lee Jones <lee@...nel.org>, devicetree@...r.kernel.org,
	Thomas Gleixner <tglx@...utronix.de>,
	Jason Cooper <jason@...edaemon.net>,
	Eric Anholt <eric@...olt.net>
Subject: [PATCH] irq-bcm2836: Move SMP boot to the irqchip code.

Signed-off-by: Eric Anholt <eric@...olt.net>
---

Thomas: The problem with delaying IPI unmasking until secondary boot
is that it means we need the secondary boot process to integrate with
the irqchip code, which seems unusual given the dearth of includes I
could find between arch/arm/mach-* SMP boot code and drivers/irqchip/
to get function prototypes.  However, since the irqchip is most of
this register space already, it might make sense to just have the SMP
boot live in drivers/irqchip/.  Here's a patch that would do that,
that could be squashed into my change.

 drivers/irqchip/irq-bcm2836.c | 57 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 50 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index 87340b0..5f2a40e 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -49,14 +49,16 @@
 /* Same status bits as above, but for FIQ. */
 #define LOCAL_FIQ_PENDING0		0x070
 /*
- * Mailbox0 write-to-set bits.  There are 16 mailboxes, 4 per CPU, and
+ * Mailbox write-to-set bits.  There are 16 mailboxes, 4 per CPU, and
  * these bits are organized by mailbox number and then CPU number.  We
  * use mailbox 0 for IPIs.  The mailbox's interrupt is raised while
  * any bit is set.
  */
 #define LOCAL_MAILBOX0_SET0		0x080
+#define LOCAL_MAILBOX3_SET0		0x08c
 /* Mailbox0 write-to-clear bits. */
 #define LOCAL_MAILBOX0_CLR0		0x0c0
+#define LOCAL_MAILBOX3_CLR0		0x0cc
 
 #define LOCAL_IRQ_CNTPSIRQ	0
 #define LOCAL_IRQ_CNTPNSIRQ	1
@@ -195,6 +197,46 @@ static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask,
 		writel(1 << ipi, mailbox0_base + 16 * cpu);
 	}
 }
+
+/* Requests boot of a secondary CPU.
+ *
+ * The Raspberry Pi firmware has already started up the CPU and set it
+ * spinning in a loop in low memory waiting for a value in mailbox 3
+ * indicating what OS code it should jump to.
+ */
+int __init bcm2836_smp_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	int timeout = 20;
+	void __iomem *mailbox3_set_base = intc.base + LOCAL_MAILBOX3_SET0;
+	void __iomem *mailbox3_clr_base = intc.base + LOCAL_MAILBOX3_CLR0;
+	unsigned long secondary_startup_phys =
+		(unsigned long) virt_to_phys((void *)secondary_startup);
+
+	/* Unmask IPIs to the target cpu. */
+	bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_MAILBOX_INT_CONTROL0, 0,
+					       cpu);
+
+	dsb();
+
+	writel(secondary_startup_phys, mailbox3_set_base + 16 * cpu);
+
+	while (true) {
+		int val = readl(mailbox3_clr_base + 16 * cpu);
+
+		if (val == 0)
+			return 0;
+		if (timeout-- == 0)
+			return -ETIMEDOUT;
+		cpu_relax();
+	}
+
+	return 0;
+}
+
+static struct smp_operations bcm2836_smp_ops __initdata = {
+	.smp_boot_secondary	= bcm2836_smp_boot_secondary,
+};
+
 #endif
 
 static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
@@ -205,14 +247,15 @@ static void
 bcm2836_arm_irqchip_smp_init(void)
 {
 #ifdef CONFIG_SMP
-	int i;
+	/* Unmask IPIs to the boot CPU. Other CPUs will be unmasked as
+	 * they're brought up.
+	 */
+	bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_MAILBOX_INT_CONTROL0, 0,
+					       smp_processor_id());
 
-	/* unmask IPIs */
-	for_each_possible_cpu(i) {
-		bcm2836_arm_irqchip_unmask_per_cpu_irq(
-			LOCAL_MAILBOX_INT_CONTROL0, 0, i);
-	}
 	set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
+
+	smp_set_ops(&bcm2836_smp_ops);
 #endif
 }
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ