Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2817395imu; Thu, 29 Nov 2018 10:41:43 -0800 (PST) X-Google-Smtp-Source: AFSGD/VbNVhEEz6uBpLE8Ft1V4uW1RxmHGB2H1TDQFtyUo9hAi9JHUXeI6Eu1TOZ71iT1tRHrAi+ X-Received: by 2002:a63:dc0c:: with SMTP id s12mr995832pgg.398.1543516902972; Thu, 29 Nov 2018 10:41:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543516902; cv=none; d=google.com; s=arc-20160816; b=cM1KAbicCIBSdmc+9uhVjqT8jL5kvBWMxxy+3BIifaqg8SvTGzFdDJE03QnDH7zCCf lo1Zs/IVLfd2dJFFGZvu6kQPjFh9CxtAO9JR0JUnMMXrk3jB9Wmgks5OoEnISEkY5ahm N60PVi+reoqjVdT+ZfFfxjQsECD72ho7z0v5Xeoho9cKp53jF9fbHVI6hdPCDzCXSVWW OE6QSq3qu503KPpJCn4+JgHJkDpafQBPwz8+DV4AIyrJ+hhJpFaSypIYWrxXbOyqf919 qcDg9M07GzDZDMnHau9EE2vyDMrqndnDYV+zbpTAasgAg3qp4MnvY0fJbFNaF1MIoWly aSqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=7rVtnXD/AbUn8AEyBpfAFoxzTcIxdqZ/2QBMNHqimfE=; b=K3LGwRgzTBkasha3c1UKztLYdPzOnfUd0iYKFVgVLofJcuE2bmaLWMzA/bEsUfYwqD EIji6mWDQdhq0Yrobn8APD4plkKpxQiFShnHwjEkg0UZnepG8XNX7C+cUU2jTU0QT4KM FhP3RrfYhVn+D0W/AbDE11cqSU0z/mQgC3OMw23MhVqpOmfIIVS9PLllZDHrtPsZy9ds mBHBfU1ZnfzkvjTb+RQ66YTFOoA0svZOJ9VUWnrQ4xxa2KxhqfChYLAxLVTqChkBtDRG 0RnNAxQNbnzHCOgcOUlpR1jnoSV8kUqtYYfNBDugBCNjR+sMs3dqdZ2nNcji6g3F0Eva 2uJQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l24si2577173pgb.489.2018.11.29.10.41.27; Thu, 29 Nov 2018 10:41:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730707AbeK3Euv (ORCPT + 99 others); Thu, 29 Nov 2018 23:50:51 -0500 Received: from foss.arm.com ([217.140.101.70]:41362 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730453AbeK3Euu (ORCPT ); Thu, 29 Nov 2018 23:50:50 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4FDA580D; Thu, 29 Nov 2018 09:44:41 -0800 (PST) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 82A783F575; Thu, 29 Nov 2018 09:44:39 -0800 (PST) Date: Thu, 29 Nov 2018 17:44:37 +0000 From: Mark Rutland To: Julien Thierry Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, daniel.thompson@linaro.org, joel@joelfernandes.org, marc.zyngier@arm.com, christoffer.dall@arm.com, james.morse@arm.com, catalin.marinas@arm.com, will.deacon@arm.com Subject: Re: [PATCH v6 08/24] arm64: Unmask PMR before going idle Message-ID: <20181129174436.avqjydyzvv6ubnjd@lakrids.cambridge.arm.com> References: <1542023835-21446-1-git-send-email-julien.thierry@arm.com> <1542023835-21446-9-git-send-email-julien.thierry@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1542023835-21446-9-git-send-email-julien.thierry@arm.com> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Nov 12, 2018 at 11:56:59AM +0000, Julien Thierry wrote: > CPU does not received signals for interrupts with a priority masked by > ICC_PMR_EL1. This means the CPU might not come back from a WFI > instruction. > > Make sure ICC_PMR_EL1 does not mask interrupts when doing a WFI. > > Signed-off-by: Julien Thierry > Suggested-by: Daniel Thompson > Cc: Catalin Marinas > Cc: Will Deacon > --- > arch/arm64/mm/proc.S | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > > diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S > index 2c75b0b..3c7064c 100644 > --- a/arch/arm64/mm/proc.S > +++ b/arch/arm64/mm/proc.S > @@ -20,6 +20,7 @@ > > #include > #include > +#include > #include > #include > #include > @@ -53,10 +54,27 @@ > * cpu_do_idle() > * > * Idle the processor (wait for interrupt). > + * > + * If the CPU supports priority masking we must do additional work to > + * ensure that interrupts are not masked at the PMR (because the core will > + * not wake up if we block the wake up signal in the interrupt controller). > */ > ENTRY(cpu_do_idle) > +alternative_if_not ARM64_HAS_IRQ_PRIO_MASKING > + dsb sy // WFI may enter a low-power mode > + wfi > + ret > +alternative_else > + mrs x0, daif // save I bit > + msr daifset, #2 // set I bit > + mrs_s x1, SYS_ICC_PMR_EL1 // save PMR > +alternative_endif > + mov x2, #GIC_PRIO_IRQON > + msr_s SYS_ICC_PMR_EL1, x2 // unmask PMR > dsb sy // WFI may enter a low-power mode Is the DSB SY sufficient and necessary to synchronise the update of SYS_ICC_PMR_EL1? We don't need an ISB too? > wfi > + msr_s SYS_ICC_PMR_EL1, x1 // restore PMR Likewise, we don't need any barriers here before we poke DAIF? > + msr daif, x0 // restore I bit > ret > ENDPROC(cpu_do_idle) If we build without CONFIG_ARM64_PSEUDO_NMI surely we don't want to emit the alternative? How about we move this to C, and have something like the below? For the !CONFIG_ARM64_PSEUDO_NMI case it generates identical assembly to the existing cpu_do_idle(). Note that I've assumed we don't need barriers, which (as above) I'm not certain of. Thanks, Mark. ---->8---- diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 7f1628effe6d..ccd2ad8c5e2f 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -73,6 +73,40 @@ EXPORT_SYMBOL_GPL(pm_power_off); void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); +static inline void __cpu_do_idle(void) +{ + /* WFI may enter a low-power mode */ + dsb(sy); + wfi(); +} + +/* + * When using priority masking we need to take extra care, etc. + */ +static inline void __cpu_do_idle_irqprio(void) +{ + unsigned long flags = arch_local_irq_save(); + unsigned long pmr = gic_read_pmr(); + + gic_write_pmr(GIC_PRIO_IRQON); + + __cpu_do_idle(); + + gic_write_pmr(pmr); + arch_local_irq_enable(); +} + +/* + * Idle the processor (wait for interrupt). + */ +void cpu_do_idle(void) +{ + if (system_uses_irq_prio_masking()) + __cpu_do_idle_irqprio(); + else + __cpu_do_idle(); +} + /* * This is our default idle handler. */ diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 03646e6a2ef4..38c0171e52e2 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -49,17 +49,6 @@ #define MAIR(attr, mt) ((attr) << ((mt) * 8)) -/* - * cpu_do_idle() - * - * Idle the processor (wait for interrupt). - */ -ENTRY(cpu_do_idle) - dsb sy // WFI may enter a low-power mode - wfi - ret -ENDPROC(cpu_do_idle) - #ifdef CONFIG_CPU_PM /** * cpu_do_suspend - save CPU registers context