* RE: [PATCH V3 00/15] arm64: dts: imx8: architecture improvement and adding imx8qm support
From: Aisheng Dong @ 2019-09-13 16:43 UTC (permalink / raw)
To: Oliver Graute
Cc: devicetree@vger.kernel.org, dongas86@gmail.com,
catalin.marinas@arm.com, will.deacon@arm.com, robh+dt@kernel.org,
dl-linux-imx, kernel@pengutronix.de, Fabio Estevam,
shawnguo@kernel.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190913121608.GD16292@optiplex>
> From: Oliver Graute <oliver.graute@gmail.com>
> Sent: Friday, September 13, 2019 8:16 PM
>
> On 12/09/19, Dong Aisheng wrote:
> > IMX SCU based platforms (e.g. MX8QM/MX8QXP) are comprised of a
> number
> > of SS (Subsystems), those SS may be shared between different SoCs
> > while most of them can be reused like Devices Resources, Clocks, Power
> domains and etc.
> >
> > This patch series aims to improve the MX8 architecture to comply with
> > the HW design to save a lot of duplicated codes and benefits us a
> > better maintainability and scalability in the future.
> >
> > This patch series depends on another clk new binding series:
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatc
> >
> hwork.kernel.org%2Fcover%2F11046287%2F&data=02%7C01%7Caishen
> g.dong
> > %40nxp.com%7C2dffe4b2a0734c5a031408d738447876%7C686ea1d3bc2b
> 4c6fa92cd9
> >
> 9c5c301635%7C0%7C1%7C637039739035971290&sdata=JsAy8vUkkCp
> n5HYh79oC
> > vekH3SJAICg7VQnLMP01O3c%3D&reserved=0
>
> Thx for your update of this patch series. I'am running into the issue that my
> linux next-20190904 unfortunately is not booting with it on my imx8QM
> board. Kernel is just stuck during boot see below.
>
> I applied your v5 of your clock binding patches series and applied this series in
> v3. Your former two patch series worked well with next-20190716.
>
> The last messages from the kernel are:
>
> [ 1.019208] imx-scu scu: mbox_request_channel_byname() could not
> locate channel named "gip3"
> [ 1.027316] imx-scu scu: failed to request mbox chan gip3, ret -22
> [ 1.033480] imx-scu scu: failed to enable general irq channel: -22
> [ 1.039646] imx-scu scu: NXP i.MX SCU Initialized
> [ 1.047414] a35_clk: failed to get clock rate -22
> [ 1.058682] lcd0-pwm0: failed to power up resource 188 ret -22
> [ 1.064314] imx-scu-clk: probe of pwm_clk failed with error -22
> [ 1.070538] lcd0: failed to power up resource 187 ret -22
> [ 1.075690] imx-scu-clk: probe of lcd_clk failed with error -22
> [ 1.085965] mipi_csi0_core_clk: failed to attached the power domain -2
> [ 1.092359] mipi_csi0_esc_clk: failed to attached the power domain -2
> [ 1.098777] mipi_csi0_i2c0_clk: failed to attached the power domain -2
> [ 1.105278] mipi_csi0_pwm0_clk: failed to attached the power domain -2
> [ 1.115744] imx8qm-pinctrl scu:pinctrl: initialized IMX pinctrl driver
> [ 1.123923] gpio-mxc 5d080000.gpio: IRQ index 1 not found
> [ 1.130276] gpio-mxc 5d090000.gpio: IRQ index 1 not found
>
> I see similar messages also with your older working patches, only the last two
> lines are new errors.
>
Those warnings are because we are still missing some domains added into the
pd driver support, it does not block the booting.
But I did miss to send another power domain patch to avoid gate of console domain
which may result in the console hang.
Please try below patch:
From 4685f604938b2a8d91d9b14081c15cb554c5711f Mon Sep 17 00:00:00 2001
From: Dong Aisheng <aisheng.dong@nxp.com>
Date: Sun, 7 Jul 2019 19:37:33 +0800
Subject: [PATCH 1/1] firmware: imx: scu-pd: do not power off console domain
Do not power off console domain in runtime pm.
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
drivers/firmware/imx/scu-pd.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index b556612..770e368 100644
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -85,6 +85,8 @@ struct imx_sc_pd_soc {
u8 num_ranges;
};
+int imx_con_rsrc;
+
static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
/* LSIO SS */
{ "pwm", IMX_SC_R_PWM_0, 8, true, 0 },
@@ -173,6 +175,23 @@ to_imx_sc_pd(struct generic_pm_domain *genpd)
return container_of(genpd, struct imx_sc_pm_domain, pd);
}
+static void imx_sc_pd_get_console_rsrc(void)
+{
+ struct of_phandle_args specs;
+ int ret;
+
+ if (!of_stdout)
+ return;
+
+ ret = of_parse_phandle_with_args(of_stdout, "power-domains",
+ "#power-domain-cells",
+ 0, &specs);
+ if (ret)
+ return;
+
+ imx_con_rsrc = specs.args[0];
+}
+
static int imx_sc_pd_power(struct generic_pm_domain *domain, bool power_on)
{
struct imx_sc_msg_req_set_resource_power_mode msg;
@@ -233,6 +252,7 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
const struct imx_sc_pd_range *pd_ranges)
{
struct imx_sc_pm_domain *sc_pd;
+ bool is_off = true;
int ret;
sc_pd = devm_kzalloc(dev, sizeof(*sc_pd), GFP_KERNEL);
@@ -251,6 +271,10 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
"%s", pd_ranges->name);
sc_pd->pd.name = sc_pd->name;
+ if (imx_con_rsrc == sc_pd->rsrc) {
+ sc_pd->pd.flags = GENPD_FLAG_RPM_ALWAYS_ON;
+ is_off = false;
+ }
if (sc_pd->rsrc >= IMX_SC_R_LAST) {
dev_warn(dev, "invalid pd %s rsrc id %d found",
@@ -260,7 +284,7 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
return NULL;
}
- ret = pm_genpd_init(&sc_pd->pd, NULL, true);
+ ret = pm_genpd_init(&sc_pd->pd, NULL, is_off);
if (ret) {
dev_warn(dev, "failed to init pd %s rsrc id %d",
sc_pd->name, sc_pd->rsrc);
@@ -326,6 +350,8 @@ static int imx_sc_pd_probe(struct platform_device *pdev)
if (!pd_soc)
return -ENODEV;
+ imx_sc_pd_get_console_rsrc();
+
return imx_scu_init_pm_domains(&pdev->dev, pd_soc);
}
--
2.7.4
Regards
Aisheng
> Best regards,
>
> Oliver
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] arm64: dts: mt8183: Add node for the Mali GPU
From: Alyssa Rosenzweig @ 2019-09-13 18:17 UTC (permalink / raw)
To: Nicolas Boichat
Cc: Mark Rutland, devicetree, linux-kernel@vger.kernel.org,
Rob Herring, moderated list:ARM/Mediatek SoC support,
Boris Brezillon, Matthias Brugger, Nick Fan,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CANMq1KCTPdFhJG1SLf-i+-557Yx-1WLzWCHu3tT_5Q2BF+JgdQ@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 1189 bytes --]
> > > The binding we use with out-of-tree Mali drivers includes more
> > > clocks, I assume this would be required eventually if we have an
> > > in-tree driver:
> >
> > We have an in-tree driver...
>
> Right but AFAICT it does not support Bifrost GPU (yet?).
By the time MT8183 shows up in more concrete devices, it will, certainly
in kernel-space and likely in userspace as well. At present, the DDK can
be modified to run on top of the in-tree Mali drivers, i.e. "Bifrost on
mainline linux-next (+ page table/compatible patches), with blob
userspace".
While the open userspace isn't ready here quite yet, I would definitely
encourage upstream kernel for ChromeOS, since then there's no need to
maintain the out-of-tree GPU driver.
---
More immediately, per Rob's review, it's important that the bindings
accepted upstream work with the in-tree Bifrost driver. Conceptually,
once Mesa supports Bifrost, if I install Debian on a MT8183 board,
everything should just work. I shouldn't need MT-specific changes / need
to change names for the DT. Regardless of which kernel driver you end up
using, minimally sharing the DT is good for everyone :-)
-Alyssa
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RFC PATCH v2 00/12] Unify SMP stop generic logic to common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
Hi all,
the logic underlying SMP stop and kexec crash procedures, beside containing
some arch-specific bits, is mostly generic and common across all archs:
despite this fact, such logic is now scattered across all architectures and
on some of them is flawed, in such a way that, under some specific
conditions, you can end up with a CPU left still running after a panic and
possibly lost across a subsequent kexec crash reboot. [1]
Beside the flaws on some archs, there is anyway lots of code duplication,
so this patch series attempts to move into common code all the generic SMP
stop and crash logic, fixing observed issues, and leaving only the arch
specific bits inside properly provided arch-specific helpers.
An architecture willing to rely on this SMP common logic has to define its
own helpers and set CONFIG_ARCH_USE_COMMON_SMP_STOP=y.
This series wire this up for arm64, x86, arm, sparc64.
Behaviour is not changed for architectures not adopting this new common
logic.
In v2 the SMP common stop/crash code is generalized a bit more to address
the needs of the newly ported architectures (x86, arm, sparc64).
Tested as follows:
- arm64:
1. boot/reboot/emergency reboot
2. panic on a starting CPU within a 2 CPUs system (freezing properly)
3. kexec reboot after a panic like 2. (not losing any CPU on reboot)
4. kexec reboot after a panic like 2. and a simultaneous reboot
(instrumenting code to delay the stop messages transmission
to have time to inject a reboot -f)
- x86:
1. boot/reboot/emergency reboot/emergency reboot with VMX enabled
2. panic on a starting CPU within a 2 CPUs system
2. panic sysrq 4-CPus
3. kexec reboot after a panic
- arm:
1. boot
- sparc64:
1. build
A couple more of still to be done potential enhancements have been noted
on specific commits, and a lot more of testing remains surely to be done
as of now, but, in the context of this RFC, any thoughts on this approach
in general ?
Thanks,
Cristian
Changes:
--------
v1-->v2:
- rebased on v5.3-rc8
- moved common Kconfig bits to arch/Kconfig
- extended SMP common stop/crash generic code to address new architectures
needs: custom wait/timeouts, max_retries, attempt numbers.
- ported x86 to SMP common stop/crash code
- ported arm to SMP common stop/crash code
- ported sparc64 to SMP common stop code
[1]
[root@arch ~]# echo 1 > /sys/devices/system/cpu/cpu1/online
[root@arch ~]# [ 152.583368] ------------[ cut here ]------------
[ 152.583872] kernel BUG at arch/arm64/kernel/cpufeature.c:852!
[ 152.584693] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[ 152.585228] Modules linked in:
[ 152.586040] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.3.0-rc5-00001-gcabd12118c4a-dirty #2
[ 152.586218] Hardware name: Foundation-v8A (DT)
[ 152.586478] pstate: 000001c5 (nzcv dAIF -PAN -UAO)
[ 152.587260] pc : has_cpuid_feature+0x35c/0x360
[ 152.587398] lr : verify_local_elf_hwcaps+0x6c/0xf0
[ 152.587520] sp : ffff0000118bbf60
[ 152.587605] x29: ffff0000118bbf60 x28: 0000000000000000
[ 152.587784] x27: 0000000000000000 x26: 0000000000000000
[ 152.587882] x25: ffff00001167a010 x24: ffff0000112f59f8
[ 152.587992] x23: 0000000000000000 x22: 0000000000000000
[ 152.588085] x21: ffff0000112ea018 x20: ffff000010fe5518
[ 152.588180] x19: ffff000010ba3f30 x18: 0000000000000036
[ 152.588285] x17: 0000000000000000 x16: 0000000000000000
[ 152.588380] x15: 0000000000000000 x14: ffff80087a821210
[ 152.588481] x13: 0000000000000000 x12: 0000000000000000
[ 152.588599] x11: 0000000000000080 x10: 00400032b5503510
[ 152.588709] x9 : 0000000000000000 x8 : ffff000010b93204
[ 152.588810] x7 : 00000000800001d8 x6 : 0000000000000005
[ 152.588910] x5 : 0000000000000000 x4 : 0000000000000000
[ 152.589021] x3 : 0000000000000000 x2 : 0000000000008000
[ 152.589121] x1 : 0000000000180480 x0 : 0000000000180480
[ 152.589379] Call trace:
[ 152.589646] has_cpuid_feature+0x35c/0x360
[ 152.589763] verify_local_elf_hwcaps+0x6c/0xf0
[ 152.589858] check_local_cpu_capabilities+0x88/0x118
[ 152.589968] secondary_start_kernel+0xc4/0x168
[ 152.590530] Code: d53801e0 17ffff58 d5380600 17ffff56 (d4210000)
[ 152.592215] ---[ end trace 80ea98416149c87e ]---
[ 152.592734] Kernel panic - not syncing: Attempted to kill the idle task!
[ 152.593173] Kernel Offset: disabled
[ 152.593501] CPU features: 0x0004,20c02008
[ 152.593678] Memory Limit: none
[ 152.594208] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
[root@arch ~]# bash: echo: write error: Input/output error
[root@arch ~]#
[root@arch ~]#
[root@arch ~]# echo HELO
HELO
Cristian Marussi (12):
smp: add generic SMP-stop support to common code
smp: unify crash_ and smp_send_stop() logic
smp: coordinate concurrent crash/smp stop calls
smp: address races of starting CPUs while stopping
arm64: smp: use generic SMP stop common code
arm64: smp: use SMP crash-stop common code
arm64: smp: add arch specific cpu parking helper
x86: smp: use generic SMP stop common code
x86: smp: use SMP crash-stop common code
arm: smp: use generic SMP stop common code
arm: smp: use SMP crash-stop common code
sparc64: smp: use generic SMP stop common code
arch/Kconfig | 7 ++
arch/arm/Kconfig | 1 +
arch/arm/kernel/machine_kexec.c | 27 ++---
arch/arm/kernel/smp.c | 18 +---
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/smp.h | 2 -
arch/arm64/kernel/smp.c | 127 +++++++-----------------
arch/sparc/Kconfig | 1 +
arch/sparc/kernel/smp_64.c | 15 +--
arch/x86/Kconfig | 1 +
arch/x86/include/asm/reboot.h | 2 +
arch/x86/include/asm/smp.h | 6 --
arch/x86/kernel/crash.c | 27 +----
arch/x86/kernel/reboot.c | 50 ++++++----
arch/x86/kernel/smp.c | 98 ++++++++----------
include/linux/smp.h | 109 ++++++++++++++++++++
kernel/panic.c | 26 -----
kernel/smp.c | 170 ++++++++++++++++++++++++++++++++
18 files changed, 418 insertions(+), 270 deletions(-)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RFC PATCH v2 01/12] smp: add generic SMP-stop support to common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
There was a lot of code duplication across architectures regarding the
SMP stop procedures' logic; moreover some of this duplicated code logic
happened to be similarly faulty across a few architectures: while fixing
such logic, move such generic logic as much as possible inside common
code.
Collect all the common logic related to SMP stop operations into the
common SMP code; any architecture willing to use such centralized logic
can select CONFIG_ARCH_USE_COMMON_STOP=y and provide the related
arch-specific helpers: in such a scenario, those architectures will
transparently start using the common code provided by smp_send_stop()
common function.
On the other side, Architectures not willing to use common code SMP stop
logic will simply leave CONFIG_ARCH_USE_COMMON_STOP undefined and carry
on executing their local arch-specific smp_send_stop() as before.
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- moved related Kconfig to common code inside arch/Kconfig
- introduced additional CONFIG_USE_COMMON_STOP selected by
CONFIG_ARCH_USE_COMMON_STOP
- introduced helpers to let architectures optionally alter
the default common code behaviour while waiting for CPUs:
change timeout or wait for ever. (will be needed by x86)
---
arch/Kconfig | 7 +++++
include/linux/smp.h | 55 +++++++++++++++++++++++++++++++++++++
kernel/smp.c | 67 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 129 insertions(+)
diff --git a/arch/Kconfig b/arch/Kconfig
index a7b57dd42c26..89766e6c0ac8 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -166,6 +166,13 @@ config ARCH_USE_BUILTIN_BSWAP
instructions should set this. And it shouldn't hurt to set it
on architectures that don't have such instructions.
+config ARCH_USE_COMMON_SMP_STOP
+ def_bool n
+
+config USE_COMMON_SMP_STOP
+ depends on SMP && ARCH_USE_COMMON_SMP_STOP
+ def_bool y
+
config KRETPROBES
def_bool y
depends on KPROBES && HAVE_KRETPROBES
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 6fc856c9eda5..381a14bfcd96 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -77,6 +77,61 @@ int smp_call_function_single_async(int cpu, call_single_data_t *csd);
*/
extern void smp_send_stop(void);
+#ifdef CONFIG_USE_COMMON_SMP_STOP
+static atomic_t wait_forever;
+static atomic_t wait_timeout = ATOMIC_INIT(USEC_PER_SEC);
+
+/*
+ * An Architecture can optionally decide to use this helper to change the
+ * waiting behaviour of common STOP logic, forcing to wait forever for
+ * all CPUs to be stopped.
+ */
+static inline void smp_stop_set_wait_forever(int wait)
+{
+ atomic_set(&wait_forever, wait);
+ /* ensure wait atomic-op is visible */
+ smp_mb__after_atomic();
+}
+
+/*
+ * An Architecture can optionally decide to use this helper to change the
+ * waiting timeout of common STOP logic. A ZERO timeout means no timeout
+ * at all as long as wait_forever was not previously set.
+ *
+ * Note that wait_forever and timeout must remain individually selectable:
+ * so you can temporarily request wait_forever while keeping the same timeout
+ * settings.
+ */
+static inline void smp_stop_set_wait_timeout_us(unsigned long timeout)
+{
+ atomic_set(&wait_timeout, timeout);
+ /* ensure timeout atomic-op is visible */
+ smp_mb__after_atomic();
+}
+
+/* Retrieve the current wait settings. */
+static inline bool smp_stop_get_wait_timeout_us(unsigned long *timeout)
+{
+ if (timeout)
+ *timeout = atomic_read(&wait_timeout);
+ return atomic_read(&wait_forever);
+}
+
+/*
+ * Any Architecture willing to use STOP common logic implementation
+ * MUST at least provide the arch_smp_stop_call() helper which is in
+ * charge of its own arch-specific CPU-stop mechanism.
+ */
+extern void arch_smp_stop_call(cpumask_t *cpus);
+
+/*
+ * An Architecture CAN also provide the arch_smp_cpus_stop_complete()
+ * dedicated helper, to perform any final arch-specific operation on
+ * the local CPU once the other CPUs have been successfully stopped.
+ */
+void arch_smp_cpus_stop_complete(void);
+#endif
+
/*
* sends a 'reschedule' event to another CPU:
*/
diff --git a/kernel/smp.c b/kernel/smp.c
index 7dbcb402c2fc..72f99bf13fd0 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -20,6 +20,7 @@
#include <linux/sched.h>
#include <linux/sched/idle.h>
#include <linux/hypervisor.h>
+#include <linux/delay.h>
#include "smpboot.h"
@@ -817,3 +818,69 @@ int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par, bool phys)
return sscs.ret;
}
EXPORT_SYMBOL_GPL(smp_call_on_cpu);
+
+#ifdef CONFIG_USE_COMMON_SMP_STOP
+void __weak arch_smp_cpus_stop_complete(void) { }
+
+static inline bool any_other_cpus_online(cpumask_t *mask,
+ unsigned int this_cpu_id)
+{
+ cpumask_copy(mask, cpu_online_mask);
+ cpumask_clear_cpu(this_cpu_id, mask);
+
+ return !cpumask_empty(mask);
+}
+
+/*
+ * This centralizes the common logic to:
+ *
+ * - evaluate which CPUs are online and needs to be notified for stop,
+ * while considering properly the status of the calling CPU
+ *
+ * - call the arch-specific helpers to request the effective stop
+ *
+ * - wait for the stop operation to be completed across all involved CPUs
+ * monitoring the cpu_online_mask
+ */
+void smp_send_stop(void)
+{
+ unsigned int this_cpu_id;
+ cpumask_t mask;
+
+ this_cpu_id = smp_processor_id();
+ if (any_other_cpus_online(&mask, this_cpu_id)) {
+ bool wait;
+ unsigned long timeout;
+ unsigned int this_cpu_online = cpu_online(this_cpu_id);
+
+ if (system_state <= SYSTEM_RUNNING)
+ pr_crit("stopping secondary CPUs\n");
+ arch_smp_stop_call(&mask);
+
+ /*
+ * Defaults to wait up to one second for other CPUs to stop;
+ * architectures can modify the default timeout or request
+ * to wait forever.
+ *
+ * Here we rely simply on cpu_online_mask to sync with
+ * arch-specific stop code without bloating the code with an
+ * additional atomic_t ad-hoc counter.
+ *
+ * As a consequence we'll need proper explicit memory barriers
+ * in case the other CPUs running the arch-specific stop-code
+ * would need to commit to memory some data (like saved_regs).
+ */
+ wait = smp_stop_get_wait_timeout_us(&timeout);
+ while (num_online_cpus() > this_cpu_online &&
+ (wait || timeout--))
+ udelay(1);
+ /* ensure any stopping-CPUs memory access is made visible */
+ smp_rmb();
+ if (num_online_cpus() > this_cpu_online)
+ pr_warn("failed to stop secondary CPUs %*pbl\n",
+ cpumask_pr_args(cpu_online_mask));
+ }
+ /* Perform final (possibly arch-specific) work on this CPU */
+ arch_smp_cpus_stop_complete();
+}
+#endif
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 02/12] smp: unify crash_ and smp_send_stop() logic
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
crash_smp_send_stop() logic was fairly similar to smp_send_stop():
a lot of logic and code was duplicated between the two code paths and
across a few different architectures.
Unify this underlying common logic into the existing SMP common stop
code: use a common workhorse function for both paths to perform the
common tasks while taking care to propagate to the underlying
architecture code the intent of the stop operation: a simple stop or
a crash dump stop.
Relocate the __weak crash_smp_send_stop() function from panic.c to smp.c,
since it is the crash dump entry point for the crash stop process and now
calls into this new common logic (only if this latter is enabled by
ARCH_USE_COMMON_SMP_STOP=y).
Introduce a few more helpers so that the architectures willing to use
the common code logic can provide their arch-specific bits to handle
the differences between a stop and a crash stop; architectures can
anyway decide to override as a whole the common logic providing their
own custom solution in crash_smp_send_stop() (as it was before).
Provide also a new common code method to inquiry on the outcome of an
ongoing crash_stop procedure: smp_crash_stop_failed().
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- using new CONFIG_USE_COMMON_SMP_STOP
- added arch_smp_cpus_crash_complete()
---
include/linux/smp.h | 34 +++++++++++++++++++++++
kernel/panic.c | 26 -----------------
kernel/smp.c | 68 ++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 98 insertions(+), 30 deletions(-)
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 381a14bfcd96..0f95bbd2cb5c 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -130,8 +130,36 @@ extern void arch_smp_stop_call(cpumask_t *cpus);
* the local CPU once the other CPUs have been successfully stopped.
*/
void arch_smp_cpus_stop_complete(void);
+
+/*
+ * An Architecture CAN also provide the arch_smp_cpus_crash_complete()
+ * dedicated helper, to perform any final arch-specific operation on
+ * the local CPU once the other CPUs have been successfully crash stopped.
+ * When not overridden by the user, this defaults to call straight away
+ * arch_smp_cpus_stop_complete()
+ */
+void arch_smp_cpus_crash_complete(void);
+
+/*
+ * An Architecture CAN additionally provide the arch_smp_crash_call()
+ * helper which implements the arch-specific crash dump related operations.
+ *
+ * If such arch wants to fully support crash dump, this MUST be provided;
+ * when not provided the crash dump procedure will fallback to behave like
+ * a normal stop. (no saved regs, no arch-specific features disabled)
+ */
+extern void arch_smp_crash_call(cpumask_t *cpus);
+
+/* Helper to query the outcome of an ongoing crash_stop operation */
+bool smp_crash_stop_failed(void);
#endif
+/*
+ * stops all CPUs but the current one propagating to all other CPUs
+ * the information that a crash_kexec is ongoing:
+ */
+void crash_smp_send_stop(void);
+
/*
* sends a 'reschedule' event to another CPU:
*/
@@ -195,6 +223,12 @@ static inline int get_boot_cpu_id(void)
static inline void smp_send_stop(void) { }
+static inline void crash_smp_send_stop(void) { }
+
+#ifdef CONFIG_USE_COMMON_SMP_STOP
+static inline bool smp_crash_stop_failed(void) { }
+#endif
+
/*
* These macros fold the SMP functionality into a single CPU system
*/
diff --git a/kernel/panic.c b/kernel/panic.c
index 057540b6eee9..bc0dbf9c9b75 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -86,32 +86,6 @@ void __weak nmi_panic_self_stop(struct pt_regs *regs)
panic_smp_self_stop();
}
-/*
- * Stop other CPUs in panic. Architecture dependent code may override this
- * with more suitable version. For example, if the architecture supports
- * crash dump, it should save registers of each stopped CPU and disable
- * per-CPU features such as virtualization extensions.
- */
-void __weak crash_smp_send_stop(void)
-{
- static int cpus_stopped;
-
- /*
- * This function can be called twice in panic path, but obviously
- * we execute this only once.
- */
- if (cpus_stopped)
- return;
-
- /*
- * Note smp_send_stop is the usual smp shutdown function, which
- * unfortunately means it may not be hardened to work in a panic
- * situation.
- */
- smp_send_stop();
- cpus_stopped = 1;
-}
-
atomic_t panic_cpu = ATOMIC_INIT(PANIC_CPU_INVALID);
/*
diff --git a/kernel/smp.c b/kernel/smp.c
index 72f99bf13fd0..b05d2648a168 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -820,8 +820,14 @@ int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par, bool phys)
EXPORT_SYMBOL_GPL(smp_call_on_cpu);
#ifdef CONFIG_USE_COMMON_SMP_STOP
+
void __weak arch_smp_cpus_stop_complete(void) { }
+void __weak arch_smp_cpus_crash_complete(void)
+{
+ arch_smp_cpus_stop_complete();
+}
+
static inline bool any_other_cpus_online(cpumask_t *mask,
unsigned int this_cpu_id)
{
@@ -831,6 +837,12 @@ static inline bool any_other_cpus_online(cpumask_t *mask,
return !cpumask_empty(mask);
}
+void __weak arch_smp_crash_call(cpumask_t *cpus)
+{
+ pr_debug("SMP: Using generic %s() as SMP crash call.\n", __func__);
+ arch_smp_stop_call(cpus);
+}
+
/*
* This centralizes the common logic to:
*
@@ -842,7 +854,7 @@ static inline bool any_other_cpus_online(cpumask_t *mask,
* - wait for the stop operation to be completed across all involved CPUs
* monitoring the cpu_online_mask
*/
-void smp_send_stop(void)
+static inline void __smp_send_stop_all(bool reason_crash)
{
unsigned int this_cpu_id;
cpumask_t mask;
@@ -855,8 +867,11 @@ void smp_send_stop(void)
if (system_state <= SYSTEM_RUNNING)
pr_crit("stopping secondary CPUs\n");
- arch_smp_stop_call(&mask);
-
+ /* smp and crash arch-backends helpers are kept distinct */
+ if (!reason_crash)
+ arch_smp_stop_call(&mask);
+ else
+ arch_smp_crash_call(&mask);
/*
* Defaults to wait up to one second for other CPUs to stop;
* architectures can modify the default timeout or request
@@ -881,6 +896,51 @@ void smp_send_stop(void)
cpumask_pr_args(cpu_online_mask));
}
/* Perform final (possibly arch-specific) work on this CPU */
- arch_smp_cpus_stop_complete();
+ if (!reason_crash)
+ arch_smp_cpus_stop_complete();
+ else
+ arch_smp_cpus_crash_complete();
+}
+
+void smp_send_stop(void)
+{
+ __smp_send_stop_all(false);
}
+
+bool __weak smp_crash_stop_failed(void)
+{
+ return (num_online_cpus() > cpu_online(smp_processor_id()));
+}
+#endif
+
+/*
+ * Stop other CPUs while passing down the additional information that a
+ * crash_kexec is ongoing: it's up to the architecture implementation
+ * decide what to do.
+ *
+ * For example, Architectures supporting crash dump should provide
+ * specialized support for saving registers and disabling per-CPU features
+ * like virtualization extensions.
+ *
+ * Behaviour in the CONFIG_USE_COMMON_SMP_STOP=n case is preserved
+ * as it was before.
+ */
+void __weak crash_smp_send_stop(void)
+{
+ static int cpus_stopped;
+
+ /*
+ * This function can be called twice in panic path, but obviously
+ * we execute this only once.
+ */
+ if (cpus_stopped)
+ return;
+
+#ifdef CONFIG_USE_COMMON_SMP_STOP
+ __smp_send_stop_all(true);
+#else
+ smp_send_stop();
#endif
+
+ cpus_stopped = 1;
+}
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 03/12] smp: coordinate concurrent crash/smp stop calls
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Once a stop request is in progress on one CPU, it must be carefully
evaluated what to do if another stop request is issued concurrently
on another CPU.
Given that panic and crash dump code flows are mutually exclusive,
the only alternative possible scenario which instead could lead to
concurrent stop requests, is represented by the simultaneous stop
requests possibly triggered by a concurrent halt/reboot/shutdown.
In such a case, prioritize the panic/crash procedure and most importantly
immediately park the offending CPU that was attempting the concurrent stop
request: force it to idle quietly, waiting for the ongoing stop/dump
requests to arrive.
Failing to do so would result in the offending CPU being effectively lost
on the next possible reboot triggered by the crash dump. [1]
Another scenario, where the crash/stop code path was known to be executed
twice, was during a normal panic/crash with crash_kexec_post_notifiers=1;
since this issue is similar, fold also this case-handling into this new
logic.
[1]
<<<<<---------- TRIGGERED PANIC
[ 225.676014] ------------[ cut here ]------------
[ 225.676656] kernel BUG at arch/arm64/kernel/cpufeature.c:852!
[ 225.677253] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[ 225.677660] Modules linked in:
[ 225.678458] CPU: 3 PID: 0 Comm: swapper/3 Kdump: loaded Not tainted 5.3.0-rc5-00004-gb8a210cd3c32-dirty #2
[ 225.678621] Hardware name: Foundation-v8A (DT)
[ 225.678868] pstate: 000001c5 (nzcv dAIF -PAN -UAO)
[ 225.679523] pc : has_cpuid_feature+0x35c/0x360
[ 225.679649] lr : verify_local_elf_hwcaps+0x6c/0xf0
[ 225.679759] sp : ffff0000118cbf60
[ 225.679855] x29: ffff0000118cbf60 x28: 0000000000000000
[ 225.680026] x27: 0000000000000000 x26: 0000000000000000
[ 225.680115] x25: ffff00001167a010 x24: ffff0000112f59f8
[ 225.680207] x23: 0000000000000000 x22: 0000000000000000
[ 225.680290] x21: ffff0000112ea018 x20: ffff000010fe5538
[ 225.680372] x19: ffff000010ba3f30 x18: 000000000000001e
[ 225.680465] x17: 0000000000000000 x16: 0000000000000000
[ 225.680546] x15: 0000000000000000 x14: 0000000000000008
[ 225.680629] x13: 0209018b7a9404f4 x12: 0000000000000001
[ 225.680719] x11: 0000000000000080 x10: 00400032b5503510
[ 225.680803] x9 : 0000000000000000 x8 : ffff000010b93204
[ 225.680884] x7 : 00000000800001d8 x6 : 0000000000000005
[ 225.680975] x5 : 0000000000000000 x4 : 0000000000000000
[ 225.681056] x3 : 0000000000000000 x2 : 0000000000008000
[ 225.681139] x1 : 0000000000180480 x0 : 0000000000180480
[ 225.681423] Call trace:
[ 225.681669] has_cpuid_feature+0x35c/0x360
[ 225.681762] verify_local_elf_hwcaps+0x6c/0xf0
[ 225.681836] check_local_cpu_capabilities+0x88/0x118
[ 225.681939] secondary_start_kernel+0xc4/0x168
[ 225.682432] Code: d53801e0 17ffff58 d5380600 17ffff56 (d4210000)
[ 225.683998] smp: stopping secondary CPUs
[ 225.684130] Delaying stop.... <<<<<------ INSTRUMENTED DEBUG_DELAY
Rebooting. <<<<<------ MANUAL SIMULTANEOUS REBOOT
[ 232.647472] reboot: Restarting system
[ 232.648363] Reboot failed -- System halted
[ 239.552413] smp: failed to stop secondary CPUs 0
[ 239.554730] Starting crashdump kernel...
[ 239.555194] ------------[ cut here ]------------
[ 239.555406] Some CPUs may be stale, kdump will be unreliable.
[ 239.555802] WARNING: CPU: 3 PID: 0 at arch/arm64/kernel/machine_kexec.c:156 machine_kexec+0x3c/0x2b0
[ 239.556044] Modules linked in:
[ 239.556244] CPU: 3 PID: 0 Comm: swapper/3 Kdump: loaded Not tainted 5.3.0-rc5-00004-gb8a210cd3c32-dirty #2
[ 239.556340] Hardware name: Foundation-v8A (DT)
[ 239.556459] pstate: 600003c5 (nZCv DAIF -PAN -UAO)
[ 239.556587] pc : machine_kexec+0x3c/0x2b0
[ 239.556700] lr : machine_kexec+0x3c/0x2b0
[ 239.556775] sp : ffff0000118cbad0
[ 239.556876] x29: ffff0000118cbad0 x28: ffff80087a8c3700
[ 239.557012] x27: 0000000000000000 x26: 0000000000000000
[ 239.557278] x25: ffff000010fe3ef0 x24: 00000000000003c0
....
[ 239.561568] Bye!
[ 0.000000] Booting Linux on physical CPU 0x0000000003 [0x410fd0f0]
[ 0.000000] Linux version 5.2.0-rc4-00001-g93bd4bc234d5-dirty
[ 0.000000] Machine model: Foundation-v8A
...
[ 0.197991] smp: Bringing up secondary CPUs ...
[ 0.232643] psci: failed to boot CPU1 (-22) <<<<--- LOST CPU ON REBOOT
[ 0.232861] CPU1: failed to boot: -22
[ 0.306291] Detected PIPT I-cache on CPU2
[ 0.310524] GICv3: CPU2: found redistributor 1 region 0:0x000000002f120000
[ 0.315618] CPU2: Booted secondary processor 0x0000000001 [0x410fd0f0]
[ 0.395576] Detected PIPT I-cache on CPU3
[ 0.400431] GICv3: CPU3: found redistributor 2 region 0:0x000000002f140000
[ 0.407252] CPU3: Booted secondary processor 0x0000000002 [0x410fd0f0]
[ 0.431811] smp: Brought up 1 node, 3 CPUs
[ 0.439898] SMP: Total of 3 processors activated.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- using new CONFIG_USE_COMMON_SMP_STOP
---
include/linux/smp.h | 3 +++
kernel/smp.c | 48 ++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 0f95bbd2cb5c..2ae7dd48b33c 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -152,6 +152,9 @@ extern void arch_smp_crash_call(cpumask_t *cpus);
/* Helper to query the outcome of an ongoing crash_stop operation */
bool smp_crash_stop_failed(void);
+
+/* A generic cpu parking helper, possibly overridden by architecture code */
+void arch_smp_cpu_park(void) __noreturn;
#endif
/*
diff --git a/kernel/smp.c b/kernel/smp.c
index b05d2648a168..d92ce59ae538 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -821,6 +821,12 @@ EXPORT_SYMBOL_GPL(smp_call_on_cpu);
#ifdef CONFIG_USE_COMMON_SMP_STOP
+void __weak arch_smp_cpu_park(void)
+{
+ while (1)
+ cpu_relax();
+}
+
void __weak arch_smp_cpus_stop_complete(void) { }
void __weak arch_smp_cpus_crash_complete(void)
@@ -843,6 +849,9 @@ void __weak arch_smp_crash_call(cpumask_t *cpus)
arch_smp_stop_call(cpus);
}
+#define REASON_STOP 1
+#define REASON_CRASH 2
+
/*
* This centralizes the common logic to:
*
@@ -858,8 +867,38 @@ static inline void __smp_send_stop_all(bool reason_crash)
{
unsigned int this_cpu_id;
cpumask_t mask;
+ static atomic_t stopping;
+ int was_reason;
this_cpu_id = smp_processor_id();
+ /* make sure that concurrent stop requests are handled properly */
+ was_reason = atomic_cmpxchg(&stopping, 0,
+ reason_crash ? REASON_CRASH : REASON_STOP);
+ if (was_reason) {
+ /*
+ * This function can be called twice in panic path if
+ * crash_kexec is called with crash_kexec_post_notifiers=1,
+ * but obviously we execute this only once.
+ */
+ if (reason_crash && was_reason == REASON_CRASH)
+ return;
+ /*
+ * In case of other concurrent STOP calls (like in a REBOOT
+ * started simultaneously as an ongoing PANIC/CRASH/REBOOT)
+ * we want to prioritize the ongoing PANIC/KEXEC call and
+ * force here the offending CPU that was attempting the
+ * concurrent STOP to just sit idle waiting to die.
+ * Failing to do so would result in a lost CPU on the next
+ * possible reboot triggered by crash_kexec().
+ */
+ if (!reason_crash) {
+ pr_crit("CPU%d - kernel already stopping, parking myself.\n",
+ this_cpu_id);
+ local_irq_enable();
+ /* does not return */
+ arch_smp_cpu_park();
+ }
+ }
if (any_other_cpus_online(&mask, this_cpu_id)) {
bool wait;
unsigned long timeout;
@@ -927,6 +966,9 @@ bool __weak smp_crash_stop_failed(void)
*/
void __weak crash_smp_send_stop(void)
{
+#ifdef CONFIG_USE_COMMON_SMP_STOP
+ __smp_send_stop_all(true);
+#else
static int cpus_stopped;
/*
@@ -936,11 +978,7 @@ void __weak crash_smp_send_stop(void)
if (cpus_stopped)
return;
-#ifdef CONFIG_USE_COMMON_SMP_STOP
- __smp_send_stop_all(true);
-#else
smp_send_stop();
-#endif
-
cpus_stopped = 1;
+#endif
}
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 04/12] smp: address races of starting CPUs while stopping
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Add to SMP stop common code a best-effort retry logic, re-issuing a stop
request when any CPU is detected to be still online after the first
stop request cycle has completed.
While retrying provide to architectures' helpers an 'attempt' argument
so that, after a possible first failed attempt, they can autonomously
decide to adopt different approaches in subsequent retries.
Address the case in which some CPUs could still be starting up when the
stop process is initiated, remaining so undetected and coming fully online
only after the SMP stop procedure was already started: such officially
still offline CPUs would be missed by an ongoing stop procedure.
Being a best effort approach, though, it is not always guaranteed to be
able to stop any CPU that happened to finally come online after the whole
SMP stop retry cycle has completed.
(i.e. the race-window is reduced but not eliminated)
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- added attempt_num param to arch helpers, to let arch implementation
know if a retry is ongoing because some CPU failed to stop.
(some arch like x86 attempts the retry with different means like NMI)
- added some helpers to let archs decide on the number of retries
---
A more deterministic approach has been also attempted in order to catch
any concurrently starting CPUs at the very last moment and make them
kill themselves by:
- adding a new set_cpus_stopping() in cpumask.h used to set a
__cpus_stopping atomic internal flag
- modifying set_cpu_online() to check on __cpus_stopping only when
coming online, and force the offending CPU to kill itself in that case
Anyway it has proved tricky and complex (beside faulty) to implement the
above 'kill-myself' phase in a reliable way while remaining architecture
agnostic and still distingushing properly regular stops from crash kexec.
So given that the main idea underlying this patch series was instead of
simplifying and unifying code and the residual races not caught by the
best-effort logic seemed not very likely, this more deterministic approach
has been dropped in favour of the best effort retry logic.
Moreover, the current retry logic will be anyway needed to support some
architectures, like x86, that prefer to use different CPU's stopping
methods in subsequent retries.
---
include/linux/smp.h | 21 +++++++++++++++++++--
kernel/smp.c | 19 ++++++++++++-------
2 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 2ae7dd48b33c..63e4322d52e1 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -78,8 +78,11 @@ int smp_call_function_single_async(int cpu, call_single_data_t *csd);
extern void smp_send_stop(void);
#ifdef CONFIG_USE_COMMON_SMP_STOP
+#define DEFAULT_MAX_STOP_RETRIES 2
+
static atomic_t wait_forever;
static atomic_t wait_timeout = ATOMIC_INIT(USEC_PER_SEC);
+static atomic_t max_stop_retries = ATOMIC_INIT(DEFAULT_MAX_STOP_RETRIES);
/*
* An Architecture can optionally decide to use this helper to change the
@@ -117,12 +120,26 @@ static inline bool smp_stop_get_wait_timeout_us(unsigned long *timeout)
return atomic_read(&wait_forever);
}
+/* Change common SMP STOP logic maximum retries */
+static inline void smp_stop_set_max_retries(unsigned int max_retries)
+{
+ atomic_set(&max_stop_retries, max_retries);
+ /* ensure retries atomics are visible */
+ smp_mb__after_atomic();
+}
+
+/* Get currently set maximum retries attempt */
+static inline unsigned int smp_stop_get_max_retries(void)
+{
+ return atomic_read(&max_stop_retries);
+}
+
/*
* Any Architecture willing to use STOP common logic implementation
* MUST at least provide the arch_smp_stop_call() helper which is in
* charge of its own arch-specific CPU-stop mechanism.
*/
-extern void arch_smp_stop_call(cpumask_t *cpus);
+extern void arch_smp_stop_call(cpumask_t *cpus, unsigned int attempt_num);
/*
* An Architecture CAN also provide the arch_smp_cpus_stop_complete()
@@ -148,7 +165,7 @@ void arch_smp_cpus_crash_complete(void);
* when not provided the crash dump procedure will fallback to behave like
* a normal stop. (no saved regs, no arch-specific features disabled)
*/
-extern void arch_smp_crash_call(cpumask_t *cpus);
+extern void arch_smp_crash_call(cpumask_t *cpus, unsigned int attempt_num);
/* Helper to query the outcome of an ongoing crash_stop operation */
bool smp_crash_stop_failed(void);
diff --git a/kernel/smp.c b/kernel/smp.c
index d92ce59ae538..5b966c62d557 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -843,10 +843,10 @@ static inline bool any_other_cpus_online(cpumask_t *mask,
return !cpumask_empty(mask);
}
-void __weak arch_smp_crash_call(cpumask_t *cpus)
+void __weak arch_smp_crash_call(cpumask_t *cpus, unsigned int attempt_num)
{
pr_debug("SMP: Using generic %s() as SMP crash call.\n", __func__);
- arch_smp_stop_call(cpus);
+ arch_smp_stop_call(cpus, attempt_num);
}
#define REASON_STOP 1
@@ -865,10 +865,10 @@ void __weak arch_smp_crash_call(cpumask_t *cpus)
*/
static inline void __smp_send_stop_all(bool reason_crash)
{
- unsigned int this_cpu_id;
cpumask_t mask;
static atomic_t stopping;
int was_reason;
+ unsigned int this_cpu_id, max_retries, attempt = 0;
this_cpu_id = smp_processor_id();
/* make sure that concurrent stop requests are handled properly */
@@ -899,7 +899,9 @@ static inline void __smp_send_stop_all(bool reason_crash)
arch_smp_cpu_park();
}
}
- if (any_other_cpus_online(&mask, this_cpu_id)) {
+ max_retries = smp_stop_get_max_retries();
+ while (++attempt <= max_retries &&
+ any_other_cpus_online(&mask, this_cpu_id)) {
bool wait;
unsigned long timeout;
unsigned int this_cpu_online = cpu_online(this_cpu_id);
@@ -908,9 +910,9 @@ static inline void __smp_send_stop_all(bool reason_crash)
pr_crit("stopping secondary CPUs\n");
/* smp and crash arch-backends helpers are kept distinct */
if (!reason_crash)
- arch_smp_stop_call(&mask);
+ arch_smp_stop_call(&mask, attempt);
else
- arch_smp_crash_call(&mask);
+ arch_smp_crash_call(&mask, attempt);
/*
* Defaults to wait up to one second for other CPUs to stop;
* architectures can modify the default timeout or request
@@ -930,9 +932,12 @@ static inline void __smp_send_stop_all(bool reason_crash)
udelay(1);
/* ensure any stopping-CPUs memory access is made visible */
smp_rmb();
- if (num_online_cpus() > this_cpu_online)
+ if (num_online_cpus() > this_cpu_online) {
pr_warn("failed to stop secondary CPUs %*pbl\n",
cpumask_pr_args(cpu_online_mask));
+ if (attempt < max_retries)
+ pr_warn("Retrying SMP stop call...\n");
+ }
}
/* Perform final (possibly arch-specific) work on this CPU */
if (!reason_crash)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 05/12] arm64: smp: use generic SMP stop common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Make arm64 use the generic SMP-stop logic provided by common code
unified smp_send_stop() function.
arm64 smp_send_stop() logic had a bug in it: it failed to consider the
online status of the calling CPU when evaluating if any stop message
needed to be sent to other CPus at all: this resulted, on a 2-CPUs
system, in the failure to stop all cpus if one paniced while starting
up, leaving such system in an unexpected lively state.
[root@arch ~]# echo 1 > /sys/devices/system/cpu/cpu1/online
[root@arch ~]# [ 152.583368] ------------[ cut here ]------------
[ 152.583872] kernel BUG at arch/arm64/kernel/cpufeature.c:852!
[ 152.584693] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[ 152.585228] Modules linked in:
[ 152.586040] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.3.0-rc5-00001-gcabd12118c4a-dirty #2
[ 152.586218] Hardware name: Foundation-v8A (DT)
[ 152.586478] pstate: 000001c5 (nzcv dAIF -PAN -UAO)
[ 152.587260] pc : has_cpuid_feature+0x35c/0x360
[ 152.587398] lr : verify_local_elf_hwcaps+0x6c/0xf0
[ 152.587520] sp : ffff0000118bbf60
[ 152.587605] x29: ffff0000118bbf60 x28: 0000000000000000
[ 152.587784] x27: 0000000000000000 x26: 0000000000000000
[ 152.587882] x25: ffff00001167a010 x24: ffff0000112f59f8
[ 152.587992] x23: 0000000000000000 x22: 0000000000000000
[ 152.588085] x21: ffff0000112ea018 x20: ffff000010fe5518
[ 152.588180] x19: ffff000010ba3f30 x18: 0000000000000036
[ 152.588285] x17: 0000000000000000 x16: 0000000000000000
[ 152.588380] x15: 0000000000000000 x14: ffff80087a821210
[ 152.588481] x13: 0000000000000000 x12: 0000000000000000
[ 152.588599] x11: 0000000000000080 x10: 00400032b5503510
[ 152.588709] x9 : 0000000000000000 x8 : ffff000010b93204
[ 152.588810] x7 : 00000000800001d8 x6 : 0000000000000005
[ 152.588910] x5 : 0000000000000000 x4 : 0000000000000000
[ 152.589021] x3 : 0000000000000000 x2 : 0000000000008000
[ 152.589121] x1 : 0000000000180480 x0 : 0000000000180480
[ 152.589379] Call trace:
[ 152.589646] has_cpuid_feature+0x35c/0x360
[ 152.589763] verify_local_elf_hwcaps+0x6c/0xf0
[ 152.589858] check_local_cpu_capabilities+0x88/0x118
[ 152.589968] secondary_start_kernel+0xc4/0x168
[ 152.590530] Code: d53801e0 17ffff58 d5380600 17ffff56 (d4210000)
[ 152.592215] ---[ end trace 80ea98416149c87e ]---
[ 152.592734] Kernel panic - not syncing: Attempted to kill the idle task!
[ 152.593173] Kernel Offset: disabled
[ 152.593501] CPU features: 0x0004,20c02008
[ 152.593678] Memory Limit: none
[ 152.594208] ---[ end Kernel panic - not syncing: Attempted to kill the idle
task! ]---
[root@arch ~]# bash: echo: write error: Input/output error
[root@arch ~]#
[root@arch ~]#
[root@arch ~]# echo HELO
HELO
Get rid of such bug, switching arm64 to use the common SMP stop code.
Reported-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 --> v2
- now selecting arch/Kconfig ARCH_USE_COMMON_SMP_STOP
- added attempt_num arch_smp_stop_call() helper
---
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/smp.c | 29 ++++++-----------------------
2 files changed, 7 insertions(+), 23 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3adcec05b1f6..33f88381702b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -67,6 +67,7 @@ config ARM64
select ARCH_USE_CMPXCHG_LOCKREF
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
+ select ARCH_USE_COMMON_SMP_STOP
select ARCH_SUPPORTS_MEMORY_FAILURE
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_INT128 if GCC_VERSION >= 50000 || CC_IS_CLANG
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 018a33e01b0e..3e87fdbb9f74 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -953,33 +953,16 @@ void tick_broadcast(const struct cpumask *mask)
}
#endif
-void smp_send_stop(void)
+void arch_smp_cpus_stop_complete(void)
{
- unsigned long timeout;
-
- if (num_online_cpus() > 1) {
- cpumask_t mask;
-
- cpumask_copy(&mask, cpu_online_mask);
- cpumask_clear_cpu(smp_processor_id(), &mask);
-
- if (system_state <= SYSTEM_RUNNING)
- pr_crit("SMP: stopping secondary CPUs\n");
- smp_cross_call(&mask, IPI_CPU_STOP);
- }
-
- /* Wait up to one second for other CPUs to stop */
- timeout = USEC_PER_SEC;
- while (num_online_cpus() > 1 && timeout--)
- udelay(1);
-
- if (num_online_cpus() > 1)
- pr_warning("SMP: failed to stop secondary CPUs %*pbl\n",
- cpumask_pr_args(cpu_online_mask));
-
sdei_mask_local_cpu();
}
+void arch_smp_stop_call(cpumask_t *cpus, unsigned int __unused)
+{
+ smp_cross_call(cpus, IPI_CPU_STOP);
+}
+
#ifdef CONFIG_KEXEC_CORE
void crash_smp_send_stop(void)
{
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 06/12] arm64: smp: use SMP crash-stop common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Make arm64 use the SMP common implementation of crash_smp_send_stop() and
its generic logic, by removing the arm64 crash_smp_send_stop() definition
and providing the needed arch specific helpers.
Additionally, simplify the arch-specific stop and crash dump ISRs backends
(which are in charge of effectively receiving and interpreting the
stop/crash messages) and unify them as much as possible.
Using the SMP common code, it is no more needed to make use of an atomic_t
counter to make sure that each CPU had time to perform its crash dump
related shutdown-ops before the world ends: simply take care to synchronize
on cpu_online_mask, and add proper explicit memory barriers where needed.
Moreover, remove arm64 specific smp_crash_stop_failed() helper as a whole
and rely on the common code provided homonym function to lookup the state
of an ongoing crash_stop operation.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
v1 --> v2
- added attempt_num param to arch_smp_crash_call()
---
arch/arm64/include/asm/smp.h | 2 -
arch/arm64/kernel/smp.c | 100 +++++++++--------------------------
2 files changed, 26 insertions(+), 76 deletions(-)
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index a0c8a0b65259..d98c409f9225 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -150,8 +150,6 @@ static inline void cpu_panic_kernel(void)
*/
bool cpus_are_stuck_in_kernel(void);
-extern void crash_smp_send_stop(void);
-extern bool smp_crash_stop_failed(void);
#endif /* ifndef __ASSEMBLY__ */
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 3e87fdbb9f74..f0cc2bf84aaa 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -825,12 +825,30 @@ void arch_irq_work_raise(void)
}
#endif
-static void local_cpu_stop(void)
+static void local_cpu_crash_or_stop(struct pt_regs *crash_regs)
{
- set_cpu_online(smp_processor_id(), false);
+ unsigned int cpu = smp_processor_id();
- local_daif_mask();
+ if (IS_ENABLED(CONFIG_KEXEC_CORE) && crash_regs) {
+#ifdef CONFIG_KEXEC_CORE
+ /* crash stop requested: save regs before going offline */
+ crash_save_cpu(crash_regs, cpu);
+#endif
+ local_irq_disable();
+ } else {
+ local_daif_mask();
+ }
sdei_mask_local_cpu();
+ /* ensure dumped regs are visible once cpu is seen offline */
+ smp_wmb();
+ set_cpu_online(cpu, false);
+ /* ensure all writes are globally visible before cpu parks */
+ wmb();
+#if defined(CONFIG_KEXEC_CORE) && defined(CONFIG_HOTPLUG_CPU)
+ if (cpu_ops[cpu]->cpu_die)
+ cpu_ops[cpu]->cpu_die(cpu);
+#endif
+ /* just in case */
cpu_park_loop();
}
@@ -841,31 +859,7 @@ static void local_cpu_stop(void)
*/
void panic_smp_self_stop(void)
{
- local_cpu_stop();
-}
-
-#ifdef CONFIG_KEXEC_CORE
-static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0);
-#endif
-
-static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
-{
-#ifdef CONFIG_KEXEC_CORE
- crash_save_cpu(regs, cpu);
-
- atomic_dec(&waiting_for_crash_ipi);
-
- local_irq_disable();
- sdei_mask_local_cpu();
-
-#ifdef CONFIG_HOTPLUG_CPU
- if (cpu_ops[cpu]->cpu_die)
- cpu_ops[cpu]->cpu_die(cpu);
-#endif
-
- /* just in case */
- cpu_park_loop();
-#endif
+ local_cpu_crash_or_stop(NULL);
}
/*
@@ -894,14 +888,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
case IPI_CPU_STOP:
irq_enter();
- local_cpu_stop();
+ local_cpu_crash_or_stop(NULL);
irq_exit();
break;
case IPI_CPU_CRASH_STOP:
if (IS_ENABLED(CONFIG_KEXEC_CORE)) {
irq_enter();
- ipi_cpu_crash_stop(cpu, regs);
+ local_cpu_crash_or_stop(regs);
unreachable();
}
@@ -963,52 +957,10 @@ void arch_smp_stop_call(cpumask_t *cpus, unsigned int __unused)
smp_cross_call(cpus, IPI_CPU_STOP);
}
-#ifdef CONFIG_KEXEC_CORE
-void crash_smp_send_stop(void)
+void arch_smp_crash_call(cpumask_t *cpus, unsigned int __unused)
{
- static int cpus_stopped;
- cpumask_t mask;
- unsigned long timeout;
-
- /*
- * This function can be called twice in panic path, but obviously
- * we execute this only once.
- */
- if (cpus_stopped)
- return;
-
- cpus_stopped = 1;
-
- if (num_online_cpus() == 1) {
- sdei_mask_local_cpu();
- return;
- }
-
- cpumask_copy(&mask, cpu_online_mask);
- cpumask_clear_cpu(smp_processor_id(), &mask);
-
- atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
-
- pr_crit("SMP: stopping secondary CPUs\n");
- smp_cross_call(&mask, IPI_CPU_CRASH_STOP);
-
- /* Wait up to one second for other CPUs to stop */
- timeout = USEC_PER_SEC;
- while ((atomic_read(&waiting_for_crash_ipi) > 0) && timeout--)
- udelay(1);
-
- if (atomic_read(&waiting_for_crash_ipi) > 0)
- pr_warning("SMP: failed to stop secondary CPUs %*pbl\n",
- cpumask_pr_args(&mask));
-
- sdei_mask_local_cpu();
-}
-
-bool smp_crash_stop_failed(void)
-{
- return (atomic_read(&waiting_for_crash_ipi) > 0);
+ smp_cross_call(cpus, IPI_CPU_CRASH_STOP);
}
-#endif
/*
* not supported here
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 07/12] arm64: smp: add arch specific cpu parking helper
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Add an arm64 specific helper which parks the cpu in a more architecture
efficient way.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
arch/arm64/kernel/smp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index f0cc2bf84aaa..539e8db5c1ba 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -947,6 +947,12 @@ void tick_broadcast(const struct cpumask *mask)
}
#endif
+void arch_smp_cpu_park(void)
+{
+ while (1)
+ cpu_park_loop();
+}
+
void arch_smp_cpus_stop_complete(void)
{
sdei_mask_local_cpu();
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 08/12] x86: smp: use generic SMP stop common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Make x86 use the generic SMP-stop logic provided by common code unified
smp_send_stop() function.
Introduce needed arch_smp_stop_call()/arch_smp_cpus_stop_complete()
helpers that implement the backend architectures specific functionalities
previously provided by native_stop_other_cpus(): common logic is now
delegated to common SMP stop code.
Remove arch-specific smp_send_stop(), and redefine original function
native_stop_other_cpus() to rely instead on the unified common code
version of smp_send_stop(): native_stop_other_cpus() is anyway kept
since it is wired to smp_ops.stop_other_cpus() which get called at
reboot time with particular waiting settings.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
Note that in this patch we kept in use the original x86 local handling
of 'stopping_cpu' variable:
atomic_cmpxchg(&stopping_cpu, -1, safe_smp_processor_id());
Instead, common SMP stop code could have been easily extended to keep and
expose to architectures backends such value using some additional helper
like smp_stop_get_stopping_cpu_id().
This has not been addressed in this series.
---
arch/x86/Kconfig | 1 +
arch/x86/include/asm/smp.h | 5 --
arch/x86/kernel/smp.c | 95 ++++++++++++++++----------------------
3 files changed, 41 insertions(+), 60 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 222855cc0158..0fcee2f03a5b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -92,6 +92,7 @@ config X86
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
+ select ARCH_USE_COMMON_SMP_STOP
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
select ARCH_WANT_HUGE_PMD_SHARE
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index e1356a3b8223..5cf590259d68 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -67,11 +67,6 @@ extern void set_cpu_sibling_map(int cpu);
#ifdef CONFIG_SMP
extern struct smp_ops smp_ops;
-static inline void smp_send_stop(void)
-{
- smp_ops.stop_other_cpus(0);
-}
-
static inline void stop_other_cpus(void)
{
smp_ops.stop_other_cpus(1);
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 96421f97e75c..0942cae46fee 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -179,78 +179,63 @@ asmlinkage __visible void smp_reboot_interrupt(void)
irq_exit();
}
-static void native_stop_other_cpus(int wait)
+void arch_smp_stop_call(cpumask_t *cpus, unsigned int attempt_num)
{
- unsigned long flags;
- unsigned long timeout;
-
if (reboot_force)
return;
- /*
- * Use an own vector here because smp_call_function
- * does lots of things not suitable in a panic situation.
- */
-
- /*
- * We start by using the REBOOT_VECTOR irq.
- * The irq is treated as a sync point to allow critical
- * regions of code on other cpus to release their spin locks
- * and re-enable irqs. Jumping straight to an NMI might
- * accidentally cause deadlocks with further shutdown/panic
- * code. By syncing, we give the cpus up to one second to
- * finish their work before we force them off with the NMI.
- */
- if (num_online_cpus() > 1) {
- /* did someone beat us here? */
- if (atomic_cmpxchg(&stopping_cpu, -1, safe_smp_processor_id()) != -1)
- return;
-
- /* sync above data before sending IRQ */
- wmb();
-
- apic->send_IPI_allbutself(REBOOT_VECTOR);
-
+ if (attempt_num == 1) {
/*
- * Don't wait longer than a second if the caller
- * didn't ask us to wait.
+ * We start by using the REBOOT_VECTOR irq.
+ * The irq is treated as a sync point to allow critical
+ * regions of code on other cpus to release their spin locks
+ * and re-enable irqs. Jumping straight to an NMI might
+ * accidentally cause deadlocks with further shutdown/panic
+ * code. By syncing, we give the cpus up to one second to
+ * finish their work before we force them off with the NMI.
*/
- timeout = USEC_PER_SEC;
- while (num_online_cpus() > 1 && (wait || timeout--))
- udelay(1);
- }
-
- /* if the REBOOT_VECTOR didn't work, try with the NMI */
- if ((num_online_cpus() > 1) && (!smp_no_nmi_ipi)) {
- if (register_nmi_handler(NMI_LOCAL, smp_stop_nmi_callback,
- NMI_FLAG_FIRST, "smp_stop"))
- /* Note: we ignore failures here */
- /* Hope the REBOOT_IRQ is good enough */
- goto finish;
+
+ /* Used by NMI handler callback to skip the stopping_cpu. */
+ atomic_cmpxchg(&stopping_cpu, -1, safe_smp_processor_id());
/* sync above data before sending IRQ */
wmb();
-
- pr_emerg("Shutting down cpus with NMI\n");
-
- apic->send_IPI_allbutself(NMI_VECTOR);
-
- /*
- * Don't wait longer than a 10 ms if the caller
- * didn't ask us to wait.
- */
- timeout = USEC_PER_MSEC * 10;
- while (num_online_cpus() > 1 && (wait || timeout--))
- udelay(1);
+ apic->send_IPI_mask(cpus, REBOOT_VECTOR);
+ } else if (attempt_num > 1 && !smp_no_nmi_ipi) {
+ /* if the REBOOT_VECTOR didn't work, try with the NMI */
+
+ /* Don't wait longer than 10 ms when not asked to wait */
+ smp_stop_set_wait_timeout_us(USEC_PER_MSEC * 10);
+
+ /* Note: we ignore failures here */
+ /* Hope the REBOOT_IRQ was good enough */
+ if (!register_nmi_handler(NMI_LOCAL, smp_stop_nmi_callback,
+ NMI_FLAG_FIRST, "smp_stop")) {
+ /* sync above data before sending IRQ */
+ wmb();
+ pr_emerg("Shutting down cpus with NMI\n");
+ apic->send_IPI_mask(cpus, NMI_VECTOR);
+ }
}
+}
+
+void arch_smp_cpus_stop_complete(void)
+{
+ unsigned long flags;
-finish:
local_irq_save(flags);
disable_local_APIC();
mcheck_cpu_clear(this_cpu_ptr(&cpu_info));
local_irq_restore(flags);
}
+static void native_stop_other_cpus(int wait)
+{
+ smp_stop_set_wait_forever(wait);
+ /* use common SMP stop code */
+ smp_send_stop();
+}
+
/*
* Reschedule call back. KVM uses this interrupt to force a cpu out of
* guest mode
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 09/12] x86: smp: use SMP crash-stop common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Make x86 use the SMP common implementation of crash_smp_send_stop() and
its generic logic, by removing the x86 crash_smp_send_stop() definition
and providing the needed arch specific helpers.
Remove also redundant smp_ops.crash_stop_other_cpus(); add shared util
function common_nmi_shootdown_cpus(), which is a generalization of the
previous nmi_shootdown_cpus(), and it is used by architecture backend
helper arch_smp_crash_call().
Modify original crash_nmi_callback() to properly set cpu offline flag
and adding needed memory barriers.
Modify original nmi_shootdown_cpus() to rely on common code logic
provided by generic crash_smp_send_stop(): this was needed because the
original nmi_shootdown_cpus() was used also on the emergency reboot
path, employing a different callback. Reuse the same shootdown_callback
mechanism to properly handle both a crash and an emergency reboot through
the same common code crash path.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
Note that in this patch we kept in use the original x86 local handling
of 'crashing_cpu' variable:
crashing_cpu = safe_smp_processor_id();
Instead, common SMP stop code could have been easily extended to keep and
expose to architectures backends such value using some additional helper
like smp_stop_get_stopping_cpu_id().
This has not been addressed in this series.
---
arch/x86/include/asm/reboot.h | 2 ++
arch/x86/include/asm/smp.h | 1 -
arch/x86/kernel/crash.c | 27 ++++---------------
arch/x86/kernel/reboot.c | 50 ++++++++++++++++++++++-------------
arch/x86/kernel/smp.c | 3 ---
5 files changed, 38 insertions(+), 45 deletions(-)
diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h
index 04c17be9b5fd..a1a9cbed6df5 100644
--- a/arch/x86/include/asm/reboot.h
+++ b/arch/x86/include/asm/reboot.h
@@ -3,6 +3,7 @@
#define _ASM_X86_REBOOT_H
#include <linux/kdebug.h>
+#include <linux/cpumask.h>
struct pt_regs;
@@ -28,6 +29,7 @@ void __noreturn machine_real_restart(unsigned int type);
typedef void (*nmi_shootdown_cb)(int, struct pt_regs*);
void nmi_panic_self_stop(struct pt_regs *regs);
void nmi_shootdown_cpus(nmi_shootdown_cb callback);
+void common_nmi_shootdown_cpus(cpumask_t *cpus, nmi_shootdown_cb callback);
void run_crash_ipi_callback(struct pt_regs *regs);
#endif /* _ASM_X86_REBOOT_H */
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 5cf590259d68..684643ad71e4 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -49,7 +49,6 @@ struct smp_ops {
void (*smp_cpus_done)(unsigned max_cpus);
void (*stop_other_cpus)(int wait);
- void (*crash_stop_other_cpus)(void);
void (*smp_send_reschedule)(int cpu);
int (*cpu_up)(unsigned cpu, struct task_struct *tidle);
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 2bf70a2fed90..8fff06c7cd26 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -96,34 +96,16 @@ static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
disable_local_APIC();
}
-void kdump_nmi_shootdown_cpus(void)
+void arch_smp_crash_call(cpumask_t *cpus, unsigned int __unused)
{
- nmi_shootdown_cpus(kdump_nmi_callback);
-
- disable_local_APIC();
+ common_nmi_shootdown_cpus(cpus, kdump_nmi_callback);
}
-/* Override the weak function in kernel/panic.c */
-void crash_smp_send_stop(void)
+void arch_smp_cpus_crash_complete(void)
{
- static int cpus_stopped;
-
- if (cpus_stopped)
- return;
-
- if (smp_ops.crash_stop_other_cpus)
- smp_ops.crash_stop_other_cpus();
- else
- smp_send_stop();
-
- cpus_stopped = 1;
+ disable_local_APIC();
}
-#else
-void crash_smp_send_stop(void)
-{
- /* There are no cpus to shootdown */
-}
#endif
void native_machine_crash_shutdown(struct pt_regs *regs)
@@ -139,6 +121,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
/* The kernel is broken so disable interrupts */
local_irq_disable();
+ /* calling into SMP common stop code */
crash_smp_send_stop();
/*
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 09d6bded3c1e..69f894e28fec 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -799,7 +799,6 @@ int crashing_cpu = -1;
static nmi_shootdown_cb shootdown_callback;
-static atomic_t waiting_for_crash_ipi;
static int crash_ipi_issued;
static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
@@ -819,7 +818,12 @@ static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
shootdown_callback(cpu, regs);
- atomic_dec(&waiting_for_crash_ipi);
+ /* ensure all shootdown writes are visible once cpu is seen offline */
+ smp_wmb();
+ set_cpu_online(cpu, false);
+ /* ensure all writes are globally visible before cpu parks */
+ wmb();
+
/* Assume hlt works */
halt();
for (;;)
@@ -828,29 +832,44 @@ static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
return NMI_HANDLED;
}
-static void smp_send_nmi_allbutself(void)
-{
- apic->send_IPI_allbutself(NMI_VECTOR);
-}
-
/*
* Halt all other CPUs, calling the specified function on each of them
*
* This function can be used to halt all other CPUs on crash
* or emergency reboot time. The function passed as parameter
* will be called inside a NMI handler on all CPUs.
+ *
+ * It relies on crash_smp_send_stop() common code logic to shutdown CPUs.
*/
void nmi_shootdown_cpus(nmi_shootdown_cb callback)
{
- unsigned long msecs;
+ local_irq_disable();
+
+ shootdown_callback = callback;
+ /* ensure callback in place before calling into common crash code */
+ wmb();
+ /* call into common SMP Crash Stop to reuse the logic */
+ crash_smp_send_stop();
+}
+
+/*
+ * Halt the specified @cpus, calling the provided @callback on each of them
+ * unless a shootdown_callback was already installed previously: this way
+ * we can handle here also the emergency reboot requests issued via
+ * nmi_shootdown_cpus() and routed via usual common code crash_smp_send_stop()
+ *
+ * Called by arch_smp_crash_call() arch-helper.
+ */
+void common_nmi_shootdown_cpus(cpumask_t *cpus, nmi_shootdown_cb callback)
+{
local_irq_disable();
/* Make a note of crashing cpu. Will be used in NMI callback. */
crashing_cpu = safe_smp_processor_id();
- shootdown_callback = callback;
-
- atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+ /* skip when the callback has been already set by nmi_shootdown_cpus */
+ if (!shootdown_callback)
+ shootdown_callback = callback;
/* Would it be better to replace the trap vector here? */
if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback,
NMI_FLAG_FIRST, "crash"))
@@ -860,18 +879,11 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback)
* out the NMI
*/
wmb();
-
- smp_send_nmi_allbutself();
+ apic->send_IPI_mask(cpus, NMI_VECTOR);
/* Kick CPUs looping in NMI context. */
WRITE_ONCE(crash_ipi_issued, 1);
- msecs = 1000; /* Wait at most a second for the other cpus to stop */
- while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
- mdelay(1);
- msecs--;
- }
-
/* Leave the nmi callback set */
}
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 0942cae46fee..d718b185c6a9 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -295,9 +295,6 @@ struct smp_ops smp_ops = {
.smp_cpus_done = native_smp_cpus_done,
.stop_other_cpus = native_stop_other_cpus,
-#if defined(CONFIG_KEXEC_CORE)
- .crash_stop_other_cpus = kdump_nmi_shootdown_cpus,
-#endif
.smp_send_reschedule = native_smp_send_reschedule,
.cpu_up = native_cpu_up,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 10/12] arm: smp: use generic SMP stop common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Make arm use the generic SMP-stop logic provided by common code
unified smp_send_stop() function.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
arch/arm/Kconfig | 1 +
arch/arm/kernel/smp.c | 18 ++----------------
2 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 24360211534a..0a3a9c9a0b2e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -34,6 +34,7 @@ config ARM
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF
+ select ARCH_USE_COMMON_SMP_STOP
select ARCH_WANT_IPC_PARSE_VERSION
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
select BUILDTIME_EXTABLE_SORT if MMU
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index aab8ba40ce38..bf5c04691fab 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -703,23 +703,9 @@ void smp_send_reschedule(int cpu)
smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
}
-void smp_send_stop(void)
+void arch_smp_stop_call(cpumask_t *cpus, unsigned int __unused)
{
- unsigned long timeout;
- struct cpumask mask;
-
- cpumask_copy(&mask, cpu_online_mask);
- cpumask_clear_cpu(smp_processor_id(), &mask);
- if (!cpumask_empty(&mask))
- smp_cross_call(&mask, IPI_CPU_STOP);
-
- /* Wait up to one second for other CPUs to stop */
- timeout = USEC_PER_SEC;
- while (num_online_cpus() > 1 && timeout--)
- udelay(1);
-
- if (num_online_cpus() > 1)
- pr_warn("SMP: failed to stop secondary CPUs\n");
+ smp_cross_call(cpus, IPI_CPU_STOP);
}
/* In case panic() and panic() called at the same time on CPU1 and CPU2,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 11/12] arm: smp: use SMP crash-stop common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Make arm use the SMP common implementation of crash_smp_send_stop() and
its generic logic, by removing the arm crash_smp_send_stop() definition
and providing the needed arch specific helpers.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
arch/arm/kernel/machine_kexec.c | 27 ++++++---------------------
1 file changed, 6 insertions(+), 21 deletions(-)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 76300f3813e8..d53973cae362 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -29,8 +29,6 @@ extern unsigned long kexec_indirection_page;
extern unsigned long kexec_mach_type;
extern unsigned long kexec_boot_atags;
-static atomic_t waiting_for_crash_ipi;
-
/*
* Provide a dummy crash_notes definition while crash dump arrives to arm.
* This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -89,34 +87,21 @@ void machine_crash_nonpanic_core(void *unused)
crash_save_cpu(®s, smp_processor_id());
flush_cache_all();
+ /* ensure saved regs writes are visible before going offline */
+ smp_wmb();
set_cpu_online(smp_processor_id(), false);
- atomic_dec(&waiting_for_crash_ipi);
+ /* ensure all writes visible before parking */
+ wmb();
while (1) {
cpu_relax();
wfe();
}
}
-void crash_smp_send_stop(void)
+void arch_smp_crash_call(cpumask_t *cpus, unsigned int __unused)
{
- static int cpus_stopped;
- unsigned long msecs;
-
- if (cpus_stopped)
- return;
-
- atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
- smp_call_function(machine_crash_nonpanic_core, NULL, false);
- msecs = 1000; /* Wait at most a second for the other cpus to stop */
- while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
- mdelay(1);
- msecs--;
- }
- if (atomic_read(&waiting_for_crash_ipi) > 0)
- pr_warn("Non-crashing CPUs did not react to IPI\n");
-
- cpus_stopped = 1;
+ smp_call_function_many(cpus, machine_crash_nonpanic_core, NULL, false);
}
static void machine_kexec_mask_interrupts(void)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v2 12/12] sparc64: smp: use generic SMP stop common code
From: Cristian Marussi @ 2019-09-13 18:19 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux, davem, hch, takahiro.akashi, mingo,
james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
Make sparc64 use the generic SMP-stop logic provided by common code
unified smp_send_stop() function.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
arch/sparc/Kconfig | 1 +
arch/sparc/kernel/smp_64.c | 15 ++++++++-------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 7926a2e11bdc..67d8bb741378 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -95,6 +95,7 @@ config SPARC64
select ARCH_HAS_PTE_SPECIAL
select PCI_DOMAINS if PCI
select ARCH_HAS_GIGANTIC_PAGE
+ select ARCH_USE_COMMON_SMP_STOP
config ARCH_DEFCONFIG
string
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index a8275fea4b70..759e5fd867c5 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1537,7 +1537,12 @@ static void stop_this_cpu(void *dummy)
prom_stopself();
}
-void smp_send_stop(void)
+void arch_smp_cpus_stop_complete(void)
+{
+ smp_call_function(stop_this_cpu, NULL, 0);
+}
+
+void arch_smp_stop_call(cpumask_t *cpus, unsigned int __unused)
{
int cpu;
@@ -1546,10 +1551,7 @@ void smp_send_stop(void)
#ifdef CONFIG_SERIAL_SUNHV
sunhv_migrate_hvcons_irq(this_cpu);
#endif
- for_each_online_cpu(cpu) {
- if (cpu == this_cpu)
- continue;
-
+ for_each_cpu(cpu, cpus) {
set_cpu_online(cpu, false);
#ifdef CONFIG_SUN_LDOMS
if (ldom_domaining_enabled) {
@@ -1562,8 +1564,7 @@ void smp_send_stop(void)
#endif
prom_stopcpu_cpuid(cpu);
}
- } else
- smp_call_function(stop_this_cpu, NULL, 0);
+ }
}
/**
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [RFC PATCH v2 00/12] Unify SMP stop generic logic to common code
From: Russell King - ARM Linux admin @ 2019-09-13 18:27 UTC (permalink / raw)
To: Cristian Marussi
Cc: linux-arch, mark.rutland, sparclinux, dzickus, ehabkost, peterz,
catalin.marinas, x86, linux-kernel, davem, hch, takahiro.akashi,
mingo, james.morse, hidehiro.kawai.ez, tglx, will, dave.martin,
linux-arm-kernel
In-Reply-To: <20190913181953.45748-1-cristian.marussi@arm.com>
On Fri, Sep 13, 2019 at 07:19:41PM +0100, Cristian Marussi wrote:
> Tested as follows:
>
> - arm:
> 1. boot
So this basically means the code paths you're touching are untested on
ARM... given that, and the variety of systems we have out there, why
should the patches touching ARM be taken?
Given that you're an ARM Ltd employee, I'm sure you can find 32-bit
systems to test - or have ARM Ltd got rid of everything that isn't
64-bit? ;)
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 5/6] media: sun4i: Add H3 deinterlace driver
From: Jernej Škrabec @ 2019-09-13 20:06 UTC (permalink / raw)
To: Maxime Ripard
Cc: mark.rutland, devicetree, linux-sunxi, linux-kernel, hverkuil,
wens, robh+dt, mchehab, linux-arm-kernel, linux-media
In-Reply-To: <20190913091147.42nsldzxwzfjoiak@localhost.localdomain>
Hi!
Dne petek, 13. september 2019 ob 11:11:47 CEST je Maxime Ripard napisal(a):
> Hi,
>
> On Thu, Sep 12, 2019 at 10:43:28PM +0200, Jernej Škrabec wrote:
> > Dne četrtek, 12. september 2019 ob 22:26:47 CEST je Maxime Ripard
napisal(a):
> > > > + clk_set_rate(dev->mod_clk, 300000000);
>
> I just realized I missed this too. If you really need the rate to be
> fixed, and if the controller cannot operate properly at any other
> frequency, you probably want to use clk_set_rate_exclusive there.
I don't think that's needed. Parents of deinterlace clock are pll-periph0 and
pll-periph1 which both have fixed clock and thus deinterlace clock will never
be changed. I just set it to same frequency as it is set in BSP driver. I
think it works with 600 MHz too, but that's overkill.
Best regards,
Jernej
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 6/8] ARM: dts: omap36xx: using OPP1G needs to control the abb_ldo
From: Adam Ford @ 2019-09-13 21:13 UTC (permalink / raw)
To: H. Nikolaus Schaller
Cc: Mark Rutland, devicetree, Discussions about the Letux Kernel,
linux-pm, Tony Lindgren, Viresh Kumar, Rafael J. Wysocki,
Linux Kernel Mailing List, Enric Balletbo i Serra, Rob Herring,
André Roth, Benoît Cousson, kernel, Teresa Remmet,
Javier Martinez Canillas, Linux-OMAP, arm-soc, Roger Quadros
In-Reply-To: <59a0f6267c75859c25665548db2e8a9c4229d3b4.1568224033.git.hns@goldelico.com>
On Wed, Sep 11, 2019 at 12:47 PM H. Nikolaus Schaller <hns@goldelico.com> wrote:
>
> See DM3730,DM275 data sheet (SPRS685B) footnote (6) in Table 4-19
> which says that ABB must be switched to FBB mode when using the
> OPP1G.
>
> The LOD definition abb_mpu_iva already exists so that we need
> to add plumbing for vbb-supply = <&abb_mpu_iva>
> and define two voltage vectors for each OPP so that the abb LDO
> is also updated by the ti-cpufreq driver.
>
> We also must switch the ti_cpufreq_soc_data to multi_regulator.
>
> Note: reading out the abb reglator voltage to verify that
> it does do transitions can be done by
>
> cat /sys/devices/platform/68000000.ocp/483072f0.regulator-abb-mpu/regulator/regulator.*/microvolts
>
> Likewise, read the twl4030 provided VDD voltage by
>
> cat /sys/devices/platform/68000000.ocp/48070000.i2c/i2c-0/0-0048/48070000.i2c:twl@48:regulator-vdd1/regulator/regulator.*/microvolts
>
> Note: to check if the ABB FBB is enabled/disabled, check
> registers
>
> PRM_LDO_ABB_CTRL 0x483072F4 bit 3:0 1=bypass 5=FBB
> PRM_LDO_ABB_SETUP 0x483072F0 0x00=bypass 0x11=FBB
>
> e.g.
>
> /dev/mem opened.
> Memory mapped at address 0xb6fe4000.
> Value at address 0x483072F4 (0xb6fe42f4): 0x3205
> /dev/mem opened.
> Memory mapped at address 0xb6f89000.
> Value at address 0x483072F4 (0xb6f892f4): 0x3201
>
> Note: omap34xx and am3517 have/need no comparable LDO
> or mechanism.
>
> Suggested-by: Adam Ford <aford173@gmail.com>
> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
> ---
> arch/arm/boot/dts/omap36xx.dtsi | 21 ++++++++++++++++-----
> drivers/cpufreq/ti-cpufreq.c | 2 +-
> 2 files changed, 17 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi
> index cb5bd0969124..4bb4f534afe2 100644
> --- a/arch/arm/boot/dts/omap36xx.dtsi
> +++ b/arch/arm/boot/dts/omap36xx.dtsi
> @@ -23,6 +23,7 @@
> cpu: cpu@0 {
> operating-points-v2 = <&cpu0_opp_table>;
>
> + vbb-supply = <&abb_mpu_iva>;
> clock-latency = <300000>; /* From omap-cpufreq driver */
> };
> };
> @@ -37,9 +38,11 @@
> /*
> * we currently only select the max voltage from table
> * Table 4-19 of the DM3730 Data sheet (SPRS685B)
> - * Format is: <target min max>
> + * Format is: cpu0-supply: <target min max>
> + * vbb-supply: <target min max>
> */
> - opp-microvolt = <1012500 1012500 1012500>;
> + opp-microvolt = <1012500 1012500 1012500>,
> + <1012500 1012500 1012500>;
> /*
> * first value is silicon revision bit mask
> * second one is "speed binned" bit mask
> @@ -50,25 +53,33 @@
>
> opp100-600000000 {
> opp-hz = /bits/ 64 <600000000>;
> - opp-microvolt = <1200000 1200000 1200000>;
> + opp-microvolt = <1200000 1200000 1200000>,
> + <1200000 1200000 1200000>;
> opp-supported-hw = <0xffffffff 3>;
> };
>
> opp130-800000000 {
> opp-hz = /bits/ 64 <800000000>;
> - opp-microvolt = <1325000 1325000 1325000>;
> + opp-microvolt = <1325000 1325000 1325000>,
> + <1325000 1325000 1325000>;
> opp-supported-hw = <0xffffffff 3>;
> };
>
> opp1g-1000000000 {
> opp-hz = /bits/ 64 <1000000000>;
> - opp-microvolt = <1375000 1375000 1375000>;
> + opp-microvolt = <1375000 1375000 1375000>,
> + <1375000 1375000 1375000>;
> /* only on am/dm37x with speed-binned bit set */
> opp-supported-hw = <0xffffffff 2>;
> turbo-mode;
If / when the thermal changes I submitted get approved, would you
entertain dropping this turbo-mode flag so it's enabled by default?
adam
> };
> };
>
> + opp_supply_mpu_iva: opp_supply {
> + compatible = "ti,omap-opp-supply";
> + ti,absolute-max-voltage-uv = <1375000>;
> + };
> +
> ocp@68000000 {
> uart4: serial@49042000 {
> compatible = "ti,omap3-uart";
> diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
> index 1a3073a3093e..f4704f9033e0 100644
> --- a/drivers/cpufreq/ti-cpufreq.c
> +++ b/drivers/cpufreq/ti-cpufreq.c
> @@ -174,7 +174,7 @@ static struct ti_cpufreq_soc_data omap36xx_soc_data = {
> .efuse_shift = 9,
> .efuse_mask = BIT(9),
> .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
> - .multi_regulator = false,
> + .multi_regulator = true,
> };
>
> /**
> --
> 2.19.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: KASAN: slab-out-of-bounds Read in handle_vmptrld
From: Paolo Bonzini @ 2019-09-13 21:39 UTC (permalink / raw)
To: Robin Murphy, Greg Kroah-Hartman
Cc: mark.rutland, wanpengli, kvm, narmstrong, catalin.marinas,
will.deacon, rkrcmar, hpa, khilman, joro, x86, mingo,
linux-arm-kernel, syzbot, devicetree, syzkaller-bugs, robh+dt, bp,
linux-amlogic, tglx, Dmitry Vyukov, jmattson, USB list,
linux-kernel, sean.j.christopherson, carlo, Vitaly Kuznetsov
In-Reply-To: <462660f4-1537-cece-b55f-0ceba0269eb8@arm.com>
On 13/09/19 17:32, Robin Murphy wrote:
> Oh, that bit of usbdev_mmap() is already known to be pretty much totally
> bogus for various reasons - there have been a few threads about it, of
> which I think [1] is both the most recent and the most informative.
> There was another patch[2], but that might have stalled (and might need
> reworking with additional hcd_uses_dma() checks anyway).
Neither is enough, see my reply to Alan. Memory from kmalloc just
*cannot* be passed down to remap_pfn_range, dma_mmap_coherent or
anything like that. It's a simple alignment issue.
Paolo
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH V3 1/5] dt-bindings: mt8183: Added DIP dt-bindings
From: Rob Herring @ 2019-09-13 21:48 UTC (permalink / raw)
To: frederic.chen
Cc: laurent.pinchart+renesas, Rynn.Wu, Allan.Yang, suleiman,
Jerry-ch.Chen, jungo.lin, hans.verkuil, frederic.chen,
linux-media, devicetree, holmes.chiou, shik, yuzhao,
linux-mediatek, matthias.bgg, mchehab, linux-arm-kernel,
Sean.Cheng, srv_heupstream, sj.huang, tfiga, christie.yu, zwisler
In-Reply-To: <20190909192244.9367-2-frederic.chen@mediatek.com>
On Tue, 10 Sep 2019 03:22:40 +0800, <frederic.chen@mediatek.com> wrote:
> From: Frederic Chen <frederic.chen@mediatek.com>
>
> This patch adds DT binding documentation for the Digital Image
> Processing (DIP) unit of camera ISP system on Mediatek's SoCs.
>
> It depends on the SCP and MDP 3 patch as following:
>
> 1. dt-bindings: Add a binding for Mediatek SCP
> https://patchwork.kernel.org/patch/11027247/
> 2. dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
> https://patchwork.kernel.org/patch/10945603/
>
> Signed-off-by: Frederic Chen <frederic.chen@mediatek.com>
> ---
> .../bindings/media/mediatek,mt8183-dip.txt | 40 +++++++++++++++++++
> 1 file changed, 40 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/mediatek,mt8183-dip.txt
>
Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.
If a tag was not added on purpose, please state why and what changed.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v1 2/2] of: Let of_for_each_phandle fallback to non-negative cell_count
From: Rob Herring @ 2019-09-13 21:58 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: devicetree, Will Deacon, Joerg Roedel, linux-kernel, iommu,
linux-mediatek, kernel, Matthias Brugger, Frank Rowand,
linux-arm-kernel, Robin Murphy
In-Reply-To: <20190824132846.8589-2-u.kleine-koenig@pengutronix.de>
On Sat, 24 Aug 2019 15:28:46 +0200, =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= wrote:
> Referencing device tree nodes from a property allows to pass arguments.
> This is for example used for referencing gpios. This looks as follows:
>
> gpio_ctrl: gpio-controller {
> #gpio-cells = <2>
> ...
> }
>
> someothernode {
> gpios = <&gpio_ctrl 5 0 &gpio_ctrl 3 0>;
> ...
> }
>
> To know the number of arguments this must be either fixed, or the
> referenced node is checked for a $cells_name (here: "#gpio-cells")
> property and with this information the start of the second reference can
> be determined.
>
> Currently regulators are referenced with no additional arguments. To
> allow some optional arguments without having to change all referenced
> nodes this change introduces a way to specify a default cell_count. So
> when a phandle is parsed we check for the $cells_name property and use
> it as before if present. If it is not present we fall back to
> cells_count if non-negative and only fail if cells_count is smaller than
> zero.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> ---
> drivers/of/base.c | 25 +++++++++++++++++--------
> 1 file changed, 17 insertions(+), 8 deletions(-)
>
Applied both patches, thanks.
Rob
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] iommu/arm-smmu: Report USF more clearly
From: Doug Anderson @ 2019-09-13 22:44 UTC (permalink / raw)
To: Robin Murphy
Cc: list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>, ,
Will Deacon,
list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>, ,
Linux ARM
In-Reply-To: <2762ffd4c196dc91d62e10eb8b753f256ea9b629.1568375317.git.robin.murphy@arm.com>
Hi,
On Fri, Sep 13, 2019 at 4:48 AM Robin Murphy <robin.murphy@arm.com> wrote:
>
> Although CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT is a welcome tool
> for smoking out inadequate firmware, the failure mode is non-obvious
> and can be confusing for end users. Add some special-case reporting of
> Unidentified Stream Faults to help clarify this particular symptom.
>
> CC: Douglas Anderson <dianders@chromium.org>
nit that I believe that "Cc" (lowercase 2nd c) is correct.
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
> drivers/iommu/arm-smmu.c | 5 +++++
> drivers/iommu/arm-smmu.h | 2 ++
> 2 files changed, 7 insertions(+)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index b7cf24402a94..76ac8c180695 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -499,6 +499,11 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
> dev_err_ratelimited(smmu->dev,
> "\tGFSR 0x%08x, GFSYNR0 0x%08x, GFSYNR1 0x%08x, GFSYNR2 0x%08x\n",
> gfsr, gfsynr0, gfsynr1, gfsynr2);
> + if (IS_ENABLED(CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT) &&
> + (gfsr & sGFSR_USF))
> + dev_err_ratelimited(smmu->dev,
> + "Stream ID %hu may not be described by firmware, try booting with \"arm-smmu.disable_bypass=0\"\n",
> + (u16)gfsynr1);
In general it seems like a sane idea to surface an error like this. I
guess a few nits:
1. "By firmware" might be a bit misleading. In most cases I'm aware
of the problem is in the device tree that was bundled together with
the kernel. If there are actually cases where firmware has baked in a
device tree and it got this wrong then we might want to spend time
figuring out what to do about it.
2. Presumably booting with "arm-smmu.disable_bypass=0" is in most
cases the least desirable option available. I always consider kernel
command line parameters as something of a last resort for
configuration and would only be something that and end user might do
if they were given a kernel compiled by someone else (like if someone
where taking a prebuilt Linux distro and trying to install it onto a
generic PC). Are you seeing cases where this is happening? If people
are compiling their own kernel I'd argue that telling them to set
"CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT" to "no" is much better
than trying to jam a command line option on. Command line options
don't scale well.
3. Any chance you could make it more obvious that this change is
undesirable and a last resort? AKA:
"Stream ID x blocked for security reasons; allow anyway by booting
with arm-smmu.disable_bypass=0"
-Doug
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RFC PATCH v1 0/1] Add support for arm64 to carry ima measurement log in kexec_file_load
From: Prakhar Srivastava @ 2019-09-13 22:50 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, linux-integrity, kexec
Cc: mark.rutland, jean-philippe, arnd, takahiro.akashi, sboyd,
catalin.marinas, zohar, yamada.masahiro, kristina.martsenko, duwe,
bauerman, james.morse, tglx, allison
Add support for arm64 to carry ima measurement log
to the next kexec'ed session triggered via kexec_file_load.
- Top of Linux 5.3-rc6
Currently during kexec the kernel file signatures are/can be validated
prior to actual load, the information(PE/ima signature) is not carried
to the next session. This lead to loss of information.
Carrying forward the ima measurement log to the next kexec'ed session
allows a verifying party to get the entire runtime event log since the
last full reboot, since that is when PCRs were last reset.
Changelog:
v1:
- add new fdt porperties to mark start and end for ima measurement
log.
- use fdt_* functions to add/remove fdt properties and memory
allocations.
- remove additional check for endian-ness as they are checked
in fdt_* functions.
v0:
- Add support to carry ima measurement log in arm64,
uses same code as powerpc.
Prakhar Srivastava (1):
Add support for arm64 to carry ima measurement log in kexec_file_load
arch/arm64/Kconfig | 7 +
arch/arm64/include/asm/ima.h | 29 ++++
arch/arm64/include/asm/kexec.h | 5 +
arch/arm64/kernel/Makefile | 3 +-
arch/arm64/kernel/ima_kexec.c | 213 +++++++++++++++++++++++++
arch/arm64/kernel/machine_kexec_file.c | 6 +
6 files changed, 262 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/include/asm/ima.h
create mode 100644 arch/arm64/kernel/ima_kexec.c
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RFC PATCH v1 1/1] Add support for arm64 to carry ima measurement log in kexec_file_load
From: Prakhar Srivastava @ 2019-09-13 22:50 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, linux-integrity, kexec
Cc: mark.rutland, jean-philippe, arnd, takahiro.akashi, sboyd,
catalin.marinas, zohar, yamada.masahiro, kristina.martsenko, duwe,
bauerman, james.morse, tglx, allison
In-Reply-To: <20190913225009.3406-1-prsriva@linux.microsoft.com>
During kexec_file_load, carrying forward the ima measurement log allows
a verifying party to get the entire runtime event log since the last
full reboot since that is when PCRs were last reset.
Signed-off-by: Prakhar Srivastava <prsriva@linux.microsoft.com>
---
arch/arm64/Kconfig | 7 +
arch/arm64/include/asm/ima.h | 29 ++++
arch/arm64/include/asm/kexec.h | 5 +
arch/arm64/kernel/Makefile | 3 +-
arch/arm64/kernel/ima_kexec.c | 213 +++++++++++++++++++++++++
arch/arm64/kernel/machine_kexec_file.c | 6 +
6 files changed, 262 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/include/asm/ima.h
create mode 100644 arch/arm64/kernel/ima_kexec.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3adcec05b1f6..f39b12dbf9e8 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -976,6 +976,13 @@ config KEXEC_VERIFY_SIG
verification for the corresponding kernel image type being
loaded in order for this to work.
+config HAVE_IMA_KEXEC
+ bool "Carry over IMA measurement log during kexec_file_load() syscall"
+ depends on KEXEC_FILE
+ help
+ Select this option to carry over IMA measurement log during
+ kexec_file_load.
+
config KEXEC_IMAGE_VERIFY_SIG
bool "Enable Image signature verification support"
default y
diff --git a/arch/arm64/include/asm/ima.h b/arch/arm64/include/asm/ima.h
new file mode 100644
index 000000000000..e23cee84729f
--- /dev/null
+++ b/arch/arm64/include/asm/ima.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARM64_IMA_H
+#define _ASM_ARM64_IMA_H
+
+struct kimage;
+
+int ima_get_kexec_buffer(void **addr, size_t *size);
+int ima_free_kexec_buffer(void);
+
+#ifdef CONFIG_IMA
+void remove_ima_buffer(void *fdt, int chosen_node);
+#else
+static inline void remove_ima_buffer(void *fdt, int chosen_node) {}
+#endif
+
+#ifdef CONFIG_IMA_KEXEC
+int arch_ima_add_kexec_buffer(struct kimage *image, unsigned long load_addr,
+ size_t size);
+
+int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node);
+#else
+static inline int setup_ima_buffer(const struct kimage *image, void *fdt,
+ int chosen_node)
+{
+ remove_ima_buffer(fdt, chosen_node);
+ return 0;
+}
+#endif /* CONFIG_IMA_KEXEC */
+#endif /* _ASM_ARM64_IMA_H */
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 12a561a54128..e8d2412066e7 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -96,6 +96,11 @@ static inline void crash_post_resume(void) {}
struct kimage_arch {
void *dtb;
unsigned long dtb_mem;
+
+#ifdef CONFIG_IMA_KEXEC
+ phys_addr_t ima_buffer_addr;
+ size_t ima_buffer_size;
+#endif
};
extern const struct kexec_file_ops kexec_image_ops;
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 478491f07b4f..580238f2e9a7 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -55,7 +55,8 @@ obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o \
cpu-reset.o
-obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
+obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o \
+ ima_kexec.o
obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
diff --git a/arch/arm64/kernel/ima_kexec.c b/arch/arm64/kernel/ima_kexec.c
new file mode 100644
index 000000000000..b14326d541f3
--- /dev/null
+++ b/arch/arm64/kernel/ima_kexec.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Microsoft Corporation.
+ *
+ * Authors:
+ * Prakhar Srivastava <prsriva@linux.microsoft.com>
+ */
+
+#include <linux/slab.h>
+#include <linux/kexec.h>
+#include <linux/of.h>
+#include <linux/memblock.h>
+#include <linux/libfdt.h>
+
+
+/**
+ * delete_fdt_mem_rsv - delete memory reservation with given address and size
+ * @fdt - pointer to the fdt.
+ * @start - start address of the memory.
+ * @size - number of cells to be deletd.
+ *
+ * Return: 0 on success, or negative errno on error.
+ */
+int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size)
+{
+ int i, ret, num_rsvs = fdt_num_mem_rsv(fdt);
+
+ for (i = 0; i < num_rsvs; i++) {
+ uint64_t rsv_start, rsv_size;
+
+ ret = fdt_get_mem_rsv(fdt, i, &rsv_start, &rsv_size);
+ if (ret) {
+ pr_err("Malformed device tree\n");
+ return -EINVAL;
+ }
+
+ if (rsv_start == start && rsv_size == size) {
+ ret = fdt_del_mem_rsv(fdt, i);
+ if (ret) {
+ pr_err("Error deleting device tree reservation\n");
+ return -EINVAL;
+ }
+
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+/**
+ * remove_ima_buffer - remove the IMA buffer property and reservation
+ * @fdt - pointer the fdt.
+ * @chosen_node - node under which property can be found.
+ *
+ * The IMA measurement buffer is either read by now and freeed or a kexec call
+ * needs to replace the ima measurement buffer, clear the property and memory
+ * reservation.
+ */
+void remove_ima_buffer(void *fdt, int chosen_node)
+{
+ int ret, len;
+ const void *prop;
+ uint64_t tmp_start, tmp_end;
+
+ prop = fdt_getprop(fdt, chosen_node, "linux,ima-kexec-buffer", &len);
+ if (prop) {
+ tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
+
+ prop = fdt_getprop(fdt, chosen_node,
+ "linux,ima-kexec-buffer-end", &len);
+ if (!prop)
+ return;
+
+ tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
+
+ ret = delete_fdt_mem_rsv(fdt, tmp_start, tmp_end - tmp_start);
+
+ if (ret == 0)
+ pr_debug("Removed old IMA buffer reservation.\n");
+ else if (ret != -ENOENT)
+ return;
+
+ fdt_delprop(fdt, chosen_node, "linux,ima-kexec-buffer");
+ fdt_delprop(fdt, chosen_node, "linux,ima-kexec-buffer-end");
+ }
+}
+
+/**
+ * ima_get_kexec_buffer - get IMA buffer from the previous kernel
+ * @addr: On successful return, set to point to the buffer contents.
+ * @size: On successful return, set to the buffer size.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int ima_get_kexec_buffer(void **addr, size_t *size)
+{
+ int len;
+ const void *prop;
+ uint64_t tmp_start, tmp_end;
+
+ prop = of_get_property(of_chosen, "linux,ima-kexec-buffer", &len);
+ if (!prop)
+ return -ENOENT;
+
+ tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
+
+ prop = of_get_property(of_chosen, "linux,ima-kexec-buffer-end", &len);
+ if (!prop)
+ return -ENOENT;
+
+ tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
+
+ *addr = __va(tmp_start);
+ *size = tmp_end - tmp_start;
+
+ return 0;
+}
+
+/**
+ * ima_free_kexec_buffer - free memory used by the IMA buffer
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int ima_free_kexec_buffer(void)
+{
+ int ret;
+ void *propStart, *propEnd;
+ uint64_t tmp_start, tmp_end;
+
+ propStart = of_find_property(of_chosen, "linux,ima-kexec-buffer",
+ NULL);
+ if (propStart) {
+ tmp_start = fdt64_to_cpu(*((const fdt64_t *) propStart));
+ ret = of_remove_property(of_chosen, propStart);
+ if (!ret) {
+ return ret;
+ }
+
+ propEnd = of_find_property(of_chosen,
+ "linux,ima-kexec-buffer-end", NULL);
+ if (!propEnd) {
+ return -EINVAL;
+ }
+
+ tmp_end = fdt64_to_cpu(*((const fdt64_t *) propEnd));
+
+ ret = of_remove_property(of_chosen, propEnd);
+ if (!ret) {
+ return ret;
+ }
+
+ return memblock_free(tmp_start, tmp_end - tmp_start);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_IMA_KEXEC
+/**
+ * arch_ima_add_kexec_buffer - do arch-specific steps to add the IMA
+ * measurement log.
+ * @image: - pointer to the kimage, to store the address and size of the
+ * IMA measurement log.
+ * @load_addr: - the address where the IMA measurement log is stored.
+ * @size - size of the IMA measurement log.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int arch_ima_add_kexec_buffer(struct kimage *image, unsigned long load_addr,
+ size_t size)
+{
+ image->arch.ima_buffer_addr = load_addr;
+ image->arch.ima_buffer_size = size;
+ return 0;
+}
+
+/**
+ * setup_ima_buffer - update the fdt to contain the ima mesasurement log
+ * @image: - pointer to the kimage, containing the address and size of
+ * the IMA measurement log.
+ * @fdt: - pointer to the fdt.
+ * @chosen_node: - node under which property is to be defined.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node)
+{
+ int ret;
+
+ remove_ima_buffer(fdt, chosen_node);
+
+ if (!image->arch.ima_buffer_size)
+ return 0;
+
+ ret = fdt_setprop_u64(fdt, chosen_node, "linux,ima-kexec-buffer",
+ image->arch.ima_buffer_addr);
+ if (ret < 0)
+ return ret;
+
+ ret = fdt_setprop_u64(fdt, chosen_node, "linux,ima-kexec-buffer-end",
+ image->arch.ima_buffer_addr +
+ image->arch.ima_buffer_size);
+ if (ret < 0)
+ return ret;
+
+ ret = fdt_add_mem_rsv(fdt, image->arch.ima_buffer_addr,
+ image->arch.ima_buffer_size);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+#endif /* CONFIG_IMA_KEXEC */
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 58871333737a..de5452539c67 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -21,6 +21,7 @@
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <asm/byteorder.h>
+#include <asm/ima.h>
/* relevant device tree properties */
#define FDT_PROP_INITRD_START "linux,initrd-start"
@@ -85,6 +86,11 @@ static int setup_dtb(struct kimage *image,
goto out;
}
+ /* add ima measuremnet log buffer */
+ ret = setup_ima_buffer(image, dtb, off);
+ if (ret)
+ goto out;
+
/* add kaslr-seed */
ret = fdt_delprop(dtb, off, FDT_PROP_KASLR_SEED);
if (ret == -FDT_ERR_NOTFOUND)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] iommu/arm-smmu: Report USF more clearly
From: Russell King - ARM Linux admin @ 2019-09-13 22:59 UTC (permalink / raw)
To: Robin Murphy; +Cc: joro, will, iommu, linux-arm-kernel, Douglas Anderson
In-Reply-To: <2762ffd4c196dc91d62e10eb8b753f256ea9b629.1568375317.git.robin.murphy@arm.com>
On Fri, Sep 13, 2019 at 12:48:37PM +0100, Robin Murphy wrote:
> Although CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT is a welcome tool
> for smoking out inadequate firmware, the failure mode is non-obvious
> and can be confusing for end users. Add some special-case reporting of
> Unidentified Stream Faults to help clarify this particular symptom.
Having encountered this on a board that turned up this week, it may
be better to use the hex representation of the stream ID, especially
as it seems normal for the stream ID to be made up of implementation
defined bitfields.
If we want to stick with decimal, maybe masking the stream ID with
the number of allowable bits would be a good idea, so that the
decimal value remains meaningful should other bits be non-zero?
> CC: Douglas Anderson <dianders@chromium.org>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
> drivers/iommu/arm-smmu.c | 5 +++++
> drivers/iommu/arm-smmu.h | 2 ++
> 2 files changed, 7 insertions(+)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index b7cf24402a94..76ac8c180695 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -499,6 +499,11 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
> dev_err_ratelimited(smmu->dev,
> "\tGFSR 0x%08x, GFSYNR0 0x%08x, GFSYNR1 0x%08x, GFSYNR2 0x%08x\n",
> gfsr, gfsynr0, gfsynr1, gfsynr2);
> + if (IS_ENABLED(CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT) &&
> + (gfsr & sGFSR_USF))
> + dev_err_ratelimited(smmu->dev,
> + "Stream ID %hu may not be described by firmware, try booting with \"arm-smmu.disable_bypass=0\"\n",
> + (u16)gfsynr1);
>
> arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sGFSR, gfsr);
> return IRQ_HANDLED;
> diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
> index c9c13b5785f2..46f7e161e83e 100644
> --- a/drivers/iommu/arm-smmu.h
> +++ b/drivers/iommu/arm-smmu.h
> @@ -79,6 +79,8 @@
> #define ID7_MINOR GENMASK(3, 0)
>
> #define ARM_SMMU_GR0_sGFSR 0x48
> +#define sGFSR_USF BIT(2)
I do wonder if this is another instance where writing "(1 << 1)"
would have resulted in less chance of a mistake being made...
wrapping stuff up into macros is not always better!
9.6.15 SMMU_sGFSR, Global Fault Status Register
The SMMU_sGFSR bit assignments are:
USF, bit[1] Unidentified stream fault. The possible values of this
bit are:
0 No Unidentified stream fault.
1 Unidentified stream fault.
So this wants to be:
#define sGFSR_USF BIT(1)
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox