From: james.morse@arm.com (James Morse)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 05/11] arm64: KVM/mm: Move SEA handling behind a single 'claim' interface
Date: Thu, 15 Feb 2018 18:56:00 +0000 [thread overview]
Message-ID: <20180215185606.26736-6-james.morse@arm.com> (raw)
In-Reply-To: <20180215185606.26736-1-james.morse@arm.com>
To split up APEIs in_nmi() path, we need the nmi-like callers to always
be in_nmi(). Add a helper to do the work and claim the notification.
When KVM or the arch code takes an exception that might be a RAS
notification, it asks the APEI firmware-first code whether it wants
to claim the exception. We can then go on to see if (a future)
kernel-first mechanism wants to claim the notification, before
falling through to the existing default behaviour.
The NOTIFY_SEA code was merged before we had multiple, possibly
interacting, NMI-like notifications and the need to consider kernel
first in the future. Make the 'claiming' behaviour explicit.
As we're restructuring the APEI code to allow multiple NMI-like
notifications, any notification that might interrupt interrupts-masked
code must always be wrapped in nmi_enter()/nmi_exit(). This allows APEI
to use in_nmi() so choose between the raw/regular spinlock routines.
We mask SError over this window to prevent an asynchronous RAS error
arriving and tripping 'nmi_enter()'s BUG_ON(in_nmi()).
Signed-off-by: James Morse <james.morse@arm.com>
CC: Tyler Baicar <tbaicar@codeaurora.org>
---
Why does apei_claim_sea() take a pt_regs? This gets used later to take
APEI by the hand through NMI->IRQ context, depending on what we
interrupted.
arch/arm64/include/asm/acpi.h | 3 +++
arch/arm64/include/asm/daifflags.h | 1 +
arch/arm64/include/asm/kvm_ras.h | 20 +++++++++++++++++++-
arch/arm64/kernel/acpi.c | 30 ++++++++++++++++++++++++++++++
arch/arm64/mm/fault.c | 31 +++++++------------------------
5 files changed, 60 insertions(+), 25 deletions(-)
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 32f465a80e4e..256811cd4b8b 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -16,6 +16,7 @@
#include <linux/psci.h>
#include <asm/cputype.h>
+#include <asm/ptrace.h>
#include <asm/smp_plat.h>
#include <asm/tlbflush.h>
@@ -94,6 +95,8 @@ void __init acpi_init_cpus(void);
static inline void acpi_init_cpus(void) { }
#endif /* CONFIG_ACPI */
+int apei_claim_sea(struct pt_regs *regs);
+
#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
bool acpi_parking_protocol_valid(int cpu);
void __init
diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
index 22e4c83de5a5..cbd753855bf3 100644
--- a/arch/arm64/include/asm/daifflags.h
+++ b/arch/arm64/include/asm/daifflags.h
@@ -20,6 +20,7 @@
#define DAIF_PROCCTX 0
#define DAIF_PROCCTX_NOIRQ PSR_I_BIT
+#define DAIF_ERRCTX (PSR_I_BIT | PSR_A_BIT)
/* mask/save/unmask/restore all exceptions, including interrupts. */
static inline void local_daif_mask(void)
diff --git a/arch/arm64/include/asm/kvm_ras.h b/arch/arm64/include/asm/kvm_ras.h
index 5f72b07b7912..9d52bc333110 100644
--- a/arch/arm64/include/asm/kvm_ras.h
+++ b/arch/arm64/include/asm/kvm_ras.h
@@ -4,8 +4,26 @@
#ifndef __ARM64_KVM_RAS_H__
#define __ARM64_KVM_RAS_H__
+#include <linux/acpi.h>
+#include <linux/errno.h>
#include <linux/types.h>
-int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr);
+#include <asm/acpi.h>
+
+/*
+ * Was this synchronous external abort a RAS notification?
+ * Returns '0' for errors handled by some RAS subsystem, or -ENOENT.
+ *
+ * Call with irqs unmaksed.
+ */
+static inline int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr)
+{
+ int ret = -ENOENT;
+
+ if (IS_ENABLED(CONFIG_ACPI_APEI_SEA))
+ ret = apei_claim_sea(NULL);
+
+ return ret;
+}
#endif /* __ARM64_KVM_RAS_H__ */
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 7b09487ff8fb..6a4823a3eb5e 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -33,6 +33,8 @@
#ifdef CONFIG_ACPI_APEI
# include <linux/efi.h>
+# include <acpi/ghes.h>
+# include <asm/daifflags.h>
# include <asm/pgtable.h>
#endif
@@ -261,4 +263,32 @@ pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
return __pgprot(PROT_NORMAL_NC);
return __pgprot(PROT_DEVICE_nGnRnE);
}
+
+
+/*
+ * Claim Synchronous External Aborts as a firmware first notification.
+ *
+ * Used by KVM and the arch do_sea handler.
+ * @regs may be NULL when called from process context.
+ */
+int apei_claim_sea(struct pt_regs *regs)
+{
+ int err = -ENOENT;
+ unsigned long current_flags = arch_local_save_flags();
+
+ if (!IS_ENABLED(CONFIG_ACPI_APEI_SEA))
+ return err;
+
+ /*
+ * APEI expects an NMI-like notification to always be called
+ * in NMI context.
+ */
+ local_daif_restore(DAIF_ERRCTX);
+ nmi_enter();
+ err = ghes_notify_sea();
+ nmi_exit();
+ local_daif_restore(current_flags);
+
+ return err;
+}
#endif
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index adac28ce9be3..8cbbd9a5ec7d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/acpi.h>
#include <linux/extable.h>
#include <linux/signal.h>
#include <linux/mm.h>
@@ -33,6 +34,7 @@
#include <linux/preempt.h>
#include <linux/hugetlb.h>
+#include <asm/acpi.h>
#include <asm/bug.h>
#include <asm/cmpxchg.h>
#include <asm/cpufeature.h>
@@ -44,8 +46,6 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
-#include <acpi/ghes.h>
-
struct fault_info {
int (*fn)(unsigned long addr, unsigned int esr,
struct pt_regs *regs);
@@ -579,19 +579,12 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
inf->name, esr, addr);
- /*
- * Synchronous aborts may interrupt code which had interrupts masked.
- * Before calling out into the wider kernel tell the interested
- * subsystems.
- */
if (IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {
- if (interrupts_enabled(regs))
- nmi_enter();
-
- ghes_notify_sea();
-
- if (interrupts_enabled(regs))
- nmi_exit();
+ /*
+ * Return value ignored as we rely on signal merging.
+ * Future patches will make this more robust.
+ */
+ apei_claim_sea(regs);
}
info.si_signo = SIGBUS;
@@ -673,16 +666,6 @@ static const struct fault_info fault_info[] = {
{ do_bad, SIGBUS, BUS_FIXME, "unknown 63" },
};
-int kvm_handle_guest_sea(phys_addr_t addr, unsigned int esr)
-{
- int ret = -ENOENT;
-
- if (IS_ENABLED(CONFIG_ACPI_APEI_SEA))
- ret = ghes_notify_sea();
-
- return ret;
-}
-
asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
struct pt_regs *regs)
{
--
2.15.1
next prev parent reply other threads:[~2018-02-15 18:56 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-15 18:55 [PATCH 00/11] APEI in_nmi() rework and arm64 SDEI wire-up James Morse
2018-02-15 18:55 ` [PATCH 01/11] ACPI / APEI: Move the estatus queue code up, and under its own ifdef James Morse
2018-02-20 18:26 ` Punit Agrawal
2018-02-20 19:28 ` Borislav Petkov
2018-02-23 18:02 ` James Morse
2018-02-23 18:07 ` Borislav Petkov
2018-02-15 18:55 ` [PATCH 02/11] ACPI / APEI: Generalise the estatus queue's add/remove and notify code James Morse
2018-02-20 18:26 ` Punit Agrawal
2018-02-23 18:21 ` James Morse
2018-03-01 15:01 ` Borislav Petkov
2018-03-01 18:06 ` Punit Agrawal
2018-03-01 22:35 ` Borislav Petkov
2018-03-07 18:15 ` James Morse
2018-03-08 10:44 ` Borislav Petkov
2018-03-19 14:29 ` James Morse
2018-03-27 17:25 ` Borislav Petkov
2018-03-28 16:30 ` James Morse
2018-04-17 15:10 ` Borislav Petkov
2018-02-15 18:55 ` [PATCH 03/11] ACPI / APEI: Switch NOTIFY_SEA to use the estatus queue James Morse
2018-02-15 18:55 ` [PATCH 04/11] KVM: arm/arm64: Add kvm_ras.h to collect kvm specific RAS plumbing James Morse
2018-02-15 18:56 ` James Morse [this message]
2018-02-20 18:30 ` [PATCH 05/11] arm64: KVM/mm: Move SEA handling behind a single 'claim' interface Punit Agrawal
2018-02-15 18:56 ` [PATCH 06/11] ACPI / APEI: Make the fixmap_idx per-ghes to allow multiple in_nmi() users James Morse
2018-02-20 21:18 ` Tyler Baicar
2018-02-22 17:47 ` James Morse
2018-02-15 18:56 ` [PATCH 07/11] ACPI / APEI: Split fixmap pages for arm64 NMI-like notifications James Morse
2018-02-15 18:56 ` [PATCH 08/11] firmware: arm_sdei: Add ACPI GHES registration helper James Morse
2018-02-20 18:31 ` Punit Agrawal
2018-02-15 18:56 ` [PATCH 09/11] ACPI / APEI: Add support for the SDEI GHES Notification type James Morse
2018-02-15 18:56 ` [PATCH 10/11] mm/memory-failure: increase queued recovery work's priority James Morse
2018-02-15 18:56 ` [PATCH 11/11] arm64: acpi: Make apei_claim_sea() synchronise with APEI's irq work James Morse
2018-02-19 21:05 ` [PATCH 00/11] APEI in_nmi() rework and arm64 SDEI wire-up Borislav Petkov
2018-02-20 18:42 ` Punit Agrawal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180215185606.26736-6-james.morse@arm.com \
--to=james.morse@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).