Re: [RFC PATCH 2/7] arm64: kernel: Add a WFI hook.

From: Arnd Bergmann
Date: Thu Jan 21 2021 - 06:39:36 EST


On Thu, Jan 21, 2021 at 12:01 PM Mohamed Mediouni
<mohamed.mediouni@xxxxxxxxxxxx> wrote:
> > On 21 Jan 2021, at 11:52, Arnd Bergmann <arnd@xxxxxxxxxx> wrote:
> >
> > On Wed, Jan 20, 2021 at 2:27 PM Mohamed Mediouni
> > <mohamed.mediouni@xxxxxxxxxxxx> wrote:
> >> --- a/arch/arm64/kernel/cpu_ops.c
> >> +++ b/arch/arm64/kernel/cpu_ops.c
> >
> >> #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
> >> #include <linux/stackprotector.h>
> >> @@ -74,8 +75,14 @@ void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
> >>
> >> static void noinstr __cpu_do_idle(void)
> >> {
> >> - dsb(sy);
> >> - wfi();
> >> + const struct cpu_operations *ops = get_cpu_ops(task_cpu(current));
> >> +
> >> + if (ops->cpu_wfi) {
> >> + ops->cpu_wfi();
> >> + } else {
> >> + dsb(sy);
> >> + wfi();
> >> + }
> >> }
> >
> > I think the correct place to put this would be a platform specific driver
> > in drivers/cpuidle/ instead of an added low-level callback in the
> > default idle function and a custom cpu_operations structure.
>
> Can we make sure that wfi never gets called even on early
> boot when using a cpuidle driver?

Good question, I don't know what all the possible call sites are
for this, but if there is nothing else works (such as what Alex suggested),
it may be possible to just patch out the wfi instruction here and
do a busy loop until the cpuidle driver has come up.

The main issue here is the existence of the custom cpu_operations
in the first place: I don't think we want or need the custom start_secondary
at the moment (as commented in the other patch), but then there is
no obvious place to put the custom wfi.

Note that there are a few other uses of the wfi instruction besides the
one in __cpu_do_idle(), so whatever you do here may also apply to the
others.

arch/arm64/include/asm/smp.h: wfi();
arch/arm64/kernel/head.S: wfi
arch/arm64/kernel/head.S: wfi
arch/arm64/kernel/head.S: wfi
arch/arm64/kernel/process.c: wfi();
arch/arm64/kvm/hyp/nvhe/hyp-init.S: wfi

Arnd