All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-10-19 14:57 ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

Hello,

The aim of this series is to enable IESB and add ESB-instructions to let us
kick any pending RAS errors into firmware to be handled by firmware-first.

Not all systems will have this firmware, so these RAS errors will become
pending SErrors. We should take these as quickly as possible and avoid
panic()ing for errors where we could have continued.

This first part of this series reworks the DAIF masking so that SError is
unmasked unless we are handling a debug exception.

The last part provides the same minimal handling for SError that interrupt
KVM. KVM is currently unable to handle SErrors during world-switch, unless
they occur during a magic single-instruction window, it hyp-panics. I suspect
this will be easier to fix once the VHE world-switch is further optimised.

KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
and all-zeros has a RAS meaning.

KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
These are errors where we don't know what they mean, they may not be
synchronised by ESB. Today we blame the guest.
My half-baked suggestion would be to make a virtual SError pending, but then
exit to user-space to give Qemu the change to quit (for virtual machines that
don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
continue and take KVMs default all-zeros impdef ESR.

Known issues:
 * Synchronous external abort SET severity is not yet considered, all
   synchronous-external-aborts are still considered fatal.

 * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
   HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
   hasn't taken it yet...?

 * KVM unmasks SError and IRQ before calling handle_exit, we may be rescheduled
   while holding an uncontained ESR... (this is currently an improvement on
   assuming its an impdef error we can blame on the guest)
    * We need to fix this for APEI's SEI or kernel-first RAS, the guest-exit
      SError handling will need to move to before kvm_arm_vhe_guest_exit().


Changes from v3:
 * Symbol naming around daif flag helpers
 * Removed the IESB kconfig option
 * Moved that nop out of the firing line in the vaxorcism code
 * Added last patch to Trap ERR registers and make them RAZ/WI


Comments and contradictions welcome,

James


Dongjiu Geng (1):
  KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA

James Morse (18):
  arm64: explicitly mask all exceptions
  arm64: introduce an order for exceptions
  arm64: Move the async/fiq helpers to explicitly set process context
    flags
  arm64: Mask all exceptions during kernel_exit
  arm64: entry.S: Remove disable_dbg
  arm64: entry.S: convert el1_sync
  arm64: entry.S convert el0_sync
  arm64: entry.S: convert elX_irq
  KVM: arm/arm64: mask/unmask daif around VHE guests
  arm64: kernel: Survive corrected RAS errors notified by SError
  arm64: cpufeature: Enable IESB on exception entry/return for
    firmware-first
  arm64: kernel: Prepare for a DISR user
  KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  KVM: arm64: Save/Restore guest DISR_EL1
  KVM: arm64: Save ESR_EL2 on guest SError
  KVM: arm64: Handle RAS SErrors from EL1 on guest exit
  KVM: arm64: Handle RAS SErrors from EL2 on guest exit
  KVM: arm64: Take any host SError before entering the guest

Xie XiuQi (2):
  arm64: entry.S: move SError handling into a C function for future
    expansion
  arm64: cpufeature: Detect CPU RAS Extentions

 arch/arm64/Kconfig                   | 18 +++++++-
 arch/arm64/include/asm/assembler.h   | 51 ++++++++++++++-------
 arch/arm64/include/asm/barrier.h     |  1 +
 arch/arm64/include/asm/cpucaps.h     |  4 +-
 arch/arm64/include/asm/daifflags.h   | 72 ++++++++++++++++++++++++++++++
 arch/arm64/include/asm/esr.h         | 17 +++++++
 arch/arm64/include/asm/exception.h   | 14 ++++++
 arch/arm64/include/asm/irqflags.h    | 40 ++++++-----------
 arch/arm64/include/asm/kvm_arm.h     |  2 +
 arch/arm64/include/asm/kvm_emulate.h | 17 +++++++
 arch/arm64/include/asm/kvm_host.h    | 16 +++++++
 arch/arm64/include/asm/processor.h   |  2 +
 arch/arm64/include/asm/sysreg.h      | 16 +++++++
 arch/arm64/include/asm/traps.h       | 36 +++++++++++++++
 arch/arm64/kernel/asm-offsets.c      |  1 +
 arch/arm64/kernel/cpufeature.c       | 41 +++++++++++++++++
 arch/arm64/kernel/debug-monitors.c   |  5 ++-
 arch/arm64/kernel/entry.S            | 86 +++++++++++++++++++++---------------
 arch/arm64/kernel/hibernate.c        |  5 ++-
 arch/arm64/kernel/machine_kexec.c    |  4 +-
 arch/arm64/kernel/process.c          |  3 ++
 arch/arm64/kernel/setup.c            |  8 ++--
 arch/arm64/kernel/signal.c           |  8 +++-
 arch/arm64/kernel/smp.c              | 12 ++---
 arch/arm64/kernel/suspend.c          |  7 +--
 arch/arm64/kernel/traps.c            | 64 ++++++++++++++++++++++++++-
 arch/arm64/kvm/handle_exit.c         | 19 +++++++-
 arch/arm64/kvm/hyp-init.S            |  3 ++
 arch/arm64/kvm/hyp/entry.S           | 13 ++++++
 arch/arm64/kvm/hyp/switch.c          | 19 ++++++--
 arch/arm64/kvm/hyp/sysreg-sr.c       |  6 +++
 arch/arm64/kvm/inject_fault.c        | 13 +++++-
 arch/arm64/kvm/sys_regs.c            | 11 +++++
 arch/arm64/mm/proc.S                 | 14 +++---
 virt/kvm/arm/arm.c                   |  4 ++
 35 files changed, 537 insertions(+), 115 deletions(-)
 create mode 100644 arch/arm64/include/asm/daifflags.h

-- 
2.13.3

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-10-19 14:57 ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

The aim of this series is to enable IESB and add ESB-instructions to let us
kick any pending RAS errors into firmware to be handled by firmware-first.

Not all systems will have this firmware, so these RAS errors will become
pending SErrors. We should take these as quickly as possible and avoid
panic()ing for errors where we could have continued.

This first part of this series reworks the DAIF masking so that SError is
unmasked unless we are handling a debug exception.

The last part provides the same minimal handling for SError that interrupt
KVM. KVM is currently unable to handle SErrors during world-switch, unless
they occur during a magic single-instruction window, it hyp-panics. I suspect
this will be easier to fix once the VHE world-switch is further optimised.

KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
and all-zeros has a RAS meaning.

KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
These are errors where we don't know what they mean, they may not be
synchronised by ESB. Today we blame the guest.
My half-baked suggestion would be to make a virtual SError pending, but then
exit to user-space to give Qemu the change to quit (for virtual machines that
don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
continue and take KVMs default all-zeros impdef ESR.

Known issues:
 * Synchronous external abort SET severity is not yet considered, all
   synchronous-external-aborts are still considered fatal.

 * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
   HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
   hasn't taken it yet...?

 * KVM unmasks SError and IRQ before calling handle_exit, we may be rescheduled
   while holding an uncontained ESR... (this is currently an improvement on
   assuming its an impdef error we can blame on the guest)
    * We need to fix this for APEI's SEI or kernel-first RAS, the guest-exit
      SError handling will need to move to before kvm_arm_vhe_guest_exit().


Changes from v3:
 * Symbol naming around daif flag helpers
 * Removed the IESB kconfig option
 * Moved that nop out of the firing line in the vaxorcism code
 * Added last patch to Trap ERR registers and make them RAZ/WI


Comments and contradictions welcome,

James


Dongjiu Geng (1):
  KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA

James Morse (18):
  arm64: explicitly mask all exceptions
  arm64: introduce an order for exceptions
  arm64: Move the async/fiq helpers to explicitly set process context
    flags
  arm64: Mask all exceptions during kernel_exit
  arm64: entry.S: Remove disable_dbg
  arm64: entry.S: convert el1_sync
  arm64: entry.S convert el0_sync
  arm64: entry.S: convert elX_irq
  KVM: arm/arm64: mask/unmask daif around VHE guests
  arm64: kernel: Survive corrected RAS errors notified by SError
  arm64: cpufeature: Enable IESB on exception entry/return for
    firmware-first
  arm64: kernel: Prepare for a DISR user
  KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  KVM: arm64: Save/Restore guest DISR_EL1
  KVM: arm64: Save ESR_EL2 on guest SError
  KVM: arm64: Handle RAS SErrors from EL1 on guest exit
  KVM: arm64: Handle RAS SErrors from EL2 on guest exit
  KVM: arm64: Take any host SError before entering the guest

Xie XiuQi (2):
  arm64: entry.S: move SError handling into a C function for future
    expansion
  arm64: cpufeature: Detect CPU RAS Extentions

 arch/arm64/Kconfig                   | 18 +++++++-
 arch/arm64/include/asm/assembler.h   | 51 ++++++++++++++-------
 arch/arm64/include/asm/barrier.h     |  1 +
 arch/arm64/include/asm/cpucaps.h     |  4 +-
 arch/arm64/include/asm/daifflags.h   | 72 ++++++++++++++++++++++++++++++
 arch/arm64/include/asm/esr.h         | 17 +++++++
 arch/arm64/include/asm/exception.h   | 14 ++++++
 arch/arm64/include/asm/irqflags.h    | 40 ++++++-----------
 arch/arm64/include/asm/kvm_arm.h     |  2 +
 arch/arm64/include/asm/kvm_emulate.h | 17 +++++++
 arch/arm64/include/asm/kvm_host.h    | 16 +++++++
 arch/arm64/include/asm/processor.h   |  2 +
 arch/arm64/include/asm/sysreg.h      | 16 +++++++
 arch/arm64/include/asm/traps.h       | 36 +++++++++++++++
 arch/arm64/kernel/asm-offsets.c      |  1 +
 arch/arm64/kernel/cpufeature.c       | 41 +++++++++++++++++
 arch/arm64/kernel/debug-monitors.c   |  5 ++-
 arch/arm64/kernel/entry.S            | 86 +++++++++++++++++++++---------------
 arch/arm64/kernel/hibernate.c        |  5 ++-
 arch/arm64/kernel/machine_kexec.c    |  4 +-
 arch/arm64/kernel/process.c          |  3 ++
 arch/arm64/kernel/setup.c            |  8 ++--
 arch/arm64/kernel/signal.c           |  8 +++-
 arch/arm64/kernel/smp.c              | 12 ++---
 arch/arm64/kernel/suspend.c          |  7 +--
 arch/arm64/kernel/traps.c            | 64 ++++++++++++++++++++++++++-
 arch/arm64/kvm/handle_exit.c         | 19 +++++++-
 arch/arm64/kvm/hyp-init.S            |  3 ++
 arch/arm64/kvm/hyp/entry.S           | 13 ++++++
 arch/arm64/kvm/hyp/switch.c          | 19 ++++++--
 arch/arm64/kvm/hyp/sysreg-sr.c       |  6 +++
 arch/arm64/kvm/inject_fault.c        | 13 +++++-
 arch/arm64/kvm/sys_regs.c            | 11 +++++
 arch/arm64/mm/proc.S                 | 14 +++---
 virt/kvm/arm/arm.c                   |  4 ++
 35 files changed, 537 insertions(+), 115 deletions(-)
 create mode 100644 arch/arm64/include/asm/daifflags.h

-- 
2.13.3

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 01/21] arm64: explicitly mask all exceptions
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

There are a few places where we want to mask all exceptions. Today we
do this in a piecemeal fashion, typically we expect the caller to
have masked irqs and the arch code masks debug exceptions, ignoring
serror which is probably masked.

Make it clear that 'mask all exceptions' is the intention by adding
helpers to do exactly that.

This will let us unmask SError without having to add 'oh and SError'
to these paths.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Remove the disable IRQs comment above cpu_die(): we return from idle via
cpu_resume. This comment is confusing once the local_irq_disable() call
is changed.

Changes since v3:
 * Split local_mask_daif into a save and mask versions,
 * swapped verb/daif word-order.
 * Removed {asm,linux} includes - one will always include the other

 arch/arm64/include/asm/assembler.h | 17 ++++++++++
 arch/arm64/include/asm/daifflags.h | 69 ++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/hibernate.c      |  5 +--
 arch/arm64/kernel/machine_kexec.c  |  4 +--
 arch/arm64/kernel/smp.c            |  9 ++---
 arch/arm64/kernel/suspend.c        |  7 ++--
 arch/arm64/kernel/traps.c          |  3 +-
 arch/arm64/mm/proc.S               |  9 +++--
 8 files changed, 104 insertions(+), 19 deletions(-)
 create mode 100644 arch/arm64/include/asm/daifflags.h

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index d58a6253c6ab..114e741ca873 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -31,6 +31,23 @@
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
 
+	.macro save_and_disable_daif, flags
+	mrs	\flags, daif
+	msr	daifset, #0xf
+	.endm
+
+	.macro disable_daif
+	msr	daifset, #0xf
+	.endm
+
+	.macro enable_daif
+	msr	daifclr, #0xf
+	.endm
+
+	.macro	restore_daif, flags:req
+	msr	daif, \flags
+	.endm
+
 /*
  * Enable and disable interrupts.
  */
diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
new file mode 100644
index 000000000000..55e2598a8c4c
--- /dev/null
+++ b/arch/arm64/include/asm/daifflags.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_DAIFFLAGS_H
+#define __ASM_DAIFFLAGS_H
+
+#include <linux/irqflags.h>
+
+/* mask/save/unmask/restore all exceptions, including interrupts. */
+static inline void local_daif_mask(void)
+{
+	asm volatile(
+		"msr	daifset, #0xf		// local_daif_mask\n"
+		:
+		:
+		: "memory");
+	trace_hardirqs_off();
+}
+
+static inline unsigned long local_daif_save(void)
+{
+	unsigned long flags;
+
+	asm volatile(
+		"mrs	%0, daif		// local_daif_save\n"
+		: "=r" (flags)
+		:
+		: "memory");
+	local_daif_mask();
+
+	return flags;
+}
+
+static inline void local_daif_unmask(void)
+{
+	trace_hardirqs_on();
+	asm volatile(
+		"msr	daifclr, #0xf		// local_daif_unmask"
+		:
+		:
+		: "memory");
+}
+
+static inline void local_daif_restore(unsigned long flags)
+{
+	if (!arch_irqs_disabled_flags(flags))
+		trace_hardirqs_on();
+	asm volatile(
+		"msr	daif, %0		// local_daif_restore"
+		:
+		: "r" (flags)
+		: "memory");
+	if (arch_irqs_disabled_flags(flags))
+		trace_hardirqs_off();
+}
+
+#endif
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 095d3c170f5d..3009b8b80f08 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -27,6 +27,7 @@
 #include <asm/barrier.h>
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
+#include <asm/daifflags.h>
 #include <asm/irqflags.h>
 #include <asm/kexec.h>
 #include <asm/memory.h>
@@ -285,7 +286,7 @@ int swsusp_arch_suspend(void)
 		return -EBUSY;
 	}
 
-	local_dbg_save(flags);
+	flags = local_daif_save();
 
 	if (__cpu_suspend_enter(&state)) {
 		/* make the crash dump kernel image visible/saveable */
@@ -315,7 +316,7 @@ int swsusp_arch_suspend(void)
 		__cpu_suspend_exit();
 	}
 
-	local_dbg_restore(flags);
+	local_daif_restore(flags);
 
 	return ret;
 }
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 11121f608eb5..f76ea92dff91 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -18,6 +18,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
+#include <asm/daifflags.h>
 #include <asm/memory.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
@@ -195,8 +196,7 @@ void machine_kexec(struct kimage *kimage)
 
 	pr_info("Bye!\n");
 
-	/* Disable all DAIF exceptions. */
-	asm volatile ("msr daifset, #0xf" : : : "memory");
+	local_daif_mask();
 
 	/*
 	 * cpu_soft_restart will shutdown the MMU, disable data caches, then
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 9f7195a5773e..5a407eba01f7 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -47,6 +47,7 @@
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
+#include <asm/daifflags.h>
 #include <asm/mmu_context.h>
 #include <asm/numa.h>
 #include <asm/pgtable.h>
@@ -368,10 +369,6 @@ void __cpu_die(unsigned int cpu)
 /*
  * Called from the idle thread for the CPU which has been shutdown.
  *
- * Note that we disable IRQs here, but do not re-enable them
- * before returning to the caller. This is also the behaviour
- * of the other hotplug-cpu capable cores, so presumably coming
- * out of idle fixes this.
  */
 void cpu_die(void)
 {
@@ -379,7 +376,7 @@ void cpu_die(void)
 
 	idle_task_exit();
 
-	local_irq_disable();
+	local_daif_mask();
 
 	/* Tell __cpu_die() that this CPU is now safe to dispose of */
 	(void)cpu_report_death();
@@ -837,7 +834,7 @@ static void ipi_cpu_stop(unsigned int cpu)
 {
 	set_cpu_online(cpu, false);
 
-	local_irq_disable();
+	local_daif_mask();
 
 	while (1)
 		cpu_relax();
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 1e3be9064cfa..d2d2edac78f2 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -4,6 +4,7 @@
 #include <asm/alternative.h>
 #include <asm/cacheflush.h>
 #include <asm/cpufeature.h>
+#include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/exec.h>
 #include <asm/pgtable.h>
@@ -57,7 +58,7 @@ void notrace __cpu_suspend_exit(void)
 	/*
 	 * Restore HW breakpoint registers to sane values
 	 * before debug exceptions are possibly reenabled
-	 * through local_dbg_restore.
+	 * by cpu_suspend()s local_daif_restore() call.
 	 */
 	if (hw_breakpoint_restore)
 		hw_breakpoint_restore(cpu);
@@ -81,7 +82,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
 	 * updates to mdscr register (saved and restored along with
 	 * general purpose registers) from kernel debuggers.
 	 */
-	local_dbg_save(flags);
+	flags = local_daif_save();
 
 	/*
 	 * Function graph tracer state gets incosistent when the kernel
@@ -114,7 +115,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
 	 * restored, so from this point onwards, debugging is fully
 	 * renabled if it was enabled when core started shutdown.
 	 */
-	local_dbg_restore(flags);
+	local_daif_restore(flags);
 
 	return ret;
 }
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 5ea4b85aee0e..1808be65d22f 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -38,6 +38,7 @@
 
 #include <asm/atomic.h>
 #include <asm/bug.h>
+#include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/esr.h>
 #include <asm/insn.h>
@@ -642,7 +643,7 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
 		esr_get_class_string(esr));
 
 	die("Oops - bad mode", regs, 0);
-	local_irq_disable();
+	local_daif_mask();
 	panic("bad mode");
 }
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 877d42fb0df6..95233dfc4c39 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -109,10 +109,10 @@ ENTRY(cpu_do_resume)
 	/*
 	 * __cpu_setup() cleared MDSCR_EL1.MDE and friends, before unmasking
 	 * debug exceptions. By restoring MDSCR_EL1 here, we may take a debug
-	 * exception. Mask them until local_dbg_restore() in cpu_suspend()
+	 * exception. Mask them until local_daif_restore() in cpu_suspend()
 	 * resets them.
 	 */
-	disable_dbg
+	disable_daif
 	msr	mdscr_el1, x10
 
 	msr	sctlr_el1, x12
@@ -155,8 +155,7 @@ ENDPROC(cpu_do_switch_mm)
  * called by anything else. It can only be executed from a TTBR0 mapping.
  */
 ENTRY(idmap_cpu_replace_ttbr1)
-	mrs	x2, daif
-	msr	daifset, #0xf
+	save_and_disable_daif flags=x2
 
 	adrp	x1, empty_zero_page
 	msr	ttbr1_el1, x1
@@ -169,7 +168,7 @@ ENTRY(idmap_cpu_replace_ttbr1)
 	msr	ttbr1_el1, x0
 	isb
 
-	msr	daif, x2
+	restore_daif x2
 
 	ret
 ENDPROC(idmap_cpu_replace_ttbr1)
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 01/21] arm64: explicitly mask all exceptions
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

There are a few places where we want to mask all exceptions. Today we
do this in a piecemeal fashion, typically we expect the caller to
have masked irqs and the arch code masks debug exceptions, ignoring
serror which is probably masked.

Make it clear that 'mask all exceptions' is the intention by adding
helpers to do exactly that.

This will let us unmask SError without having to add 'oh and SError'
to these paths.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Remove the disable IRQs comment above cpu_die(): we return from idle via
cpu_resume. This comment is confusing once the local_irq_disable() call
is changed.

Changes since v3:
 * Split local_mask_daif into a save and mask versions,
 * swapped verb/daif word-order.
 * Removed {asm,linux} includes - one will always include the other

 arch/arm64/include/asm/assembler.h | 17 ++++++++++
 arch/arm64/include/asm/daifflags.h | 69 ++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/hibernate.c      |  5 +--
 arch/arm64/kernel/machine_kexec.c  |  4 +--
 arch/arm64/kernel/smp.c            |  9 ++---
 arch/arm64/kernel/suspend.c        |  7 ++--
 arch/arm64/kernel/traps.c          |  3 +-
 arch/arm64/mm/proc.S               |  9 +++--
 8 files changed, 104 insertions(+), 19 deletions(-)
 create mode 100644 arch/arm64/include/asm/daifflags.h

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index d58a6253c6ab..114e741ca873 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -31,6 +31,23 @@
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
 
+	.macro save_and_disable_daif, flags
+	mrs	\flags, daif
+	msr	daifset, #0xf
+	.endm
+
+	.macro disable_daif
+	msr	daifset, #0xf
+	.endm
+
+	.macro enable_daif
+	msr	daifclr, #0xf
+	.endm
+
+	.macro	restore_daif, flags:req
+	msr	daif, \flags
+	.endm
+
 /*
  * Enable and disable interrupts.
  */
diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
new file mode 100644
index 000000000000..55e2598a8c4c
--- /dev/null
+++ b/arch/arm64/include/asm/daifflags.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_DAIFFLAGS_H
+#define __ASM_DAIFFLAGS_H
+
+#include <linux/irqflags.h>
+
+/* mask/save/unmask/restore all exceptions, including interrupts. */
+static inline void local_daif_mask(void)
+{
+	asm volatile(
+		"msr	daifset, #0xf		// local_daif_mask\n"
+		:
+		:
+		: "memory");
+	trace_hardirqs_off();
+}
+
+static inline unsigned long local_daif_save(void)
+{
+	unsigned long flags;
+
+	asm volatile(
+		"mrs	%0, daif		// local_daif_save\n"
+		: "=r" (flags)
+		:
+		: "memory");
+	local_daif_mask();
+
+	return flags;
+}
+
+static inline void local_daif_unmask(void)
+{
+	trace_hardirqs_on();
+	asm volatile(
+		"msr	daifclr, #0xf		// local_daif_unmask"
+		:
+		:
+		: "memory");
+}
+
+static inline void local_daif_restore(unsigned long flags)
+{
+	if (!arch_irqs_disabled_flags(flags))
+		trace_hardirqs_on();
+	asm volatile(
+		"msr	daif, %0		// local_daif_restore"
+		:
+		: "r" (flags)
+		: "memory");
+	if (arch_irqs_disabled_flags(flags))
+		trace_hardirqs_off();
+}
+
+#endif
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 095d3c170f5d..3009b8b80f08 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -27,6 +27,7 @@
 #include <asm/barrier.h>
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
+#include <asm/daifflags.h>
 #include <asm/irqflags.h>
 #include <asm/kexec.h>
 #include <asm/memory.h>
@@ -285,7 +286,7 @@ int swsusp_arch_suspend(void)
 		return -EBUSY;
 	}
 
-	local_dbg_save(flags);
+	flags = local_daif_save();
 
 	if (__cpu_suspend_enter(&state)) {
 		/* make the crash dump kernel image visible/saveable */
@@ -315,7 +316,7 @@ int swsusp_arch_suspend(void)
 		__cpu_suspend_exit();
 	}
 
-	local_dbg_restore(flags);
+	local_daif_restore(flags);
 
 	return ret;
 }
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 11121f608eb5..f76ea92dff91 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -18,6 +18,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
+#include <asm/daifflags.h>
 #include <asm/memory.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
@@ -195,8 +196,7 @@ void machine_kexec(struct kimage *kimage)
 
 	pr_info("Bye!\n");
 
-	/* Disable all DAIF exceptions. */
-	asm volatile ("msr daifset, #0xf" : : : "memory");
+	local_daif_mask();
 
 	/*
 	 * cpu_soft_restart will shutdown the MMU, disable data caches, then
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 9f7195a5773e..5a407eba01f7 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -47,6 +47,7 @@
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
+#include <asm/daifflags.h>
 #include <asm/mmu_context.h>
 #include <asm/numa.h>
 #include <asm/pgtable.h>
@@ -368,10 +369,6 @@ void __cpu_die(unsigned int cpu)
 /*
  * Called from the idle thread for the CPU which has been shutdown.
  *
- * Note that we disable IRQs here, but do not re-enable them
- * before returning to the caller. This is also the behaviour
- * of the other hotplug-cpu capable cores, so presumably coming
- * out of idle fixes this.
  */
 void cpu_die(void)
 {
@@ -379,7 +376,7 @@ void cpu_die(void)
 
 	idle_task_exit();
 
-	local_irq_disable();
+	local_daif_mask();
 
 	/* Tell __cpu_die() that this CPU is now safe to dispose of */
 	(void)cpu_report_death();
@@ -837,7 +834,7 @@ static void ipi_cpu_stop(unsigned int cpu)
 {
 	set_cpu_online(cpu, false);
 
-	local_irq_disable();
+	local_daif_mask();
 
 	while (1)
 		cpu_relax();
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 1e3be9064cfa..d2d2edac78f2 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -4,6 +4,7 @@
 #include <asm/alternative.h>
 #include <asm/cacheflush.h>
 #include <asm/cpufeature.h>
+#include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/exec.h>
 #include <asm/pgtable.h>
@@ -57,7 +58,7 @@ void notrace __cpu_suspend_exit(void)
 	/*
 	 * Restore HW breakpoint registers to sane values
 	 * before debug exceptions are possibly reenabled
-	 * through local_dbg_restore.
+	 * by cpu_suspend()s local_daif_restore() call.
 	 */
 	if (hw_breakpoint_restore)
 		hw_breakpoint_restore(cpu);
@@ -81,7 +82,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
 	 * updates to mdscr register (saved and restored along with
 	 * general purpose registers) from kernel debuggers.
 	 */
-	local_dbg_save(flags);
+	flags = local_daif_save();
 
 	/*
 	 * Function graph tracer state gets incosistent when the kernel
@@ -114,7 +115,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
 	 * restored, so from this point onwards, debugging is fully
 	 * renabled if it was enabled when core started shutdown.
 	 */
-	local_dbg_restore(flags);
+	local_daif_restore(flags);
 
 	return ret;
 }
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 5ea4b85aee0e..1808be65d22f 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -38,6 +38,7 @@
 
 #include <asm/atomic.h>
 #include <asm/bug.h>
+#include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/esr.h>
 #include <asm/insn.h>
@@ -642,7 +643,7 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
 		esr_get_class_string(esr));
 
 	die("Oops - bad mode", regs, 0);
-	local_irq_disable();
+	local_daif_mask();
 	panic("bad mode");
 }
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 877d42fb0df6..95233dfc4c39 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -109,10 +109,10 @@ ENTRY(cpu_do_resume)
 	/*
 	 * __cpu_setup() cleared MDSCR_EL1.MDE and friends, before unmasking
 	 * debug exceptions. By restoring MDSCR_EL1 here, we may take a debug
-	 * exception. Mask them until local_dbg_restore() in cpu_suspend()
+	 * exception. Mask them until local_daif_restore() in cpu_suspend()
 	 * resets them.
 	 */
-	disable_dbg
+	disable_daif
 	msr	mdscr_el1, x10
 
 	msr	sctlr_el1, x12
@@ -155,8 +155,7 @@ ENDPROC(cpu_do_switch_mm)
  * called by anything else. It can only be executed from a TTBR0 mapping.
  */
 ENTRY(idmap_cpu_replace_ttbr1)
-	mrs	x2, daif
-	msr	daifset, #0xf
+	save_and_disable_daif flags=x2
 
 	adrp	x1, empty_zero_page
 	msr	ttbr1_el1, x1
@@ -169,7 +168,7 @@ ENTRY(idmap_cpu_replace_ttbr1)
 	msr	ttbr1_el1, x0
 	isb
 
-	msr	daif, x2
+	restore_daif x2
 
 	ret
 ENDPROC(idmap_cpu_replace_ttbr1)
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 02/21] arm64: introduce an order for exceptions
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

Currently SError is always masked in the kernel. To support RAS exceptions
using SError on hardware with the v8.2 RAS Extensions we need to unmask
SError as much as possible.

Let's define an order for masking and unmasking exceptions. 'dai' is
memorable and effectively what we have today.

Disabling debug exceptions should cause all other exceptions to be masked.
Masking SError should mask irq, but not disable debug exceptions.
Masking irqs has no side effects for other flags. Keeping to this order
makes it easier for entry.S to know which exceptions should be unmasked.

FIQ is never expected, but we mask it when we mask debug exceptions, and
unmask it at all other times.

Given masking debug exceptions masks everything, we don't need macros
to save/restore that bit independently. Remove them and switch the last
caller over to use the daif calls.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Changes since v3:
 * Use save_daif version, swapped verb/daif word-order.
 * tweak last sentence of commit message.

 arch/arm64/include/asm/irqflags.h  | 34 +++++++++++++---------------------
 arch/arm64/kernel/debug-monitors.c |  5 +++--
 2 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index 8c581281fa12..9ecdca7011f0 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -21,6 +21,19 @@
 #include <asm/ptrace.h>
 
 /*
+ * Aarch64 has flags for masking: Debug, Asynchronous (serror), Interrupts and
+ * FIQ exceptions, in the 'daif' register. We mask and unmask them in 'dai'
+ * order:
+ * Masking debug exceptions causes all other exceptions to be masked too/
+ * Masking SError masks irq, but not debug exceptions. Masking irqs has no
+ * side effects for other flags. Keeping to this order makes it easier for
+ * entry.S to know which exceptions should be unmasked.
+ *
+ * FIQ is never expected, but we mask it when we disable debug exceptions, and
+ * unmask it at all other times.
+ */
+
+/*
  * CPU interrupt mask handling.
  */
 static inline unsigned long arch_local_irq_save(void)
@@ -89,26 +102,5 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
 {
 	return flags & PSR_I_BIT;
 }
-
-/*
- * save and restore debug state
- */
-#define local_dbg_save(flags)						\
-	do {								\
-		typecheck(unsigned long, flags);			\
-		asm volatile(						\
-		"mrs    %0, daif		// local_dbg_save\n"	\
-		"msr    daifset, #8"					\
-		: "=r" (flags) : : "memory");				\
-	} while (0)
-
-#define local_dbg_restore(flags)					\
-	do {								\
-		typecheck(unsigned long, flags);			\
-		asm volatile(						\
-		"msr    daif, %0		// local_dbg_restore\n"	\
-		: : "r" (flags) : "memory");				\
-	} while (0)
-
 #endif
 #endif
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index c7ef99904934..a88b6ccebbb4 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -30,6 +30,7 @@
 
 #include <asm/cpufeature.h>
 #include <asm/cputype.h>
+#include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/system_misc.h>
 
@@ -46,9 +47,9 @@ u8 debug_monitors_arch(void)
 static void mdscr_write(u32 mdscr)
 {
 	unsigned long flags;
-	local_dbg_save(flags);
+	flags = local_daif_save();
 	write_sysreg(mdscr, mdscr_el1);
-	local_dbg_restore(flags);
+	local_daif_restore(flags);
 }
 NOKPROBE_SYMBOL(mdscr_write);
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 02/21] arm64: introduce an order for exceptions
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Currently SError is always masked in the kernel. To support RAS exceptions
using SError on hardware with the v8.2 RAS Extensions we need to unmask
SError as much as possible.

Let's define an order for masking and unmasking exceptions. 'dai' is
memorable and effectively what we have today.

Disabling debug exceptions should cause all other exceptions to be masked.
Masking SError should mask irq, but not disable debug exceptions.
Masking irqs has no side effects for other flags. Keeping to this order
makes it easier for entry.S to know which exceptions should be unmasked.

FIQ is never expected, but we mask it when we mask debug exceptions, and
unmask it at all other times.

Given masking debug exceptions masks everything, we don't need macros
to save/restore that bit independently. Remove them and switch the last
caller over to use the daif calls.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Changes since v3:
 * Use save_daif version, swapped verb/daif word-order.
 * tweak last sentence of commit message.

 arch/arm64/include/asm/irqflags.h  | 34 +++++++++++++---------------------
 arch/arm64/kernel/debug-monitors.c |  5 +++--
 2 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index 8c581281fa12..9ecdca7011f0 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -21,6 +21,19 @@
 #include <asm/ptrace.h>
 
 /*
+ * Aarch64 has flags for masking: Debug, Asynchronous (serror), Interrupts and
+ * FIQ exceptions, in the 'daif' register. We mask and unmask them in 'dai'
+ * order:
+ * Masking debug exceptions causes all other exceptions to be masked too/
+ * Masking SError masks irq, but not debug exceptions. Masking irqs has no
+ * side effects for other flags. Keeping to this order makes it easier for
+ * entry.S to know which exceptions should be unmasked.
+ *
+ * FIQ is never expected, but we mask it when we disable debug exceptions, and
+ * unmask it at all other times.
+ */
+
+/*
  * CPU interrupt mask handling.
  */
 static inline unsigned long arch_local_irq_save(void)
@@ -89,26 +102,5 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
 {
 	return flags & PSR_I_BIT;
 }
-
-/*
- * save and restore debug state
- */
-#define local_dbg_save(flags)						\
-	do {								\
-		typecheck(unsigned long, flags);			\
-		asm volatile(						\
-		"mrs    %0, daif		// local_dbg_save\n"	\
-		"msr    daifset, #8"					\
-		: "=r" (flags) : : "memory");				\
-	} while (0)
-
-#define local_dbg_restore(flags)					\
-	do {								\
-		typecheck(unsigned long, flags);			\
-		asm volatile(						\
-		"msr    daif, %0		// local_dbg_restore\n"	\
-		: : "r" (flags) : "memory");				\
-	} while (0)
-
 #endif
 #endif
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index c7ef99904934..a88b6ccebbb4 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -30,6 +30,7 @@
 
 #include <asm/cpufeature.h>
 #include <asm/cputype.h>
+#include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/system_misc.h>
 
@@ -46,9 +47,9 @@ u8 debug_monitors_arch(void)
 static void mdscr_write(u32 mdscr)
 {
 	unsigned long flags;
-	local_dbg_save(flags);
+	flags = local_daif_save();
 	write_sysreg(mdscr, mdscr_el1);
-	local_dbg_restore(flags);
+	local_daif_restore(flags);
 }
 NOKPROBE_SYMBOL(mdscr_write);
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 03/21] arm64: Move the async/fiq helpers to explicitly set process context flags
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

Remove the local_{async,fiq}_{en,dis}able macros as they don't respect
our newly defined order and are only used to set the flags for process
context when we bring CPUs online.

Add a helper to do this. The IRQ flag varies as we want it masked on
the boot CPU until we are ready to handle interrupts.
The boot CPU unmasks SError during early boot once it can print an error
message. If we can print an error message about SError, we can do the
same for FIQ. Debug exceptions are already enabled by __cpu_setup(),
which has also configured MDSCR_EL1 to disable MDE and KDE.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Changes since v3:
 * swapped verb/daif word-order.

 arch/arm64/include/asm/daifflags.h | 3 +++
 arch/arm64/include/asm/irqflags.h  | 6 ------
 arch/arm64/kernel/setup.c          | 8 +++++---
 arch/arm64/kernel/smp.c            | 3 +--
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
index 55e2598a8c4c..22e4c83de5a5 100644
--- a/arch/arm64/include/asm/daifflags.h
+++ b/arch/arm64/include/asm/daifflags.h
@@ -18,6 +18,9 @@
 
 #include <linux/irqflags.h>
 
+#define DAIF_PROCCTX		0
+#define DAIF_PROCCTX_NOIRQ	PSR_I_BIT
+
 /* mask/save/unmask/restore all exceptions, including interrupts. */
 static inline void local_daif_mask(void)
 {
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index 9ecdca7011f0..24692edf1a69 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -66,12 +66,6 @@ static inline void arch_local_irq_disable(void)
 		: "memory");
 }
 
-#define local_fiq_enable()	asm("msr	daifclr, #1" : : : "memory")
-#define local_fiq_disable()	asm("msr	daifset, #1" : : : "memory")
-
-#define local_async_enable()	asm("msr	daifclr, #4" : : : "memory")
-#define local_async_disable()	asm("msr	daifset, #4" : : : "memory")
-
 /*
  * Save the current interrupt enable state.
  */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index d4b740538ad5..ad285f024934 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -48,6 +48,7 @@
 #include <asm/fixmap.h>
 #include <asm/cpu.h>
 #include <asm/cputype.h>
+#include <asm/daifflags.h>
 #include <asm/elf.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
@@ -262,10 +263,11 @@ void __init setup_arch(char **cmdline_p)
 	parse_early_param();
 
 	/*
-	 *  Unmask asynchronous aborts after bringing up possible earlycon.
-	 * (Report possible System Errors once we can report this occurred)
+	 * Unmask asynchronous aborts and fiq after bringing up possible
+	 * earlycon. (Report possible System Errors once we can report this
+	 * occurred).
 	 */
-	local_async_enable();
+	local_daif_restore(DAIF_PROCCTX_NOIRQ);
 
 	/*
 	 * TTBR0 is only used for the identity mapping at this stage. Make it
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 5a407eba01f7..d92e03faa51a 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -272,8 +272,7 @@ asmlinkage void secondary_start_kernel(void)
 	set_cpu_online(cpu, true);
 	complete(&cpu_running);
 
-	local_irq_enable();
-	local_async_enable();
+	local_daif_restore(DAIF_PROCCTX);
 
 	/*
 	 * OK, it's off to the idle thread for us
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 03/21] arm64: Move the async/fiq helpers to explicitly set process context flags
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the local_{async,fiq}_{en,dis}able macros as they don't respect
our newly defined order and are only used to set the flags for process
context when we bring CPUs online.

Add a helper to do this. The IRQ flag varies as we want it masked on
the boot CPU until we are ready to handle interrupts.
The boot CPU unmasks SError during early boot once it can print an error
message. If we can print an error message about SError, we can do the
same for FIQ. Debug exceptions are already enabled by __cpu_setup(),
which has also configured MDSCR_EL1 to disable MDE and KDE.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Changes since v3:
 * swapped verb/daif word-order.

 arch/arm64/include/asm/daifflags.h | 3 +++
 arch/arm64/include/asm/irqflags.h  | 6 ------
 arch/arm64/kernel/setup.c          | 8 +++++---
 arch/arm64/kernel/smp.c            | 3 +--
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
index 55e2598a8c4c..22e4c83de5a5 100644
--- a/arch/arm64/include/asm/daifflags.h
+++ b/arch/arm64/include/asm/daifflags.h
@@ -18,6 +18,9 @@
 
 #include <linux/irqflags.h>
 
+#define DAIF_PROCCTX		0
+#define DAIF_PROCCTX_NOIRQ	PSR_I_BIT
+
 /* mask/save/unmask/restore all exceptions, including interrupts. */
 static inline void local_daif_mask(void)
 {
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index 9ecdca7011f0..24692edf1a69 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -66,12 +66,6 @@ static inline void arch_local_irq_disable(void)
 		: "memory");
 }
 
-#define local_fiq_enable()	asm("msr	daifclr, #1" : : : "memory")
-#define local_fiq_disable()	asm("msr	daifset, #1" : : : "memory")
-
-#define local_async_enable()	asm("msr	daifclr, #4" : : : "memory")
-#define local_async_disable()	asm("msr	daifset, #4" : : : "memory")
-
 /*
  * Save the current interrupt enable state.
  */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index d4b740538ad5..ad285f024934 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -48,6 +48,7 @@
 #include <asm/fixmap.h>
 #include <asm/cpu.h>
 #include <asm/cputype.h>
+#include <asm/daifflags.h>
 #include <asm/elf.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
@@ -262,10 +263,11 @@ void __init setup_arch(char **cmdline_p)
 	parse_early_param();
 
 	/*
-	 *  Unmask asynchronous aborts after bringing up possible earlycon.
-	 * (Report possible System Errors once we can report this occurred)
+	 * Unmask asynchronous aborts and fiq after bringing up possible
+	 * earlycon. (Report possible System Errors once we can report this
+	 * occurred).
 	 */
-	local_async_enable();
+	local_daif_restore(DAIF_PROCCTX_NOIRQ);
 
 	/*
 	 * TTBR0 is only used for the identity mapping at this stage. Make it
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 5a407eba01f7..d92e03faa51a 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -272,8 +272,7 @@ asmlinkage void secondary_start_kernel(void)
 	set_cpu_online(cpu, true);
 	complete(&cpu_running);
 
-	local_irq_enable();
-	local_async_enable();
+	local_daif_restore(DAIF_PROCCTX);
 
 	/*
 	 * OK, it's off to the idle thread for us
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 04/21] arm64: Mask all exceptions during kernel_exit
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

To take RAS Exceptions as quickly as possible we need to keep SError
unmasked as much as possible. We need to mask it during kernel_exit
as taking an error from this code will overwrite the exception-registers.

Adding a naked 'disable_daif' to kernel_exit causes a performance problem
for micro-benchmarks that do no real work, (e.g. calling getpid() in a
loop). This is because the ret_to_user loop has already masked IRQs so
that the TIF_WORK_MASK thread flags can't change underneath it, adding
disable_daif is an additional self-synchronising operation.

In the future, the RAS APEI code may need to modify the TIF_WORK_MASK
flags from an SError, in which case the ret_to_user loop must mask SError
while it examines the flags.

Disable all exceptions for return to EL1. For return to EL0 get the
ret_to_user loop to leave all exceptions masked once it has done its
work, this avoids an extra pstate-write.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Changes since v3:
* swapped verb/daif word-order.

 arch/arm64/kernel/entry.S  | 10 +++++-----
 arch/arm64/kernel/signal.c |  8 ++++++--
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index e1c59d4008a8..f7d7bf9d76e7 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -221,6 +221,8 @@ alternative_else_nop_endif
 
 	.macro	kernel_exit, el
 	.if	\el != 0
+	disable_daif
+
 	/* Restore the task's original addr_limit. */
 	ldr	x20, [sp, #S_ORIG_ADDR_LIMIT]
 	str	x20, [tsk, #TSK_TI_ADDR_LIMIT]
@@ -517,8 +519,6 @@ el1_da:
 	mov	x2, sp				// struct pt_regs
 	bl	do_mem_abort
 
-	// disable interrupts before pulling preserved data off the stack
-	disable_irq
 	kernel_exit 1
 el1_sp_pc:
 	/*
@@ -793,7 +793,7 @@ ENDPROC(el0_irq)
  * and this includes saving x0 back into the kernel stack.
  */
 ret_fast_syscall:
-	disable_irq				// disable interrupts
+	disable_daif
 	str	x0, [sp, #S_X0]			// returned x0
 	ldr	x1, [tsk, #TSK_TI_FLAGS]	// re-check for syscall tracing
 	and	x2, x1, #_TIF_SYSCALL_WORK
@@ -803,7 +803,7 @@ ret_fast_syscall:
 	enable_step_tsk x1, x2
 	kernel_exit 0
 ret_fast_syscall_trace:
-	enable_irq				// enable interrupts
+	enable_daif
 	b	__sys_trace_return_skipped	// we already saved x0
 
 /*
@@ -821,7 +821,7 @@ work_pending:
  * "slow" syscall return path.
  */
 ret_to_user:
-	disable_irq				// disable interrupts
+	disable_daif
 	ldr	x1, [tsk, #TSK_TI_FLAGS]
 	and	x2, x1, #_TIF_WORK_MASK
 	cbnz	x2, work_pending
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 0bdc96c61bc0..8e6500c9471b 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -31,6 +31,7 @@
 #include <linux/ratelimit.h>
 #include <linux/syscalls.h>
 
+#include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/elf.h>
 #include <asm/cacheflush.h>
@@ -756,9 +757,12 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 		addr_limit_user_check();
 
 		if (thread_flags & _TIF_NEED_RESCHED) {
+			/* Unmask Debug and SError for the next task */
+			local_daif_restore(DAIF_PROCCTX_NOIRQ);
+
 			schedule();
 		} else {
-			local_irq_enable();
+			local_daif_restore(DAIF_PROCCTX);
 
 			if (thread_flags & _TIF_UPROBE)
 				uprobe_notify_resume(regs);
@@ -775,7 +779,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 				fpsimd_restore_current_state();
 		}
 
-		local_irq_disable();
+		local_daif_mask();
 		thread_flags = READ_ONCE(current_thread_info()->flags);
 	} while (thread_flags & _TIF_WORK_MASK);
 }
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 04/21] arm64: Mask all exceptions during kernel_exit
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

To take RAS Exceptions as quickly as possible we need to keep SError
unmasked as much as possible. We need to mask it during kernel_exit
as taking an error from this code will overwrite the exception-registers.

Adding a naked 'disable_daif' to kernel_exit causes a performance problem
for micro-benchmarks that do no real work, (e.g. calling getpid() in a
loop). This is because the ret_to_user loop has already masked IRQs so
that the TIF_WORK_MASK thread flags can't change underneath it, adding
disable_daif is an additional self-synchronising operation.

In the future, the RAS APEI code may need to modify the TIF_WORK_MASK
flags from an SError, in which case the ret_to_user loop must mask SError
while it examines the flags.

Disable all exceptions for return to EL1. For return to EL0 get the
ret_to_user loop to leave all exceptions masked once it has done its
work, this avoids an extra pstate-write.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Changes since v3:
* swapped verb/daif word-order.

 arch/arm64/kernel/entry.S  | 10 +++++-----
 arch/arm64/kernel/signal.c |  8 ++++++--
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index e1c59d4008a8..f7d7bf9d76e7 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -221,6 +221,8 @@ alternative_else_nop_endif
 
 	.macro	kernel_exit, el
 	.if	\el != 0
+	disable_daif
+
 	/* Restore the task's original addr_limit. */
 	ldr	x20, [sp, #S_ORIG_ADDR_LIMIT]
 	str	x20, [tsk, #TSK_TI_ADDR_LIMIT]
@@ -517,8 +519,6 @@ el1_da:
 	mov	x2, sp				// struct pt_regs
 	bl	do_mem_abort
 
-	// disable interrupts before pulling preserved data off the stack
-	disable_irq
 	kernel_exit 1
 el1_sp_pc:
 	/*
@@ -793,7 +793,7 @@ ENDPROC(el0_irq)
  * and this includes saving x0 back into the kernel stack.
  */
 ret_fast_syscall:
-	disable_irq				// disable interrupts
+	disable_daif
 	str	x0, [sp, #S_X0]			// returned x0
 	ldr	x1, [tsk, #TSK_TI_FLAGS]	// re-check for syscall tracing
 	and	x2, x1, #_TIF_SYSCALL_WORK
@@ -803,7 +803,7 @@ ret_fast_syscall:
 	enable_step_tsk x1, x2
 	kernel_exit 0
 ret_fast_syscall_trace:
-	enable_irq				// enable interrupts
+	enable_daif
 	b	__sys_trace_return_skipped	// we already saved x0
 
 /*
@@ -821,7 +821,7 @@ work_pending:
  * "slow" syscall return path.
  */
 ret_to_user:
-	disable_irq				// disable interrupts
+	disable_daif
 	ldr	x1, [tsk, #TSK_TI_FLAGS]
 	and	x2, x1, #_TIF_WORK_MASK
 	cbnz	x2, work_pending
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 0bdc96c61bc0..8e6500c9471b 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -31,6 +31,7 @@
 #include <linux/ratelimit.h>
 #include <linux/syscalls.h>
 
+#include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
 #include <asm/elf.h>
 #include <asm/cacheflush.h>
@@ -756,9 +757,12 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 		addr_limit_user_check();
 
 		if (thread_flags & _TIF_NEED_RESCHED) {
+			/* Unmask Debug and SError for the next task */
+			local_daif_restore(DAIF_PROCCTX_NOIRQ);
+
 			schedule();
 		} else {
-			local_irq_enable();
+			local_daif_restore(DAIF_PROCCTX);
 
 			if (thread_flags & _TIF_UPROBE)
 				uprobe_notify_resume(regs);
@@ -775,7 +779,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 				fpsimd_restore_current_state();
 		}
 
-		local_irq_disable();
+		local_daif_mask();
 		thread_flags = READ_ONCE(current_thread_info()->flags);
 	} while (thread_flags & _TIF_WORK_MASK);
 }
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 05/21] arm64: entry.S: Remove disable_dbg
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

enable_step_tsk is the only user of disable_dbg, which doesn't respect
our 'dai' order for exception masking. enable_step_tsk may enable
single-step, so previously needed to mask debug exceptions to prevent us
from single-stepping kernel_exit. enable_step_tsk is called at the end
of the ret_to_user loop, which has already masked all exceptions so this
is no longer needed.

Remove disable_dbg, add a comment that enable_step_tsk's caller should
have masked debug.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/assembler.h | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 114e741ca873..1b0972046a72 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -68,13 +68,6 @@
 	msr	daif, \flags
 	.endm
 
-/*
- * Enable and disable debug exceptions.
- */
-	.macro	disable_dbg
-	msr	daifset, #8
-	.endm
-
 	.macro	enable_dbg
 	msr	daifclr, #8
 	.endm
@@ -88,9 +81,9 @@
 9990:
 	.endm
 
+	/* call with daif masked */
 	.macro	enable_step_tsk, flgs, tmp
 	tbz	\flgs, #TIF_SINGLESTEP, 9990f
-	disable_dbg
 	mrs	\tmp, mdscr_el1
 	orr	\tmp, \tmp, #1
 	msr	mdscr_el1, \tmp
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 05/21] arm64: entry.S: Remove disable_dbg
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

enable_step_tsk is the only user of disable_dbg, which doesn't respect
our 'dai' order for exception masking. enable_step_tsk may enable
single-step, so previously needed to mask debug exceptions to prevent us
from single-stepping kernel_exit. enable_step_tsk is called at the end
of the ret_to_user loop, which has already masked all exceptions so this
is no longer needed.

Remove disable_dbg, add a comment that enable_step_tsk's caller should
have masked debug.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/assembler.h | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 114e741ca873..1b0972046a72 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -68,13 +68,6 @@
 	msr	daif, \flags
 	.endm
 
-/*
- * Enable and disable debug exceptions.
- */
-	.macro	disable_dbg
-	msr	daifset, #8
-	.endm
-
 	.macro	enable_dbg
 	msr	daifclr, #8
 	.endm
@@ -88,9 +81,9 @@
 9990:
 	.endm
 
+	/* call with daif masked */
 	.macro	enable_step_tsk, flgs, tmp
 	tbz	\flgs, #TIF_SINGLESTEP, 9990f
-	disable_dbg
 	mrs	\tmp, mdscr_el1
 	orr	\tmp, \tmp, #1
 	msr	mdscr_el1, \tmp
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 06/21] arm64: entry.S: convert el1_sync
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

el1_sync unmasks exceptions on a case-by-case basis, debug exceptions
are unmasked, unless this was a debug exception. IRQs are unmasked
for instruction and data aborts only if the interupted context had
irqs unmasked.

Following our 'dai' order, el1_dbg should run with everything masked.
For the other cases we can inherit whatever we interrupted.

Add a macro inherit_daif to set daif based on the interrupted pstate.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/assembler.h |  6 ++++++
 arch/arm64/kernel/entry.S          | 12 ++++--------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 1b0972046a72..abb5abd61ddb 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -48,6 +48,12 @@
 	msr	daif, \flags
 	.endm
 
+	/* Only on aarch64 pstate, PSR_D_BIT is different for aarch32 */
+	.macro	inherit_daif, pstate:req, tmp:req
+	and	\tmp, \pstate, #(PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
+	msr	daif, \tmp
+	.endm
+
 /*
  * Enable and disable interrupts.
  */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index f7d7bf9d76e7..bd54115972a4 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -510,11 +510,7 @@ el1_da:
 	 * Data abort handling
 	 */
 	mrs	x3, far_el1
-	enable_dbg
-	// re-enable interrupts if they were enabled in the aborted context
-	tbnz	x23, #7, 1f			// PSR_I_BIT
-	enable_irq
-1:
+	inherit_daif	pstate=x23, tmp=x2
 	clear_address_tag x0, x3
 	mov	x2, sp				// struct pt_regs
 	bl	do_mem_abort
@@ -525,7 +521,7 @@ el1_sp_pc:
 	 * Stack or PC alignment exception handling
 	 */
 	mrs	x0, far_el1
-	enable_dbg
+	inherit_daif	pstate=x23, tmp=x2
 	mov	x2, sp
 	bl	do_sp_pc_abort
 	ASM_BUG()
@@ -533,7 +529,7 @@ el1_undef:
 	/*
 	 * Undefined instruction
 	 */
-	enable_dbg
+	inherit_daif	pstate=x23, tmp=x2
 	mov	x0, sp
 	bl	do_undefinstr
 	ASM_BUG()
@@ -550,7 +546,7 @@ el1_dbg:
 	kernel_exit 1
 el1_inv:
 	// TODO: add support for undefined instructions in kernel mode
-	enable_dbg
+	inherit_daif	pstate=x23, tmp=x2
 	mov	x0, sp
 	mov	x2, x1
 	mov	x1, #BAD_SYNC
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 06/21] arm64: entry.S: convert el1_sync
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

el1_sync unmasks exceptions on a case-by-case basis, debug exceptions
are unmasked, unless this was a debug exception. IRQs are unmasked
for instruction and data aborts only if the interupted context had
irqs unmasked.

Following our 'dai' order, el1_dbg should run with everything masked.
For the other cases we can inherit whatever we interrupted.

Add a macro inherit_daif to set daif based on the interrupted pstate.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/assembler.h |  6 ++++++
 arch/arm64/kernel/entry.S          | 12 ++++--------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 1b0972046a72..abb5abd61ddb 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -48,6 +48,12 @@
 	msr	daif, \flags
 	.endm
 
+	/* Only on aarch64 pstate, PSR_D_BIT is different for aarch32 */
+	.macro	inherit_daif, pstate:req, tmp:req
+	and	\tmp, \pstate, #(PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
+	msr	daif, \tmp
+	.endm
+
 /*
  * Enable and disable interrupts.
  */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index f7d7bf9d76e7..bd54115972a4 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -510,11 +510,7 @@ el1_da:
 	 * Data abort handling
 	 */
 	mrs	x3, far_el1
-	enable_dbg
-	// re-enable interrupts if they were enabled in the aborted context
-	tbnz	x23, #7, 1f			// PSR_I_BIT
-	enable_irq
-1:
+	inherit_daif	pstate=x23, tmp=x2
 	clear_address_tag x0, x3
 	mov	x2, sp				// struct pt_regs
 	bl	do_mem_abort
@@ -525,7 +521,7 @@ el1_sp_pc:
 	 * Stack or PC alignment exception handling
 	 */
 	mrs	x0, far_el1
-	enable_dbg
+	inherit_daif	pstate=x23, tmp=x2
 	mov	x2, sp
 	bl	do_sp_pc_abort
 	ASM_BUG()
@@ -533,7 +529,7 @@ el1_undef:
 	/*
 	 * Undefined instruction
 	 */
-	enable_dbg
+	inherit_daif	pstate=x23, tmp=x2
 	mov	x0, sp
 	bl	do_undefinstr
 	ASM_BUG()
@@ -550,7 +546,7 @@ el1_dbg:
 	kernel_exit 1
 el1_inv:
 	// TODO: add support for undefined instructions in kernel mode
-	enable_dbg
+	inherit_daif	pstate=x23, tmp=x2
 	mov	x0, sp
 	mov	x2, x1
 	mov	x1, #BAD_SYNC
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 07/21] arm64: entry.S convert el0_sync
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

el0_sync also unmasks exceptions on a case-by-case basis, debug exceptions
are enabled, unless this was a debug exception. Irqs are unmasked for
some exception types but not for others.

el0_dbg should run with everything masked to prevent us taking a debug
exception from do_debug_exception. For the other cases we can unmask
everything. This changes the behaviour of fpsimd_{acc,exc} and el0_inv
which previously ran with irqs masked.

This patch removed the last user of enable_dbg_and_irq, remove it.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/assembler.h |  9 ---------
 arch/arm64/kernel/entry.S          | 24 ++++++++++--------------
 2 files changed, 10 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index abb5abd61ddb..c2a37e2f733c 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -97,15 +97,6 @@
 	.endm
 
 /*
- * Enable both debug exceptions and interrupts. This is likely to be
- * faster than two daifclr operations, since writes to this register
- * are self-synchronising.
- */
-	.macro	enable_dbg_and_irq
-	msr	daifclr, #(8 | 2)
-	.endm
-
-/*
  * SMP data memory barrier
  */
 	.macro	smp_dmb, opt
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index bd54115972a4..f7dfe5d2b1fb 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -670,8 +670,7 @@ el0_da:
 	 * Data abort handling
 	 */
 	mrs	x26, far_el1
-	// enable interrupts before calling the main handler
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	clear_address_tag x0, x26
 	mov	x1, x25
@@ -683,8 +682,7 @@ el0_ia:
 	 * Instruction abort handling
 	 */
 	mrs	x26, far_el1
-	// enable interrupts before calling the main handler
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	mov	x0, x26
 	mov	x1, x25
@@ -695,7 +693,7 @@ el0_fpsimd_acc:
 	/*
 	 * Floating Point or Advanced SIMD access
 	 */
-	enable_dbg
+	enable_daif
 	ct_user_exit
 	mov	x0, x25
 	mov	x1, sp
@@ -705,7 +703,7 @@ el0_fpsimd_exc:
 	/*
 	 * Floating Point or Advanced SIMD exception
 	 */
-	enable_dbg
+	enable_daif
 	ct_user_exit
 	mov	x0, x25
 	mov	x1, sp
@@ -716,8 +714,7 @@ el0_sp_pc:
 	 * Stack or PC alignment exception handling
 	 */
 	mrs	x26, far_el1
-	// enable interrupts before calling the main handler
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	mov	x0, x26
 	mov	x1, x25
@@ -728,8 +725,7 @@ el0_undef:
 	/*
 	 * Undefined instruction
 	 */
-	// enable interrupts before calling the main handler
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	mov	x0, sp
 	bl	do_undefinstr
@@ -738,7 +734,7 @@ el0_sys:
 	/*
 	 * System instructions, for trapped cache maintenance instructions
 	 */
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	mov	x0, x25
 	mov	x1, sp
@@ -753,11 +749,11 @@ el0_dbg:
 	mov	x1, x25
 	mov	x2, sp
 	bl	do_debug_exception
-	enable_dbg
+	enable_daif
 	ct_user_exit
 	b	ret_to_user
 el0_inv:
-	enable_dbg
+	enable_daif
 	ct_user_exit
 	mov	x0, sp
 	mov	x1, #BAD_SYNC
@@ -836,7 +832,7 @@ el0_svc:
 	mov	wsc_nr, #__NR_syscalls
 el0_svc_naked:					// compat entry point
 	stp	x0, xscno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit 1
 
 	ldr	x16, [tsk, #TSK_TI_FLAGS]	// check for syscall hooks
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 07/21] arm64: entry.S convert el0_sync
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

el0_sync also unmasks exceptions on a case-by-case basis, debug exceptions
are enabled, unless this was a debug exception. Irqs are unmasked for
some exception types but not for others.

el0_dbg should run with everything masked to prevent us taking a debug
exception from do_debug_exception. For the other cases we can unmask
everything. This changes the behaviour of fpsimd_{acc,exc} and el0_inv
which previously ran with irqs masked.

This patch removed the last user of enable_dbg_and_irq, remove it.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/assembler.h |  9 ---------
 arch/arm64/kernel/entry.S          | 24 ++++++++++--------------
 2 files changed, 10 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index abb5abd61ddb..c2a37e2f733c 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -97,15 +97,6 @@
 	.endm
 
 /*
- * Enable both debug exceptions and interrupts. This is likely to be
- * faster than two daifclr operations, since writes to this register
- * are self-synchronising.
- */
-	.macro	enable_dbg_and_irq
-	msr	daifclr, #(8 | 2)
-	.endm
-
-/*
  * SMP data memory barrier
  */
 	.macro	smp_dmb, opt
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index bd54115972a4..f7dfe5d2b1fb 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -670,8 +670,7 @@ el0_da:
 	 * Data abort handling
 	 */
 	mrs	x26, far_el1
-	// enable interrupts before calling the main handler
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	clear_address_tag x0, x26
 	mov	x1, x25
@@ -683,8 +682,7 @@ el0_ia:
 	 * Instruction abort handling
 	 */
 	mrs	x26, far_el1
-	// enable interrupts before calling the main handler
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	mov	x0, x26
 	mov	x1, x25
@@ -695,7 +693,7 @@ el0_fpsimd_acc:
 	/*
 	 * Floating Point or Advanced SIMD access
 	 */
-	enable_dbg
+	enable_daif
 	ct_user_exit
 	mov	x0, x25
 	mov	x1, sp
@@ -705,7 +703,7 @@ el0_fpsimd_exc:
 	/*
 	 * Floating Point or Advanced SIMD exception
 	 */
-	enable_dbg
+	enable_daif
 	ct_user_exit
 	mov	x0, x25
 	mov	x1, sp
@@ -716,8 +714,7 @@ el0_sp_pc:
 	 * Stack or PC alignment exception handling
 	 */
 	mrs	x26, far_el1
-	// enable interrupts before calling the main handler
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	mov	x0, x26
 	mov	x1, x25
@@ -728,8 +725,7 @@ el0_undef:
 	/*
 	 * Undefined instruction
 	 */
-	// enable interrupts before calling the main handler
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	mov	x0, sp
 	bl	do_undefinstr
@@ -738,7 +734,7 @@ el0_sys:
 	/*
 	 * System instructions, for trapped cache maintenance instructions
 	 */
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit
 	mov	x0, x25
 	mov	x1, sp
@@ -753,11 +749,11 @@ el0_dbg:
 	mov	x1, x25
 	mov	x2, sp
 	bl	do_debug_exception
-	enable_dbg
+	enable_daif
 	ct_user_exit
 	b	ret_to_user
 el0_inv:
-	enable_dbg
+	enable_daif
 	ct_user_exit
 	mov	x0, sp
 	mov	x1, #BAD_SYNC
@@ -836,7 +832,7 @@ el0_svc:
 	mov	wsc_nr, #__NR_syscalls
 el0_svc_naked:					// compat entry point
 	stp	x0, xscno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
-	enable_dbg_and_irq
+	enable_daif
 	ct_user_exit 1
 
 	ldr	x16, [tsk, #TSK_TI_FLAGS]	// check for syscall hooks
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 08/21] arm64: entry.S: convert elX_irq
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

Following our 'dai' order, irqs should be processed with debug and
serror exceptions unmasked.

Add a helper to unmask these two, (and fiq for good measure).

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Changes since v3:
* Added comment against enable_da_f

 arch/arm64/include/asm/assembler.h | 5 +++++
 arch/arm64/kernel/entry.S          | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index c2a37e2f733c..e4ac505b7b3d 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -54,6 +54,11 @@
 	msr	daif, \tmp
 	.endm
 
+	/* IRQ is the lowest priority flag, unconditionally unmask the rest. */
+	.macro enable_da_f
+	msr	daifclr, #(8 | 4 | 1)
+	.endm
+
 /*
  * Enable and disable interrupts.
  */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index f7dfe5d2b1fb..df085ec003b0 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -557,7 +557,7 @@ ENDPROC(el1_sync)
 	.align	6
 el1_irq:
 	kernel_entry 1
-	enable_dbg
+	enable_da_f
 #ifdef CONFIG_TRACE_IRQFLAGS
 	bl	trace_hardirqs_off
 #endif
@@ -766,7 +766,7 @@ ENDPROC(el0_sync)
 el0_irq:
 	kernel_entry 0
 el0_irq_naked:
-	enable_dbg
+	enable_da_f
 #ifdef CONFIG_TRACE_IRQFLAGS
 	bl	trace_hardirqs_off
 #endif
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 08/21] arm64: entry.S: convert elX_irq
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Following our 'dai' order, irqs should be processed with debug and
serror exceptions unmasked.

Add a helper to unmask these two, (and fiq for good measure).

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Julien Thierry <julien.thierry@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Changes since v3:
* Added comment against enable_da_f

 arch/arm64/include/asm/assembler.h | 5 +++++
 arch/arm64/kernel/entry.S          | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index c2a37e2f733c..e4ac505b7b3d 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -54,6 +54,11 @@
 	msr	daif, \tmp
 	.endm
 
+	/* IRQ is the lowest priority flag, unconditionally unmask the rest. */
+	.macro enable_da_f
+	msr	daifclr, #(8 | 4 | 1)
+	.endm
+
 /*
  * Enable and disable interrupts.
  */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index f7dfe5d2b1fb..df085ec003b0 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -557,7 +557,7 @@ ENDPROC(el1_sync)
 	.align	6
 el1_irq:
 	kernel_entry 1
-	enable_dbg
+	enable_da_f
 #ifdef CONFIG_TRACE_IRQFLAGS
 	bl	trace_hardirqs_off
 #endif
@@ -766,7 +766,7 @@ ENDPROC(el0_sync)
 el0_irq:
 	kernel_entry 0
 el0_irq_naked:
-	enable_dbg
+	enable_da_f
 #ifdef CONFIG_TRACE_IRQFLAGS
 	bl	trace_hardirqs_off
 #endif
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

Non-VHE systems take an exception to EL2 in order to world-switch into the
guest. When returning from the guest KVM implicitly restores the DAIF
flags when it returns to the kernel at EL1.

With VHE none of this exception-level jumping happens, so KVMs
world-switch code is exposed to the host kernel's DAIF values, and KVM
spills the guest-exit DAIF values back into the host kernel.
On entry to a guest we have Debug and SError exceptions unmasked, KVM
has switched VBAR but isn't prepared to handle these. On guest exit
Debug exceptions are left disabled once we return to the host and will
stay this way until we enter user space.

Add a helper to mask/unmask DAIF around VHE guests. The unmask can only
happen after the hosts VBAR value has been synchronised by the isb in
__vhe_hyp_call (via kvm_call_hyp()). Masking could be as late as
setting KVMs VBAR value, but is kept here for symmetry.

Signed-off-by: James Morse <james.morse@arm.com>

---
Give me a kick if you want this reworked as a fix (which will then
conflict with this series), or a backportable version.

 arch/arm64/include/asm/kvm_host.h | 10 ++++++++++
 virt/kvm/arm/arm.c                |  4 ++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e923b58606e2..a0e2f7962401 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/kvm_types.h>
 #include <asm/cpufeature.h>
+#include <asm/daifflags.h>
 #include <asm/kvm.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmio.h>
@@ -384,4 +385,13 @@ static inline void __cpu_init_stage2(void)
 		  "PARange is %d bits, unsupported configuration!", parange);
 }
 
+static inline void kvm_arm_vhe_guest_enter(void)
+{
+	local_daif_mask();
+}
+
+static inline void kvm_arm_vhe_guest_exit(void)
+{
+	local_daif_restore(DAIF_PROCCTX_NOIRQ);
+}
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index b9f68e4add71..665529924b34 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -698,9 +698,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		 */
 		trace_kvm_entry(*vcpu_pc(vcpu));
 		guest_enter_irqoff();
+		if (has_vhe())
+			kvm_arm_vhe_guest_enter();
 
 		ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
 
+		if (has_vhe())
+			kvm_arm_vhe_guest_exit();
 		vcpu->mode = OUTSIDE_GUEST_MODE;
 		vcpu->stat.exits++;
 		/*
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Non-VHE systems take an exception to EL2 in order to world-switch into the
guest. When returning from the guest KVM implicitly restores the DAIF
flags when it returns to the kernel at EL1.

With VHE none of this exception-level jumping happens, so KVMs
world-switch code is exposed to the host kernel's DAIF values, and KVM
spills the guest-exit DAIF values back into the host kernel.
On entry to a guest we have Debug and SError exceptions unmasked, KVM
has switched VBAR but isn't prepared to handle these. On guest exit
Debug exceptions are left disabled once we return to the host and will
stay this way until we enter user space.

Add a helper to mask/unmask DAIF around VHE guests. The unmask can only
happen after the hosts VBAR value has been synchronised by the isb in
__vhe_hyp_call (via kvm_call_hyp()). Masking could be as late as
setting KVMs VBAR value, but is kept here for symmetry.

Signed-off-by: James Morse <james.morse@arm.com>

---
Give me a kick if you want this reworked as a fix (which will then
conflict with this series), or a backportable version.

 arch/arm64/include/asm/kvm_host.h | 10 ++++++++++
 virt/kvm/arm/arm.c                |  4 ++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e923b58606e2..a0e2f7962401 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/kvm_types.h>
 #include <asm/cpufeature.h>
+#include <asm/daifflags.h>
 #include <asm/kvm.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmio.h>
@@ -384,4 +385,13 @@ static inline void __cpu_init_stage2(void)
 		  "PARange is %d bits, unsupported configuration!", parange);
 }
 
+static inline void kvm_arm_vhe_guest_enter(void)
+{
+	local_daif_mask();
+}
+
+static inline void kvm_arm_vhe_guest_exit(void)
+{
+	local_daif_restore(DAIF_PROCCTX_NOIRQ);
+}
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index b9f68e4add71..665529924b34 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -698,9 +698,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		 */
 		trace_kvm_entry(*vcpu_pc(vcpu));
 		guest_enter_irqoff();
+		if (has_vhe())
+			kvm_arm_vhe_guest_enter();
 
 		ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
 
+		if (has_vhe())
+			kvm_arm_vhe_guest_exit();
 		vcpu->mode = OUTSIDE_GUEST_MODE;
 		vcpu->stat.exits++;
 		/*
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 10/21] arm64: entry.S: move SError handling into a C function for future expansion
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Wang Xiongfeng, Dongjiu Geng,
	kvmarm

From: Xie XiuQi <xiexiuqi@huawei.com>

Today SError is taken using the inv_entry macro that ends up in
bad_mode.

SError can be used by the RAS Extensions to notify either the OS or
firmware of CPU problems, some of which may have been corrected.

To allow this handling to be added, add a do_serror() C function
that just panic()s. Add the entry.S boiler plate to save/restore the
CPU registers and unmask debug exceptions. Future patches may change
do_serror() to return if the SError Interrupt was notification of a
corrected error.

Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: Wang Xiongfeng <wangxiongfengi2@huawei.com>
[Split out of a bigger patch, added compat path, renamed, enabled debug
 exceptions]
Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/Kconfig        |  2 +-
 arch/arm64/kernel/entry.S | 36 +++++++++++++++++++++++++++++-------
 arch/arm64/kernel/traps.c | 13 +++++++++++++
 3 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0df64a6a56d4..70dfe4e9ccc5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -98,7 +98,7 @@ config ARM64
 	select HAVE_IRQ_TIME_ACCOUNTING
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP if NUMA
-	select HAVE_NMI if ACPI_APEI_SEA
+	select HAVE_NMI
 	select HAVE_PATA_PLATFORM
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index df085ec003b0..e147c1d00b41 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -375,18 +375,18 @@ ENTRY(vectors)
 	kernel_ventry	el1_sync			// Synchronous EL1h
 	kernel_ventry	el1_irq				// IRQ EL1h
 	kernel_ventry	el1_fiq_invalid			// FIQ EL1h
-	kernel_ventry	el1_error_invalid		// Error EL1h
+	kernel_ventry	el1_error			// Error EL1h
 
 	kernel_ventry	el0_sync			// Synchronous 64-bit EL0
 	kernel_ventry	el0_irq				// IRQ 64-bit EL0
 	kernel_ventry	el0_fiq_invalid			// FIQ 64-bit EL0
-	kernel_ventry	el0_error_invalid		// Error 64-bit EL0
+	kernel_ventry	el0_error			// Error 64-bit EL0
 
 #ifdef CONFIG_COMPAT
 	kernel_ventry	el0_sync_compat			// Synchronous 32-bit EL0
 	kernel_ventry	el0_irq_compat			// IRQ 32-bit EL0
 	kernel_ventry	el0_fiq_invalid_compat		// FIQ 32-bit EL0
-	kernel_ventry	el0_error_invalid_compat	// Error 32-bit EL0
+	kernel_ventry	el0_error_compat		// Error 32-bit EL0
 #else
 	kernel_ventry	el0_sync_invalid		// Synchronous 32-bit EL0
 	kernel_ventry	el0_irq_invalid			// IRQ 32-bit EL0
@@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid)
 el0_fiq_invalid_compat:
 	inv_entry 0, BAD_FIQ, 32
 ENDPROC(el0_fiq_invalid_compat)
-
-el0_error_invalid_compat:
-	inv_entry 0, BAD_ERROR, 32
-ENDPROC(el0_error_invalid_compat)
 #endif
 
 el1_sync_invalid:
@@ -663,6 +659,10 @@ el0_svc_compat:
 el0_irq_compat:
 	kernel_entry 0, 32
 	b	el0_irq_naked
+
+el0_error_compat:
+	kernel_entry 0, 32
+	b	el0_error_naked
 #endif
 
 el0_da:
@@ -780,6 +780,28 @@ el0_irq_naked:
 	b	ret_to_user
 ENDPROC(el0_irq)
 
+el1_error:
+	kernel_entry 1
+	mrs	x1, esr_el1
+	enable_dbg
+	mov	x0, sp
+	bl	do_serror
+	kernel_exit 1
+ENDPROC(el1_error)
+
+el0_error:
+	kernel_entry 0
+el0_error_naked:
+	mrs	x1, esr_el1
+	enable_dbg
+	mov	x0, sp
+	bl	do_serror
+	enable_daif
+	ct_user_exit
+	b	ret_to_user
+ENDPROC(el0_error)
+
+
 /*
  * This is the fast syscall return path.  We do as little as possible here,
  * and this includes saving x0 back into the kernel stack.
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 1808be65d22f..773aae69c376 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -709,6 +709,19 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
 }
 #endif
 
+asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
+{
+	nmi_enter();
+
+	console_verbose();
+
+	pr_crit("SError Interrupt on CPU%d, code 0x%08x -- %s\n",
+		smp_processor_id(), esr, esr_get_class_string(esr));
+	__show_regs(regs);
+
+	panic("Asynchronous SError Interrupt");
+}
+
 void __pte_error(const char *file, int line, unsigned long val)
 {
 	pr_err("%s:%d: bad pte %016lx.\n", file, line, val);
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 10/21] arm64: entry.S: move SError handling into a C function for future expansion
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Xie XiuQi <xiexiuqi@huawei.com>

Today SError is taken using the inv_entry macro that ends up in
bad_mode.

SError can be used by the RAS Extensions to notify either the OS or
firmware of CPU problems, some of which may have been corrected.

To allow this handling to be added, add a do_serror() C function
that just panic()s. Add the entry.S boiler plate to save/restore the
CPU registers and unmask debug exceptions. Future patches may change
do_serror() to return if the SError Interrupt was notification of a
corrected error.

Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: Wang Xiongfeng <wangxiongfengi2@huawei.com>
[Split out of a bigger patch, added compat path, renamed, enabled debug
 exceptions]
Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/Kconfig        |  2 +-
 arch/arm64/kernel/entry.S | 36 +++++++++++++++++++++++++++++-------
 arch/arm64/kernel/traps.c | 13 +++++++++++++
 3 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0df64a6a56d4..70dfe4e9ccc5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -98,7 +98,7 @@ config ARM64
 	select HAVE_IRQ_TIME_ACCOUNTING
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP if NUMA
-	select HAVE_NMI if ACPI_APEI_SEA
+	select HAVE_NMI
 	select HAVE_PATA_PLATFORM
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index df085ec003b0..e147c1d00b41 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -375,18 +375,18 @@ ENTRY(vectors)
 	kernel_ventry	el1_sync			// Synchronous EL1h
 	kernel_ventry	el1_irq				// IRQ EL1h
 	kernel_ventry	el1_fiq_invalid			// FIQ EL1h
-	kernel_ventry	el1_error_invalid		// Error EL1h
+	kernel_ventry	el1_error			// Error EL1h
 
 	kernel_ventry	el0_sync			// Synchronous 64-bit EL0
 	kernel_ventry	el0_irq				// IRQ 64-bit EL0
 	kernel_ventry	el0_fiq_invalid			// FIQ 64-bit EL0
-	kernel_ventry	el0_error_invalid		// Error 64-bit EL0
+	kernel_ventry	el0_error			// Error 64-bit EL0
 
 #ifdef CONFIG_COMPAT
 	kernel_ventry	el0_sync_compat			// Synchronous 32-bit EL0
 	kernel_ventry	el0_irq_compat			// IRQ 32-bit EL0
 	kernel_ventry	el0_fiq_invalid_compat		// FIQ 32-bit EL0
-	kernel_ventry	el0_error_invalid_compat	// Error 32-bit EL0
+	kernel_ventry	el0_error_compat		// Error 32-bit EL0
 #else
 	kernel_ventry	el0_sync_invalid		// Synchronous 32-bit EL0
 	kernel_ventry	el0_irq_invalid			// IRQ 32-bit EL0
@@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid)
 el0_fiq_invalid_compat:
 	inv_entry 0, BAD_FIQ, 32
 ENDPROC(el0_fiq_invalid_compat)
-
-el0_error_invalid_compat:
-	inv_entry 0, BAD_ERROR, 32
-ENDPROC(el0_error_invalid_compat)
 #endif
 
 el1_sync_invalid:
@@ -663,6 +659,10 @@ el0_svc_compat:
 el0_irq_compat:
 	kernel_entry 0, 32
 	b	el0_irq_naked
+
+el0_error_compat:
+	kernel_entry 0, 32
+	b	el0_error_naked
 #endif
 
 el0_da:
@@ -780,6 +780,28 @@ el0_irq_naked:
 	b	ret_to_user
 ENDPROC(el0_irq)
 
+el1_error:
+	kernel_entry 1
+	mrs	x1, esr_el1
+	enable_dbg
+	mov	x0, sp
+	bl	do_serror
+	kernel_exit 1
+ENDPROC(el1_error)
+
+el0_error:
+	kernel_entry 0
+el0_error_naked:
+	mrs	x1, esr_el1
+	enable_dbg
+	mov	x0, sp
+	bl	do_serror
+	enable_daif
+	ct_user_exit
+	b	ret_to_user
+ENDPROC(el0_error)
+
+
 /*
  * This is the fast syscall return path.  We do as little as possible here,
  * and this includes saving x0 back into the kernel stack.
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 1808be65d22f..773aae69c376 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -709,6 +709,19 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
 }
 #endif
 
+asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
+{
+	nmi_enter();
+
+	console_verbose();
+
+	pr_crit("SError Interrupt on CPU%d, code 0x%08x -- %s\n",
+		smp_processor_id(), esr, esr_get_class_string(esr));
+	__show_regs(regs);
+
+	panic("Asynchronous SError Interrupt");
+}
+
 void __pte_error(const char *file, int line, unsigned long val)
 {
 	pr_err("%s:%d: bad pte %016lx.\n", file, line, val);
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 11/21] arm64: cpufeature: Detect CPU RAS Extentions
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

From: Xie XiuQi <xiexiuqi@huawei.com>

ARM's v8.2 Extentions add support for Reliability, Availability and
Serviceability (RAS). On CPUs with these extensions system software
can use additional barriers to isolate errors and determine if faults
are pending.

Add cpufeature detection and a barrier in the context-switch code.
There is no need to use alternatives for this as CPUs that don't
support this feature will treat the instruction as a nop.

Platform level RAS support may require additional firmware support.

Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
[Rebased, added esb and config option, reworded commit message]
Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/Kconfig               | 16 ++++++++++++++++
 arch/arm64/include/asm/barrier.h |  1 +
 arch/arm64/include/asm/cpucaps.h |  3 ++-
 arch/arm64/include/asm/sysreg.h  |  2 ++
 arch/arm64/kernel/cpufeature.c   | 13 +++++++++++++
 arch/arm64/kernel/process.c      |  3 +++
 6 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 70dfe4e9ccc5..b68f5e93baac 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -973,6 +973,22 @@ config ARM64_PMEM
 	  operations if DC CVAP is not supported (following the behaviour of
 	  DC CVAP itself if the system does not define a point of persistence).
 
+config ARM64_RAS_EXTN
+	bool "Enable support for RAS CPU Extensions"
+	default y
+	help
+	  CPUs that support the Reliability, Availability and Serviceability
+	  (RAS) Extensions, part of ARMv8.2 are able to track faults and
+	  errors, classify them and report them to software.
+
+	  On CPUs with these extensions system software can use additional
+	  barriers to determine if faults are pending and read the
+	  classification from a new set of registers.
+
+	  Selecting this feature will allow the kernel to use these barriers
+	  and access the new registers if the system supports the extension.
+	  Platform RAS features may additionally depend on firmware support.
+
 endmenu
 
 config ARM64_MODULE_CMODEL_LARGE
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index 0fe7e43b7fbc..8b0a0eb67625 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -30,6 +30,7 @@
 #define isb()		asm volatile("isb" : : : "memory")
 #define dmb(opt)	asm volatile("dmb " #opt : : : "memory")
 #define dsb(opt)	asm volatile("dsb " #opt : : : "memory")
+#define esb()		asm volatile("hint #16"  : : : "memory")
 
 #define mb()		dsb(sy)
 #define rmb()		dsb(ld)
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 8da621627d7c..4820d441bfb9 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -40,7 +40,8 @@
 #define ARM64_WORKAROUND_858921			19
 #define ARM64_WORKAROUND_CAVIUM_30115		20
 #define ARM64_HAS_DCPOP				21
+#define ARM64_HAS_RAS_EXTN			22
 
-#define ARM64_NCAPS				22
+#define ARM64_NCAPS				23
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index f707fed5886f..64e2a80fd749 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -332,6 +332,7 @@
 #define ID_AA64ISAR1_DPB_SHIFT		0
 
 /* id_aa64pfr0 */
+#define ID_AA64PFR0_RAS_SHIFT		28
 #define ID_AA64PFR0_GIC_SHIFT		24
 #define ID_AA64PFR0_ASIMD_SHIFT		20
 #define ID_AA64PFR0_FP_SHIFT		16
@@ -340,6 +341,7 @@
 #define ID_AA64PFR0_EL1_SHIFT		4
 #define ID_AA64PFR0_EL0_SHIFT		0
 
+#define ID_AA64PFR0_RAS_V1		0x1
 #define ID_AA64PFR0_FP_NI		0xf
 #define ID_AA64PFR0_FP_SUPPORTED	0x0
 #define ID_AA64PFR0_ASIMD_NI		0xf
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index cd52d365d1f0..0fc017b55cb1 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -125,6 +125,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64PFR0_RAS_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64PFR0_GIC_SHIFT, 4, 0),
 	S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI),
 	S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI),
@@ -900,6 +901,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.min_field_value = 1,
 	},
 #endif
+#ifdef CONFIG_ARM64_RAS_EXTN
+	{
+		.desc = "RAS Extension Support",
+		.capability = ARM64_HAS_RAS_EXTN,
+		.def_scope = SCOPE_SYSTEM,
+		.matches = has_cpuid_feature,
+		.sys_reg = SYS_ID_AA64PFR0_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64PFR0_RAS_SHIFT,
+		.min_field_value = ID_AA64PFR0_RAS_V1,
+	},
+#endif /* CONFIG_ARM64_RAS_EXTN */
 	{},
 };
 
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 2dc0f8482210..5e5d2f0a1d0a 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -365,6 +365,9 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
 	 */
 	dsb(ish);
 
+	/* Deliver any pending SError from prev */
+	esb();
+
 	/* the actual thread switch */
 	last = cpu_switch_to(prev, next);
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 11/21] arm64: cpufeature: Detect CPU RAS Extentions
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Xie XiuQi <xiexiuqi@huawei.com>

ARM's v8.2 Extentions add support for Reliability, Availability and
Serviceability (RAS). On CPUs with these extensions system software
can use additional barriers to isolate errors and determine if faults
are pending.

Add cpufeature detection and a barrier in the context-switch code.
There is no need to use alternatives for this as CPUs that don't
support this feature will treat the instruction as a nop.

Platform level RAS support may require additional firmware support.

Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
[Rebased, added esb and config option, reworded commit message]
Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/Kconfig               | 16 ++++++++++++++++
 arch/arm64/include/asm/barrier.h |  1 +
 arch/arm64/include/asm/cpucaps.h |  3 ++-
 arch/arm64/include/asm/sysreg.h  |  2 ++
 arch/arm64/kernel/cpufeature.c   | 13 +++++++++++++
 arch/arm64/kernel/process.c      |  3 +++
 6 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 70dfe4e9ccc5..b68f5e93baac 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -973,6 +973,22 @@ config ARM64_PMEM
 	  operations if DC CVAP is not supported (following the behaviour of
 	  DC CVAP itself if the system does not define a point of persistence).
 
+config ARM64_RAS_EXTN
+	bool "Enable support for RAS CPU Extensions"
+	default y
+	help
+	  CPUs that support the Reliability, Availability and Serviceability
+	  (RAS) Extensions, part of ARMv8.2 are able to track faults and
+	  errors, classify them and report them to software.
+
+	  On CPUs with these extensions system software can use additional
+	  barriers to determine if faults are pending and read the
+	  classification from a new set of registers.
+
+	  Selecting this feature will allow the kernel to use these barriers
+	  and access the new registers if the system supports the extension.
+	  Platform RAS features may additionally depend on firmware support.
+
 endmenu
 
 config ARM64_MODULE_CMODEL_LARGE
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index 0fe7e43b7fbc..8b0a0eb67625 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -30,6 +30,7 @@
 #define isb()		asm volatile("isb" : : : "memory")
 #define dmb(opt)	asm volatile("dmb " #opt : : : "memory")
 #define dsb(opt)	asm volatile("dsb " #opt : : : "memory")
+#define esb()		asm volatile("hint #16"  : : : "memory")
 
 #define mb()		dsb(sy)
 #define rmb()		dsb(ld)
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 8da621627d7c..4820d441bfb9 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -40,7 +40,8 @@
 #define ARM64_WORKAROUND_858921			19
 #define ARM64_WORKAROUND_CAVIUM_30115		20
 #define ARM64_HAS_DCPOP				21
+#define ARM64_HAS_RAS_EXTN			22
 
-#define ARM64_NCAPS				22
+#define ARM64_NCAPS				23
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index f707fed5886f..64e2a80fd749 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -332,6 +332,7 @@
 #define ID_AA64ISAR1_DPB_SHIFT		0
 
 /* id_aa64pfr0 */
+#define ID_AA64PFR0_RAS_SHIFT		28
 #define ID_AA64PFR0_GIC_SHIFT		24
 #define ID_AA64PFR0_ASIMD_SHIFT		20
 #define ID_AA64PFR0_FP_SHIFT		16
@@ -340,6 +341,7 @@
 #define ID_AA64PFR0_EL1_SHIFT		4
 #define ID_AA64PFR0_EL0_SHIFT		0
 
+#define ID_AA64PFR0_RAS_V1		0x1
 #define ID_AA64PFR0_FP_NI		0xf
 #define ID_AA64PFR0_FP_SUPPORTED	0x0
 #define ID_AA64PFR0_ASIMD_NI		0xf
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index cd52d365d1f0..0fc017b55cb1 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -125,6 +125,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64PFR0_RAS_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64PFR0_GIC_SHIFT, 4, 0),
 	S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI),
 	S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI),
@@ -900,6 +901,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.min_field_value = 1,
 	},
 #endif
+#ifdef CONFIG_ARM64_RAS_EXTN
+	{
+		.desc = "RAS Extension Support",
+		.capability = ARM64_HAS_RAS_EXTN,
+		.def_scope = SCOPE_SYSTEM,
+		.matches = has_cpuid_feature,
+		.sys_reg = SYS_ID_AA64PFR0_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64PFR0_RAS_SHIFT,
+		.min_field_value = ID_AA64PFR0_RAS_V1,
+	},
+#endif /* CONFIG_ARM64_RAS_EXTN */
 	{},
 };
 
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 2dc0f8482210..5e5d2f0a1d0a 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -365,6 +365,9 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
 	 */
 	dsb(ish);
 
+	/* Deliver any pending SError from prev */
+	esb();
+
 	/* the actual thread switch */
 	last = cpu_switch_to(prev, next);
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 12/21] arm64: kernel: Survive corrected RAS errors notified by SError
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

Prior to v8.2, SError is an uncontainable fatal exception. The v8.2 RAS
extensions use SError to notify software about RAS errors, these can be
contained by the ESB instruction.

An ACPI system with firmware-first may use SError as its 'SEI'
notification. Future patches may add code to 'claim' this SError as a
notification.

Other systems can distinguish these RAS errors from the SError ESR and
use the AET bits and additional data from RAS-Error registers to handle
the error. Future patches may add this kernel-first handling.

Without support for either of these we will panic(), even if we received
a corrected error. Add code to decode the severity of RAS errors. We can
safely ignore contained errors where the CPU can continue to make
progress. For all other errors we continue to panic().

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
I couldn't come up with a concise way to capture 'can continue to make
progress', so opted for 'blocking' instead.

 arch/arm64/include/asm/esr.h   | 10 ++++++++
 arch/arm64/include/asm/traps.h | 36 ++++++++++++++++++++++++++
 arch/arm64/kernel/traps.c      | 58 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 99 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 66ed8b6b9976..8ea52f15bf1c 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -85,6 +85,15 @@
 #define ESR_ELx_WNR_SHIFT	(6)
 #define ESR_ELx_WNR		(UL(1) << ESR_ELx_WNR_SHIFT)
 
+/* Asynchronous Error Type */
+#define ESR_ELx_AET		(UL(0x7) << 10)
+
+#define ESR_ELx_AET_UC		(UL(0) << 10)	/* Uncontainable */
+#define ESR_ELx_AET_UEU		(UL(1) << 10)	/* Uncorrected Unrecoverable */
+#define ESR_ELx_AET_UEO		(UL(2) << 10)	/* Uncorrected Restartable */
+#define ESR_ELx_AET_UER		(UL(3) << 10)	/* Uncorrected Recoverable */
+#define ESR_ELx_AET_CE		(UL(6) << 10)	/* Corrected */
+
 /* Shared ISS field definitions for Data/Instruction aborts */
 #define ESR_ELx_SET_SHIFT	(11)
 #define ESR_ELx_SET_MASK	(UL(3) << ESR_ELx_SET_SHIFT)
@@ -99,6 +108,7 @@
 #define ESR_ELx_FSC		(0x3F)
 #define ESR_ELx_FSC_TYPE	(0x3C)
 #define ESR_ELx_FSC_EXTABT	(0x10)
+#define ESR_ELx_FSC_SERROR	(0x11)
 #define ESR_ELx_FSC_ACCESS	(0x08)
 #define ESR_ELx_FSC_FAULT	(0x04)
 #define ESR_ELx_FSC_PERM	(0x0C)
diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
index d131501c6222..8d2a1fff5c6b 100644
--- a/arch/arm64/include/asm/traps.h
+++ b/arch/arm64/include/asm/traps.h
@@ -19,6 +19,7 @@
 #define __ASM_TRAP_H
 
 #include <linux/list.h>
+#include <asm/esr.h>
 #include <asm/sections.h>
 
 struct pt_regs;
@@ -58,4 +59,39 @@ static inline int in_entry_text(unsigned long ptr)
 	return ptr >= (unsigned long)&__entry_text_start &&
 	       ptr < (unsigned long)&__entry_text_end;
 }
+
+static inline bool arm64_is_ras_serror(u32 esr)
+{
+	bool impdef = esr & ESR_ELx_ISV; /* aka IDS */
+
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+		return !impdef;
+
+	return false;
+}
+
+/* Return the AET bits of an SError ESR, or 0/uncontainable/uncategorized */
+static inline u32 arm64_ras_serror_get_severity(u32 esr)
+{
+	u32 aet = esr & ESR_ELx_AET;
+
+	if (!arm64_is_ras_serror(esr)) {
+		/* Not a RAS error, we can't interpret the ESR */
+		return 0;
+	}
+
+	/*
+	 * AET is RES0 if 'the value returned in the DFSC field is not
+	 * [ESR_ELx_FSC_SERROR]'
+	 */
+	if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
+		/* No severity information */
+		return 0;
+	}
+
+	return aet;
+}
+
+bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr);
+void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
 #endif
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 773aae69c376..53aeb25158b0 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -709,17 +709,65 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
 }
 #endif
 
-asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
+void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr)
 {
-	nmi_enter();
-
 	console_verbose();
 
 	pr_crit("SError Interrupt on CPU%d, code 0x%08x -- %s\n",
 		smp_processor_id(), esr, esr_get_class_string(esr));
-	__show_regs(regs);
+	if (regs)
+		__show_regs(regs);
+
+	/* KVM may call this this from a preemptible context */
+	preempt_disable();
+
+	/*
+	 * panic() unmasks interrupts, which unmasks SError. Use nmi_panic()
+	 * to avoid re-entering panic.
+	 */
+	nmi_panic(regs, "Asynchronous SError Interrupt");
+
+	cpu_park_loop();
+	unreachable();
+}
+
+bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr)
+{
+	u32 aet = arm64_ras_serror_get_severity(esr);
+
+	switch (aet) {
+	case ESR_ELx_AET_CE:	/* corrected error */
+	case ESR_ELx_AET_UEO:	/* restartable, not yet consumed */
+		/*
+		 * The CPU can make progress. We may take UEO again as
+		 * a more severe error.
+		 */
+		return false;
+
+	case ESR_ELx_AET_UEU:	/* Uncorrected Unrecoverable */
+	case ESR_ELx_AET_UER:	/* Uncorrected Recoverable */
+		/*
+		 * The CPU can't make progress. The exception may have
+		 * been imprecise.
+		 */
+		return true;
+
+	case ESR_ELx_AET_UC:	/* Uncontainable error */
+	default:
+		/* Error has been silently propagated */
+		arm64_serror_panic(regs, esr);
+	}
+}
+
+asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
+{
+	nmi_enter();
+
+	/* non-RAS errors are not containable */
+	if (!arm64_is_ras_serror(esr) || arm64_blocking_ras_serror(regs, esr))
+		arm64_serror_panic(regs, esr);
 
-	panic("Asynchronous SError Interrupt");
+	nmi_exit();
 }
 
 void __pte_error(const char *file, int line, unsigned long val)
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 12/21] arm64: kernel: Survive corrected RAS errors notified by SError
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Prior to v8.2, SError is an uncontainable fatal exception. The v8.2 RAS
extensions use SError to notify software about RAS errors, these can be
contained by the ESB instruction.

An ACPI system with firmware-first may use SError as its 'SEI'
notification. Future patches may add code to 'claim' this SError as a
notification.

Other systems can distinguish these RAS errors from the SError ESR and
use the AET bits and additional data from RAS-Error registers to handle
the error. Future patches may add this kernel-first handling.

Without support for either of these we will panic(), even if we received
a corrected error. Add code to decode the severity of RAS errors. We can
safely ignore contained errors where the CPU can continue to make
progress. For all other errors we continue to panic().

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
I couldn't come up with a concise way to capture 'can continue to make
progress', so opted for 'blocking' instead.

 arch/arm64/include/asm/esr.h   | 10 ++++++++
 arch/arm64/include/asm/traps.h | 36 ++++++++++++++++++++++++++
 arch/arm64/kernel/traps.c      | 58 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 99 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 66ed8b6b9976..8ea52f15bf1c 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -85,6 +85,15 @@
 #define ESR_ELx_WNR_SHIFT	(6)
 #define ESR_ELx_WNR		(UL(1) << ESR_ELx_WNR_SHIFT)
 
+/* Asynchronous Error Type */
+#define ESR_ELx_AET		(UL(0x7) << 10)
+
+#define ESR_ELx_AET_UC		(UL(0) << 10)	/* Uncontainable */
+#define ESR_ELx_AET_UEU		(UL(1) << 10)	/* Uncorrected Unrecoverable */
+#define ESR_ELx_AET_UEO		(UL(2) << 10)	/* Uncorrected Restartable */
+#define ESR_ELx_AET_UER		(UL(3) << 10)	/* Uncorrected Recoverable */
+#define ESR_ELx_AET_CE		(UL(6) << 10)	/* Corrected */
+
 /* Shared ISS field definitions for Data/Instruction aborts */
 #define ESR_ELx_SET_SHIFT	(11)
 #define ESR_ELx_SET_MASK	(UL(3) << ESR_ELx_SET_SHIFT)
@@ -99,6 +108,7 @@
 #define ESR_ELx_FSC		(0x3F)
 #define ESR_ELx_FSC_TYPE	(0x3C)
 #define ESR_ELx_FSC_EXTABT	(0x10)
+#define ESR_ELx_FSC_SERROR	(0x11)
 #define ESR_ELx_FSC_ACCESS	(0x08)
 #define ESR_ELx_FSC_FAULT	(0x04)
 #define ESR_ELx_FSC_PERM	(0x0C)
diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
index d131501c6222..8d2a1fff5c6b 100644
--- a/arch/arm64/include/asm/traps.h
+++ b/arch/arm64/include/asm/traps.h
@@ -19,6 +19,7 @@
 #define __ASM_TRAP_H
 
 #include <linux/list.h>
+#include <asm/esr.h>
 #include <asm/sections.h>
 
 struct pt_regs;
@@ -58,4 +59,39 @@ static inline int in_entry_text(unsigned long ptr)
 	return ptr >= (unsigned long)&__entry_text_start &&
 	       ptr < (unsigned long)&__entry_text_end;
 }
+
+static inline bool arm64_is_ras_serror(u32 esr)
+{
+	bool impdef = esr & ESR_ELx_ISV; /* aka IDS */
+
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+		return !impdef;
+
+	return false;
+}
+
+/* Return the AET bits of an SError ESR, or 0/uncontainable/uncategorized */
+static inline u32 arm64_ras_serror_get_severity(u32 esr)
+{
+	u32 aet = esr & ESR_ELx_AET;
+
+	if (!arm64_is_ras_serror(esr)) {
+		/* Not a RAS error, we can't interpret the ESR */
+		return 0;
+	}
+
+	/*
+	 * AET is RES0 if 'the value returned in the DFSC field is not
+	 * [ESR_ELx_FSC_SERROR]'
+	 */
+	if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
+		/* No severity information */
+		return 0;
+	}
+
+	return aet;
+}
+
+bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr);
+void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
 #endif
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 773aae69c376..53aeb25158b0 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -709,17 +709,65 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
 }
 #endif
 
-asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
+void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr)
 {
-	nmi_enter();
-
 	console_verbose();
 
 	pr_crit("SError Interrupt on CPU%d, code 0x%08x -- %s\n",
 		smp_processor_id(), esr, esr_get_class_string(esr));
-	__show_regs(regs);
+	if (regs)
+		__show_regs(regs);
+
+	/* KVM may call this this from a preemptible context */
+	preempt_disable();
+
+	/*
+	 * panic() unmasks interrupts, which unmasks SError. Use nmi_panic()
+	 * to avoid re-entering panic.
+	 */
+	nmi_panic(regs, "Asynchronous SError Interrupt");
+
+	cpu_park_loop();
+	unreachable();
+}
+
+bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr)
+{
+	u32 aet = arm64_ras_serror_get_severity(esr);
+
+	switch (aet) {
+	case ESR_ELx_AET_CE:	/* corrected error */
+	case ESR_ELx_AET_UEO:	/* restartable, not yet consumed */
+		/*
+		 * The CPU can make progress. We may take UEO again as
+		 * a more severe error.
+		 */
+		return false;
+
+	case ESR_ELx_AET_UEU:	/* Uncorrected Unrecoverable */
+	case ESR_ELx_AET_UER:	/* Uncorrected Recoverable */
+		/*
+		 * The CPU can't make progress. The exception may have
+		 * been imprecise.
+		 */
+		return true;
+
+	case ESR_ELx_AET_UC:	/* Uncontainable error */
+	default:
+		/* Error has been silently propagated */
+		arm64_serror_panic(regs, esr);
+	}
+}
+
+asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
+{
+	nmi_enter();
+
+	/* non-RAS errors are not containable */
+	if (!arm64_is_ras_serror(esr) || arm64_blocking_ras_serror(regs, esr))
+		arm64_serror_panic(regs, esr);
 
-	panic("Asynchronous SError Interrupt");
+	nmi_exit();
 }
 
 void __pte_error(const char *file, int line, unsigned long val)
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 13/21] arm64: cpufeature: Enable IESB on exception entry/return for firmware-first
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:57   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

ARM v8.2 has a feature to add implicit error synchronization barriers
whenever the CPU enters or returns from an exception level. Add code to
detect this feature and enable the SCTLR_ELx.IESB bit.

This feature causes RAS errors that are not yet visible to software to
become pending SErrors. We expect to have firmware-first RAS support
so synchronised RAS errors will be take immediately to EL3.
Any system without firmware-first handling of errors will take the SError
either immediatly after exception return, or when we unmask SError after
entry.S's work.

Platform level RAS support may require additional firmware support.

Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Note the sneaky KVM change,

Changes since v3:
 * removed IESB Kconfig option

 arch/arm64/include/asm/cpucaps.h   |  3 ++-
 arch/arm64/include/asm/processor.h |  1 +
 arch/arm64/include/asm/sysreg.h    |  1 +
 arch/arm64/kernel/cpufeature.c     | 19 +++++++++++++++++++
 arch/arm64/kvm/hyp-init.S          |  3 +++
 5 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 4820d441bfb9..7a2bbbfdff49 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -41,7 +41,8 @@
 #define ARM64_WORKAROUND_CAVIUM_30115		20
 #define ARM64_HAS_DCPOP				21
 #define ARM64_HAS_RAS_EXTN			22
+#define ARM64_HAS_IESB				23
 
-#define ARM64_NCAPS				23
+#define ARM64_NCAPS				24
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 29adab8138c3..6b72ddc33d06 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -193,5 +193,6 @@ static inline void spin_lock_prefetch(const void *ptr)
 
 int cpu_enable_pan(void *__unused);
 int cpu_enable_cache_maint_trap(void *__unused);
+int cpu_enable_iesb(void *__unused);
 
 #endif /* __ASM_PROCESSOR_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 64e2a80fd749..4500a70c6a57 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -297,6 +297,7 @@
 
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_EE    (1 << 25)
+#define SCTLR_ELx_IESB	(1 << 21)
 #define SCTLR_ELx_I	(1 << 12)
 #define SCTLR_ELx_SA	(1 << 3)
 #define SCTLR_ELx_C	(1 << 2)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0fc017b55cb1..356a5de51f5e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -912,6 +912,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.field_pos = ID_AA64PFR0_RAS_SHIFT,
 		.min_field_value = ID_AA64PFR0_RAS_V1,
 	},
+	{
+		.desc = "Implicit Error Synchronization Barrier",
+		.capability = ARM64_HAS_IESB,
+		.def_scope = SCOPE_SYSTEM,
+		.matches = has_cpuid_feature,
+		.sys_reg = SYS_ID_AA64MMFR2_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR2_IESB_SHIFT,
+		.min_field_value = 1,
+		.enable = cpu_enable_iesb,
+	},
 #endif /* CONFIG_ARM64_RAS_EXTN */
 	{},
 };
@@ -1321,3 +1332,11 @@ static int __init enable_mrs_emulation(void)
 }
 
 late_initcall(enable_mrs_emulation);
+
+int cpu_enable_iesb(void *__unused)
+{
+	if (cpus_have_cap(ARM64_HAS_RAS_EXTN))
+		config_sctlr_el1(0, SCTLR_ELx_IESB);
+
+	return 0;
+}
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 3f9615582377..8983e9473017 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -113,6 +113,9 @@ __do_hyp_init:
 	 */
 	ldr	x4, =(SCTLR_EL2_RES1 | (SCTLR_ELx_FLAGS & ~SCTLR_ELx_A))
 CPU_BE(	orr	x4, x4, #SCTLR_ELx_EE)
+alternative_if ARM64_HAS_IESB
+	orr	x4, x4, #SCTLR_ELx_IESB
+alternative_else_nop_endif
 	msr	sctlr_el2, x4
 	isb
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 13/21] arm64: cpufeature: Enable IESB on exception entry/return for firmware-first
@ 2017-10-19 14:57   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

ARM v8.2 has a feature to add implicit error synchronization barriers
whenever the CPU enters or returns from an exception level. Add code to
detect this feature and enable the SCTLR_ELx.IESB bit.

This feature causes RAS errors that are not yet visible to software to
become pending SErrors. We expect to have firmware-first RAS support
so synchronised RAS errors will be take immediately to EL3.
Any system without firmware-first handling of errors will take the SError
either immediatly after exception return, or when we unmask SError after
entry.S's work.

Platform level RAS support may require additional firmware support.

Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

---
Note the sneaky KVM change,

Changes since v3:
 * removed IESB Kconfig option

 arch/arm64/include/asm/cpucaps.h   |  3 ++-
 arch/arm64/include/asm/processor.h |  1 +
 arch/arm64/include/asm/sysreg.h    |  1 +
 arch/arm64/kernel/cpufeature.c     | 19 +++++++++++++++++++
 arch/arm64/kvm/hyp-init.S          |  3 +++
 5 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 4820d441bfb9..7a2bbbfdff49 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -41,7 +41,8 @@
 #define ARM64_WORKAROUND_CAVIUM_30115		20
 #define ARM64_HAS_DCPOP				21
 #define ARM64_HAS_RAS_EXTN			22
+#define ARM64_HAS_IESB				23
 
-#define ARM64_NCAPS				23
+#define ARM64_NCAPS				24
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 29adab8138c3..6b72ddc33d06 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -193,5 +193,6 @@ static inline void spin_lock_prefetch(const void *ptr)
 
 int cpu_enable_pan(void *__unused);
 int cpu_enable_cache_maint_trap(void *__unused);
+int cpu_enable_iesb(void *__unused);
 
 #endif /* __ASM_PROCESSOR_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 64e2a80fd749..4500a70c6a57 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -297,6 +297,7 @@
 
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_EE    (1 << 25)
+#define SCTLR_ELx_IESB	(1 << 21)
 #define SCTLR_ELx_I	(1 << 12)
 #define SCTLR_ELx_SA	(1 << 3)
 #define SCTLR_ELx_C	(1 << 2)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0fc017b55cb1..356a5de51f5e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -912,6 +912,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.field_pos = ID_AA64PFR0_RAS_SHIFT,
 		.min_field_value = ID_AA64PFR0_RAS_V1,
 	},
+	{
+		.desc = "Implicit Error Synchronization Barrier",
+		.capability = ARM64_HAS_IESB,
+		.def_scope = SCOPE_SYSTEM,
+		.matches = has_cpuid_feature,
+		.sys_reg = SYS_ID_AA64MMFR2_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR2_IESB_SHIFT,
+		.min_field_value = 1,
+		.enable = cpu_enable_iesb,
+	},
 #endif /* CONFIG_ARM64_RAS_EXTN */
 	{},
 };
@@ -1321,3 +1332,11 @@ static int __init enable_mrs_emulation(void)
 }
 
 late_initcall(enable_mrs_emulation);
+
+int cpu_enable_iesb(void *__unused)
+{
+	if (cpus_have_cap(ARM64_HAS_RAS_EXTN))
+		config_sctlr_el1(0, SCTLR_ELx_IESB);
+
+	return 0;
+}
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 3f9615582377..8983e9473017 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -113,6 +113,9 @@ __do_hyp_init:
 	 */
 	ldr	x4, =(SCTLR_EL2_RES1 | (SCTLR_ELx_FLAGS & ~SCTLR_ELx_A))
 CPU_BE(	orr	x4, x4, #SCTLR_ELx_EE)
+alternative_if ARM64_HAS_IESB
+	orr	x4, x4, #SCTLR_ELx_IESB
+alternative_else_nop_endif
 	msr	sctlr_el2, x4
 	isb
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 14/21] arm64: kernel: Prepare for a DISR user
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:58   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

KVM would like to consume any pending SError (or RAS error) after guest
exit. Today it has to unmask SError and use dsb+isb to synchronise the
CPU. With the RAS extensions we can use ESB to synchronise any pending
SError.

Add the necessary macros to allow DISR to be read and converted to an
ESR.

We clear the DISR register when we enable the RAS cpufeature. While the
kernel has issued ESB instructions before this point it has only done so
with SError unmasked, any value we find in DISR must have belonged to
firmware. Executing an ESB instruction is the only way to update DISR,
so we can expect firmware to have handled any deferred SError. By the
same logic we clear DISR in the idle path.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/assembler.h |  7 +++++++
 arch/arm64/include/asm/esr.h       |  7 +++++++
 arch/arm64/include/asm/exception.h | 14 ++++++++++++++
 arch/arm64/include/asm/processor.h |  1 +
 arch/arm64/include/asm/sysreg.h    |  1 +
 arch/arm64/kernel/cpufeature.c     |  9 +++++++++
 arch/arm64/mm/proc.S               |  5 +++++
 7 files changed, 44 insertions(+)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index e4ac505b7b3d..7a918a4cf4f7 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -109,6 +109,13 @@
 	.endm
 
 /*
+ * RAS Error Synchronization barrier
+ */
+	.macro  esb
+	hint    #16
+	.endm
+
+/*
  * NOP sequence
  */
 	.macro	nops, num
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 8ea52f15bf1c..b3f17fd18b14 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -136,6 +136,13 @@
 #define ESR_ELx_WFx_ISS_WFE	(UL(1) << 0)
 #define ESR_ELx_xVC_IMM_MASK	((1UL << 16) - 1)
 
+#define DISR_EL1_IDS		(UL(1) << 24)
+/*
+ * DISR_EL1 and ESR_ELx share the bottom 13 bits, but the RES0 bits may mean
+ * different things in the future...
+ */
+#define DISR_EL1_ESR_MASK	(ESR_ELx_AET | ESR_ELx_EA | ESR_ELx_FSC)
+
 /* ESR value templates for specific events */
 
 /* BRK instruction trap from AArch64 state */
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 0c2eec490abf..bc30429d8e91 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -18,6 +18,8 @@
 #ifndef __ASM_EXCEPTION_H
 #define __ASM_EXCEPTION_H
 
+#include <asm/esr.h>
+
 #include <linux/interrupt.h>
 
 #define __exception	__attribute__((section(".exception.text")))
@@ -27,4 +29,16 @@
 #define __exception_irq_entry	__exception
 #endif
 
+static inline u32 disr_to_esr(u64 disr)
+{
+	unsigned int esr = ESR_ELx_EC_SERROR << ESR_ELx_EC_SHIFT;
+
+	if ((disr & DISR_EL1_IDS) == 0)
+		esr |= (disr & DISR_EL1_ESR_MASK);
+	else
+		esr |= (disr & ESR_ELx_ISS_MASK);
+
+	return esr;
+}
+
 #endif	/* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6b72ddc33d06..9de3f839be8a 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -194,5 +194,6 @@ static inline void spin_lock_prefetch(const void *ptr)
 int cpu_enable_pan(void *__unused);
 int cpu_enable_cache_maint_trap(void *__unused);
 int cpu_enable_iesb(void *__unused);
+int cpu_clear_disr(void *__unused);
 
 #endif /* __ASM_PROCESSOR_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 4500a70c6a57..427c36bc5dd6 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -179,6 +179,7 @@
 #define SYS_AMAIR_EL1			sys_reg(3, 0, 10, 3, 0)
 
 #define SYS_VBAR_EL1			sys_reg(3, 0, 12, 0, 0)
+#define SYS_DISR_EL1			sys_reg(3, 0, 12, 1,  1)
 
 #define SYS_ICC_IAR0_EL1		sys_reg(3, 0, 12, 8, 0)
 #define SYS_ICC_EOIR0_EL1		sys_reg(3, 0, 12, 8, 1)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 356a5de51f5e..e799b72f1395 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -911,6 +911,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_RAS_SHIFT,
 		.min_field_value = ID_AA64PFR0_RAS_V1,
+		.enable = cpu_clear_disr,
 	},
 	{
 		.desc = "Implicit Error Synchronization Barrier",
@@ -1340,3 +1341,11 @@ int cpu_enable_iesb(void *__unused)
 
 	return 0;
 }
+
+int cpu_clear_disr(void *__unused)
+{
+	/* Firmware may have left a deferred SError in this register. */
+	write_sysreg_s(0, SYS_DISR_EL1);
+
+	return 0;
+}
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 95233dfc4c39..ac571223672d 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -124,6 +124,11 @@ ENTRY(cpu_do_resume)
 	ubfx	x11, x11, #1, #1
 	msr	oslar_el1, x11
 	reset_pmuserenr_el0 x0			// Disable PMU access from EL0
+
+alternative_if ARM64_HAS_RAS_EXTN
+	msr_s	SYS_DISR_EL1, xzr
+alternative_else_nop_endif
+
 	isb
 	ret
 ENDPROC(cpu_do_resume)
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 14/21] arm64: kernel: Prepare for a DISR user
@ 2017-10-19 14:58   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

KVM would like to consume any pending SError (or RAS error) after guest
exit. Today it has to unmask SError and use dsb+isb to synchronise the
CPU. With the RAS extensions we can use ESB to synchronise any pending
SError.

Add the necessary macros to allow DISR to be read and converted to an
ESR.

We clear the DISR register when we enable the RAS cpufeature. While the
kernel has issued ESB instructions before this point it has only done so
with SError unmasked, any value we find in DISR must have belonged to
firmware. Executing an ESB instruction is the only way to update DISR,
so we can expect firmware to have handled any deferred SError. By the
same logic we clear DISR in the idle path.

Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/assembler.h |  7 +++++++
 arch/arm64/include/asm/esr.h       |  7 +++++++
 arch/arm64/include/asm/exception.h | 14 ++++++++++++++
 arch/arm64/include/asm/processor.h |  1 +
 arch/arm64/include/asm/sysreg.h    |  1 +
 arch/arm64/kernel/cpufeature.c     |  9 +++++++++
 arch/arm64/mm/proc.S               |  5 +++++
 7 files changed, 44 insertions(+)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index e4ac505b7b3d..7a918a4cf4f7 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -109,6 +109,13 @@
 	.endm
 
 /*
+ * RAS Error Synchronization barrier
+ */
+	.macro  esb
+	hint    #16
+	.endm
+
+/*
  * NOP sequence
  */
 	.macro	nops, num
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 8ea52f15bf1c..b3f17fd18b14 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -136,6 +136,13 @@
 #define ESR_ELx_WFx_ISS_WFE	(UL(1) << 0)
 #define ESR_ELx_xVC_IMM_MASK	((1UL << 16) - 1)
 
+#define DISR_EL1_IDS		(UL(1) << 24)
+/*
+ * DISR_EL1 and ESR_ELx share the bottom 13 bits, but the RES0 bits may mean
+ * different things in the future...
+ */
+#define DISR_EL1_ESR_MASK	(ESR_ELx_AET | ESR_ELx_EA | ESR_ELx_FSC)
+
 /* ESR value templates for specific events */
 
 /* BRK instruction trap from AArch64 state */
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 0c2eec490abf..bc30429d8e91 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -18,6 +18,8 @@
 #ifndef __ASM_EXCEPTION_H
 #define __ASM_EXCEPTION_H
 
+#include <asm/esr.h>
+
 #include <linux/interrupt.h>
 
 #define __exception	__attribute__((section(".exception.text")))
@@ -27,4 +29,16 @@
 #define __exception_irq_entry	__exception
 #endif
 
+static inline u32 disr_to_esr(u64 disr)
+{
+	unsigned int esr = ESR_ELx_EC_SERROR << ESR_ELx_EC_SHIFT;
+
+	if ((disr & DISR_EL1_IDS) == 0)
+		esr |= (disr & DISR_EL1_ESR_MASK);
+	else
+		esr |= (disr & ESR_ELx_ISS_MASK);
+
+	return esr;
+}
+
 #endif	/* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6b72ddc33d06..9de3f839be8a 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -194,5 +194,6 @@ static inline void spin_lock_prefetch(const void *ptr)
 int cpu_enable_pan(void *__unused);
 int cpu_enable_cache_maint_trap(void *__unused);
 int cpu_enable_iesb(void *__unused);
+int cpu_clear_disr(void *__unused);
 
 #endif /* __ASM_PROCESSOR_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 4500a70c6a57..427c36bc5dd6 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -179,6 +179,7 @@
 #define SYS_AMAIR_EL1			sys_reg(3, 0, 10, 3, 0)
 
 #define SYS_VBAR_EL1			sys_reg(3, 0, 12, 0, 0)
+#define SYS_DISR_EL1			sys_reg(3, 0, 12, 1,  1)
 
 #define SYS_ICC_IAR0_EL1		sys_reg(3, 0, 12, 8, 0)
 #define SYS_ICC_EOIR0_EL1		sys_reg(3, 0, 12, 8, 1)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 356a5de51f5e..e799b72f1395 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -911,6 +911,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_RAS_SHIFT,
 		.min_field_value = ID_AA64PFR0_RAS_V1,
+		.enable = cpu_clear_disr,
 	},
 	{
 		.desc = "Implicit Error Synchronization Barrier",
@@ -1340,3 +1341,11 @@ int cpu_enable_iesb(void *__unused)
 
 	return 0;
 }
+
+int cpu_clear_disr(void *__unused)
+{
+	/* Firmware may have left a deferred SError in this register. */
+	write_sysreg_s(0, SYS_DISR_EL1);
+
+	return 0;
+}
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 95233dfc4c39..ac571223672d 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -124,6 +124,11 @@ ENTRY(cpu_do_resume)
 	ubfx	x11, x11, #1, #1
 	msr	oslar_el1, x11
 	reset_pmuserenr_el0 x0			// Disable PMU access from EL0
+
+alternative_if ARM64_HAS_RAS_EXTN
+	msr_s	SYS_DISR_EL1, xzr
+alternative_else_nop_endif
+
 	isb
 	ret
 ENDPROC(cpu_do_resume)
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:58   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
generated an SError with an implementation defined ESR_EL1.ISS, because we
had no mechanism to specify the ESR value.

On Juno this generates an all-zero ESR, the most significant bit 'ISV'
is clear indicating the remainder of the ISS field is invalid.

With the RAS Extensions we have a mechanism to specify this value, and the
most significant bit has a new meaning: 'IDS - Implementation Defined
Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
instead of 'no valid ISS'.

Add KVM support for the VSESR_EL2 register to specify an ESR value when
HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
specify an implementation-defined value.

We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
save/restores this bit during __deactivate_traps() and hardware clears the
bit once the guest has consumed the virtual-SError.

Future patches may add an API (or KVM CAP) to pend a virtual SError with
a specified ESR.

Cc: Dongjiu Geng <gengdongjiu@huawei.com>
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_emulate.h |  5 +++++
 arch/arm64/include/asm/kvm_host.h    |  3 +++
 arch/arm64/include/asm/sysreg.h      |  1 +
 arch/arm64/kvm/hyp/switch.c          |  4 ++++
 arch/arm64/kvm/inject_fault.c        | 13 ++++++++++++-
 5 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index e5df3fce0008..8a7a838eb17a 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -61,6 +61,11 @@ static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
 	vcpu->arch.hcr_el2 = hcr;
 }
 
+static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
+{
+	vcpu->arch.vsesr_el2 = vsesr;
+}
+
 static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
 {
 	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a0e2f7962401..28a4de85edee 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -277,6 +277,9 @@ struct kvm_vcpu_arch {
 
 	/* Detect first run of a vcpu */
 	bool has_run_once;
+
+	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
+	u64 vsesr_el2;
 };
 
 #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 427c36bc5dd6..a493e93de296 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -253,6 +253,7 @@
 
 #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
 #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
+#define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
 #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
 
 #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 945e79c641c4..af37658223a0 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
 		isb();
 	}
 	write_sysreg(val, hcr_el2);
+
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
+		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
+
 	/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
 	write_sysreg(1 << 15, hstr_el2);
 	/*
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index da6a8cfa54a0..52f7f66f1356 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -232,14 +232,25 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
 		inject_undef64(vcpu);
 }
 
+static void pend_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
+{
+	vcpu_set_vsesr(vcpu, esr);
+	vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
+}
+
 /**
  * kvm_inject_vabt - inject an async abort / SError into the guest
  * @vcpu: The VCPU to receive the exception
  *
  * It is assumed that this code is called from the VCPU thread and that the
  * VCPU therefore is not currently executing guest code.
+ *
+ * Systems with the RAS Extensions specify an imp-def ESR (ISV/IDS = 1) with
+ * the remaining ISS all-zeros so that this error is not interpreted as an
+ * uncatagorized RAS error. Without the RAS Extensions we can't specify an ESR
+ * value, so the CPU generates an imp-def value.
  */
 void kvm_inject_vabt(struct kvm_vcpu *vcpu)
 {
-	vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
+	pend_guest_serror(vcpu, ESR_ELx_ISV);
 }
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-19 14:58   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
generated an SError with an implementation defined ESR_EL1.ISS, because we
had no mechanism to specify the ESR value.

On Juno this generates an all-zero ESR, the most significant bit 'ISV'
is clear indicating the remainder of the ISS field is invalid.

With the RAS Extensions we have a mechanism to specify this value, and the
most significant bit has a new meaning: 'IDS - Implementation Defined
Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
instead of 'no valid ISS'.

Add KVM support for the VSESR_EL2 register to specify an ESR value when
HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
specify an implementation-defined value.

We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
save/restores this bit during __deactivate_traps() and hardware clears the
bit once the guest has consumed the virtual-SError.

Future patches may add an API (or KVM CAP) to pend a virtual SError with
a specified ESR.

Cc: Dongjiu Geng <gengdongjiu@huawei.com>
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_emulate.h |  5 +++++
 arch/arm64/include/asm/kvm_host.h    |  3 +++
 arch/arm64/include/asm/sysreg.h      |  1 +
 arch/arm64/kvm/hyp/switch.c          |  4 ++++
 arch/arm64/kvm/inject_fault.c        | 13 ++++++++++++-
 5 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index e5df3fce0008..8a7a838eb17a 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -61,6 +61,11 @@ static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
 	vcpu->arch.hcr_el2 = hcr;
 }
 
+static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
+{
+	vcpu->arch.vsesr_el2 = vsesr;
+}
+
 static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
 {
 	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a0e2f7962401..28a4de85edee 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -277,6 +277,9 @@ struct kvm_vcpu_arch {
 
 	/* Detect first run of a vcpu */
 	bool has_run_once;
+
+	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
+	u64 vsesr_el2;
 };
 
 #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 427c36bc5dd6..a493e93de296 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -253,6 +253,7 @@
 
 #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
 #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
+#define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
 #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
 
 #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 945e79c641c4..af37658223a0 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
 		isb();
 	}
 	write_sysreg(val, hcr_el2);
+
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
+		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
+
 	/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
 	write_sysreg(1 << 15, hstr_el2);
 	/*
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index da6a8cfa54a0..52f7f66f1356 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -232,14 +232,25 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
 		inject_undef64(vcpu);
 }
 
+static void pend_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
+{
+	vcpu_set_vsesr(vcpu, esr);
+	vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
+}
+
 /**
  * kvm_inject_vabt - inject an async abort / SError into the guest
  * @vcpu: The VCPU to receive the exception
  *
  * It is assumed that this code is called from the VCPU thread and that the
  * VCPU therefore is not currently executing guest code.
+ *
+ * Systems with the RAS Extensions specify an imp-def ESR (ISV/IDS = 1) with
+ * the remaining ISS all-zeros so that this error is not interpreted as an
+ * uncatagorized RAS error. Without the RAS Extensions we can't specify an ESR
+ * value, so the CPU generates an imp-def value.
  */
 void kvm_inject_vabt(struct kvm_vcpu *vcpu)
 {
-	vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
+	pend_guest_serror(vcpu, ESR_ELx_ISV);
 }
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 16/21] KVM: arm64: Save/Restore guest DISR_EL1
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:58   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

If we deliver a virtual SError to the guest, the guest may defer it
with an ESB instruction. The guest reads the deferred value via DISR_EL1,
but the guests view of DISR_EL1 is re-mapped to VDISR_EL2 when HCR_EL2.AMO
is set.

Add the KVM code to save/restore VDISR_EL2, and make it accessible to
userspace as DISR_EL1.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 1 +
 arch/arm64/include/asm/sysreg.h   | 1 +
 arch/arm64/kvm/hyp/sysreg-sr.c    | 6 ++++++
 arch/arm64/kvm/sys_regs.c         | 1 +
 4 files changed, 9 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 28a4de85edee..97438cc3a9ad 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -120,6 +120,7 @@ enum vcpu_sysreg {
 	PAR_EL1,	/* Physical Address Register */
 	MDSCR_EL1,	/* Monitor Debug System Control Register */
 	MDCCINT_EL1,	/* Monitor Debug Comms Channel Interrupt Enable Reg */
+	DISR_EL1,	/* Deferred Interrupt Status Register */
 
 	/* Performance Monitors Registers */
 	PMCR_EL0,	/* Control Register */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index a493e93de296..1b8b9012234d 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -256,6 +256,7 @@
 #define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
 #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
 
+#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1,  1)
 #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
 #define SYS_ICH_AP0R0_EL2		__SYS__AP0Rx_EL2(0)
 #define SYS_ICH_AP0R1_EL2		__SYS__AP0Rx_EL2(1)
diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
index 934137647837..f4d604803b29 100644
--- a/arch/arm64/kvm/hyp/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/sysreg-sr.c
@@ -66,6 +66,9 @@ static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
 	ctxt->gp_regs.sp_el1		= read_sysreg(sp_el1);
 	ctxt->gp_regs.elr_el1		= read_sysreg_el1(elr);
 	ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
+
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+		ctxt->sys_regs[DISR_EL1] = read_sysreg_s(SYS_VDISR_EL2);
 }
 
 static hyp_alternate_select(__sysreg_call_save_host_state,
@@ -119,6 +122,9 @@ static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
 	write_sysreg(ctxt->gp_regs.sp_el1,		sp_el1);
 	write_sysreg_el1(ctxt->gp_regs.elr_el1,		elr);
 	write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
+
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+		write_sysreg_s(ctxt->sys_regs[DISR_EL1], SYS_VDISR_EL2);
 }
 
 static hyp_alternate_select(__sysreg_call_restore_host_state,
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 2e070d3baf9f..713275b501ce 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -963,6 +963,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
 
 	{ SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
+	{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
 
 	{ SYS_DESC(SYS_ICC_IAR0_EL1), write_to_read_only },
 	{ SYS_DESC(SYS_ICC_EOIR0_EL1), read_from_write_only },
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 16/21] KVM: arm64: Save/Restore guest DISR_EL1
@ 2017-10-19 14:58   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

If we deliver a virtual SError to the guest, the guest may defer it
with an ESB instruction. The guest reads the deferred value via DISR_EL1,
but the guests view of DISR_EL1 is re-mapped to VDISR_EL2 when HCR_EL2.AMO
is set.

Add the KVM code to save/restore VDISR_EL2, and make it accessible to
userspace as DISR_EL1.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 1 +
 arch/arm64/include/asm/sysreg.h   | 1 +
 arch/arm64/kvm/hyp/sysreg-sr.c    | 6 ++++++
 arch/arm64/kvm/sys_regs.c         | 1 +
 4 files changed, 9 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 28a4de85edee..97438cc3a9ad 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -120,6 +120,7 @@ enum vcpu_sysreg {
 	PAR_EL1,	/* Physical Address Register */
 	MDSCR_EL1,	/* Monitor Debug System Control Register */
 	MDCCINT_EL1,	/* Monitor Debug Comms Channel Interrupt Enable Reg */
+	DISR_EL1,	/* Deferred Interrupt Status Register */
 
 	/* Performance Monitors Registers */
 	PMCR_EL0,	/* Control Register */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index a493e93de296..1b8b9012234d 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -256,6 +256,7 @@
 #define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
 #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
 
+#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1,  1)
 #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
 #define SYS_ICH_AP0R0_EL2		__SYS__AP0Rx_EL2(0)
 #define SYS_ICH_AP0R1_EL2		__SYS__AP0Rx_EL2(1)
diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
index 934137647837..f4d604803b29 100644
--- a/arch/arm64/kvm/hyp/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/sysreg-sr.c
@@ -66,6 +66,9 @@ static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
 	ctxt->gp_regs.sp_el1		= read_sysreg(sp_el1);
 	ctxt->gp_regs.elr_el1		= read_sysreg_el1(elr);
 	ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
+
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+		ctxt->sys_regs[DISR_EL1] = read_sysreg_s(SYS_VDISR_EL2);
 }
 
 static hyp_alternate_select(__sysreg_call_save_host_state,
@@ -119,6 +122,9 @@ static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
 	write_sysreg(ctxt->gp_regs.sp_el1,		sp_el1);
 	write_sysreg_el1(ctxt->gp_regs.elr_el1,		elr);
 	write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
+
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+		write_sysreg_s(ctxt->sys_regs[DISR_EL1], SYS_VDISR_EL2);
 }
 
 static hyp_alternate_select(__sysreg_call_restore_host_state,
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 2e070d3baf9f..713275b501ce 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -963,6 +963,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
 
 	{ SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
+	{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
 
 	{ SYS_DESC(SYS_ICC_IAR0_EL1), write_to_read_only },
 	{ SYS_DESC(SYS_ICC_EOIR0_EL1), read_from_write_only },
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:58   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

When we exit a guest due to an SError the vcpu fault info isn't updated
with the ESR. Today this is only done for traps.

The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
fault_info with the ESR on SError so that handle_exit() can determine
if this was a RAS SError and decode its severity.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index af37658223a0..cba6d8ac105c 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -230,13 +230,20 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
 	return true;
 }
 
+static void __hyp_text __populate_fault_info_esr(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
+}
+
 static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
 {
-	u64 esr = read_sysreg_el2(esr);
-	u8 ec = ESR_ELx_EC(esr);
+	u8 ec;
+	u64 esr;
 	u64 hpfar, far;
 
-	vcpu->arch.fault.esr_el2 = esr;
+	__populate_fault_info_esr(vcpu);
+	esr = vcpu->arch.fault.esr_el2;
+	ec = ESR_ELx_EC(esr);
 
 	if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
 		return true;
@@ -325,6 +332,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 	 */
 	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
 		goto again;
+	else if (ARM_EXCEPTION_CODE(exit_code) == ARM_EXCEPTION_EL1_SERROR)
+		__populate_fault_info_esr(vcpu);
 
 	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
 	    exit_code == ARM_EXCEPTION_TRAP) {
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError
@ 2017-10-19 14:58   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

When we exit a guest due to an SError the vcpu fault info isn't updated
with the ESR. Today this is only done for traps.

The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
fault_info with the ESR on SError so that handle_exit() can determine
if this was a RAS SError and decode its severity.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index af37658223a0..cba6d8ac105c 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -230,13 +230,20 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
 	return true;
 }
 
+static void __hyp_text __populate_fault_info_esr(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
+}
+
 static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
 {
-	u64 esr = read_sysreg_el2(esr);
-	u8 ec = ESR_ELx_EC(esr);
+	u8 ec;
+	u64 esr;
 	u64 hpfar, far;
 
-	vcpu->arch.fault.esr_el2 = esr;
+	__populate_fault_info_esr(vcpu);
+	esr = vcpu->arch.fault.esr_el2;
+	ec = ESR_ELx_EC(esr);
 
 	if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
 		return true;
@@ -325,6 +332,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 	 */
 	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
 		goto again;
+	else if (ARM_EXCEPTION_CODE(exit_code) == ARM_EXCEPTION_EL1_SERROR)
+		__populate_fault_info_esr(vcpu);
 
 	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
 	    exit_code == ARM_EXCEPTION_TRAP) {
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 18/21] KVM: arm64: Handle RAS SErrors from EL1 on guest exit
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:58   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

We expect to have firmware-first handling of RAS SErrors, with errors
notified via an APEI method. For systems without firmware-first, add
some minimal handling to KVM.

There are two ways KVM can take an SError due to a guest, either may be a
RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.

For SError that interrupt a guest and are routed to EL2 the existing
behaviour is to inject an impdef SError into the guest.

Add code to handle RAS SError based on the ESR. For uncontained errors
arm64_is_blocking_ras_serror() will panic(), these errors compromise
the host too. All other error types are contained: For the 'blocking'
errors the vCPU can't make progress, so we inject a virtual SError.
We ignore contained errors where we can make progress as if we're lucky,
we may not hit them again.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/kvm/handle_exit.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 7debb74843a0..345fdbba6c2e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -28,12 +28,19 @@
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_psci.h>
+#include <asm/traps.h>
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
 typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
 
+static void kvm_handle_guest_serror(struct kvm_vcpu *vcpu, u32 esr)
+{
+	if (!arm64_is_ras_serror(esr) || arm64_blocking_ras_serror(NULL, esr))
+		kvm_inject_vabt(vcpu);
+}
+
 static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
 	int ret;
@@ -211,7 +218,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
 	case ARM_EXCEPTION_IRQ:
 		return 1;
 	case ARM_EXCEPTION_EL1_SERROR:
-		kvm_inject_vabt(vcpu);
+		kvm_handle_guest_serror(vcpu, kvm_vcpu_get_hsr(vcpu));
 		return 1;
 	case ARM_EXCEPTION_TRAP:
 		/*
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 18/21] KVM: arm64: Handle RAS SErrors from EL1 on guest exit
@ 2017-10-19 14:58   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

We expect to have firmware-first handling of RAS SErrors, with errors
notified via an APEI method. For systems without firmware-first, add
some minimal handling to KVM.

There are two ways KVM can take an SError due to a guest, either may be a
RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.

For SError that interrupt a guest and are routed to EL2 the existing
behaviour is to inject an impdef SError into the guest.

Add code to handle RAS SError based on the ESR. For uncontained errors
arm64_is_blocking_ras_serror() will panic(), these errors compromise
the host too. All other error types are contained: For the 'blocking'
errors the vCPU can't make progress, so we inject a virtual SError.
We ignore contained errors where we can make progress as if we're lucky,
we may not hit them again.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/kvm/handle_exit.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 7debb74843a0..345fdbba6c2e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -28,12 +28,19 @@
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_psci.h>
+#include <asm/traps.h>
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
 typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
 
+static void kvm_handle_guest_serror(struct kvm_vcpu *vcpu, u32 esr)
+{
+	if (!arm64_is_ras_serror(esr) || arm64_blocking_ras_serror(NULL, esr))
+		kvm_inject_vabt(vcpu);
+}
+
 static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
 	int ret;
@@ -211,7 +218,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
 	case ARM_EXCEPTION_IRQ:
 		return 1;
 	case ARM_EXCEPTION_EL1_SERROR:
-		kvm_inject_vabt(vcpu);
+		kvm_handle_guest_serror(vcpu, kvm_vcpu_get_hsr(vcpu));
 		return 1;
 	case ARM_EXCEPTION_TRAP:
 		/*
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:58   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

We expect to have firmware-first handling of RAS SErrors, with errors
notified via an APEI method. For systems without firmware-first, add
some minimal handling to KVM.

There are two ways KVM can take an SError due to a guest, either may be a
RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.

The current SError from EL2 code unmasks SError and tries to fence any
pending SError into a single instruction window. It then leaves SError
unmasked.

With the v8.2 RAS Extensions we may take an SError for a 'corrected'
error, but KVM is only able to handle SError from EL2 if they occur
during this single instruction window...

The RAS Extensions give us a new instruction to synchronise and
consume SErrors. The RAS Extensions document (ARM DDI0587),
'2.4.1 ESB and Unrecoverable errors' describes ESB as synchronising
SError interrupts generated by 'instructions, translation table walks,
hardware updates to the translation tables, and instruction fetches on
the same PE'. This makes ESB equivalent to KVMs existing
'dsb, mrs-daifclr, isb' sequence.

Use the alternatives to synchronise and consume any SError using ESB
instead of unmasking and taking the SError. Set ARM_EXIT_WITH_SERROR_BIT
in the exit_code so that we can restart the vcpu if it turns out this
SError has no impact on the vcpu.

Signed-off-by: James Morse <james.morse@arm.com>

---
Changes since v3:
 * Moved that nop out of the firing line

 arch/arm64/include/asm/kvm_emulate.h |  5 +++++
 arch/arm64/include/asm/kvm_host.h    |  1 +
 arch/arm64/kernel/asm-offsets.c      |  1 +
 arch/arm64/kvm/handle_exit.c         | 10 +++++++++-
 arch/arm64/kvm/hyp/entry.S           | 13 +++++++++++++
 5 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 8a7a838eb17a..8274d16df3cd 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -173,6 +173,11 @@ static inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu)
 	return ((phys_addr_t)vcpu->arch.fault.hpfar_el2 & HPFAR_MASK) << 8;
 }
 
+static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.fault.disr_el1;
+}
+
 static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu)
 {
 	return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_xVC_IMM_MASK;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 97438cc3a9ad..cf5d78ba14b5 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -89,6 +89,7 @@ struct kvm_vcpu_fault_info {
 	u32 esr_el2;		/* Hyp Syndrom Register */
 	u64 far_el2;		/* Hyp Fault Address Register */
 	u64 hpfar_el2;		/* Hyp IPA Fault Address Register */
+	u64 disr_el1;		/* Deferred [SError] Status Register */
 };
 
 /*
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 71bf088f1e4b..121889c49542 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -130,6 +130,7 @@ int main(void)
   BLANK();
 #ifdef CONFIG_KVM_ARM_HOST
   DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
+  DEFINE(VCPU_FAULT_DISR,	offsetof(struct kvm_vcpu, arch.fault.disr_el1));
   DEFINE(CPU_GP_REGS,		offsetof(struct kvm_cpu_context, gp_regs));
   DEFINE(CPU_USER_PT_REGS,	offsetof(struct kvm_regs, regs));
   DEFINE(CPU_FP_REGS,		offsetof(struct kvm_regs, fp_regs));
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 345fdbba6c2e..e1e6cfe7d4d9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -23,6 +23,7 @@
 #include <linux/kvm_host.h>
 
 #include <asm/esr.h>
+#include <asm/exception.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_coproc.h>
 #include <asm/kvm_emulate.h>
@@ -208,7 +209,14 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
 			*vcpu_pc(vcpu) -= adj;
 		}
 
-		kvm_inject_vabt(vcpu);
+		if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
+			u64 disr = kvm_vcpu_get_disr(vcpu);
+
+			kvm_handle_guest_serror(vcpu, disr_to_esr(disr));
+		} else {
+			kvm_inject_vabt(vcpu);
+		}
+
 		return 1;
 	}
 
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index 12ee62d6d410..024c7afc78f8 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -124,6 +124,17 @@ ENTRY(__guest_exit)
 	// Now restore the host regs
 	restore_callee_saved_regs x2
 
+alternative_if ARM64_HAS_RAS_EXTN
+	// If we have the RAS extensions we can consume a pending error
+	// without an unmask-SError and isb.
+	esb
+	mrs_s	x2, SYS_DISR_EL1
+	str	x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
+	cbz	x2, 1f
+	msr_s	SYS_DISR_EL1, xzr
+	orr	x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
+1:	ret
+alternative_else
 	// If we have a pending asynchronous abort, now is the
 	// time to find out. From your VAXorcist book, page 666:
 	// "Threaten me not, oh Evil one!  For I speak with
@@ -134,7 +145,9 @@ ENTRY(__guest_exit)
 	mov	x5, x0
 
 	dsb	sy		// Synchronize against in-flight ld/st
+	nop
 	msr	daifclr, #4	// Unmask aborts
+alternative_endif
 
 	// This is our single instruction exception window. A pending
 	// SError is guaranteed to occur at the earliest when we unmask
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
@ 2017-10-19 14:58   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

We expect to have firmware-first handling of RAS SErrors, with errors
notified via an APEI method. For systems without firmware-first, add
some minimal handling to KVM.

There are two ways KVM can take an SError due to a guest, either may be a
RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.

The current SError from EL2 code unmasks SError and tries to fence any
pending SError into a single instruction window. It then leaves SError
unmasked.

With the v8.2 RAS Extensions we may take an SError for a 'corrected'
error, but KVM is only able to handle SError from EL2 if they occur
during this single instruction window...

The RAS Extensions give us a new instruction to synchronise and
consume SErrors. The RAS Extensions document (ARM DDI0587),
'2.4.1 ESB and Unrecoverable errors' describes ESB as synchronising
SError interrupts generated by 'instructions, translation table walks,
hardware updates to the translation tables, and instruction fetches on
the same PE'. This makes ESB equivalent to KVMs existing
'dsb, mrs-daifclr, isb' sequence.

Use the alternatives to synchronise and consume any SError using ESB
instead of unmasking and taking the SError. Set ARM_EXIT_WITH_SERROR_BIT
in the exit_code so that we can restart the vcpu if it turns out this
SError has no impact on the vcpu.

Signed-off-by: James Morse <james.morse@arm.com>

---
Changes since v3:
 * Moved that nop out of the firing line

 arch/arm64/include/asm/kvm_emulate.h |  5 +++++
 arch/arm64/include/asm/kvm_host.h    |  1 +
 arch/arm64/kernel/asm-offsets.c      |  1 +
 arch/arm64/kvm/handle_exit.c         | 10 +++++++++-
 arch/arm64/kvm/hyp/entry.S           | 13 +++++++++++++
 5 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 8a7a838eb17a..8274d16df3cd 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -173,6 +173,11 @@ static inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu)
 	return ((phys_addr_t)vcpu->arch.fault.hpfar_el2 & HPFAR_MASK) << 8;
 }
 
+static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.fault.disr_el1;
+}
+
 static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu)
 {
 	return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_xVC_IMM_MASK;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 97438cc3a9ad..cf5d78ba14b5 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -89,6 +89,7 @@ struct kvm_vcpu_fault_info {
 	u32 esr_el2;		/* Hyp Syndrom Register */
 	u64 far_el2;		/* Hyp Fault Address Register */
 	u64 hpfar_el2;		/* Hyp IPA Fault Address Register */
+	u64 disr_el1;		/* Deferred [SError] Status Register */
 };
 
 /*
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 71bf088f1e4b..121889c49542 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -130,6 +130,7 @@ int main(void)
   BLANK();
 #ifdef CONFIG_KVM_ARM_HOST
   DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
+  DEFINE(VCPU_FAULT_DISR,	offsetof(struct kvm_vcpu, arch.fault.disr_el1));
   DEFINE(CPU_GP_REGS,		offsetof(struct kvm_cpu_context, gp_regs));
   DEFINE(CPU_USER_PT_REGS,	offsetof(struct kvm_regs, regs));
   DEFINE(CPU_FP_REGS,		offsetof(struct kvm_regs, fp_regs));
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 345fdbba6c2e..e1e6cfe7d4d9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -23,6 +23,7 @@
 #include <linux/kvm_host.h>
 
 #include <asm/esr.h>
+#include <asm/exception.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_coproc.h>
 #include <asm/kvm_emulate.h>
@@ -208,7 +209,14 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
 			*vcpu_pc(vcpu) -= adj;
 		}
 
-		kvm_inject_vabt(vcpu);
+		if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
+			u64 disr = kvm_vcpu_get_disr(vcpu);
+
+			kvm_handle_guest_serror(vcpu, disr_to_esr(disr));
+		} else {
+			kvm_inject_vabt(vcpu);
+		}
+
 		return 1;
 	}
 
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index 12ee62d6d410..024c7afc78f8 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -124,6 +124,17 @@ ENTRY(__guest_exit)
 	// Now restore the host regs
 	restore_callee_saved_regs x2
 
+alternative_if ARM64_HAS_RAS_EXTN
+	// If we have the RAS extensions we can consume a pending error
+	// without an unmask-SError and isb.
+	esb
+	mrs_s	x2, SYS_DISR_EL1
+	str	x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
+	cbz	x2, 1f
+	msr_s	SYS_DISR_EL1, xzr
+	orr	x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
+1:	ret
+alternative_else
 	// If we have a pending asynchronous abort, now is the
 	// time to find out. From your VAXorcist book, page 666:
 	// "Threaten me not, oh Evil one!  For I speak with
@@ -134,7 +145,9 @@ ENTRY(__guest_exit)
 	mov	x5, x0
 
 	dsb	sy		// Synchronize against in-flight ld/st
+	nop
 	msr	daifclr, #4	// Unmask aborts
+alternative_endif
 
 	// This is our single instruction exception window. A pending
 	// SError is guaranteed to occur@the earliest when we unmask
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:58   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

On VHE systems KVM masks SError before switching the VBAR value. Any
host RAS error that the CPU knew about before world-switch may become
pending as an SError during world-switch, and only be taken once we enter
the guest.

Until KVM can take RAS SErrors during world switch, add an ESB to
force any RAS errors to be synchronised and taken on the host before
we enter world switch.

RAS errors that become pending during world switch are still taken
once we enter the guest.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index cf5d78ba14b5..5dc6f2877762 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
 
 static inline void kvm_arm_vhe_guest_enter(void)
 {
+	esb();
 	local_daif_mask();
 }
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
@ 2017-10-19 14:58   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

On VHE systems KVM masks SError before switching the VBAR value. Any
host RAS error that the CPU knew about before world-switch may become
pending as an SError during world-switch, and only be taken once we enter
the guest.

Until KVM can take RAS SErrors during world switch, add an ESB to
force any RAS errors to be synchronised and taken on the host before
we enter world switch.

RAS errors that become pending during world switch are still taken
once we enter the guest.

Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index cf5d78ba14b5..5dc6f2877762 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
 
 static inline void kvm_arm_vhe_guest_enter(void)
 {
+	esb();
 	local_daif_mask();
 }
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 21/21] KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA
  2017-10-19 14:57 ` James Morse
@ 2017-10-19 14:58   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm

From: Dongjiu Geng <gengdongjiu@huawei.com>

ARMv8.2 adds a new bit HCR_EL2.TEA which routes synchronous external
aborts to EL2, and adds a trap control bit HCR_EL2.TERR which traps
all Non-secure EL1&0 error record accesses to EL2.

This patch enables the two bits for the guest OS, guaranteeing that
KVM takes external aborts and traps attempts to access the physical
error registers.

ERRIDR_EL1 advertises the number of error records, we return
zero meaning we can treat all the other registers as RAZ/WI too.

Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
[removed specific emulation, use trap_raz_wi() directly for everything,
 rephrased parts of the commit message]
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_arm.h     |  2 ++
 arch/arm64/include/asm/kvm_emulate.h |  7 +++++++
 arch/arm64/include/asm/sysreg.h      | 10 ++++++++++
 arch/arm64/kvm/sys_regs.c            | 10 ++++++++++
 4 files changed, 29 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 61d694c2eae5..1188272003c4 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -23,6 +23,8 @@
 #include <asm/types.h>
 
 /* Hyp Configuration Register (HCR) bits */
+#define HCR_TEA		(UL(1) << 37)
+#define HCR_TERR	(UL(1) << 36)
 #define HCR_E2H		(UL(1) << 34)
 #define HCR_ID		(UL(1) << 33)
 #define HCR_CD		(UL(1) << 32)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 8274d16df3cd..2cd666a9d47e 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -47,6 +47,13 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
 	if (is_kernel_in_hyp_mode())
 		vcpu->arch.hcr_el2 |= HCR_E2H;
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
+		/* route synchronous external abort exceptions to EL2 */
+		vcpu->arch.hcr_el2 |= HCR_TEA;
+		/* trap error record accesses */
+		vcpu->arch.hcr_el2 |= HCR_TERR;
+	}
+
 	if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
 		vcpu->arch.hcr_el2 &= ~HCR_RW;
 }
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 1b8b9012234d..0d3c5c7bb425 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -169,6 +169,16 @@
 #define SYS_AFSR0_EL1			sys_reg(3, 0, 5, 1, 0)
 #define SYS_AFSR1_EL1			sys_reg(3, 0, 5, 1, 1)
 #define SYS_ESR_EL1			sys_reg(3, 0, 5, 2, 0)
+
+#define SYS_ERRIDR_EL1			sys_reg(3, 0, 5, 3, 0)
+#define SYS_ERRSELR_EL1			sys_reg(3, 0, 5, 3, 1)
+#define SYS_ERXFR_EL1			sys_reg(3, 0, 5, 4, 0)
+#define SYS_ERXCTLR_EL1			sys_reg(3, 0, 5, 4, 1)
+#define SYS_ERXSTATUS_EL1		sys_reg(3, 0, 5, 4, 2)
+#define SYS_ERXADDR_EL1			sys_reg(3, 0, 5, 4, 3)
+#define SYS_ERXMISC0_EL1		sys_reg(3, 0, 5, 5, 0)
+#define SYS_ERXMISC1_EL1		sys_reg(3, 0, 5, 5, 1)
+
 #define SYS_FAR_EL1			sys_reg(3, 0, 6, 0, 0)
 #define SYS_PAR_EL1			sys_reg(3, 0, 7, 4, 0)
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 713275b501ce..2b3b16bf5275 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -953,6 +953,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
 	{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
 	{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
+
+	{ SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
+
 	{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
 	{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* [PATCH v4 21/21] KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA
@ 2017-10-19 14:58   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-19 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

From: Dongjiu Geng <gengdongjiu@huawei.com>

ARMv8.2 adds a new bit HCR_EL2.TEA which routes synchronous external
aborts to EL2, and adds a trap control bit HCR_EL2.TERR which traps
all Non-secure EL1&0 error record accesses to EL2.

This patch enables the two bits for the guest OS, guaranteeing that
KVM takes external aborts and traps attempts to access the physical
error registers.

ERRIDR_EL1 advertises the number of error records, we return
zero meaning we can treat all the other registers as RAZ/WI too.

Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
[removed specific emulation, use trap_raz_wi() directly for everything,
 rephrased parts of the commit message]
Signed-off-by: James Morse <james.morse@arm.com>
---
 arch/arm64/include/asm/kvm_arm.h     |  2 ++
 arch/arm64/include/asm/kvm_emulate.h |  7 +++++++
 arch/arm64/include/asm/sysreg.h      | 10 ++++++++++
 arch/arm64/kvm/sys_regs.c            | 10 ++++++++++
 4 files changed, 29 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 61d694c2eae5..1188272003c4 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -23,6 +23,8 @@
 #include <asm/types.h>
 
 /* Hyp Configuration Register (HCR) bits */
+#define HCR_TEA		(UL(1) << 37)
+#define HCR_TERR	(UL(1) << 36)
 #define HCR_E2H		(UL(1) << 34)
 #define HCR_ID		(UL(1) << 33)
 #define HCR_CD		(UL(1) << 32)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 8274d16df3cd..2cd666a9d47e 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -47,6 +47,13 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
 	if (is_kernel_in_hyp_mode())
 		vcpu->arch.hcr_el2 |= HCR_E2H;
+	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
+		/* route synchronous external abort exceptions to EL2 */
+		vcpu->arch.hcr_el2 |= HCR_TEA;
+		/* trap error record accesses */
+		vcpu->arch.hcr_el2 |= HCR_TERR;
+	}
+
 	if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
 		vcpu->arch.hcr_el2 &= ~HCR_RW;
 }
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 1b8b9012234d..0d3c5c7bb425 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -169,6 +169,16 @@
 #define SYS_AFSR0_EL1			sys_reg(3, 0, 5, 1, 0)
 #define SYS_AFSR1_EL1			sys_reg(3, 0, 5, 1, 1)
 #define SYS_ESR_EL1			sys_reg(3, 0, 5, 2, 0)
+
+#define SYS_ERRIDR_EL1			sys_reg(3, 0, 5, 3, 0)
+#define SYS_ERRSELR_EL1			sys_reg(3, 0, 5, 3, 1)
+#define SYS_ERXFR_EL1			sys_reg(3, 0, 5, 4, 0)
+#define SYS_ERXCTLR_EL1			sys_reg(3, 0, 5, 4, 1)
+#define SYS_ERXSTATUS_EL1		sys_reg(3, 0, 5, 4, 2)
+#define SYS_ERXADDR_EL1			sys_reg(3, 0, 5, 4, 3)
+#define SYS_ERXMISC0_EL1		sys_reg(3, 0, 5, 5, 0)
+#define SYS_ERXMISC1_EL1		sys_reg(3, 0, 5, 5, 1)
+
 #define SYS_FAR_EL1			sys_reg(3, 0, 6, 0, 0)
 #define SYS_PAR_EL1			sys_reg(3, 0, 7, 4, 0)
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 713275b501ce..2b3b16bf5275 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -953,6 +953,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
 	{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
 	{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
+
+	{ SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
+
 	{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
 	{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
 
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-19 14:58   ` James Morse
@ 2017-10-20 16:44     ` gengdongjiu
  -1 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-10-20 16:44 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Julien Thierry, Marc Zyngier, Catalin Marinas,
	Will Deacon, Dongjiu Geng, kvmarm, Xiongfeng Wang, arm-mail-list

2017-10-19 22:58 GMT+08:00 James Morse <james.morse@arm.com>:
> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> generated an SError with an implementation defined ESR_EL1.ISS, because we
> had no mechanism to specify the ESR value.
>
> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> is clear indicating the remainder of the ISS field is invalid.
>
> With the RAS Extensions we have a mechanism to specify this value, and the
> most significant bit has a new meaning: 'IDS - Implementation Defined
> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> instead of 'no valid ISS'.

consider again.

I still consider that it is not better set  "Implementation Defined
Syndrome" here.
I know your meaning that An all-zero SError means Uncategorized
>From the beginning,  our starting point is KVM is the architecture
related and Qemu/kvmtool is platform related.
Qemu/kvmtool is the role of host firmware.
so we let Qemu to create APEI/GHES table and record CPER,
and also injects SEA/SEI in the Qemu.

About the vsesr_el2 which is used to specify the guest ESR,   also all
set by Qemu/kvmtool are better.
including the three cases  even the ESR are  all-zero(uncategorized).
1. IMPLEMENTATION DEFINED
2  categorized,
3  uncategorized,

For this case, Qemu just set the ESR, nothing else, not passing
RAS-error to userspace.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-20 16:44     ` gengdongjiu
  0 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-10-20 16:44 UTC (permalink / raw)
  To: linux-arm-kernel

2017-10-19 22:58 GMT+08:00 James Morse <james.morse@arm.com>:
> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> generated an SError with an implementation defined ESR_EL1.ISS, because we
> had no mechanism to specify the ESR value.
>
> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> is clear indicating the remainder of the ISS field is invalid.
>
> With the RAS Extensions we have a mechanism to specify this value, and the
> most significant bit has a new meaning: 'IDS - Implementation Defined
> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> instead of 'no valid ISS'.

consider again.

I still consider that it is not better set  "Implementation Defined
Syndrome" here.
I know your meaning that An all-zero SError means Uncategorized
>From the beginning,  our starting point is KVM is the architecture
related and Qemu/kvmtool is platform related.
Qemu/kvmtool is the role of host firmware.
so we let Qemu to create APEI/GHES table and record CPER,
and also injects SEA/SEI in the Qemu.

About the vsesr_el2 which is used to specify the guest ESR,   also all
set by Qemu/kvmtool are better.
including the three cases  even the ESR are  all-zero(uncategorized).
1. IMPLEMENTATION DEFINED
2  categorized,
3  uncategorized,

For this case, Qemu just set the ESR, nothing else, not passing
RAS-error to userspace.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-20 16:44     ` gengdongjiu
@ 2017-10-23 15:26       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-23 15:26 UTC (permalink / raw)
  To: gengdongjiu
  Cc: Jonathan.Zhang, Julien Thierry, Marc Zyngier, Catalin Marinas,
	Will Deacon, Dongjiu Geng, kvmarm, Xiongfeng Wang, arm-mail-list

Hi gengdongjiu,

On 20/10/17 17:44, gengdongjiu wrote:
> 2017-10-19 22:58 GMT+08:00 James Morse <james.morse@arm.com>:
>> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
>> generated an SError with an implementation defined ESR_EL1.ISS, because we
>> had no mechanism to specify the ESR value.
>>
>> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
>> is clear indicating the remainder of the ISS field is invalid.
>>
>> With the RAS Extensions we have a mechanism to specify this value, and the
>> most significant bit has a new meaning: 'IDS - Implementation Defined
>> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
>> instead of 'no valid ISS'.
> 
> consider again.

> I still consider that it is not better set  "Implementation Defined
> Syndrome" here.

Do you agree KVM does this today?
ddb3d07cfe90 ("arm64: KVM: Inject a Virtual SError if it was pending")

All I've changed here is that you don't get a RAS error passed into the guest.
Its either deemed non-blocking and ignored, or we kick the guest with an impdef
SError.

To do any better we need kernel first support, or a firmware first notification.


> I know your meaning that An all-zero SError means Uncategorized

Uncategorized RAS error. RAS errors should be handled by the host, we should not
inject them into the guest on a path like this.

Which impdef ESR would you like to use, and why does it matter?


> From the beginning,  our starting point is KVM is the architecture
> related and Qemu/kvmtool is platform related.
> Qemu/kvmtool is the role of host firmware.
> so we let Qemu to create APEI/GHES table and record CPER,

> and also injects SEA/SEI in the Qemu.

For RAS events it generated all by itself, or was notified by the kernel using
signals.

This is not one of those cases. But that's fine as we aren't injecting a RAS error.


> About the vsesr_el2 which is used to specify the guest ESR,   also all
> set by Qemu/kvmtool are better.
> including the three cases  even the ESR are  all-zero(uncategorized).
> 1. IMPLEMENTATION DEFINED
> 2  categorized,
> 3  uncategorized,

I can't work out what you're saying here.

If you're suggesting Qemu should set a default 'unknown' ESR for use when KVM
doesn't know what to do, and SError is pretty much its only option:

Why would Qemu set anything other than impdef:all-zeros?

The only use would be to fake this back into a RAS error. Qemu isn't involved
here so this can't be used to emulate NOTIFY_SEI without the kernel support. We
don't have support for emulating the RAS ERR registers either, so this can't be
used to emulate kernel first.


If you're suggesting Qemu should specify a set of ESR values for the different
cases where KVM doesn't know what do: this would be an early shortcut that burns
us in the future, these things are going to be changed. This is too specific to
KVMs internals:

When we add NOTIFY_SEI support, we will call out of this KVM code and APEI
should 'claim' any SError that arrived with CPER records.

I expect this code to change dramatically if/when we add kernel first support.


The KVM patches on the end of this series are just the minimum needed to enable
IESB and keep the status quo for all other behaviour. And this is just so we can
tackle the other bits of support that depends on the cpufeature without
reposting all the same code.



James


> For this case, Qemu just set the ESR, nothing else, not passing
> RAS-error to userspace.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-23 15:26       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-23 15:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi gengdongjiu,

On 20/10/17 17:44, gengdongjiu wrote:
> 2017-10-19 22:58 GMT+08:00 James Morse <james.morse@arm.com>:
>> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
>> generated an SError with an implementation defined ESR_EL1.ISS, because we
>> had no mechanism to specify the ESR value.
>>
>> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
>> is clear indicating the remainder of the ISS field is invalid.
>>
>> With the RAS Extensions we have a mechanism to specify this value, and the
>> most significant bit has a new meaning: 'IDS - Implementation Defined
>> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
>> instead of 'no valid ISS'.
> 
> consider again.

> I still consider that it is not better set  "Implementation Defined
> Syndrome" here.

Do you agree KVM does this today?
ddb3d07cfe90 ("arm64: KVM: Inject a Virtual SError if it was pending")

All I've changed here is that you don't get a RAS error passed into the guest.
Its either deemed non-blocking and ignored, or we kick the guest with an impdef
SError.

To do any better we need kernel first support, or a firmware first notification.


> I know your meaning that An all-zero SError means Uncategorized

Uncategorized RAS error. RAS errors should be handled by the host, we should not
inject them into the guest on a path like this.

Which impdef ESR would you like to use, and why does it matter?


> From the beginning,  our starting point is KVM is the architecture
> related and Qemu/kvmtool is platform related.
> Qemu/kvmtool is the role of host firmware.
> so we let Qemu to create APEI/GHES table and record CPER,

> and also injects SEA/SEI in the Qemu.

For RAS events it generated all by itself, or was notified by the kernel using
signals.

This is not one of those cases. But that's fine as we aren't injecting a RAS error.


> About the vsesr_el2 which is used to specify the guest ESR,   also all
> set by Qemu/kvmtool are better.
> including the three cases  even the ESR are  all-zero(uncategorized).
> 1. IMPLEMENTATION DEFINED
> 2  categorized,
> 3  uncategorized,

I can't work out what you're saying here.

If you're suggesting Qemu should set a default 'unknown' ESR for use when KVM
doesn't know what to do, and SError is pretty much its only option:

Why would Qemu set anything other than impdef:all-zeros?

The only use would be to fake this back into a RAS error. Qemu isn't involved
here so this can't be used to emulate NOTIFY_SEI without the kernel support. We
don't have support for emulating the RAS ERR registers either, so this can't be
used to emulate kernel first.


If you're suggesting Qemu should specify a set of ESR values for the different
cases where KVM doesn't know what do: this would be an early shortcut that burns
us in the future, these things are going to be changed. This is too specific to
KVMs internals:

When we add NOTIFY_SEI support, we will call out of this KVM code and APEI
should 'claim' any SError that arrived with CPER records.

I expect this code to change dramatically if/when we add kernel first support.


The KVM patches on the end of this series are just the minimum needed to enable
IESB and keep the status quo for all other behaviour. And this is just so we can
tackle the other bits of support that depends on the cpufeature without
reposting all the same code.



James


> For this case, Qemu just set the ESR, nothing else, not passing
> RAS-error to userspace.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-23 15:26       ` James Morse
@ 2017-10-24  9:53         ` gengdongjiu
  -1 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-10-24  9:53 UTC (permalink / raw)
  To: James Morse, gengdongjiu
  Cc: Jonathan.Zhang, Julien Thierry, Marc Zyngier, Catalin Marinas,
	Will Deacon, kvmarm, Xiongfeng Wang, arm-mail-list

Hi James,

On 2017/10/23 23:26, James Morse wrote:
> If you're suggesting Qemu should set a default 'unknown' ESR for use when KVM
> doesn't know what to do, and SError is pretty much its only option:
> 
> Why would Qemu set anything other than impdef:all-zeros?
> 
> The only use would be to fake this back into a RAS error. Qemu isn't involved
> here so this can't be used to emulate NOTIFY_SEI without the kernel support. We
> don't have support for emulating the RAS ERR registers either, so this can't be
> used to emulate kernel first.
> 
> 
> If you're suggesting Qemu should specify a set of ESR values for the different
> cases where KVM doesn't know what do: this would be an early shortcut that burns
> us in the future, these things are going to be changed. This is too specific to
> KVMs internals:
> 
> When we add NOTIFY_SEI support, we will call out of this KVM code and APEI
> should 'claim' any SError that arrived with CPER records.
> 
> I expect this code to change dramatically if/when we add kernel first support.
> 
> 
> The KVM patches on the end of this series are just the minimum needed to enable
> IESB and keep the status quo for all other behaviour. And this is just so we can
> tackle the other bits of support that depends on the cpufeature without
> reposting all the same code.

Thanks very much for your explanation, understand it now.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-24  9:53         ` gengdongjiu
  0 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-10-24  9:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi James,

On 2017/10/23 23:26, James Morse wrote:
> If you're suggesting Qemu should set a default 'unknown' ESR for use when KVM
> doesn't know what to do, and SError is pretty much its only option:
> 
> Why would Qemu set anything other than impdef:all-zeros?
> 
> The only use would be to fake this back into a RAS error. Qemu isn't involved
> here so this can't be used to emulate NOTIFY_SEI without the kernel support. We
> don't have support for emulating the RAS ERR registers either, so this can't be
> used to emulate kernel first.
> 
> 
> If you're suggesting Qemu should specify a set of ESR values for the different
> cases where KVM doesn't know what do: this would be an early shortcut that burns
> us in the future, these things are going to be changed. This is too specific to
> KVMs internals:
> 
> When we add NOTIFY_SEI support, we will call out of this KVM code and APEI
> should 'claim' any SError that arrived with CPER records.
> 
> I expect this code to change dramatically if/when we add kernel first support.
> 
> 
> The KVM patches on the end of this series are just the minimum needed to enable
> IESB and keep the status quo for all other behaviour. And this is just so we can
> tackle the other bits of support that depends on the cpufeature without
> reposting all the same code.

Thanks very much for your explanation, understand it now.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
  2017-10-19 14:58   ` James Morse
@ 2017-10-27  6:26     ` gengdongjiu
  -1 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-10-27  6:26 UTC (permalink / raw)
  To: James Morse, linux-arm-kernel
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, kvmarm



On 2017/10/19 22:58, James Morse wrote:
> +alternative_if ARM64_HAS_RAS_EXTN
> +	// If we have the RAS extensions we can consume a pending error
> +	// without an unmask-SError and isb.
> +	esb
> +	mrs_s	x2, SYS_DISR_EL1
I do not think you can get the right value when esb produce a SError. when
SError happen, it will take to EL3 firmware immediately. so the disr_el1 will not record
the error and value is 0.

> +	str	x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
> +	cbz	x2, 1f
why will jump to 1, if there is not SError, also "ret"?

> +	msr_s	SYS_DISR_EL1, xzr
> +	orr	x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
> +1:	ret
> +alternative_else

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
@ 2017-10-27  6:26     ` gengdongjiu
  0 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-10-27  6:26 UTC (permalink / raw)
  To: linux-arm-kernel



On 2017/10/19 22:58, James Morse wrote:
> +alternative_if ARM64_HAS_RAS_EXTN
> +	// If we have the RAS extensions we can consume a pending error
> +	// without an unmask-SError and isb.
> +	esb
> +	mrs_s	x2, SYS_DISR_EL1
I do not think you can get the right value when esb produce a SError. when
SError happen, it will take to EL3 firmware immediately. so the disr_el1 will not record
the error and value is 0.

> +	str	x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
> +	cbz	x2, 1f
why will jump to 1, if there is not SError, also "ret"?

> +	msr_s	SYS_DISR_EL1, xzr
> +	orr	x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
> +1:	ret
> +alternative_else

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
  2017-10-27  6:26     ` gengdongjiu
@ 2017-10-27 17:38       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-27 17:38 UTC (permalink / raw)
  To: gengdongjiu
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, kvmarm

Hi gengdongjiu,

On 27/10/17 07:26, gengdongjiu wrote:
> On 2017/10/19 22:58, James Morse wrote:
>> +alternative_if ARM64_HAS_RAS_EXTN
>> +	// If we have the RAS extensions we can consume a pending error
>> +	// without an unmask-SError and isb.
>> +	esb
>> +	mrs_s	x2, SYS_DISR_EL1

> I do not think you can get the right value when esb produce a SError. when
> SError happen, it will take to EL3 firmware immediately. so the disr_el1 will not record
> the error and value is 0.

This depends on SCR_EL3.EA, which the normal-world can't know about.

Your system sets SCR_EL3.EA, and takes the SError to EL3. It's now up to
firmware to notify the normal world via some firmware-first mechanism.

What does KVM do? SCR_EL3.EA makes DISR_EL1 RAZ/WI, so yes, it reads 0 here,
notes there is no SError pending, and it continues on its merry way. Firmware is
left to pick up the pieces and notify the normal world about the error.


What if SCR_EL3.EA is clear? Now SCTLR_EL2.IESB's ErrorSynchronizationBarrier
causes any RAS error the CPU has deferred to become a pending SError. But SError
is masked because we took an exception.
Running the ESB-instruction consumes any pending SError and writes its ESR into
DISR_EL1.

What does KVM do? Reads the value and sets the ARM_EXIT_WITH_SERROR_BIT if there
was an error pending.


>> +	str	x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
>> +	cbz	x2, 1f

> why will jump to 1, if there is not SError, also "ret"?

jump to 1: to avoid the cost of writing zero back to DISR_EL1 if its already
zero and skip setting the ARM_EXIT_WITH_SERROR_BIT, as there was no SError.

ret: because this is what happens at the end of the vaxorcism code. We need to
run that as with the ARMv8.2 RAS Extensions we have a better way of consuming
SError from the CPU without taking them as an exception.


>> +	msr_s	SYS_DISR_EL1, xzr
>> +	orr	x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
>> +1:	ret
>> +alternative_else


James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
@ 2017-10-27 17:38       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-27 17:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi gengdongjiu,

On 27/10/17 07:26, gengdongjiu wrote:
> On 2017/10/19 22:58, James Morse wrote:
>> +alternative_if ARM64_HAS_RAS_EXTN
>> +	// If we have the RAS extensions we can consume a pending error
>> +	// without an unmask-SError and isb.
>> +	esb
>> +	mrs_s	x2, SYS_DISR_EL1

> I do not think you can get the right value when esb produce a SError. when
> SError happen, it will take to EL3 firmware immediately. so the disr_el1 will not record
> the error and value is 0.

This depends on SCR_EL3.EA, which the normal-world can't know about.

Your system sets SCR_EL3.EA, and takes the SError to EL3. It's now up to
firmware to notify the normal world via some firmware-first mechanism.

What does KVM do? SCR_EL3.EA makes DISR_EL1 RAZ/WI, so yes, it reads 0 here,
notes there is no SError pending, and it continues on its merry way. Firmware is
left to pick up the pieces and notify the normal world about the error.


What if SCR_EL3.EA is clear? Now SCTLR_EL2.IESB's ErrorSynchronizationBarrier
causes any RAS error the CPU has deferred to become a pending SError. But SError
is masked because we took an exception.
Running the ESB-instruction consumes any pending SError and writes its ESR into
DISR_EL1.

What does KVM do? Reads the value and sets the ARM_EXIT_WITH_SERROR_BIT if there
was an error pending.


>> +	str	x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
>> +	cbz	x2, 1f

> why will jump to 1, if there is not SError, also "ret"?

jump to 1: to avoid the cost of writing zero back to DISR_EL1 if its already
zero and skip setting the ARM_EXIT_WITH_SERROR_BIT, as there was no SError.

ret: because this is what happens at the end of the vaxorcism code. We need to
run that as with the ARMv8.2 RAS Extensions we have a better way of consuming
SError from the CPU without taking them as an exception.


>> +	msr_s	SYS_DISR_EL1, xzr
>> +	orr	x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
>> +1:	ret
>> +alternative_else


James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
  2017-10-19 14:57   ` James Morse
@ 2017-10-30  7:40     ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-30  7:40 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
> Non-VHE systems take an exception to EL2 in order to world-switch into the
> guest. When returning from the guest KVM implicitly restores the DAIF
> flags when it returns to the kernel at EL1.
> 
> With VHE none of this exception-level jumping happens, so KVMs
> world-switch code is exposed to the host kernel's DAIF values, and KVM
> spills the guest-exit DAIF values back into the host kernel.
> On entry to a guest we have Debug and SError exceptions unmasked, KVM
> has switched VBAR but isn't prepared to handle these. On guest exit
> Debug exceptions are left disabled once we return to the host and will
> stay this way until we enter user space.
> 
> Add a helper to mask/unmask DAIF around VHE guests. The unmask can only
> happen after the hosts VBAR value has been synchronised by the isb in
> __vhe_hyp_call (via kvm_call_hyp()). Masking could be as late as
> setting KVMs VBAR value, but is kept here for symmetry.
> 
> Signed-off-by: James Morse <james.morse@arm.com>
> 

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
> Give me a kick if you want this reworked as a fix (which will then
> conflict with this series), or a backportable version.

I don't know of any real-world issues where some more graceful handling
of SErrors would make sense on older kernels, so I'm fine with just
merging this together with this series.

Thanks,
-Christoffer


> 
>  arch/arm64/include/asm/kvm_host.h | 10 ++++++++++
>  virt/kvm/arm/arm.c                |  4 ++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index e923b58606e2..a0e2f7962401 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -25,6 +25,7 @@
>  #include <linux/types.h>
>  #include <linux/kvm_types.h>
>  #include <asm/cpufeature.h>
> +#include <asm/daifflags.h>
>  #include <asm/kvm.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_mmio.h>
> @@ -384,4 +385,13 @@ static inline void __cpu_init_stage2(void)
>  		  "PARange is %d bits, unsupported configuration!", parange);
>  }
>  
> +static inline void kvm_arm_vhe_guest_enter(void)
> +{
> +	local_daif_mask();
> +}
> +
> +static inline void kvm_arm_vhe_guest_exit(void)
> +{
> +	local_daif_restore(DAIF_PROCCTX_NOIRQ);
> +}
>  #endif /* __ARM64_KVM_HOST_H__ */
> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
> index b9f68e4add71..665529924b34 100644
> --- a/virt/kvm/arm/arm.c
> +++ b/virt/kvm/arm/arm.c
> @@ -698,9 +698,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  		 */
>  		trace_kvm_entry(*vcpu_pc(vcpu));
>  		guest_enter_irqoff();
> +		if (has_vhe())
> +			kvm_arm_vhe_guest_enter();
>  
>  		ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
>  
> +		if (has_vhe())
> +			kvm_arm_vhe_guest_exit();
>  		vcpu->mode = OUTSIDE_GUEST_MODE;
>  		vcpu->stat.exits++;
>  		/*
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
@ 2017-10-30  7:40     ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-30  7:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
> Non-VHE systems take an exception to EL2 in order to world-switch into the
> guest. When returning from the guest KVM implicitly restores the DAIF
> flags when it returns to the kernel at EL1.
> 
> With VHE none of this exception-level jumping happens, so KVMs
> world-switch code is exposed to the host kernel's DAIF values, and KVM
> spills the guest-exit DAIF values back into the host kernel.
> On entry to a guest we have Debug and SError exceptions unmasked, KVM
> has switched VBAR but isn't prepared to handle these. On guest exit
> Debug exceptions are left disabled once we return to the host and will
> stay this way until we enter user space.
> 
> Add a helper to mask/unmask DAIF around VHE guests. The unmask can only
> happen after the hosts VBAR value has been synchronised by the isb in
> __vhe_hyp_call (via kvm_call_hyp()). Masking could be as late as
> setting KVMs VBAR value, but is kept here for symmetry.
> 
> Signed-off-by: James Morse <james.morse@arm.com>
> 

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
> Give me a kick if you want this reworked as a fix (which will then
> conflict with this series), or a backportable version.

I don't know of any real-world issues where some more graceful handling
of SErrors would make sense on older kernels, so I'm fine with just
merging this together with this series.

Thanks,
-Christoffer


> 
>  arch/arm64/include/asm/kvm_host.h | 10 ++++++++++
>  virt/kvm/arm/arm.c                |  4 ++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index e923b58606e2..a0e2f7962401 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -25,6 +25,7 @@
>  #include <linux/types.h>
>  #include <linux/kvm_types.h>
>  #include <asm/cpufeature.h>
> +#include <asm/daifflags.h>
>  #include <asm/kvm.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_mmio.h>
> @@ -384,4 +385,13 @@ static inline void __cpu_init_stage2(void)
>  		  "PARange is %d bits, unsupported configuration!", parange);
>  }
>  
> +static inline void kvm_arm_vhe_guest_enter(void)
> +{
> +	local_daif_mask();
> +}
> +
> +static inline void kvm_arm_vhe_guest_exit(void)
> +{
> +	local_daif_restore(DAIF_PROCCTX_NOIRQ);
> +}
>  #endif /* __ARM64_KVM_HOST_H__ */
> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
> index b9f68e4add71..665529924b34 100644
> --- a/virt/kvm/arm/arm.c
> +++ b/virt/kvm/arm/arm.c
> @@ -698,9 +698,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  		 */
>  		trace_kvm_entry(*vcpu_pc(vcpu));
>  		guest_enter_irqoff();
> +		if (has_vhe())
> +			kvm_arm_vhe_guest_enter();
>  
>  		ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
>  
> +		if (has_vhe())
> +			kvm_arm_vhe_guest_exit();
>  		vcpu->mode = OUTSIDE_GUEST_MODE;
>  		vcpu->stat.exits++;
>  		/*
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-19 14:58   ` James Morse
@ 2017-10-30  7:59     ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-30  7:59 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Oct 19, 2017 at 03:58:01PM +0100, James Morse wrote:
> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> generated an SError with an implementation defined ESR_EL1.ISS, because we
> had no mechanism to specify the ESR value.
> 
> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> is clear indicating the remainder of the ISS field is invalid.
> 
> With the RAS Extensions we have a mechanism to specify this value, and the
> most significant bit has a new meaning: 'IDS - Implementation Defined
> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> instead of 'no valid ISS'.
> 
> Add KVM support for the VSESR_EL2 register to specify an ESR value when
> HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
> specify an implementation-defined value.
> 
> We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
> save/restores this bit during __deactivate_traps() and hardware clears the
> bit once the guest has consumed the virtual-SError.
> 
> Future patches may add an API (or KVM CAP) to pend a virtual SError with
> a specified ESR.
> 
> Cc: Dongjiu Geng <gengdongjiu@huawei.com>
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/include/asm/kvm_emulate.h |  5 +++++
>  arch/arm64/include/asm/kvm_host.h    |  3 +++
>  arch/arm64/include/asm/sysreg.h      |  1 +
>  arch/arm64/kvm/hyp/switch.c          |  4 ++++
>  arch/arm64/kvm/inject_fault.c        | 13 ++++++++++++-
>  5 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index e5df3fce0008..8a7a838eb17a 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -61,6 +61,11 @@ static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
>  	vcpu->arch.hcr_el2 = hcr;
>  }
>  
> +static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
> +{
> +	vcpu->arch.vsesr_el2 = vsesr;
> +}
> +
>  static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
>  {
>  	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc;
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index a0e2f7962401..28a4de85edee 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -277,6 +277,9 @@ struct kvm_vcpu_arch {
>  
>  	/* Detect first run of a vcpu */
>  	bool has_run_once;
> +
> +	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
> +	u64 vsesr_el2;
>  };
>  
>  #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 427c36bc5dd6..a493e93de296 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -253,6 +253,7 @@
>  
>  #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
>  #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
> +#define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
>  #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
>  
>  #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 945e79c641c4..af37658223a0 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>  		isb();
>  	}
>  	write_sysreg(val, hcr_el2);
> +
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
> +		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
> +

Just a heads up: If my optimization work gets merged, that will
eventually move stuff like this in to load/put hooks for system
registers, but I can deal with this easily, also adding a direct write
in pend_guest_serror when moving the logic around.

However, if we start architecting something more complex, it would be
good to keep in mind how to maintain minimum work on the switching path
after we've optimized the hypervisor.

>  	/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
>  	write_sysreg(1 << 15, hstr_el2);
>  	/*
> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
> index da6a8cfa54a0..52f7f66f1356 100644
> --- a/arch/arm64/kvm/inject_fault.c
> +++ b/arch/arm64/kvm/inject_fault.c
> @@ -232,14 +232,25 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
>  		inject_undef64(vcpu);
>  }
>  
> +static void pend_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
> +{
> +	vcpu_set_vsesr(vcpu, esr);
> +	vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
> +}
> +
>  /**
>   * kvm_inject_vabt - inject an async abort / SError into the guest
>   * @vcpu: The VCPU to receive the exception
>   *
>   * It is assumed that this code is called from the VCPU thread and that the
>   * VCPU therefore is not currently executing guest code.
> + *
> + * Systems with the RAS Extensions specify an imp-def ESR (ISV/IDS = 1) with
> + * the remaining ISS all-zeros so that this error is not interpreted as an
> + * uncatagorized RAS error. Without the RAS Extensions we can't specify an ESR

nit: uncategorized

> + * value, so the CPU generates an imp-def value.
>   */
>  void kvm_inject_vabt(struct kvm_vcpu *vcpu)
>  {
> -	vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
> +	pend_guest_serror(vcpu, ESR_ELx_ISV);
>  }
> -- 
> 2.13.3
> 

Otherwise:

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-30  7:59     ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-30  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:58:01PM +0100, James Morse wrote:
> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> generated an SError with an implementation defined ESR_EL1.ISS, because we
> had no mechanism to specify the ESR value.
> 
> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> is clear indicating the remainder of the ISS field is invalid.
> 
> With the RAS Extensions we have a mechanism to specify this value, and the
> most significant bit has a new meaning: 'IDS - Implementation Defined
> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> instead of 'no valid ISS'.
> 
> Add KVM support for the VSESR_EL2 register to specify an ESR value when
> HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
> specify an implementation-defined value.
> 
> We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
> save/restores this bit during __deactivate_traps() and hardware clears the
> bit once the guest has consumed the virtual-SError.
> 
> Future patches may add an API (or KVM CAP) to pend a virtual SError with
> a specified ESR.
> 
> Cc: Dongjiu Geng <gengdongjiu@huawei.com>
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/include/asm/kvm_emulate.h |  5 +++++
>  arch/arm64/include/asm/kvm_host.h    |  3 +++
>  arch/arm64/include/asm/sysreg.h      |  1 +
>  arch/arm64/kvm/hyp/switch.c          |  4 ++++
>  arch/arm64/kvm/inject_fault.c        | 13 ++++++++++++-
>  5 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index e5df3fce0008..8a7a838eb17a 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -61,6 +61,11 @@ static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
>  	vcpu->arch.hcr_el2 = hcr;
>  }
>  
> +static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
> +{
> +	vcpu->arch.vsesr_el2 = vsesr;
> +}
> +
>  static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
>  {
>  	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc;
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index a0e2f7962401..28a4de85edee 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -277,6 +277,9 @@ struct kvm_vcpu_arch {
>  
>  	/* Detect first run of a vcpu */
>  	bool has_run_once;
> +
> +	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
> +	u64 vsesr_el2;
>  };
>  
>  #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 427c36bc5dd6..a493e93de296 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -253,6 +253,7 @@
>  
>  #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
>  #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
> +#define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
>  #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
>  
>  #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 945e79c641c4..af37658223a0 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>  		isb();
>  	}
>  	write_sysreg(val, hcr_el2);
> +
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
> +		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
> +

Just a heads up: If my optimization work gets merged, that will
eventually move stuff like this in to load/put hooks for system
registers, but I can deal with this easily, also adding a direct write
in pend_guest_serror when moving the logic around.

However, if we start architecting something more complex, it would be
good to keep in mind how to maintain minimum work on the switching path
after we've optimized the hypervisor.

>  	/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
>  	write_sysreg(1 << 15, hstr_el2);
>  	/*
> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
> index da6a8cfa54a0..52f7f66f1356 100644
> --- a/arch/arm64/kvm/inject_fault.c
> +++ b/arch/arm64/kvm/inject_fault.c
> @@ -232,14 +232,25 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
>  		inject_undef64(vcpu);
>  }
>  
> +static void pend_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
> +{
> +	vcpu_set_vsesr(vcpu, esr);
> +	vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
> +}
> +
>  /**
>   * kvm_inject_vabt - inject an async abort / SError into the guest
>   * @vcpu: The VCPU to receive the exception
>   *
>   * It is assumed that this code is called from the VCPU thread and that the
>   * VCPU therefore is not currently executing guest code.
> + *
> + * Systems with the RAS Extensions specify an imp-def ESR (ISV/IDS = 1) with
> + * the remaining ISS all-zeros so that this error is not interpreted as an
> + * uncatagorized RAS error. Without the RAS Extensions we can't specify an ESR

nit: uncategorized

> + * value, so the CPU generates an imp-def value.
>   */
>  void kvm_inject_vabt(struct kvm_vcpu *vcpu)
>  {
> -	vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
> +	pend_guest_serror(vcpu, ESR_ELx_ISV);
>  }
> -- 
> 2.13.3
> 

Otherwise:

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-30  7:59     ` Christoffer Dall
@ 2017-10-30 10:51       ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-30 10:51 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Mon, Oct 30, 2017 at 08:59:51AM +0100, Christoffer Dall wrote:
> On Thu, Oct 19, 2017 at 03:58:01PM +0100, James Morse wrote:
> > Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> > generated an SError with an implementation defined ESR_EL1.ISS, because we
> > had no mechanism to specify the ESR value.
> > 
> > On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> > is clear indicating the remainder of the ISS field is invalid.
> > 
> > With the RAS Extensions we have a mechanism to specify this value, and the
> > most significant bit has a new meaning: 'IDS - Implementation Defined
> > Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> > instead of 'no valid ISS'.
> > 
> > Add KVM support for the VSESR_EL2 register to specify an ESR value when
> > HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
> > specify an implementation-defined value.
> > 
> > We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
> > save/restores this bit during __deactivate_traps() and hardware clears the
> > bit once the guest has consumed the virtual-SError.
> > 
> > Future patches may add an API (or KVM CAP) to pend a virtual SError with
> > a specified ESR.
> > 
> > Cc: Dongjiu Geng <gengdongjiu@huawei.com>
> > Signed-off-by: James Morse <james.morse@arm.com>
> > ---
> >  arch/arm64/include/asm/kvm_emulate.h |  5 +++++
> >  arch/arm64/include/asm/kvm_host.h    |  3 +++
> >  arch/arm64/include/asm/sysreg.h      |  1 +
> >  arch/arm64/kvm/hyp/switch.c          |  4 ++++
> >  arch/arm64/kvm/inject_fault.c        | 13 ++++++++++++-
> >  5 files changed, 25 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > index e5df3fce0008..8a7a838eb17a 100644
> > --- a/arch/arm64/include/asm/kvm_emulate.h
> > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > @@ -61,6 +61,11 @@ static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
> >  	vcpu->arch.hcr_el2 = hcr;
> >  }
> >  
> > +static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
> > +{
> > +	vcpu->arch.vsesr_el2 = vsesr;
> > +}
> > +
> >  static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
> >  {
> >  	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc;
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index a0e2f7962401..28a4de85edee 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -277,6 +277,9 @@ struct kvm_vcpu_arch {
> >  
> >  	/* Detect first run of a vcpu */
> >  	bool has_run_once;
> > +
> > +	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
> > +	u64 vsesr_el2;
> >  };
> >  
> >  #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 427c36bc5dd6..a493e93de296 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -253,6 +253,7 @@
> >  
> >  #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
> >  #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
> > +#define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
> >  #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
> >  
> >  #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
> > diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> > index 945e79c641c4..af37658223a0 100644
> > --- a/arch/arm64/kvm/hyp/switch.c
> > +++ b/arch/arm64/kvm/hyp/switch.c
> > @@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
> >  		isb();
> >  	}
> >  	write_sysreg(val, hcr_el2);
> > +
> > +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
> > +		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
> > +
> 
> Just a heads up: If my optimization work gets merged, that will
> eventually move stuff like this in to load/put hooks for system
> registers, but I can deal with this easily, also adding a direct write
> in pend_guest_serror when moving the logic around.
> 
> However, if we start architecting something more complex, it would be
> good to keep in mind how to maintain minimum work on the switching path
> after we've optimized the hypervisor.
> 

Actually, after thinking about this, if the guest can only see this via
the ESR if we set the HCR_EL2.VSE, wouldn't it make sense to just set
this value in pend_guest_serror, and if we're on a non-VHE system --
assuming that's something we want to support with this 8.2 feature -- we
jump to EL2 and back to set the value?

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-30 10:51       ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-30 10:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 30, 2017 at 08:59:51AM +0100, Christoffer Dall wrote:
> On Thu, Oct 19, 2017 at 03:58:01PM +0100, James Morse wrote:
> > Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> > generated an SError with an implementation defined ESR_EL1.ISS, because we
> > had no mechanism to specify the ESR value.
> > 
> > On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> > is clear indicating the remainder of the ISS field is invalid.
> > 
> > With the RAS Extensions we have a mechanism to specify this value, and the
> > most significant bit has a new meaning: 'IDS - Implementation Defined
> > Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> > instead of 'no valid ISS'.
> > 
> > Add KVM support for the VSESR_EL2 register to specify an ESR value when
> > HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
> > specify an implementation-defined value.
> > 
> > We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
> > save/restores this bit during __deactivate_traps() and hardware clears the
> > bit once the guest has consumed the virtual-SError.
> > 
> > Future patches may add an API (or KVM CAP) to pend a virtual SError with
> > a specified ESR.
> > 
> > Cc: Dongjiu Geng <gengdongjiu@huawei.com>
> > Signed-off-by: James Morse <james.morse@arm.com>
> > ---
> >  arch/arm64/include/asm/kvm_emulate.h |  5 +++++
> >  arch/arm64/include/asm/kvm_host.h    |  3 +++
> >  arch/arm64/include/asm/sysreg.h      |  1 +
> >  arch/arm64/kvm/hyp/switch.c          |  4 ++++
> >  arch/arm64/kvm/inject_fault.c        | 13 ++++++++++++-
> >  5 files changed, 25 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > index e5df3fce0008..8a7a838eb17a 100644
> > --- a/arch/arm64/include/asm/kvm_emulate.h
> > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > @@ -61,6 +61,11 @@ static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
> >  	vcpu->arch.hcr_el2 = hcr;
> >  }
> >  
> > +static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
> > +{
> > +	vcpu->arch.vsesr_el2 = vsesr;
> > +}
> > +
> >  static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
> >  {
> >  	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc;
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index a0e2f7962401..28a4de85edee 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -277,6 +277,9 @@ struct kvm_vcpu_arch {
> >  
> >  	/* Detect first run of a vcpu */
> >  	bool has_run_once;
> > +
> > +	/* Virtual SError ESR to restore when HCR_EL2.VSE is set */
> > +	u64 vsesr_el2;
> >  };
> >  
> >  #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 427c36bc5dd6..a493e93de296 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -253,6 +253,7 @@
> >  
> >  #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
> >  #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
> > +#define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
> >  #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
> >  
> >  #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
> > diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> > index 945e79c641c4..af37658223a0 100644
> > --- a/arch/arm64/kvm/hyp/switch.c
> > +++ b/arch/arm64/kvm/hyp/switch.c
> > @@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
> >  		isb();
> >  	}
> >  	write_sysreg(val, hcr_el2);
> > +
> > +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
> > +		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
> > +
> 
> Just a heads up: If my optimization work gets merged, that will
> eventually move stuff like this in to load/put hooks for system
> registers, but I can deal with this easily, also adding a direct write
> in pend_guest_serror when moving the logic around.
> 
> However, if we start architecting something more complex, it would be
> good to keep in mind how to maintain minimum work on the switching path
> after we've optimized the hypervisor.
> 

Actually, after thinking about this, if the guest can only see this via
the ESR if we set the HCR_EL2.VSE, wouldn't it make sense to just set
this value in pend_guest_serror, and if we're on a non-VHE system --
assuming that's something we want to support with this 8.2 feature -- we
jump to EL2 and back to set the value?

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-30 10:51       ` Christoffer Dall
@ 2017-10-30 15:44         ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-30 15:44 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi Christoffer,

On 30/10/17 10:51, Christoffer Dall wrote:
> On Mon, Oct 30, 2017 at 08:59:51AM +0100, Christoffer Dall wrote:
>> On Thu, Oct 19, 2017 at 03:58:01PM +0100, James Morse wrote:
>>> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
>>> generated an SError with an implementation defined ESR_EL1.ISS, because we
>>> had no mechanism to specify the ESR value.
>>>
>>> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
>>> is clear indicating the remainder of the ISS field is invalid.
>>>
>>> With the RAS Extensions we have a mechanism to specify this value, and the
>>> most significant bit has a new meaning: 'IDS - Implementation Defined
>>> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
>>> instead of 'no valid ISS'.
>>>
>>> Add KVM support for the VSESR_EL2 register to specify an ESR value when
>>> HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
>>> specify an implementation-defined value.
>>>
>>> We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
>>> save/restores this bit during __deactivate_traps() and hardware clears the
>>> bit once the guest has consumed the virtual-SError.
>>>
>>> Future patches may add an API (or KVM CAP) to pend a virtual SError with
>>> a specified ESR.


>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>> index 945e79c641c4..af37658223a0 100644
>>> --- a/arch/arm64/kvm/hyp/switch.c
>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>> @@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>>>  		isb();
>>>  	}
>>>  	write_sysreg(val, hcr_el2);
>>> +
>>> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
>>> +		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
>>> +

>> Just a heads up: If my optimization work gets merged, that will
>> eventually move stuff like this in to load/put hooks for system
>> registers, but I can deal with this easily, also adding a direct write
>> in pend_guest_serror when moving the logic around.

Sure. This would always be called when the vcpu is loaded, so yes it should end
up as a direct write to the system register.


>> However, if we start architecting something more complex, it would be
>> good to keep in mind how to maintain minimum work on the switching path
>> after we've optimized the hypervisor.

I think gengdongjiu's trick of only restoring VSESR if HCR_EL2.VSE is set is the
best we can do here. (Hence the Celebrate-Contribution tag).

For VDISR_EL2 we can probably only save/restore it if its non-zero. On most
systems it will never be touched so the cost is testing that whenever we exit
the guest/unload the vcpu.


> Actually, after thinking about this, if the guest can only see this via
> the ESR if we set the HCR_EL2.VSE, wouldn't it make sense to just set
> this value in pend_guest_serror, and if we're on a non-VHE system --
> assuming that's something we want to support with this 8.2 feature
> -- we jump to EL2 and back to set the value?

It thought this was the 'eventually ... direct write' above.
Once your load/put hooks are merged? Yes, just write it straight to the CPU
register and set the guests HCR_EL2.VSE.

Now? Wouldn't this get lost if we reschedule onto another cpu...


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-30 15:44         ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-30 15:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 30/10/17 10:51, Christoffer Dall wrote:
> On Mon, Oct 30, 2017 at 08:59:51AM +0100, Christoffer Dall wrote:
>> On Thu, Oct 19, 2017 at 03:58:01PM +0100, James Morse wrote:
>>> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
>>> generated an SError with an implementation defined ESR_EL1.ISS, because we
>>> had no mechanism to specify the ESR value.
>>>
>>> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
>>> is clear indicating the remainder of the ISS field is invalid.
>>>
>>> With the RAS Extensions we have a mechanism to specify this value, and the
>>> most significant bit has a new meaning: 'IDS - Implementation Defined
>>> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
>>> instead of 'no valid ISS'.
>>>
>>> Add KVM support for the VSESR_EL2 register to specify an ESR value when
>>> HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
>>> specify an implementation-defined value.
>>>
>>> We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
>>> save/restores this bit during __deactivate_traps() and hardware clears the
>>> bit once the guest has consumed the virtual-SError.
>>>
>>> Future patches may add an API (or KVM CAP) to pend a virtual SError with
>>> a specified ESR.


>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>> index 945e79c641c4..af37658223a0 100644
>>> --- a/arch/arm64/kvm/hyp/switch.c
>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>> @@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>>>  		isb();
>>>  	}
>>>  	write_sysreg(val, hcr_el2);
>>> +
>>> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
>>> +		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
>>> +

>> Just a heads up: If my optimization work gets merged, that will
>> eventually move stuff like this in to load/put hooks for system
>> registers, but I can deal with this easily, also adding a direct write
>> in pend_guest_serror when moving the logic around.

Sure. This would always be called when the vcpu is loaded, so yes it should end
up as a direct write to the system register.


>> However, if we start architecting something more complex, it would be
>> good to keep in mind how to maintain minimum work on the switching path
>> after we've optimized the hypervisor.

I think gengdongjiu's trick of only restoring VSESR if HCR_EL2.VSE is set is the
best we can do here. (Hence the Celebrate-Contribution tag).

For VDISR_EL2 we can probably only save/restore it if its non-zero. On most
systems it will never be touched so the cost is testing that whenever we exit
the guest/unload the vcpu.


> Actually, after thinking about this, if the guest can only see this via
> the ESR if we set the HCR_EL2.VSE, wouldn't it make sense to just set
> this value in pend_guest_serror, and if we're on a non-VHE system --
> assuming that's something we want to support with this 8.2 feature
> -- we jump to EL2 and back to set the value?

It thought this was the 'eventually ... direct write' above.
Once your load/put hooks are merged? Yes, just write it straight to the CPU
register and set the guests HCR_EL2.VSE.

Now? Wouldn't this get lost if we reschedule onto another cpu...


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  4:26     ` Marc Zyngier
  -1 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  4:26 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Catalin Marinas, Julien Thierry, Will Deacon,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19 2017 at  4:58:03 pm BST, James Morse <james.morse@arm.com> wrote:
> When we exit a guest due to an SError the vcpu fault info isn't updated
> with the ESR. Today this is only done for traps.
>
> The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
> fault_info with the ESR on SError so that handle_exit() can determine
> if this was a RAS SError and decode its severity.
>
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index af37658223a0..cba6d8ac105c 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -230,13 +230,20 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
>  	return true;
>  }
>  
> +static void __hyp_text __populate_fault_info_esr(struct kvm_vcpu *vcpu)
> +{
> +	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
> +}
> +
>  static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
>  {
> -	u64 esr = read_sysreg_el2(esr);
> -	u8 ec = ESR_ELx_EC(esr);
> +	u8 ec;
> +	u64 esr;
>  	u64 hpfar, far;
>  
> -	vcpu->arch.fault.esr_el2 = esr;
> +	__populate_fault_info_esr(vcpu);
> +	esr = vcpu->arch.fault.esr_el2;
> +	ec = ESR_ELx_EC(esr);
>  
>  	if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
>  		return true;
> @@ -325,6 +332,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>  	 */
>  	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
>  		goto again;
> +	else if (ARM_EXCEPTION_CODE(exit_code) == ARM_EXCEPTION_EL1_SERROR)
> +		__populate_fault_info_esr(vcpu);
>  
>  	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
>  	    exit_code == ARM_EXCEPTION_TRAP) {

With this patch, the only case were we don't save ESR_EL2 is when we
take an interrupt. I think we should bite the bullet and make it
slightly more streamlined, always saving ESR_EL2.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError
@ 2017-10-31  4:26     ` Marc Zyngier
  0 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  4:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19 2017 at  4:58:03 pm BST, James Morse <james.morse@arm.com> wrote:
> When we exit a guest due to an SError the vcpu fault info isn't updated
> with the ESR. Today this is only done for traps.
>
> The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
> fault_info with the ESR on SError so that handle_exit() can determine
> if this was a RAS SError and decode its severity.
>
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index af37658223a0..cba6d8ac105c 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -230,13 +230,20 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
>  	return true;
>  }
>  
> +static void __hyp_text __populate_fault_info_esr(struct kvm_vcpu *vcpu)
> +{
> +	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
> +}
> +
>  static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
>  {
> -	u64 esr = read_sysreg_el2(esr);
> -	u8 ec = ESR_ELx_EC(esr);
> +	u8 ec;
> +	u64 esr;
>  	u64 hpfar, far;
>  
> -	vcpu->arch.fault.esr_el2 = esr;
> +	__populate_fault_info_esr(vcpu);
> +	esr = vcpu->arch.fault.esr_el2;
> +	ec = ESR_ELx_EC(esr);
>  
>  	if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
>  		return true;
> @@ -325,6 +332,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>  	 */
>  	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
>  		goto again;
> +	else if (ARM_EXCEPTION_CODE(exit_code) == ARM_EXCEPTION_EL1_SERROR)
> +		__populate_fault_info_esr(vcpu);
>  
>  	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
>  	    exit_code == ARM_EXCEPTION_TRAP) {

With this patch, the only case were we don't save ESR_EL2 is when we
take an interrupt. I think we should bite the bullet and make it
slightly more streamlined, always saving ESR_EL2.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 16/21] KVM: arm64: Save/Restore guest DISR_EL1
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  4:27     ` Marc Zyngier
  -1 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  4:27 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Catalin Marinas, Julien Thierry, Will Deacon,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19 2017 at  4:58:02 pm BST, James Morse <james.morse@arm.com> wrote:
> If we deliver a virtual SError to the guest, the guest may defer it
> with an ESB instruction. The guest reads the deferred value via DISR_EL1,
> but the guests view of DISR_EL1 is re-mapped to VDISR_EL2 when HCR_EL2.AMO
> is set.
>
> Add the KVM code to save/restore VDISR_EL2, and make it accessible to
> userspace as DISR_EL1.
>
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 16/21] KVM: arm64: Save/Restore guest DISR_EL1
@ 2017-10-31  4:27     ` Marc Zyngier
  0 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  4:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19 2017 at  4:58:02 pm BST, James Morse <james.morse@arm.com> wrote:
> If we deliver a virtual SError to the guest, the guest may defer it
> with an ESB instruction. The guest reads the deferred value via DISR_EL1,
> but the guests view of DISR_EL1 is re-mapped to VDISR_EL2 when HCR_EL2.AMO
> is set.
>
> Add the KVM code to save/restore VDISR_EL2, and make it accessible to
> userspace as DISR_EL1.
>
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 16/21] KVM: arm64: Save/Restore guest DISR_EL1
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  5:27     ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  5:27 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Oct 19, 2017 at 03:58:02PM +0100, James Morse wrote:
> If we deliver a virtual SError to the guest, the guest may defer it
> with an ESB instruction. The guest reads the deferred value via DISR_EL1,
> but the guests view of DISR_EL1 is re-mapped to VDISR_EL2 when HCR_EL2.AMO
> is set.
> 
> Add the KVM code to save/restore VDISR_EL2, and make it accessible to
> userspace as DISR_EL1.
> 

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 1 +
>  arch/arm64/include/asm/sysreg.h   | 1 +
>  arch/arm64/kvm/hyp/sysreg-sr.c    | 6 ++++++
>  arch/arm64/kvm/sys_regs.c         | 1 +
>  4 files changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 28a4de85edee..97438cc3a9ad 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -120,6 +120,7 @@ enum vcpu_sysreg {
>  	PAR_EL1,	/* Physical Address Register */
>  	MDSCR_EL1,	/* Monitor Debug System Control Register */
>  	MDCCINT_EL1,	/* Monitor Debug Comms Channel Interrupt Enable Reg */
> +	DISR_EL1,	/* Deferred Interrupt Status Register */
>  
>  	/* Performance Monitors Registers */
>  	PMCR_EL0,	/* Control Register */
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index a493e93de296..1b8b9012234d 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -256,6 +256,7 @@
>  #define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
>  #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
>  
> +#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1,  1)
>  #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
>  #define SYS_ICH_AP0R0_EL2		__SYS__AP0Rx_EL2(0)
>  #define SYS_ICH_AP0R1_EL2		__SYS__AP0Rx_EL2(1)
> diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
> index 934137647837..f4d604803b29 100644
> --- a/arch/arm64/kvm/hyp/sysreg-sr.c
> +++ b/arch/arm64/kvm/hyp/sysreg-sr.c
> @@ -66,6 +66,9 @@ static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
>  	ctxt->gp_regs.sp_el1		= read_sysreg(sp_el1);
>  	ctxt->gp_regs.elr_el1		= read_sysreg_el1(elr);
>  	ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
> +
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
> +		ctxt->sys_regs[DISR_EL1] = read_sysreg_s(SYS_VDISR_EL2);
>  }
>  
>  static hyp_alternate_select(__sysreg_call_save_host_state,
> @@ -119,6 +122,9 @@ static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
>  	write_sysreg(ctxt->gp_regs.sp_el1,		sp_el1);
>  	write_sysreg_el1(ctxt->gp_regs.elr_el1,		elr);
>  	write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
> +
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
> +		write_sysreg_s(ctxt->sys_regs[DISR_EL1], SYS_VDISR_EL2);
>  }
>  
>  static hyp_alternate_select(__sysreg_call_restore_host_state,
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 2e070d3baf9f..713275b501ce 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -963,6 +963,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
>  
>  	{ SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
> +	{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
>  
>  	{ SYS_DESC(SYS_ICC_IAR0_EL1), write_to_read_only },
>  	{ SYS_DESC(SYS_ICC_EOIR0_EL1), read_from_write_only },
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 16/21] KVM: arm64: Save/Restore guest DISR_EL1
@ 2017-10-31  5:27     ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  5:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:58:02PM +0100, James Morse wrote:
> If we deliver a virtual SError to the guest, the guest may defer it
> with an ESB instruction. The guest reads the deferred value via DISR_EL1,
> but the guests view of DISR_EL1 is re-mapped to VDISR_EL2 when HCR_EL2.AMO
> is set.
> 
> Add the KVM code to save/restore VDISR_EL2, and make it accessible to
> userspace as DISR_EL1.
> 

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 1 +
>  arch/arm64/include/asm/sysreg.h   | 1 +
>  arch/arm64/kvm/hyp/sysreg-sr.c    | 6 ++++++
>  arch/arm64/kvm/sys_regs.c         | 1 +
>  4 files changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 28a4de85edee..97438cc3a9ad 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -120,6 +120,7 @@ enum vcpu_sysreg {
>  	PAR_EL1,	/* Physical Address Register */
>  	MDSCR_EL1,	/* Monitor Debug System Control Register */
>  	MDCCINT_EL1,	/* Monitor Debug Comms Channel Interrupt Enable Reg */
> +	DISR_EL1,	/* Deferred Interrupt Status Register */
>  
>  	/* Performance Monitors Registers */
>  	PMCR_EL0,	/* Control Register */
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index a493e93de296..1b8b9012234d 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -256,6 +256,7 @@
>  #define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
>  #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
>  
> +#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1,  1)
>  #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
>  #define SYS_ICH_AP0R0_EL2		__SYS__AP0Rx_EL2(0)
>  #define SYS_ICH_AP0R1_EL2		__SYS__AP0Rx_EL2(1)
> diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
> index 934137647837..f4d604803b29 100644
> --- a/arch/arm64/kvm/hyp/sysreg-sr.c
> +++ b/arch/arm64/kvm/hyp/sysreg-sr.c
> @@ -66,6 +66,9 @@ static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
>  	ctxt->gp_regs.sp_el1		= read_sysreg(sp_el1);
>  	ctxt->gp_regs.elr_el1		= read_sysreg_el1(elr);
>  	ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
> +
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
> +		ctxt->sys_regs[DISR_EL1] = read_sysreg_s(SYS_VDISR_EL2);
>  }
>  
>  static hyp_alternate_select(__sysreg_call_save_host_state,
> @@ -119,6 +122,9 @@ static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
>  	write_sysreg(ctxt->gp_regs.sp_el1,		sp_el1);
>  	write_sysreg_el1(ctxt->gp_regs.elr_el1,		elr);
>  	write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
> +
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
> +		write_sysreg_s(ctxt->sys_regs[DISR_EL1], SYS_VDISR_EL2);
>  }
>  
>  static hyp_alternate_select(__sysreg_call_restore_host_state,
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 2e070d3baf9f..713275b501ce 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -963,6 +963,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
>  
>  	{ SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
> +	{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
>  
>  	{ SYS_DESC(SYS_ICC_IAR0_EL1), write_to_read_only },
>  	{ SYS_DESC(SYS_ICC_EOIR0_EL1), read_from_write_only },
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError
  2017-10-31  4:26     ` Marc Zyngier
@ 2017-10-31  5:47       ` Marc Zyngier
  -1 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  5:47 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Catalin Marinas, Julien Thierry, Will Deacon,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Tue, Oct 31 2017 at  4:26:01 am GMT, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On Thu, Oct 19 2017 at  4:58:03 pm BST, James Morse <james.morse@arm.com> wrote:
>> When we exit a guest due to an SError the vcpu fault info isn't updated
>> with the ESR. Today this is only done for traps.
>>
>> The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
>> fault_info with the ESR on SError so that handle_exit() can determine
>> if this was a RAS SError and decode its severity.
>>
>> Signed-off-by: James Morse <james.morse@arm.com>
>> ---
>>  arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++---
>>  1 file changed, 12 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>> index af37658223a0..cba6d8ac105c 100644
>> --- a/arch/arm64/kvm/hyp/switch.c
>> +++ b/arch/arm64/kvm/hyp/switch.c
>> @@ -230,13 +230,20 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
>>  	return true;
>>  }
>>  
>> +static void __hyp_text __populate_fault_info_esr(struct kvm_vcpu *vcpu)
>> +{
>> +	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
>> +}
>> +
>>  static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
>>  {
>> -	u64 esr = read_sysreg_el2(esr);
>> -	u8 ec = ESR_ELx_EC(esr);
>> +	u8 ec;
>> +	u64 esr;
>>  	u64 hpfar, far;
>>  
>> -	vcpu->arch.fault.esr_el2 = esr;
>> +	__populate_fault_info_esr(vcpu);
>> +	esr = vcpu->arch.fault.esr_el2;
>> +	ec = ESR_ELx_EC(esr);
>>  
>>  	if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
>>  		return true;
>> @@ -325,6 +332,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>>  	 */
>>  	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
>>  		goto again;
>> +	else if (ARM_EXCEPTION_CODE(exit_code) == ARM_EXCEPTION_EL1_SERROR)
>> +		__populate_fault_info_esr(vcpu);
>>  
>>  	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
>>  	    exit_code == ARM_EXCEPTION_TRAP) {
>
> With this patch, the only case were we don't save ESR_EL2 is when we
> take an interrupt. I think we should bite the bullet and make it
> slightly more streamlined, always saving ESR_EL2.

Otherwise, an alternative would be to write something like:

	if (ARM_EXCEPTION_CODE(exit_code) != ARM_EXCEPTION_IRQ)
        	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);

which still avoids saving it, and is a lot more readable.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError
@ 2017-10-31  5:47       ` Marc Zyngier
  0 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  5:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 31 2017 at  4:26:01 am GMT, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On Thu, Oct 19 2017 at  4:58:03 pm BST, James Morse <james.morse@arm.com> wrote:
>> When we exit a guest due to an SError the vcpu fault info isn't updated
>> with the ESR. Today this is only done for traps.
>>
>> The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
>> fault_info with the ESR on SError so that handle_exit() can determine
>> if this was a RAS SError and decode its severity.
>>
>> Signed-off-by: James Morse <james.morse@arm.com>
>> ---
>>  arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++---
>>  1 file changed, 12 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>> index af37658223a0..cba6d8ac105c 100644
>> --- a/arch/arm64/kvm/hyp/switch.c
>> +++ b/arch/arm64/kvm/hyp/switch.c
>> @@ -230,13 +230,20 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
>>  	return true;
>>  }
>>  
>> +static void __hyp_text __populate_fault_info_esr(struct kvm_vcpu *vcpu)
>> +{
>> +	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
>> +}
>> +
>>  static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
>>  {
>> -	u64 esr = read_sysreg_el2(esr);
>> -	u8 ec = ESR_ELx_EC(esr);
>> +	u8 ec;
>> +	u64 esr;
>>  	u64 hpfar, far;
>>  
>> -	vcpu->arch.fault.esr_el2 = esr;
>> +	__populate_fault_info_esr(vcpu);
>> +	esr = vcpu->arch.fault.esr_el2;
>> +	ec = ESR_ELx_EC(esr);
>>  
>>  	if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
>>  		return true;
>> @@ -325,6 +332,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>>  	 */
>>  	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
>>  		goto again;
>> +	else if (ARM_EXCEPTION_CODE(exit_code) == ARM_EXCEPTION_EL1_SERROR)
>> +		__populate_fault_info_esr(vcpu);
>>  
>>  	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
>>  	    exit_code == ARM_EXCEPTION_TRAP) {
>
> With this patch, the only case were we don't save ESR_EL2 is when we
> take an interrupt. I think we should bite the bullet and make it
> slightly more streamlined, always saving ESR_EL2.

Otherwise, an alternative would be to write something like:

	if (ARM_EXCEPTION_CODE(exit_code) != ARM_EXCEPTION_IRQ)
        	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);

which still avoids saving it, and is a lot more readable.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-30 15:44         ` James Morse
@ 2017-10-31  5:48           ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  5:48 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Mon, Oct 30, 2017 at 03:44:17PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 30/10/17 10:51, Christoffer Dall wrote:
> > On Mon, Oct 30, 2017 at 08:59:51AM +0100, Christoffer Dall wrote:
> >> On Thu, Oct 19, 2017 at 03:58:01PM +0100, James Morse wrote:
> >>> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> >>> generated an SError with an implementation defined ESR_EL1.ISS, because we
> >>> had no mechanism to specify the ESR value.
> >>>
> >>> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> >>> is clear indicating the remainder of the ISS field is invalid.
> >>>
> >>> With the RAS Extensions we have a mechanism to specify this value, and the
> >>> most significant bit has a new meaning: 'IDS - Implementation Defined
> >>> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> >>> instead of 'no valid ISS'.
> >>>
> >>> Add KVM support for the VSESR_EL2 register to specify an ESR value when
> >>> HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
> >>> specify an implementation-defined value.
> >>>
> >>> We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
> >>> save/restores this bit during __deactivate_traps() and hardware clears the
> >>> bit once the guest has consumed the virtual-SError.
> >>>
> >>> Future patches may add an API (or KVM CAP) to pend a virtual SError with
> >>> a specified ESR.
> 
> 
> >>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> >>> index 945e79c641c4..af37658223a0 100644
> >>> --- a/arch/arm64/kvm/hyp/switch.c
> >>> +++ b/arch/arm64/kvm/hyp/switch.c
> >>> @@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
> >>>  		isb();
> >>>  	}
> >>>  	write_sysreg(val, hcr_el2);
> >>> +
> >>> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
> >>> +		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
> >>> +
> 
> >> Just a heads up: If my optimization work gets merged, that will
> >> eventually move stuff like this in to load/put hooks for system
> >> registers, but I can deal with this easily, also adding a direct write
> >> in pend_guest_serror when moving the logic around.
> 
> Sure. This would always be called when the vcpu is loaded, so yes it should end
> up as a direct write to the system register.
> 
> 
> >> However, if we start architecting something more complex, it would be
> >> good to keep in mind how to maintain minimum work on the switching path
> >> after we've optimized the hypervisor.
> 
> I think gengdongjiu's trick of only restoring VSESR if HCR_EL2.VSE is set is the
> best we can do here. (Hence the Celebrate-Contribution tag).

yes, I agree.

> 
> For VDISR_EL2 we can probably only save/restore it if its non-zero. On most
> systems it will never be touched so the cost is testing that whenever we exit
> the guest/unload the vcpu.
> 

I think VDISR_EL2 should just be saved/restored in vcpu_put/load after
the optimization.

> 
> > Actually, after thinking about this, if the guest can only see this via
> > the ESR if we set the HCR_EL2.VSE, wouldn't it make sense to just set
> > this value in pend_guest_serror, and if we're on a non-VHE system --
> > assuming that's something we want to support with this 8.2 feature
> > -- we jump to EL2 and back to set the value?
> 
> It thought this was the 'eventually ... direct write' above.

Yes, that's what I mean.

> Once your load/put hooks are merged? Yes, just write it straight to the CPU
> register and set the guests HCR_EL2.VSE.
> 
> Now? Wouldn't this get lost if we reschedule onto another cpu...
> 
> 

That's why we'd also save/restore it in vcpu_put/vcpu_load.

So, for VSESR, we'd save/restore it in put/load (conditionally on VSE
being set if we like), and we'd also set it from pend_guest_serror.

For VDISR, it's just saved/restored in put/load.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-31  5:48           ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  5:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 30, 2017 at 03:44:17PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 30/10/17 10:51, Christoffer Dall wrote:
> > On Mon, Oct 30, 2017 at 08:59:51AM +0100, Christoffer Dall wrote:
> >> On Thu, Oct 19, 2017 at 03:58:01PM +0100, James Morse wrote:
> >>> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> >>> generated an SError with an implementation defined ESR_EL1.ISS, because we
> >>> had no mechanism to specify the ESR value.
> >>>
> >>> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> >>> is clear indicating the remainder of the ISS field is invalid.
> >>>
> >>> With the RAS Extensions we have a mechanism to specify this value, and the
> >>> most significant bit has a new meaning: 'IDS - Implementation Defined
> >>> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> >>> instead of 'no valid ISS'.
> >>>
> >>> Add KVM support for the VSESR_EL2 register to specify an ESR value when
> >>> HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
> >>> specify an implementation-defined value.
> >>>
> >>> We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
> >>> save/restores this bit during __deactivate_traps() and hardware clears the
> >>> bit once the guest has consumed the virtual-SError.
> >>>
> >>> Future patches may add an API (or KVM CAP) to pend a virtual SError with
> >>> a specified ESR.
> 
> 
> >>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> >>> index 945e79c641c4..af37658223a0 100644
> >>> --- a/arch/arm64/kvm/hyp/switch.c
> >>> +++ b/arch/arm64/kvm/hyp/switch.c
> >>> @@ -86,6 +86,10 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
> >>>  		isb();
> >>>  	}
> >>>  	write_sysreg(val, hcr_el2);
> >>> +
> >>> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (val & HCR_VSE))
> >>> +		write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
> >>> +
> 
> >> Just a heads up: If my optimization work gets merged, that will
> >> eventually move stuff like this in to load/put hooks for system
> >> registers, but I can deal with this easily, also adding a direct write
> >> in pend_guest_serror when moving the logic around.
> 
> Sure. This would always be called when the vcpu is loaded, so yes it should end
> up as a direct write to the system register.
> 
> 
> >> However, if we start architecting something more complex, it would be
> >> good to keep in mind how to maintain minimum work on the switching path
> >> after we've optimized the hypervisor.
> 
> I think gengdongjiu's trick of only restoring VSESR if HCR_EL2.VSE is set is the
> best we can do here. (Hence the Celebrate-Contribution tag).

yes, I agree.

> 
> For VDISR_EL2 we can probably only save/restore it if its non-zero. On most
> systems it will never be touched so the cost is testing that whenever we exit
> the guest/unload the vcpu.
> 

I think VDISR_EL2 should just be saved/restored in vcpu_put/load after
the optimization.

> 
> > Actually, after thinking about this, if the guest can only see this via
> > the ESR if we set the HCR_EL2.VSE, wouldn't it make sense to just set
> > this value in pend_guest_serror, and if we're on a non-VHE system --
> > assuming that's something we want to support with this 8.2 feature
> > -- we jump to EL2 and back to set the value?
> 
> It thought this was the 'eventually ... direct write' above.

Yes, that's what I mean.

> Once your load/put hooks are merged? Yes, just write it straight to the CPU
> register and set the guests HCR_EL2.VSE.
> 
> Now? Wouldn't this get lost if we reschedule onto another cpu...
> 
> 

That's why we'd also save/restore it in vcpu_put/vcpu_load.

So, for VSESR, we'd save/restore it in put/load (conditionally on VSE
being set if we like), and we'd also set it from pend_guest_serror.

For VDISR, it's just saved/restored in put/load.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 18/21] KVM: arm64: Handle RAS SErrors from EL1 on guest exit
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  5:55     ` Marc Zyngier
  -1 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  5:55 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Catalin Marinas, Julien Thierry, Will Deacon,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19 2017 at  4:58:04 pm BST, James Morse <james.morse@arm.com> wrote:
> We expect to have firmware-first handling of RAS SErrors, with errors
> notified via an APEI method. For systems without firmware-first, add
> some minimal handling to KVM.
>
> There are two ways KVM can take an SError due to a guest, either may be a
> RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
> or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
>
> For SError that interrupt a guest and are routed to EL2 the existing
> behaviour is to inject an impdef SError into the guest.
>
> Add code to handle RAS SError based on the ESR. For uncontained errors
> arm64_is_blocking_ras_serror() will panic(), these errors compromise
> the host too. All other error types are contained: For the 'blocking'
> errors the vCPU can't make progress, so we inject a virtual SError.
> We ignore contained errors where we can make progress as if we're lucky,
> we may not hit them again.
>
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 18/21] KVM: arm64: Handle RAS SErrors from EL1 on guest exit
@ 2017-10-31  5:55     ` Marc Zyngier
  0 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  5:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19 2017 at  4:58:04 pm BST, James Morse <james.morse@arm.com> wrote:
> We expect to have firmware-first handling of RAS SErrors, with errors
> notified via an APEI method. For systems without firmware-first, add
> some minimal handling to KVM.
>
> There are two ways KVM can take an SError due to a guest, either may be a
> RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
> or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
>
> For SError that interrupt a guest and are routed to EL2 the existing
> behaviour is to inject an impdef SError into the guest.
>
> Add code to handle RAS SError based on the ESR. For uncontained errors
> arm64_is_blocking_ras_serror() will panic(), these errors compromise
> the host too. All other error types are contained: For the 'blocking'
> errors the vCPU can't make progress, so we inject a virtual SError.
> We ignore contained errors where we can make progress as if we're lucky,
> we may not hit them again.
>
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 18/21] KVM: arm64: Handle RAS SErrors from EL1 on guest exit
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  5:56     ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  5:56 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Oct 19, 2017 at 03:58:04PM +0100, James Morse wrote:
> We expect to have firmware-first handling of RAS SErrors, with errors
> notified via an APEI method. For systems without firmware-first, add
> some minimal handling to KVM.
> 
> There are two ways KVM can take an SError due to a guest, either may be a
> RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
> or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
> 
> For SError that interrupt a guest and are routed to EL2 the existing
> behaviour is to inject an impdef SError into the guest.
> 
> Add code to handle RAS SError based on the ESR. For uncontained errors
> arm64_is_blocking_ras_serror() will panic(), these errors compromise
> the host too. All other error types are contained: For the 'blocking'
> errors the vCPU can't make progress, so we inject a virtual SError.
> We ignore contained errors where we can make progress as if we're lucky,
> we may not hit them again.
> 
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
>  arch/arm64/kvm/handle_exit.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 7debb74843a0..345fdbba6c2e 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -28,12 +28,19 @@
>  #include <asm/kvm_emulate.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/kvm_psci.h>
> +#include <asm/traps.h>
>  
>  #define CREATE_TRACE_POINTS
>  #include "trace.h"
>  
>  typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
>  
> +static void kvm_handle_guest_serror(struct kvm_vcpu *vcpu, u32 esr)
> +{
> +	if (!arm64_is_ras_serror(esr) || arm64_blocking_ras_serror(NULL, esr))
> +		kvm_inject_vabt(vcpu);
> +}
> +
>  static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  {
>  	int ret;
> @@ -211,7 +218,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
>  	case ARM_EXCEPTION_IRQ:
>  		return 1;
>  	case ARM_EXCEPTION_EL1_SERROR:
> -		kvm_inject_vabt(vcpu);
> +		kvm_handle_guest_serror(vcpu, kvm_vcpu_get_hsr(vcpu));
>  		return 1;
>  	case ARM_EXCEPTION_TRAP:
>  		/*
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 18/21] KVM: arm64: Handle RAS SErrors from EL1 on guest exit
@ 2017-10-31  5:56     ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  5:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:58:04PM +0100, James Morse wrote:
> We expect to have firmware-first handling of RAS SErrors, with errors
> notified via an APEI method. For systems without firmware-first, add
> some minimal handling to KVM.
> 
> There are two ways KVM can take an SError due to a guest, either may be a
> RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
> or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
> 
> For SError that interrupt a guest and are routed to EL2 the existing
> behaviour is to inject an impdef SError into the guest.
> 
> Add code to handle RAS SError based on the ESR. For uncontained errors
> arm64_is_blocking_ras_serror() will panic(), these errors compromise
> the host too. All other error types are contained: For the 'blocking'
> errors the vCPU can't make progress, so we inject a virtual SError.
> We ignore contained errors where we can make progress as if we're lucky,
> we may not hit them again.
> 
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
>  arch/arm64/kvm/handle_exit.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 7debb74843a0..345fdbba6c2e 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -28,12 +28,19 @@
>  #include <asm/kvm_emulate.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/kvm_psci.h>
> +#include <asm/traps.h>
>  
>  #define CREATE_TRACE_POINTS
>  #include "trace.h"
>  
>  typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
>  
> +static void kvm_handle_guest_serror(struct kvm_vcpu *vcpu, u32 esr)
> +{
> +	if (!arm64_is_ras_serror(esr) || arm64_blocking_ras_serror(NULL, esr))
> +		kvm_inject_vabt(vcpu);
> +}
> +
>  static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  {
>  	int ret;
> @@ -211,7 +218,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
>  	case ARM_EXCEPTION_IRQ:
>  		return 1;
>  	case ARM_EXCEPTION_EL1_SERROR:
> -		kvm_inject_vabt(vcpu);
> +		kvm_handle_guest_serror(vcpu, kvm_vcpu_get_hsr(vcpu));
>  		return 1;
>  	case ARM_EXCEPTION_TRAP:
>  		/*
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  6:13     ` Marc Zyngier
  -1 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  6:13 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Catalin Marinas, Julien Thierry, Will Deacon,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19 2017 at  4:58:05 pm BST, James Morse <james.morse@arm.com> wrote:
> We expect to have firmware-first handling of RAS SErrors, with errors
> notified via an APEI method. For systems without firmware-first, add
> some minimal handling to KVM.
>
> There are two ways KVM can take an SError due to a guest, either may be a
> RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
> or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
>
> The current SError from EL2 code unmasks SError and tries to fence any
> pending SError into a single instruction window. It then leaves SError
> unmasked.
>
> With the v8.2 RAS Extensions we may take an SError for a 'corrected'
> error, but KVM is only able to handle SError from EL2 if they occur
> during this single instruction window...
>
> The RAS Extensions give us a new instruction to synchronise and
> consume SErrors. The RAS Extensions document (ARM DDI0587),
> '2.4.1 ESB and Unrecoverable errors' describes ESB as synchronising
> SError interrupts generated by 'instructions, translation table walks,
> hardware updates to the translation tables, and instruction fetches on
> the same PE'. This makes ESB equivalent to KVMs existing
> 'dsb, mrs-daifclr, isb' sequence.
>
> Use the alternatives to synchronise and consume any SError using ESB
> instead of unmasking and taking the SError. Set ARM_EXIT_WITH_SERROR_BIT
> in the exit_code so that we can restart the vcpu if it turns out this
> SError has no impact on the vcpu.
>
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
@ 2017-10-31  6:13     ` Marc Zyngier
  0 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  6:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19 2017 at  4:58:05 pm BST, James Morse <james.morse@arm.com> wrote:
> We expect to have firmware-first handling of RAS SErrors, with errors
> notified via an APEI method. For systems without firmware-first, add
> some minimal handling to KVM.
>
> There are two ways KVM can take an SError due to a guest, either may be a
> RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
> or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
>
> The current SError from EL2 code unmasks SError and tries to fence any
> pending SError into a single instruction window. It then leaves SError
> unmasked.
>
> With the v8.2 RAS Extensions we may take an SError for a 'corrected'
> error, but KVM is only able to handle SError from EL2 if they occur
> during this single instruction window...
>
> The RAS Extensions give us a new instruction to synchronise and
> consume SErrors. The RAS Extensions document (ARM DDI0587),
> '2.4.1 ESB and Unrecoverable errors' describes ESB as synchronising
> SError interrupts generated by 'instructions, translation table walks,
> hardware updates to the translation tables, and instruction fetches on
> the same PE'. This makes ESB equivalent to KVMs existing
> 'dsb, mrs-daifclr, isb' sequence.
>
> Use the alternatives to synchronise and consume any SError using ESB
> instead of unmasking and taking the SError. Set ARM_EXIT_WITH_SERROR_BIT
> in the exit_code so that we can restart the vcpu if it turns out this
> SError has no impact on the vcpu.
>
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  6:13     ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  6:13 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Oct 19, 2017 at 03:58:05PM +0100, James Morse wrote:
> We expect to have firmware-first handling of RAS SErrors, with errors
> notified via an APEI method. For systems without firmware-first, add
> some minimal handling to KVM.
> 
> There are two ways KVM can take an SError due to a guest, either may be a
> RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
> or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
> 
> The current SError from EL2 code unmasks SError and tries to fence any
> pending SError into a single instruction window. It then leaves SError
> unmasked.
> 
> With the v8.2 RAS Extensions we may take an SError for a 'corrected'
> error, but KVM is only able to handle SError from EL2 if they occur
> during this single instruction window...
> 
> The RAS Extensions give us a new instruction to synchronise and
> consume SErrors. The RAS Extensions document (ARM DDI0587),
> '2.4.1 ESB and Unrecoverable errors' describes ESB as synchronising
> SError interrupts generated by 'instructions, translation table walks,
> hardware updates to the translation tables, and instruction fetches on
> the same PE'. This makes ESB equivalent to KVMs existing
> 'dsb, mrs-daifclr, isb' sequence.
> 
> Use the alternatives to synchronise and consume any SError using ESB
> instead of unmasking and taking the SError. Set ARM_EXIT_WITH_SERROR_BIT
> in the exit_code so that we can restart the vcpu if it turns out this
> SError has no impact on the vcpu.
> 
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> 
> ---
> Changes since v3:
>  * Moved that nop out of the firing line
> 
>  arch/arm64/include/asm/kvm_emulate.h |  5 +++++
>  arch/arm64/include/asm/kvm_host.h    |  1 +
>  arch/arm64/kernel/asm-offsets.c      |  1 +
>  arch/arm64/kvm/handle_exit.c         | 10 +++++++++-
>  arch/arm64/kvm/hyp/entry.S           | 13 +++++++++++++
>  5 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 8a7a838eb17a..8274d16df3cd 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -173,6 +173,11 @@ static inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu)
>  	return ((phys_addr_t)vcpu->arch.fault.hpfar_el2 & HPFAR_MASK) << 8;
>  }
>  
> +static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu)
> +{
> +	return vcpu->arch.fault.disr_el1;
> +}
> +
>  static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu)
>  {
>  	return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_xVC_IMM_MASK;
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 97438cc3a9ad..cf5d78ba14b5 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -89,6 +89,7 @@ struct kvm_vcpu_fault_info {
>  	u32 esr_el2;		/* Hyp Syndrom Register */
>  	u64 far_el2;		/* Hyp Fault Address Register */
>  	u64 hpfar_el2;		/* Hyp IPA Fault Address Register */
> +	u64 disr_el1;		/* Deferred [SError] Status Register */
>  };
>  
>  /*
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index 71bf088f1e4b..121889c49542 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -130,6 +130,7 @@ int main(void)
>    BLANK();
>  #ifdef CONFIG_KVM_ARM_HOST
>    DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
> +  DEFINE(VCPU_FAULT_DISR,	offsetof(struct kvm_vcpu, arch.fault.disr_el1));
>    DEFINE(CPU_GP_REGS,		offsetof(struct kvm_cpu_context, gp_regs));
>    DEFINE(CPU_USER_PT_REGS,	offsetof(struct kvm_regs, regs));
>    DEFINE(CPU_FP_REGS,		offsetof(struct kvm_regs, fp_regs));
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 345fdbba6c2e..e1e6cfe7d4d9 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -23,6 +23,7 @@
>  #include <linux/kvm_host.h>
>  
>  #include <asm/esr.h>
> +#include <asm/exception.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_coproc.h>
>  #include <asm/kvm_emulate.h>
> @@ -208,7 +209,14 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
>  			*vcpu_pc(vcpu) -= adj;
>  		}
>  
> -		kvm_inject_vabt(vcpu);
> +		if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
> +			u64 disr = kvm_vcpu_get_disr(vcpu);
> +
> +			kvm_handle_guest_serror(vcpu, disr_to_esr(disr));
> +		} else {
> +			kvm_inject_vabt(vcpu);
> +		}
> +
>  		return 1;
>  	}
>  
> diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
> index 12ee62d6d410..024c7afc78f8 100644
> --- a/arch/arm64/kvm/hyp/entry.S
> +++ b/arch/arm64/kvm/hyp/entry.S
> @@ -124,6 +124,17 @@ ENTRY(__guest_exit)
>  	// Now restore the host regs
>  	restore_callee_saved_regs x2
>  
> +alternative_if ARM64_HAS_RAS_EXTN
> +	// If we have the RAS extensions we can consume a pending error
> +	// without an unmask-SError and isb.
> +	esb
> +	mrs_s	x2, SYS_DISR_EL1
> +	str	x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
> +	cbz	x2, 1f
> +	msr_s	SYS_DISR_EL1, xzr
> +	orr	x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
> +1:	ret
> +alternative_else
>  	// If we have a pending asynchronous abort, now is the
>  	// time to find out. From your VAXorcist book, page 666:
>  	// "Threaten me not, oh Evil one!  For I speak with
> @@ -134,7 +145,9 @@ ENTRY(__guest_exit)
>  	mov	x5, x0
>  
>  	dsb	sy		// Synchronize against in-flight ld/st
> +	nop
>  	msr	daifclr, #4	// Unmask aborts
> +alternative_endif
>  
>  	// This is our single instruction exception window. A pending
>  	// SError is guaranteed to occur at the earliest when we unmask
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
@ 2017-10-31  6:13     ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  6:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:58:05PM +0100, James Morse wrote:
> We expect to have firmware-first handling of RAS SErrors, with errors
> notified via an APEI method. For systems without firmware-first, add
> some minimal handling to KVM.
> 
> There are two ways KVM can take an SError due to a guest, either may be a
> RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
> or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
> 
> The current SError from EL2 code unmasks SError and tries to fence any
> pending SError into a single instruction window. It then leaves SError
> unmasked.
> 
> With the v8.2 RAS Extensions we may take an SError for a 'corrected'
> error, but KVM is only able to handle SError from EL2 if they occur
> during this single instruction window...
> 
> The RAS Extensions give us a new instruction to synchronise and
> consume SErrors. The RAS Extensions document (ARM DDI0587),
> '2.4.1 ESB and Unrecoverable errors' describes ESB as synchronising
> SError interrupts generated by 'instructions, translation table walks,
> hardware updates to the translation tables, and instruction fetches on
> the same PE'. This makes ESB equivalent to KVMs existing
> 'dsb, mrs-daifclr, isb' sequence.
> 
> Use the alternatives to synchronise and consume any SError using ESB
> instead of unmasking and taking the SError. Set ARM_EXIT_WITH_SERROR_BIT
> in the exit_code so that we can restart the vcpu if it turns out this
> SError has no impact on the vcpu.
> 
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> 
> ---
> Changes since v3:
>  * Moved that nop out of the firing line
> 
>  arch/arm64/include/asm/kvm_emulate.h |  5 +++++
>  arch/arm64/include/asm/kvm_host.h    |  1 +
>  arch/arm64/kernel/asm-offsets.c      |  1 +
>  arch/arm64/kvm/handle_exit.c         | 10 +++++++++-
>  arch/arm64/kvm/hyp/entry.S           | 13 +++++++++++++
>  5 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 8a7a838eb17a..8274d16df3cd 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -173,6 +173,11 @@ static inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu)
>  	return ((phys_addr_t)vcpu->arch.fault.hpfar_el2 & HPFAR_MASK) << 8;
>  }
>  
> +static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu)
> +{
> +	return vcpu->arch.fault.disr_el1;
> +}
> +
>  static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu)
>  {
>  	return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_xVC_IMM_MASK;
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 97438cc3a9ad..cf5d78ba14b5 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -89,6 +89,7 @@ struct kvm_vcpu_fault_info {
>  	u32 esr_el2;		/* Hyp Syndrom Register */
>  	u64 far_el2;		/* Hyp Fault Address Register */
>  	u64 hpfar_el2;		/* Hyp IPA Fault Address Register */
> +	u64 disr_el1;		/* Deferred [SError] Status Register */
>  };
>  
>  /*
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index 71bf088f1e4b..121889c49542 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -130,6 +130,7 @@ int main(void)
>    BLANK();
>  #ifdef CONFIG_KVM_ARM_HOST
>    DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
> +  DEFINE(VCPU_FAULT_DISR,	offsetof(struct kvm_vcpu, arch.fault.disr_el1));
>    DEFINE(CPU_GP_REGS,		offsetof(struct kvm_cpu_context, gp_regs));
>    DEFINE(CPU_USER_PT_REGS,	offsetof(struct kvm_regs, regs));
>    DEFINE(CPU_FP_REGS,		offsetof(struct kvm_regs, fp_regs));
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 345fdbba6c2e..e1e6cfe7d4d9 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -23,6 +23,7 @@
>  #include <linux/kvm_host.h>
>  
>  #include <asm/esr.h>
> +#include <asm/exception.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_coproc.h>
>  #include <asm/kvm_emulate.h>
> @@ -208,7 +209,14 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
>  			*vcpu_pc(vcpu) -= adj;
>  		}
>  
> -		kvm_inject_vabt(vcpu);
> +		if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
> +			u64 disr = kvm_vcpu_get_disr(vcpu);
> +
> +			kvm_handle_guest_serror(vcpu, disr_to_esr(disr));
> +		} else {
> +			kvm_inject_vabt(vcpu);
> +		}
> +
>  		return 1;
>  	}
>  
> diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
> index 12ee62d6d410..024c7afc78f8 100644
> --- a/arch/arm64/kvm/hyp/entry.S
> +++ b/arch/arm64/kvm/hyp/entry.S
> @@ -124,6 +124,17 @@ ENTRY(__guest_exit)
>  	// Now restore the host regs
>  	restore_callee_saved_regs x2
>  
> +alternative_if ARM64_HAS_RAS_EXTN
> +	// If we have the RAS extensions we can consume a pending error
> +	// without an unmask-SError and isb.
> +	esb
> +	mrs_s	x2, SYS_DISR_EL1
> +	str	x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
> +	cbz	x2, 1f
> +	msr_s	SYS_DISR_EL1, xzr
> +	orr	x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
> +1:	ret
> +alternative_else
>  	// If we have a pending asynchronous abort, now is the
>  	// time to find out. From your VAXorcist book, page 666:
>  	// "Threaten me not, oh Evil one!  For I speak with
> @@ -134,7 +145,9 @@ ENTRY(__guest_exit)
>  	mov	x5, x0
>  
>  	dsb	sy		// Synchronize against in-flight ld/st
> +	nop
>  	msr	daifclr, #4	// Unmask aborts
> +alternative_endif
>  
>  	// This is our single instruction exception window. A pending
>  	// SError is guaranteed to occur at the earliest when we unmask
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  6:23     ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  6:23 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi James,

On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
> On VHE systems KVM masks SError before switching the VBAR value. Any
> host RAS error that the CPU knew about before world-switch may become
> pending as an SError during world-switch, and only be taken once we enter
> the guest.
> 
> Until KVM can take RAS SErrors during world switch, add an ESB to
> force any RAS errors to be synchronised and taken on the host before
> we enter world switch.
> 
> RAS errors that become pending during world switch are still taken
> once we enter the guest.
> 
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index cf5d78ba14b5..5dc6f2877762 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
>  
>  static inline void kvm_arm_vhe_guest_enter(void)
>  {
> +	esb();

I don't fully appreciate what the point of this is?

As I understand it, our fundamental goal here is to try to distinguish
between errors happening on the host or in the guest.

If that's correct, then why don't we do it at the last possible moment
when we still have a scratch register left, in the world switch code
itself, and in the case abort the guest entry and report back a "host
SError" return code.

If the answer to that question is, that since we will always have some
instruction window before entering the guest and things will never be
precise anyway, so we do it here where it's more convenient, then my
counter-question would be why we do it at all then?  If we're not
precise anyway, then why not simply take our chances and hope that the
hardware delivers the SError before we mask them, and if not, tough
luck?

>  	local_daif_mask();
>  }
>  
> -- 
> 2.13.3
> 

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
@ 2017-10-31  6:23     ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi James,

On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
> On VHE systems KVM masks SError before switching the VBAR value. Any
> host RAS error that the CPU knew about before world-switch may become
> pending as an SError during world-switch, and only be taken once we enter
> the guest.
> 
> Until KVM can take RAS SErrors during world switch, add an ESB to
> force any RAS errors to be synchronised and taken on the host before
> we enter world switch.
> 
> RAS errors that become pending during world switch are still taken
> once we enter the guest.
> 
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index cf5d78ba14b5..5dc6f2877762 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
>  
>  static inline void kvm_arm_vhe_guest_enter(void)
>  {
> +	esb();

I don't fully appreciate what the point of this is?

As I understand it, our fundamental goal here is to try to distinguish
between errors happening on the host or in the guest.

If that's correct, then why don't we do it at the last possible moment
when we still have a scratch register left, in the world switch code
itself, and in the case abort the guest entry and report back a "host
SError" return code.

If the answer to that question is, that since we will always have some
instruction window before entering the guest and things will never be
precise anyway, so we do it here where it's more convenient, then my
counter-question would be why we do it at all then?  If we're not
precise anyway, then why not simply take our chances and hope that the
hardware delivers the SError before we mask them, and if not, tough
luck?

>  	local_daif_mask();
>  }
>  
> -- 
> 2.13.3
> 

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 21/21] KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  6:32     ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  6:32 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Oct 19, 2017 at 03:58:07PM +0100, James Morse wrote:
> From: Dongjiu Geng <gengdongjiu@huawei.com>
> 
> ARMv8.2 adds a new bit HCR_EL2.TEA which routes synchronous external
> aborts to EL2, and adds a trap control bit HCR_EL2.TERR which traps
> all Non-secure EL1&0 error record accesses to EL2.
> 
> This patch enables the two bits for the guest OS, guaranteeing that
> KVM takes external aborts and traps attempts to access the physical
> error registers.
> 
> ERRIDR_EL1 advertises the number of error records, we return
> zero meaning we can treat all the other registers as RAZ/WI too.
> 
> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
> [removed specific emulation, use trap_raz_wi() directly for everything,
>  rephrased parts of the commit message]
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
>  arch/arm64/include/asm/kvm_arm.h     |  2 ++
>  arch/arm64/include/asm/kvm_emulate.h |  7 +++++++
>  arch/arm64/include/asm/sysreg.h      | 10 ++++++++++
>  arch/arm64/kvm/sys_regs.c            | 10 ++++++++++
>  4 files changed, 29 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 61d694c2eae5..1188272003c4 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -23,6 +23,8 @@
>  #include <asm/types.h>
>  
>  /* Hyp Configuration Register (HCR) bits */
> +#define HCR_TEA		(UL(1) << 37)
> +#define HCR_TERR	(UL(1) << 36)
>  #define HCR_E2H		(UL(1) << 34)
>  #define HCR_ID		(UL(1) << 33)
>  #define HCR_CD		(UL(1) << 32)
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 8274d16df3cd..2cd666a9d47e 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -47,6 +47,13 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
>  	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
>  	if (is_kernel_in_hyp_mode())
>  		vcpu->arch.hcr_el2 |= HCR_E2H;
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
> +		/* route synchronous external abort exceptions to EL2 */
> +		vcpu->arch.hcr_el2 |= HCR_TEA;
> +		/* trap error record accesses */
> +		vcpu->arch.hcr_el2 |= HCR_TERR;
> +	}
> +
>  	if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
>  		vcpu->arch.hcr_el2 &= ~HCR_RW;
>  }
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 1b8b9012234d..0d3c5c7bb425 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -169,6 +169,16 @@
>  #define SYS_AFSR0_EL1			sys_reg(3, 0, 5, 1, 0)
>  #define SYS_AFSR1_EL1			sys_reg(3, 0, 5, 1, 1)
>  #define SYS_ESR_EL1			sys_reg(3, 0, 5, 2, 0)
> +
> +#define SYS_ERRIDR_EL1			sys_reg(3, 0, 5, 3, 0)
> +#define SYS_ERRSELR_EL1			sys_reg(3, 0, 5, 3, 1)
> +#define SYS_ERXFR_EL1			sys_reg(3, 0, 5, 4, 0)
> +#define SYS_ERXCTLR_EL1			sys_reg(3, 0, 5, 4, 1)
> +#define SYS_ERXSTATUS_EL1		sys_reg(3, 0, 5, 4, 2)
> +#define SYS_ERXADDR_EL1			sys_reg(3, 0, 5, 4, 3)
> +#define SYS_ERXMISC0_EL1		sys_reg(3, 0, 5, 5, 0)
> +#define SYS_ERXMISC1_EL1		sys_reg(3, 0, 5, 5, 1)
> +
>  #define SYS_FAR_EL1			sys_reg(3, 0, 6, 0, 0)
>  #define SYS_PAR_EL1			sys_reg(3, 0, 7, 4, 0)
>  
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 713275b501ce..2b3b16bf5275 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -953,6 +953,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
>  	{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
>  	{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
> +
> +	{ SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
> +
>  	{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
>  	{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
>  
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 21/21] KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA
@ 2017-10-31  6:32     ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  6:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:58:07PM +0100, James Morse wrote:
> From: Dongjiu Geng <gengdongjiu@huawei.com>
> 
> ARMv8.2 adds a new bit HCR_EL2.TEA which routes synchronous external
> aborts to EL2, and adds a trap control bit HCR_EL2.TERR which traps
> all Non-secure EL1&0 error record accesses to EL2.
> 
> This patch enables the two bits for the guest OS, guaranteeing that
> KVM takes external aborts and traps attempts to access the physical
> error registers.
> 
> ERRIDR_EL1 advertises the number of error records, we return
> zero meaning we can treat all the other registers as RAZ/WI too.
> 
> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
> [removed specific emulation, use trap_raz_wi() directly for everything,
>  rephrased parts of the commit message]
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
>  arch/arm64/include/asm/kvm_arm.h     |  2 ++
>  arch/arm64/include/asm/kvm_emulate.h |  7 +++++++
>  arch/arm64/include/asm/sysreg.h      | 10 ++++++++++
>  arch/arm64/kvm/sys_regs.c            | 10 ++++++++++
>  4 files changed, 29 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 61d694c2eae5..1188272003c4 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -23,6 +23,8 @@
>  #include <asm/types.h>
>  
>  /* Hyp Configuration Register (HCR) bits */
> +#define HCR_TEA		(UL(1) << 37)
> +#define HCR_TERR	(UL(1) << 36)
>  #define HCR_E2H		(UL(1) << 34)
>  #define HCR_ID		(UL(1) << 33)
>  #define HCR_CD		(UL(1) << 32)
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 8274d16df3cd..2cd666a9d47e 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -47,6 +47,13 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
>  	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
>  	if (is_kernel_in_hyp_mode())
>  		vcpu->arch.hcr_el2 |= HCR_E2H;
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
> +		/* route synchronous external abort exceptions to EL2 */
> +		vcpu->arch.hcr_el2 |= HCR_TEA;
> +		/* trap error record accesses */
> +		vcpu->arch.hcr_el2 |= HCR_TERR;
> +	}
> +
>  	if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
>  		vcpu->arch.hcr_el2 &= ~HCR_RW;
>  }
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 1b8b9012234d..0d3c5c7bb425 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -169,6 +169,16 @@
>  #define SYS_AFSR0_EL1			sys_reg(3, 0, 5, 1, 0)
>  #define SYS_AFSR1_EL1			sys_reg(3, 0, 5, 1, 1)
>  #define SYS_ESR_EL1			sys_reg(3, 0, 5, 2, 0)
> +
> +#define SYS_ERRIDR_EL1			sys_reg(3, 0, 5, 3, 0)
> +#define SYS_ERRSELR_EL1			sys_reg(3, 0, 5, 3, 1)
> +#define SYS_ERXFR_EL1			sys_reg(3, 0, 5, 4, 0)
> +#define SYS_ERXCTLR_EL1			sys_reg(3, 0, 5, 4, 1)
> +#define SYS_ERXSTATUS_EL1		sys_reg(3, 0, 5, 4, 2)
> +#define SYS_ERXADDR_EL1			sys_reg(3, 0, 5, 4, 3)
> +#define SYS_ERXMISC0_EL1		sys_reg(3, 0, 5, 5, 0)
> +#define SYS_ERXMISC1_EL1		sys_reg(3, 0, 5, 5, 1)
> +
>  #define SYS_FAR_EL1			sys_reg(3, 0, 6, 0, 0)
>  #define SYS_PAR_EL1			sys_reg(3, 0, 7, 4, 0)
>  
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 713275b501ce..2b3b16bf5275 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -953,6 +953,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
>  	{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
>  	{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
> +
> +	{ SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
> +	{ SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
> +
>  	{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
>  	{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
>  
> -- 
> 2.13.3
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 21/21] KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  6:32     ` Marc Zyngier
  -1 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  6:32 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Catalin Marinas, Julien Thierry, Will Deacon,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19 2017 at  4:58:07 pm BST, James Morse <james.morse@arm.com> wrote:
> From: Dongjiu Geng <gengdongjiu@huawei.com>
>
> ARMv8.2 adds a new bit HCR_EL2.TEA which routes synchronous external
> aborts to EL2, and adds a trap control bit HCR_EL2.TERR which traps
> all Non-secure EL1&0 error record accesses to EL2.
>
> This patch enables the two bits for the guest OS, guaranteeing that
> KVM takes external aborts and traps attempts to access the physical
> error registers.
>
> ERRIDR_EL1 advertises the number of error records, we return
> zero meaning we can treat all the other registers as RAZ/WI too.
>
> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
> [removed specific emulation, use trap_raz_wi() directly for everything,
>  rephrased parts of the commit message]
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 21/21] KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA
@ 2017-10-31  6:32     ` Marc Zyngier
  0 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  6:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19 2017 at  4:58:07 pm BST, James Morse <james.morse@arm.com> wrote:
> From: Dongjiu Geng <gengdongjiu@huawei.com>
>
> ARMv8.2 adds a new bit HCR_EL2.TEA which routes synchronous external
> aborts to EL2, and adds a trap control bit HCR_EL2.TERR which traps
> all Non-secure EL1&0 error record accesses to EL2.
>
> This patch enables the two bits for the guest OS, guaranteeing that
> KVM takes external aborts and traps attempts to access the physical
> error registers.
>
> ERRIDR_EL1 advertises the number of error records, we return
> zero meaning we can treat all the other registers as RAZ/WI too.
>
> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
> [removed specific emulation, use trap_raz_wi() directly for everything,
>  rephrased parts of the commit message]
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
  2017-10-19 14:58   ` James Morse
@ 2017-10-31  6:34     ` Marc Zyngier
  -1 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  6:34 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Catalin Marinas, Julien Thierry, Will Deacon,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19 2017 at  4:58:01 pm BST, James Morse <james.morse@arm.com> wrote:
> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> generated an SError with an implementation defined ESR_EL1.ISS, because we
> had no mechanism to specify the ESR value.
>
> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> is clear indicating the remainder of the ISS field is invalid.
>
> With the RAS Extensions we have a mechanism to specify this value, and the
> most significant bit has a new meaning: 'IDS - Implementation Defined
> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> instead of 'no valid ISS'.
>
> Add KVM support for the VSESR_EL2 register to specify an ESR value when
> HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
> specify an implementation-defined value.
>
> We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
> save/restores this bit during __deactivate_traps() and hardware clears the
> bit once the guest has consumed the virtual-SError.
>
> Future patches may add an API (or KVM CAP) to pend a virtual SError with
> a specified ESR.
>
> Cc: Dongjiu Geng <gengdongjiu@huawei.com>
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2.
@ 2017-10-31  6:34     ` Marc Zyngier
  0 siblings, 0 replies; 160+ messages in thread
From: Marc Zyngier @ 2017-10-31  6:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19 2017 at  4:58:01 pm BST, James Morse <james.morse@arm.com> wrote:
> Prior to v8.2's RAS Extensions, the HCR_EL2.VSE 'virtual SError' feature
> generated an SError with an implementation defined ESR_EL1.ISS, because we
> had no mechanism to specify the ESR value.
>
> On Juno this generates an all-zero ESR, the most significant bit 'ISV'
> is clear indicating the remainder of the ISS field is invalid.
>
> With the RAS Extensions we have a mechanism to specify this value, and the
> most significant bit has a new meaning: 'IDS - Implementation Defined
> Syndrome'. An all-zero SError ESR now means: 'RAS error: Uncategorized'
> instead of 'no valid ISS'.
>
> Add KVM support for the VSESR_EL2 register to specify an ESR value when
> HCR_EL2.VSE generates a virtual SError. Change kvm_inject_vabt() to
> specify an implementation-defined value.
>
> We only need to restore the VSESR_EL2 value when HCR_EL2.VSE is set, KVM
> save/restores this bit during __deactivate_traps() and hardware clears the
> bit once the guest has consumed the virtual-SError.
>
> Future patches may add an API (or KVM CAP) to pend a virtual SError with
> a specified ESR.
>
> Cc: Dongjiu Geng <gengdongjiu@huawei.com>
> Signed-off-by: James Morse <james.morse@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-10-19 14:57 ` James Morse
@ 2017-10-31  6:35   ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  6:35 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi James, Catalin, and Will,

On Thu, Oct 19, 2017 at 03:57:46PM +0100, James Morse wrote:
> Hello,
> 
> The aim of this series is to enable IESB and add ESB-instructions to let us
> kick any pending RAS errors into firmware to be handled by firmware-first.
> 
> Not all systems will have this firmware, so these RAS errors will become
> pending SErrors. We should take these as quickly as possible and avoid
> panic()ing for errors where we could have continued.
> 
> This first part of this series reworks the DAIF masking so that SError is
> unmasked unless we are handling a debug exception.
> 
> The last part provides the same minimal handling for SError that interrupt
> KVM. KVM is currently unable to handle SErrors during world-switch, unless
> they occur during a magic single-instruction window, it hyp-panics. I suspect
> this will be easier to fix once the VHE world-switch is further optimised.
> 
> KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
> and all-zeros has a RAS meaning.
> 
> KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
> These are errors where we don't know what they mean, they may not be
> synchronised by ESB. Today we blame the guest.
> My half-baked suggestion would be to make a virtual SError pending, but then
> exit to user-space to give Qemu the change to quit (for virtual machines that
> don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
> continue and take KVMs default all-zeros impdef ESR.

The KVM side of this series is looking pretty good.

What are the merge plans for this?  I am fine if you will take this via
the arm64 tree with our acks from the KVM side.  Alternatively, I
suppose you can apply all the arm64 patches and provide us with a stable
branch for that?

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-10-31  6:35   ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-10-31  6:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi James, Catalin, and Will,

On Thu, Oct 19, 2017 at 03:57:46PM +0100, James Morse wrote:
> Hello,
> 
> The aim of this series is to enable IESB and add ESB-instructions to let us
> kick any pending RAS errors into firmware to be handled by firmware-first.
> 
> Not all systems will have this firmware, so these RAS errors will become
> pending SErrors. We should take these as quickly as possible and avoid
> panic()ing for errors where we could have continued.
> 
> This first part of this series reworks the DAIF masking so that SError is
> unmasked unless we are handling a debug exception.
> 
> The last part provides the same minimal handling for SError that interrupt
> KVM. KVM is currently unable to handle SErrors during world-switch, unless
> they occur during a magic single-instruction window, it hyp-panics. I suspect
> this will be easier to fix once the VHE world-switch is further optimised.
> 
> KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
> and all-zeros has a RAS meaning.
> 
> KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
> These are errors where we don't know what they mean, they may not be
> synchronised by ESB. Today we blame the guest.
> My half-baked suggestion would be to make a virtual SError pending, but then
> exit to user-space to give Qemu the change to quit (for virtual machines that
> don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
> continue and take KVMs default all-zeros impdef ESR.

The KVM side of this series is looking pretty good.

What are the merge plans for this?  I am fine if you will take this via
the arm64 tree with our acks from the KVM side.  Alternatively, I
suppose you can apply all the arm64 patches and provide us with a stable
branch for that?

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-10-31  6:35   ` Christoffer Dall
@ 2017-10-31 10:08     ` Will Deacon
  -1 siblings, 0 replies; 160+ messages in thread
From: Will Deacon @ 2017-10-31 10:08 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Tue, Oct 31, 2017 at 07:35:35AM +0100, Christoffer Dall wrote:
> Hi James, Catalin, and Will,
> 
> On Thu, Oct 19, 2017 at 03:57:46PM +0100, James Morse wrote:
> > Hello,
> > 
> > The aim of this series is to enable IESB and add ESB-instructions to let us
> > kick any pending RAS errors into firmware to be handled by firmware-first.
> > 
> > Not all systems will have this firmware, so these RAS errors will become
> > pending SErrors. We should take these as quickly as possible and avoid
> > panic()ing for errors where we could have continued.
> > 
> > This first part of this series reworks the DAIF masking so that SError is
> > unmasked unless we are handling a debug exception.
> > 
> > The last part provides the same minimal handling for SError that interrupt
> > KVM. KVM is currently unable to handle SErrors during world-switch, unless
> > they occur during a magic single-instruction window, it hyp-panics. I suspect
> > this will be easier to fix once the VHE world-switch is further optimised.
> > 
> > KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
> > and all-zeros has a RAS meaning.
> > 
> > KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
> > These are errors where we don't know what they mean, they may not be
> > synchronised by ESB. Today we blame the guest.
> > My half-baked suggestion would be to make a virtual SError pending, but then
> > exit to user-space to give Qemu the change to quit (for virtual machines that
> > don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
> > continue and take KVMs default all-zeros impdef ESR.
> 
> The KVM side of this series is looking pretty good.
> 
> What are the merge plans for this?  I am fine if you will take this via
> the arm64 tree with our acks from the KVM side.  Alternatively, I
> suppose you can apply all the arm64 patches and provide us with a stable
> branch for that?

I'll take a look this afternoon, but we haven't had a linux next release
since the 18th so I'm starting to get nervous about conflicts if I end up
pulling in new trees now.

Will

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-10-31 10:08     ` Will Deacon
  0 siblings, 0 replies; 160+ messages in thread
From: Will Deacon @ 2017-10-31 10:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 31, 2017 at 07:35:35AM +0100, Christoffer Dall wrote:
> Hi James, Catalin, and Will,
> 
> On Thu, Oct 19, 2017 at 03:57:46PM +0100, James Morse wrote:
> > Hello,
> > 
> > The aim of this series is to enable IESB and add ESB-instructions to let us
> > kick any pending RAS errors into firmware to be handled by firmware-first.
> > 
> > Not all systems will have this firmware, so these RAS errors will become
> > pending SErrors. We should take these as quickly as possible and avoid
> > panic()ing for errors where we could have continued.
> > 
> > This first part of this series reworks the DAIF masking so that SError is
> > unmasked unless we are handling a debug exception.
> > 
> > The last part provides the same minimal handling for SError that interrupt
> > KVM. KVM is currently unable to handle SErrors during world-switch, unless
> > they occur during a magic single-instruction window, it hyp-panics. I suspect
> > this will be easier to fix once the VHE world-switch is further optimised.
> > 
> > KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
> > and all-zeros has a RAS meaning.
> > 
> > KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
> > These are errors where we don't know what they mean, they may not be
> > synchronised by ESB. Today we blame the guest.
> > My half-baked suggestion would be to make a virtual SError pending, but then
> > exit to user-space to give Qemu the change to quit (for virtual machines that
> > don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
> > continue and take KVMs default all-zeros impdef ESR.
> 
> The KVM side of this series is looking pretty good.
> 
> What are the merge plans for this?  I am fine if you will take this via
> the arm64 tree with our acks from the KVM side.  Alternatively, I
> suppose you can apply all the arm64 patches and provide us with a stable
> branch for that?

I'll take a look this afternoon, but we haven't had a linux next release
since the 18th so I'm starting to get nervous about conflicts if I end up
pulling in new trees now.

Will

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
  2017-10-31  6:23     ` Christoffer Dall
@ 2017-10-31 11:43       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-31 11:43 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi Christoffer,

On 31/10/17 06:23, Christoffer Dall wrote:
> On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
>> On VHE systems KVM masks SError before switching the VBAR value. Any
>> host RAS error that the CPU knew about before world-switch may become
>> pending as an SError during world-switch, and only be taken once we enter
>> the guest.
>>
>> Until KVM can take RAS SErrors during world switch, add an ESB to
>> force any RAS errors to be synchronised and taken on the host before
>> we enter world switch.
>>
>> RAS errors that become pending during world switch are still taken
>> once we enter the guest.

>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index cf5d78ba14b5..5dc6f2877762 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
>>  
>>  static inline void kvm_arm_vhe_guest_enter(void)
>>  {
>> +	esb();

> I don't fully appreciate what the point of this is?
> 
> As I understand it, our fundamental goal here is to try to distinguish
> between errors happening on the host or in the guest.

Not just host/guest, but also those we can and can't handle.

KVM can't currently take an SError during world switch, so a RAS error that the
CPU was hoping to defer may spread from the host into KVM's
no-SError:world-switch code. If this happens it will (almost certainly) have to
be re-classified as uncontainable.

There is also a firmware-first angle here: NOTIFY_SEI can't be delivered if the
normal world has SError masked, so any error that spreads past this point
becomes a reboot-by-firmware instead of an OS notification and almost-helpful
error message.


> If that's correct, then why don't we do it at the last possible moment
> when we still have a scratch register left, in the world switch code
> itself, and in the case abort the guest entry and report back a "host
> SError" return code.

We have IESB to run the error-barrier as we enter the guest. This would make any
host error pending as an SError, and we would exit the guest immediately. But if
there was an RAS error during world switch, by this point its likely to be
classified as uncontainable.

This esb() is trying to keep this window of code as small as possible, to just
errors that occur during world switch.

With your vcpu load/save this window becomes a lot smaller, it may be possible
to get a VHE-host's arch-code SError handler to take errors from EL2, in which
case this barrier can disappear.
(note to self: guest may still own the debug hardware)


Thanks,

James


> If the answer to that question is, that since we will always have some
> instruction window before entering the guest and things will never be
> precise anyway, so we do it here where it's more convenient, then my
> counter-question would be why we do it at all then?  If we're not
> precise anyway, then why not simply take our chances and hope that the
> hardware delivers the SError before we mask them, and if not, tough
> luck?

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
@ 2017-10-31 11:43       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-10-31 11:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 31/10/17 06:23, Christoffer Dall wrote:
> On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
>> On VHE systems KVM masks SError before switching the VBAR value. Any
>> host RAS error that the CPU knew about before world-switch may become
>> pending as an SError during world-switch, and only be taken once we enter
>> the guest.
>>
>> Until KVM can take RAS SErrors during world switch, add an ESB to
>> force any RAS errors to be synchronised and taken on the host before
>> we enter world switch.
>>
>> RAS errors that become pending during world switch are still taken
>> once we enter the guest.

>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index cf5d78ba14b5..5dc6f2877762 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
>>  
>>  static inline void kvm_arm_vhe_guest_enter(void)
>>  {
>> +	esb();

> I don't fully appreciate what the point of this is?
> 
> As I understand it, our fundamental goal here is to try to distinguish
> between errors happening on the host or in the guest.

Not just host/guest, but also those we can and can't handle.

KVM can't currently take an SError during world switch, so a RAS error that the
CPU was hoping to defer may spread from the host into KVM's
no-SError:world-switch code. If this happens it will (almost certainly) have to
be re-classified as uncontainable.

There is also a firmware-first angle here: NOTIFY_SEI can't be delivered if the
normal world has SError masked, so any error that spreads past this point
becomes a reboot-by-firmware instead of an OS notification and almost-helpful
error message.


> If that's correct, then why don't we do it at the last possible moment
> when we still have a scratch register left, in the world switch code
> itself, and in the case abort the guest entry and report back a "host
> SError" return code.

We have IESB to run the error-barrier as we enter the guest. This would make any
host error pending as an SError, and we would exit the guest immediately. But if
there was an RAS error during world switch, by this point its likely to be
classified as uncontainable.

This esb() is trying to keep this window of code as small as possible, to just
errors that occur during world switch.

With your vcpu load/save this window becomes a lot smaller, it may be possible
to get a VHE-host's arch-code SError handler to take errors from EL2, in which
case this barrier can disappear.
(note to self: guest may still own the debug hardware)


Thanks,

James


> If the answer to that question is, that since we will always have some
> instruction window before entering the guest and things will never be
> precise anyway, so we do it here where it's more convenient, then my
> counter-question would be why we do it at all then?  If we're not
> precise anyway, then why not simply take our chances and hope that the
> hardware delivers the SError before we mask them, and if not, tough
> luck?

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 11/21] arm64: cpufeature: Detect CPU RAS Extentions
  2017-10-19 14:57   ` James Morse
@ 2017-10-31 13:14     ` Will Deacon
  -1 siblings, 0 replies; 160+ messages in thread
From: Will Deacon @ 2017-10-31 13:14 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19, 2017 at 03:57:57PM +0100, James Morse wrote:
> From: Xie XiuQi <xiexiuqi@huawei.com>
> 
> ARM's v8.2 Extentions add support for Reliability, Availability and
> Serviceability (RAS). On CPUs with these extensions system software
> can use additional barriers to isolate errors and determine if faults
> are pending.
> 
> Add cpufeature detection and a barrier in the context-switch code.
> There is no need to use alternatives for this as CPUs that don't
> support this feature will treat the instruction as a nop.
> 
> Platform level RAS support may require additional firmware support.
> 
> Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
> [Rebased, added esb and config option, reworded commit message]
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm64/Kconfig               | 16 ++++++++++++++++
>  arch/arm64/include/asm/barrier.h |  1 +
>  arch/arm64/include/asm/cpucaps.h |  3 ++-
>  arch/arm64/include/asm/sysreg.h  |  2 ++
>  arch/arm64/kernel/cpufeature.c   | 13 +++++++++++++
>  arch/arm64/kernel/process.c      |  3 +++
>  6 files changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 70dfe4e9ccc5..b68f5e93baac 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -973,6 +973,22 @@ config ARM64_PMEM
>  	  operations if DC CVAP is not supported (following the behaviour of
>  	  DC CVAP itself if the system does not define a point of persistence).
>  
> +config ARM64_RAS_EXTN
> +	bool "Enable support for RAS CPU Extensions"
> +	default y
> +	help
> +	  CPUs that support the Reliability, Availability and Serviceability
> +	  (RAS) Extensions, part of ARMv8.2 are able to track faults and
> +	  errors, classify them and report them to software.
> +
> +	  On CPUs with these extensions system software can use additional
> +	  barriers to determine if faults are pending and read the
> +	  classification from a new set of registers.
> +
> +	  Selecting this feature will allow the kernel to use these barriers
> +	  and access the new registers if the system supports the extension.
> +	  Platform RAS features may additionally depend on firmware support.
> +
>  endmenu
>  
>  config ARM64_MODULE_CMODEL_LARGE
> diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
> index 0fe7e43b7fbc..8b0a0eb67625 100644
> --- a/arch/arm64/include/asm/barrier.h
> +++ b/arch/arm64/include/asm/barrier.h
> @@ -30,6 +30,7 @@
>  #define isb()		asm volatile("isb" : : : "memory")
>  #define dmb(opt)	asm volatile("dmb " #opt : : : "memory")
>  #define dsb(opt)	asm volatile("dsb " #opt : : : "memory")
> +#define esb()		asm volatile("hint #16"  : : : "memory")
>  
>  #define mb()		dsb(sy)
>  #define rmb()		dsb(ld)
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> index 8da621627d7c..4820d441bfb9 100644
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ b/arch/arm64/include/asm/cpucaps.h
> @@ -40,7 +40,8 @@
>  #define ARM64_WORKAROUND_858921			19
>  #define ARM64_WORKAROUND_CAVIUM_30115		20
>  #define ARM64_HAS_DCPOP				21
> +#define ARM64_HAS_RAS_EXTN			22
>  
> -#define ARM64_NCAPS				22
> +#define ARM64_NCAPS				23
>  
>  #endif /* __ASM_CPUCAPS_H */
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index f707fed5886f..64e2a80fd749 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -332,6 +332,7 @@
>  #define ID_AA64ISAR1_DPB_SHIFT		0
>  
>  /* id_aa64pfr0 */
> +#define ID_AA64PFR0_RAS_SHIFT		28
>  #define ID_AA64PFR0_GIC_SHIFT		24
>  #define ID_AA64PFR0_ASIMD_SHIFT		20
>  #define ID_AA64PFR0_FP_SHIFT		16
> @@ -340,6 +341,7 @@
>  #define ID_AA64PFR0_EL1_SHIFT		4
>  #define ID_AA64PFR0_EL0_SHIFT		0
>  
> +#define ID_AA64PFR0_RAS_V1		0x1
>  #define ID_AA64PFR0_FP_NI		0xf
>  #define ID_AA64PFR0_FP_SUPPORTED	0x0
>  #define ID_AA64PFR0_ASIMD_NI		0xf
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index cd52d365d1f0..0fc017b55cb1 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -125,6 +125,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
>  };
>  
>  static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64PFR0_RAS_SHIFT, 4, 0),

We probably want FTR_LOWER_SAFE here now, right? (we changed the other
fields in for-next/core).

> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 2dc0f8482210..5e5d2f0a1d0a 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -365,6 +365,9 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
>  	 */
>  	dsb(ish);
>  
> +	/* Deliver any pending SError from prev */
> +	esb();

I'm assuming this is going to be expensive. What if we moved it to switch_mm
instead. Do we actually need thread granularity for error isolation?

Will

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 11/21] arm64: cpufeature: Detect CPU RAS Extentions
@ 2017-10-31 13:14     ` Will Deacon
  0 siblings, 0 replies; 160+ messages in thread
From: Will Deacon @ 2017-10-31 13:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:57:57PM +0100, James Morse wrote:
> From: Xie XiuQi <xiexiuqi@huawei.com>
> 
> ARM's v8.2 Extentions add support for Reliability, Availability and
> Serviceability (RAS). On CPUs with these extensions system software
> can use additional barriers to isolate errors and determine if faults
> are pending.
> 
> Add cpufeature detection and a barrier in the context-switch code.
> There is no need to use alternatives for this as CPUs that don't
> support this feature will treat the instruction as a nop.
> 
> Platform level RAS support may require additional firmware support.
> 
> Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
> [Rebased, added esb and config option, reworded commit message]
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm64/Kconfig               | 16 ++++++++++++++++
>  arch/arm64/include/asm/barrier.h |  1 +
>  arch/arm64/include/asm/cpucaps.h |  3 ++-
>  arch/arm64/include/asm/sysreg.h  |  2 ++
>  arch/arm64/kernel/cpufeature.c   | 13 +++++++++++++
>  arch/arm64/kernel/process.c      |  3 +++
>  6 files changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 70dfe4e9ccc5..b68f5e93baac 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -973,6 +973,22 @@ config ARM64_PMEM
>  	  operations if DC CVAP is not supported (following the behaviour of
>  	  DC CVAP itself if the system does not define a point of persistence).
>  
> +config ARM64_RAS_EXTN
> +	bool "Enable support for RAS CPU Extensions"
> +	default y
> +	help
> +	  CPUs that support the Reliability, Availability and Serviceability
> +	  (RAS) Extensions, part of ARMv8.2 are able to track faults and
> +	  errors, classify them and report them to software.
> +
> +	  On CPUs with these extensions system software can use additional
> +	  barriers to determine if faults are pending and read the
> +	  classification from a new set of registers.
> +
> +	  Selecting this feature will allow the kernel to use these barriers
> +	  and access the new registers if the system supports the extension.
> +	  Platform RAS features may additionally depend on firmware support.
> +
>  endmenu
>  
>  config ARM64_MODULE_CMODEL_LARGE
> diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
> index 0fe7e43b7fbc..8b0a0eb67625 100644
> --- a/arch/arm64/include/asm/barrier.h
> +++ b/arch/arm64/include/asm/barrier.h
> @@ -30,6 +30,7 @@
>  #define isb()		asm volatile("isb" : : : "memory")
>  #define dmb(opt)	asm volatile("dmb " #opt : : : "memory")
>  #define dsb(opt)	asm volatile("dsb " #opt : : : "memory")
> +#define esb()		asm volatile("hint #16"  : : : "memory")
>  
>  #define mb()		dsb(sy)
>  #define rmb()		dsb(ld)
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> index 8da621627d7c..4820d441bfb9 100644
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ b/arch/arm64/include/asm/cpucaps.h
> @@ -40,7 +40,8 @@
>  #define ARM64_WORKAROUND_858921			19
>  #define ARM64_WORKAROUND_CAVIUM_30115		20
>  #define ARM64_HAS_DCPOP				21
> +#define ARM64_HAS_RAS_EXTN			22
>  
> -#define ARM64_NCAPS				22
> +#define ARM64_NCAPS				23
>  
>  #endif /* __ASM_CPUCAPS_H */
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index f707fed5886f..64e2a80fd749 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -332,6 +332,7 @@
>  #define ID_AA64ISAR1_DPB_SHIFT		0
>  
>  /* id_aa64pfr0 */
> +#define ID_AA64PFR0_RAS_SHIFT		28
>  #define ID_AA64PFR0_GIC_SHIFT		24
>  #define ID_AA64PFR0_ASIMD_SHIFT		20
>  #define ID_AA64PFR0_FP_SHIFT		16
> @@ -340,6 +341,7 @@
>  #define ID_AA64PFR0_EL1_SHIFT		4
>  #define ID_AA64PFR0_EL0_SHIFT		0
>  
> +#define ID_AA64PFR0_RAS_V1		0x1
>  #define ID_AA64PFR0_FP_NI		0xf
>  #define ID_AA64PFR0_FP_SUPPORTED	0x0
>  #define ID_AA64PFR0_ASIMD_NI		0xf
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index cd52d365d1f0..0fc017b55cb1 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -125,6 +125,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
>  };
>  
>  static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64PFR0_RAS_SHIFT, 4, 0),

We probably want FTR_LOWER_SAFE here now, right? (we changed the other
fields in for-next/core).

> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 2dc0f8482210..5e5d2f0a1d0a 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -365,6 +365,9 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
>  	 */
>  	dsb(ish);
>  
> +	/* Deliver any pending SError from prev */
> +	esb();

I'm assuming this is going to be expensive. What if we moved it to switch_mm
instead. Do we actually need thread granularity for error isolation?

Will

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 12/21] arm64: kernel: Survive corrected RAS errors notified by SError
  2017-10-19 14:57   ` James Morse
@ 2017-10-31 13:50     ` Will Deacon
  -1 siblings, 0 replies; 160+ messages in thread
From: Will Deacon @ 2017-10-31 13:50 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19, 2017 at 03:57:58PM +0100, James Morse wrote:
> Prior to v8.2, SError is an uncontainable fatal exception. The v8.2 RAS
> extensions use SError to notify software about RAS errors, these can be
> contained by the ESB instruction.
> 
> An ACPI system with firmware-first may use SError as its 'SEI'
> notification. Future patches may add code to 'claim' this SError as a
> notification.
> 
> Other systems can distinguish these RAS errors from the SError ESR and
> use the AET bits and additional data from RAS-Error registers to handle
> the error. Future patches may add this kernel-first handling.
> 
> Without support for either of these we will panic(), even if we received
> a corrected error. Add code to decode the severity of RAS errors. We can
> safely ignore contained errors where the CPU can continue to make
> progress. For all other errors we continue to panic().
> 
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> 
> ---
> I couldn't come up with a concise way to capture 'can continue to make
> progress', so opted for 'blocking' instead.
> 
>  arch/arm64/include/asm/esr.h   | 10 ++++++++
>  arch/arm64/include/asm/traps.h | 36 ++++++++++++++++++++++++++
>  arch/arm64/kernel/traps.c      | 58 ++++++++++++++++++++++++++++++++++++++----
>  3 files changed, 99 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index 66ed8b6b9976..8ea52f15bf1c 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -85,6 +85,15 @@
>  #define ESR_ELx_WNR_SHIFT	(6)
>  #define ESR_ELx_WNR		(UL(1) << ESR_ELx_WNR_SHIFT)
>  
> +/* Asynchronous Error Type */
> +#define ESR_ELx_AET		(UL(0x7) << 10)

Can you add a #define for the AET shift in the Srror ISS, please? (we have
other blocks in this file for different abort types). e.g.

/* ISS fields definitions for SError interrupts */
#define ESR_ELx_AER_SHIFT	10

then use it below.

> +#define ESR_ELx_AET_UC		(UL(0) << 10)	/* Uncontainable */
> +#define ESR_ELx_AET_UEU		(UL(1) << 10)	/* Uncorrected Unrecoverable */
> +#define ESR_ELx_AET_UEO		(UL(2) << 10)	/* Uncorrected Restartable */
> +#define ESR_ELx_AET_UER		(UL(3) << 10)	/* Uncorrected Recoverable */
> +#define ESR_ELx_AET_CE		(UL(6) << 10)	/* Corrected */
> +
>  /* Shared ISS field definitions for Data/Instruction aborts */
>  #define ESR_ELx_SET_SHIFT	(11)
>  #define ESR_ELx_SET_MASK	(UL(3) << ESR_ELx_SET_SHIFT)
> @@ -99,6 +108,7 @@
>  #define ESR_ELx_FSC		(0x3F)
>  #define ESR_ELx_FSC_TYPE	(0x3C)
>  #define ESR_ELx_FSC_EXTABT	(0x10)
> +#define ESR_ELx_FSC_SERROR	(0x11)
>  #define ESR_ELx_FSC_ACCESS	(0x08)
>  #define ESR_ELx_FSC_FAULT	(0x04)
>  #define ESR_ELx_FSC_PERM	(0x0C)
> diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
> index d131501c6222..8d2a1fff5c6b 100644
> --- a/arch/arm64/include/asm/traps.h
> +++ b/arch/arm64/include/asm/traps.h
> @@ -19,6 +19,7 @@
>  #define __ASM_TRAP_H
>  
>  #include <linux/list.h>
> +#include <asm/esr.h>
>  #include <asm/sections.h>
>  
>  struct pt_regs;
> @@ -58,4 +59,39 @@ static inline int in_entry_text(unsigned long ptr)
>  	return ptr >= (unsigned long)&__entry_text_start &&
>  	       ptr < (unsigned long)&__entry_text_end;
>  }
> +
> +static inline bool arm64_is_ras_serror(u32 esr)
> +{
> +	bool impdef = esr & ESR_ELx_ISV; /* aka IDS */

I think you should add an IDS field along with the AET one I suggested.

> +
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
> +		return !impdef;
> +
> +	return false;
> +}
> +
> +/* Return the AET bits of an SError ESR, or 0/uncontainable/uncategorized */
> +static inline u32 arm64_ras_serror_get_severity(u32 esr)
> +{
> +	u32 aet = esr & ESR_ELx_AET;
> +
> +	if (!arm64_is_ras_serror(esr)) {
> +		/* Not a RAS error, we can't interpret the ESR */
> +		return 0;
> +	}
> +
> +	/*
> +	 * AET is RES0 if 'the value returned in the DFSC field is not
> +	 * [ESR_ELx_FSC_SERROR]'
> +	 */
> +	if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
> +		/* No severity information */
> +		return 0;
> +	}

Hmm, this means we can't distinguish impdef or RES0 encodings from
uncontainable errors. Is that desirable?

Also, could we end up in a situation where some CPUs support RAS and some
don't, so arm64_is_ras_serror returns false yet a correctable error is
reported by one the CPUs and we treat it as uncontainable?

> +
> +	return aet;
> +}
> +
> +bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr);
> +void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
>  #endif
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index 773aae69c376..53aeb25158b0 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -709,17 +709,65 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
>  }
>  #endif
>  
> -asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
> +void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr)
>  {
> -	nmi_enter();
> -
>  	console_verbose();
>  
>  	pr_crit("SError Interrupt on CPU%d, code 0x%08x -- %s\n",
>  		smp_processor_id(), esr, esr_get_class_string(esr));
> -	__show_regs(regs);
> +	if (regs)
> +		__show_regs(regs);
> +
> +	/* KVM may call this this from a preemptible context */
> +	preempt_disable();
> +
> +	/*
> +	 * panic() unmasks interrupts, which unmasks SError. Use nmi_panic()
> +	 * to avoid re-entering panic.
> +	 */
> +	nmi_panic(regs, "Asynchronous SError Interrupt");
> +
> +	cpu_park_loop();
> +	unreachable();
> +}
> +
> +bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr)
> +{

Since you asked... what about "fatal" instead of "blocking"?

Will

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 12/21] arm64: kernel: Survive corrected RAS errors notified by SError
@ 2017-10-31 13:50     ` Will Deacon
  0 siblings, 0 replies; 160+ messages in thread
From: Will Deacon @ 2017-10-31 13:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:57:58PM +0100, James Morse wrote:
> Prior to v8.2, SError is an uncontainable fatal exception. The v8.2 RAS
> extensions use SError to notify software about RAS errors, these can be
> contained by the ESB instruction.
> 
> An ACPI system with firmware-first may use SError as its 'SEI'
> notification. Future patches may add code to 'claim' this SError as a
> notification.
> 
> Other systems can distinguish these RAS errors from the SError ESR and
> use the AET bits and additional data from RAS-Error registers to handle
> the error. Future patches may add this kernel-first handling.
> 
> Without support for either of these we will panic(), even if we received
> a corrected error. Add code to decode the severity of RAS errors. We can
> safely ignore contained errors where the CPU can continue to make
> progress. For all other errors we continue to panic().
> 
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> 
> ---
> I couldn't come up with a concise way to capture 'can continue to make
> progress', so opted for 'blocking' instead.
> 
>  arch/arm64/include/asm/esr.h   | 10 ++++++++
>  arch/arm64/include/asm/traps.h | 36 ++++++++++++++++++++++++++
>  arch/arm64/kernel/traps.c      | 58 ++++++++++++++++++++++++++++++++++++++----
>  3 files changed, 99 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index 66ed8b6b9976..8ea52f15bf1c 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -85,6 +85,15 @@
>  #define ESR_ELx_WNR_SHIFT	(6)
>  #define ESR_ELx_WNR		(UL(1) << ESR_ELx_WNR_SHIFT)
>  
> +/* Asynchronous Error Type */
> +#define ESR_ELx_AET		(UL(0x7) << 10)

Can you add a #define for the AET shift in the Srror ISS, please? (we have
other blocks in this file for different abort types). e.g.

/* ISS fields definitions for SError interrupts */
#define ESR_ELx_AER_SHIFT	10

then use it below.

> +#define ESR_ELx_AET_UC		(UL(0) << 10)	/* Uncontainable */
> +#define ESR_ELx_AET_UEU		(UL(1) << 10)	/* Uncorrected Unrecoverable */
> +#define ESR_ELx_AET_UEO		(UL(2) << 10)	/* Uncorrected Restartable */
> +#define ESR_ELx_AET_UER		(UL(3) << 10)	/* Uncorrected Recoverable */
> +#define ESR_ELx_AET_CE		(UL(6) << 10)	/* Corrected */
> +
>  /* Shared ISS field definitions for Data/Instruction aborts */
>  #define ESR_ELx_SET_SHIFT	(11)
>  #define ESR_ELx_SET_MASK	(UL(3) << ESR_ELx_SET_SHIFT)
> @@ -99,6 +108,7 @@
>  #define ESR_ELx_FSC		(0x3F)
>  #define ESR_ELx_FSC_TYPE	(0x3C)
>  #define ESR_ELx_FSC_EXTABT	(0x10)
> +#define ESR_ELx_FSC_SERROR	(0x11)
>  #define ESR_ELx_FSC_ACCESS	(0x08)
>  #define ESR_ELx_FSC_FAULT	(0x04)
>  #define ESR_ELx_FSC_PERM	(0x0C)
> diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
> index d131501c6222..8d2a1fff5c6b 100644
> --- a/arch/arm64/include/asm/traps.h
> +++ b/arch/arm64/include/asm/traps.h
> @@ -19,6 +19,7 @@
>  #define __ASM_TRAP_H
>  
>  #include <linux/list.h>
> +#include <asm/esr.h>
>  #include <asm/sections.h>
>  
>  struct pt_regs;
> @@ -58,4 +59,39 @@ static inline int in_entry_text(unsigned long ptr)
>  	return ptr >= (unsigned long)&__entry_text_start &&
>  	       ptr < (unsigned long)&__entry_text_end;
>  }
> +
> +static inline bool arm64_is_ras_serror(u32 esr)
> +{
> +	bool impdef = esr & ESR_ELx_ISV; /* aka IDS */

I think you should add an IDS field along with the AET one I suggested.

> +
> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
> +		return !impdef;
> +
> +	return false;
> +}
> +
> +/* Return the AET bits of an SError ESR, or 0/uncontainable/uncategorized */
> +static inline u32 arm64_ras_serror_get_severity(u32 esr)
> +{
> +	u32 aet = esr & ESR_ELx_AET;
> +
> +	if (!arm64_is_ras_serror(esr)) {
> +		/* Not a RAS error, we can't interpret the ESR */
> +		return 0;
> +	}
> +
> +	/*
> +	 * AET is RES0 if 'the value returned in the DFSC field is not
> +	 * [ESR_ELx_FSC_SERROR]'
> +	 */
> +	if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
> +		/* No severity information */
> +		return 0;
> +	}

Hmm, this means we can't distinguish impdef or RES0 encodings from
uncontainable errors. Is that desirable?

Also, could we end up in a situation where some CPUs support RAS and some
don't, so arm64_is_ras_serror returns false yet a correctable error is
reported by one the CPUs and we treat it as uncontainable?

> +
> +	return aet;
> +}
> +
> +bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr);
> +void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
>  #endif
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index 773aae69c376..53aeb25158b0 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -709,17 +709,65 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
>  }
>  #endif
>  
> -asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
> +void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr)
>  {
> -	nmi_enter();
> -
>  	console_verbose();
>  
>  	pr_crit("SError Interrupt on CPU%d, code 0x%08x -- %s\n",
>  		smp_processor_id(), esr, esr_get_class_string(esr));
> -	__show_regs(regs);
> +	if (regs)
> +		__show_regs(regs);
> +
> +	/* KVM may call this this from a preemptible context */
> +	preempt_disable();
> +
> +	/*
> +	 * panic() unmasks interrupts, which unmasks SError. Use nmi_panic()
> +	 * to avoid re-entering panic.
> +	 */
> +	nmi_panic(regs, "Asynchronous SError Interrupt");
> +
> +	cpu_park_loop();
> +	unreachable();
> +}
> +
> +bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr)
> +{

Since you asked... what about "fatal" instead of "blocking"?

Will

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 13/21] arm64: cpufeature: Enable IESB on exception entry/return for firmware-first
  2017-10-19 14:57   ` James Morse
@ 2017-10-31 13:56     ` Will Deacon
  -1 siblings, 0 replies; 160+ messages in thread
From: Will Deacon @ 2017-10-31 13:56 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

On Thu, Oct 19, 2017 at 03:57:59PM +0100, James Morse wrote:
> ARM v8.2 has a feature to add implicit error synchronization barriers
> whenever the CPU enters or returns from an exception level. Add code to
> detect this feature and enable the SCTLR_ELx.IESB bit.
> 
> This feature causes RAS errors that are not yet visible to software to
> become pending SErrors. We expect to have firmware-first RAS support
> so synchronised RAS errors will be take immediately to EL3.
> Any system without firmware-first handling of errors will take the SError
> either immediatly after exception return, or when we unmask SError after
> entry.S's work.
> 
> Platform level RAS support may require additional firmware support.
> 
> Cc: Christoffer Dall <christoffer.dall@linaro.org>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

To be honest, I'd just set this bit unconditionally. I realise the
architecture would rather we didn't do that for v8 parts where it's RES0,
but we do this elsewhere (e.g. HD and HA in the TCR) and practically it's
fine.

Will

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 13/21] arm64: cpufeature: Enable IESB on exception entry/return for firmware-first
@ 2017-10-31 13:56     ` Will Deacon
  0 siblings, 0 replies; 160+ messages in thread
From: Will Deacon @ 2017-10-31 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 19, 2017 at 03:57:59PM +0100, James Morse wrote:
> ARM v8.2 has a feature to add implicit error synchronization barriers
> whenever the CPU enters or returns from an exception level. Add code to
> detect this feature and enable the SCTLR_ELx.IESB bit.
> 
> This feature causes RAS errors that are not yet visible to software to
> become pending SErrors. We expect to have firmware-first RAS support
> so synchronised RAS errors will be take immediately to EL3.
> Any system without firmware-first handling of errors will take the SError
> either immediatly after exception return, or when we unmask SError after
> entry.S's work.
> 
> Platform level RAS support may require additional firmware support.
> 
> Cc: Christoffer Dall <christoffer.dall@linaro.org>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

To be honest, I'd just set this bit unconditionally. I realise the
architecture would rather we didn't do that for v8 parts where it's RES0,
but we do this elsewhere (e.g. HD and HA in the TCR) and practically it's
fine.

Will

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
  2017-10-31 11:43       ` James Morse
@ 2017-11-01  4:55         ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-01  4:55 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Tue, Oct 31, 2017 at 11:43:42AM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 31/10/17 06:23, Christoffer Dall wrote:
> > On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
> >> On VHE systems KVM masks SError before switching the VBAR value. Any
> >> host RAS error that the CPU knew about before world-switch may become
> >> pending as an SError during world-switch, and only be taken once we enter
> >> the guest.
> >>
> >> Until KVM can take RAS SErrors during world switch, add an ESB to
> >> force any RAS errors to be synchronised and taken on the host before
> >> we enter world switch.
> >>
> >> RAS errors that become pending during world switch are still taken
> >> once we enter the guest.
> 
> >> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> >> index cf5d78ba14b5..5dc6f2877762 100644
> >> --- a/arch/arm64/include/asm/kvm_host.h
> >> +++ b/arch/arm64/include/asm/kvm_host.h
> >> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
> >>  
> >>  static inline void kvm_arm_vhe_guest_enter(void)
> >>  {
> >> +	esb();
> 
> > I don't fully appreciate what the point of this is?
> > 
> > As I understand it, our fundamental goal here is to try to distinguish
> > between errors happening on the host or in the guest.
> 
> Not just host/guest, but also those we can and can't handle.
> 
> KVM can't currently take an SError during world switch, so a RAS error that the
> CPU was hoping to defer may spread from the host into KVM's
> no-SError:world-switch code. If this happens it will (almost certainly) have to
> be re-classified as uncontainable.
> 
> There is also a firmware-first angle here: NOTIFY_SEI can't be delivered if the
> normal world has SError masked, so any error that spreads past this point
> becomes a reboot-by-firmware instead of an OS notification and almost-helpful
> error message.
> 
> 
> > If that's correct, then why don't we do it at the last possible moment
> > when we still have a scratch register left, in the world switch code
> > itself, and in the case abort the guest entry and report back a "host
> > SError" return code.
> 
> We have IESB to run the error-barrier as we enter the guest. This would make any
> host error pending as an SError, and we would exit the guest immediately. But if
> there was an RAS error during world switch, by this point its likely to be
> classified as uncontainable.
> 
> This esb() is trying to keep this window of code as small as possible, to just
> errors that occur during world switch.
> 
> With your vcpu load/save this window becomes a lot smaller, it may be possible
> to get a VHE-host's arch-code SError handler to take errors from EL2, in which
> case this barrier can disappear.
> (note to self: guest may still own the debug hardware)
> 

ok, thanks for your detailed explanation.  I didn't consider that the
classification of a RAS error as containable vs. non-containable
depended on where we take the exception.

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
@ 2017-11-01  4:55         ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-01  4:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 31, 2017 at 11:43:42AM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 31/10/17 06:23, Christoffer Dall wrote:
> > On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
> >> On VHE systems KVM masks SError before switching the VBAR value. Any
> >> host RAS error that the CPU knew about before world-switch may become
> >> pending as an SError during world-switch, and only be taken once we enter
> >> the guest.
> >>
> >> Until KVM can take RAS SErrors during world switch, add an ESB to
> >> force any RAS errors to be synchronised and taken on the host before
> >> we enter world switch.
> >>
> >> RAS errors that become pending during world switch are still taken
> >> once we enter the guest.
> 
> >> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> >> index cf5d78ba14b5..5dc6f2877762 100644
> >> --- a/arch/arm64/include/asm/kvm_host.h
> >> +++ b/arch/arm64/include/asm/kvm_host.h
> >> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
> >>  
> >>  static inline void kvm_arm_vhe_guest_enter(void)
> >>  {
> >> +	esb();
> 
> > I don't fully appreciate what the point of this is?
> > 
> > As I understand it, our fundamental goal here is to try to distinguish
> > between errors happening on the host or in the guest.
> 
> Not just host/guest, but also those we can and can't handle.
> 
> KVM can't currently take an SError during world switch, so a RAS error that the
> CPU was hoping to defer may spread from the host into KVM's
> no-SError:world-switch code. If this happens it will (almost certainly) have to
> be re-classified as uncontainable.
> 
> There is also a firmware-first angle here: NOTIFY_SEI can't be delivered if the
> normal world has SError masked, so any error that spreads past this point
> becomes a reboot-by-firmware instead of an OS notification and almost-helpful
> error message.
> 
> 
> > If that's correct, then why don't we do it at the last possible moment
> > when we still have a scratch register left, in the world switch code
> > itself, and in the case abort the guest entry and report back a "host
> > SError" return code.
> 
> We have IESB to run the error-barrier as we enter the guest. This would make any
> host error pending as an SError, and we would exit the guest immediately. But if
> there was an RAS error during world switch, by this point its likely to be
> classified as uncontainable.
> 
> This esb() is trying to keep this window of code as small as possible, to just
> errors that occur during world switch.
> 
> With your vcpu load/save this window becomes a lot smaller, it may be possible
> to get a VHE-host's arch-code SError handler to take errors from EL2, in which
> case this barrier can disappear.
> (note to self: guest may still own the debug hardware)
> 

ok, thanks for your detailed explanation.  I didn't consider that the
classification of a RAS error as containable vs. non-containable
depended on where we take the exception.

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-10-31 10:08     ` Will Deacon
@ 2017-11-01 15:23       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-01 15:23 UTC (permalink / raw)
  To: Will Deacon, Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

Hi guys,

On 31/10/17 10:08, Will Deacon wrote:
> On Tue, Oct 31, 2017 at 07:35:35AM +0100, Christoffer Dall wrote:
>> On Thu, Oct 19, 2017 at 03:57:46PM +0100, James Morse wrote:
>>> The aim of this series is to enable IESB and add ESB-instructions to let us
>>> kick any pending RAS errors into firmware to be handled by firmware-first.
>>>
>>> Not all systems will have this firmware, so these RAS errors will become
>>> pending SErrors. We should take these as quickly as possible and avoid
>>> panic()ing for errors where we could have continued.
>>>
>>> This first part of this series reworks the DAIF masking so that SError is
>>> unmasked unless we are handling a debug exception.
>>>
>>> The last part provides the same minimal handling for SError that interrupt
>>> KVM. KVM is currently unable to handle SErrors during world-switch, unless
>>> they occur during a magic single-instruction window, it hyp-panics. I suspect
>>> this will be easier to fix once the VHE world-switch is further optimised.
>>>
>>> KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
>>> and all-zeros has a RAS meaning.
>>>
>>> KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
>>> These are errors where we don't know what they mean, they may not be
>>> synchronised by ESB. Today we blame the guest.
>>> My half-baked suggestion would be to make a virtual SError pending, but then
>>> exit to user-space to give Qemu the change to quit (for virtual machines that
>>> don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
>>> continue and take KVMs default all-zeros impdef ESR.
>>
>> The KVM side of this series is looking pretty good.
>>
>> What are the merge plans for this?  I am fine if you will take this via
>> the arm64 tree with our acks from the KVM side.  Alternatively, I
>> suppose you can apply all the arm64 patches and provide us with a stable
>> branch for that?
> 
> I'll take a look this afternoon, but we haven't had a linux next release
> since the 18th so I'm starting to get nervous about conflicts if I end up
> pulling in new trees now.

Will's 'what about mixed RAS support' comment will take me a while to get to
fix, and I don't think I can test that before the end of the week.

Unless there is an rc8+linux-next I think this is too late, but I will split off
and repost the SError_rework bits as that seems uncontentious...


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-01 15:23       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-01 15:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi guys,

On 31/10/17 10:08, Will Deacon wrote:
> On Tue, Oct 31, 2017 at 07:35:35AM +0100, Christoffer Dall wrote:
>> On Thu, Oct 19, 2017 at 03:57:46PM +0100, James Morse wrote:
>>> The aim of this series is to enable IESB and add ESB-instructions to let us
>>> kick any pending RAS errors into firmware to be handled by firmware-first.
>>>
>>> Not all systems will have this firmware, so these RAS errors will become
>>> pending SErrors. We should take these as quickly as possible and avoid
>>> panic()ing for errors where we could have continued.
>>>
>>> This first part of this series reworks the DAIF masking so that SError is
>>> unmasked unless we are handling a debug exception.
>>>
>>> The last part provides the same minimal handling for SError that interrupt
>>> KVM. KVM is currently unable to handle SErrors during world-switch, unless
>>> they occur during a magic single-instruction window, it hyp-panics. I suspect
>>> this will be easier to fix once the VHE world-switch is further optimised.
>>>
>>> KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
>>> and all-zeros has a RAS meaning.
>>>
>>> KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
>>> These are errors where we don't know what they mean, they may not be
>>> synchronised by ESB. Today we blame the guest.
>>> My half-baked suggestion would be to make a virtual SError pending, but then
>>> exit to user-space to give Qemu the change to quit (for virtual machines that
>>> don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
>>> continue and take KVMs default all-zeros impdef ESR.
>>
>> The KVM side of this series is looking pretty good.
>>
>> What are the merge plans for this?  I am fine if you will take this via
>> the arm64 tree with our acks from the KVM side.  Alternatively, I
>> suppose you can apply all the arm64 patches and provide us with a stable
>> branch for that?
> 
> I'll take a look this afternoon, but we haven't had a linux next release
> since the 18th so I'm starting to get nervous about conflicts if I end up
> pulling in new trees now.

Will's 'what about mixed RAS support' comment will take me a while to get to
fix, and I don't think I can test that before the end of the week.

Unless there is an rc8+linux-next I think this is too late, but I will split off
and repost the SError_rework bits as that seems uncontentious...


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError
  2017-10-31  5:47       ` Marc Zyngier
@ 2017-11-01 17:42         ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-01 17:42 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Jonathan.Zhang, Catalin Marinas, Julien Thierry, Will Deacon,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

Hi Marc,

On 31/10/17 05:47, Marc Zyngier wrote:
> On Tue, Oct 31 2017 at  4:26:01 am GMT, Marc Zyngier <marc.zyngier@arm.com> wrote:
>> On Thu, Oct 19 2017 at  4:58:03 pm BST, James Morse <james.morse@arm.com> wrote:
>>> When we exit a guest due to an SError the vcpu fault info isn't updated
>>> with the ESR. Today this is only done for traps.
>>>
>>> The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
>>> fault_info with the ESR on SError so that handle_exit() can determine
>>> if this was a RAS SError and decode its severity.

>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>> index af37658223a0..cba6d8ac105c 100644
>>> --- a/arch/arm64/kvm/hyp/switch.c
>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>> @@ -230,13 +230,20 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
>>>  	return true;
>>>  }
>>>  
>>> +static void __hyp_text __populate_fault_info_esr(struct kvm_vcpu *vcpu)
>>> +{
>>> +	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
>>> +}
>>> +
>>>  static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
>>>  {
>>> -	u64 esr = read_sysreg_el2(esr);
>>> -	u8 ec = ESR_ELx_EC(esr);
>>> +	u8 ec;
>>> +	u64 esr;
>>>  	u64 hpfar, far;
>>>  
>>> -	vcpu->arch.fault.esr_el2 = esr;
>>> +	__populate_fault_info_esr(vcpu);
>>> +	esr = vcpu->arch.fault.esr_el2;
>>> +	ec = ESR_ELx_EC(esr);
>>>  
>>>  	if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
>>>  		return true;
>>> @@ -325,6 +332,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>>>  	 */
>>>  	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
>>>  		goto again;
>>> +	else if (ARM_EXCEPTION_CODE(exit_code) == ARM_EXCEPTION_EL1_SERROR)
>>> +		__populate_fault_info_esr(vcpu);
>>>  
>>>  	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
>>>  	    exit_code == ARM_EXCEPTION_TRAP) {
>>
>> With this patch, the only case were we don't save ESR_EL2 is when we
>> take an interrupt. I think we should bite the bullet and make it
>> slightly more streamlined, always saving ESR_EL2.

We always read it __guest_exit, just in case we take an SError and have to put
it back.


> Otherwise, an alternative would be to write something like:
> 
> 	if (ARM_EXCEPTION_CODE(exit_code) != ARM_EXCEPTION_IRQ)
>         	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
> 
> which still avoids saving it, and is a lot more readable.

I'll switch to this in the next version.


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError
@ 2017-11-01 17:42         ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-01 17:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

On 31/10/17 05:47, Marc Zyngier wrote:
> On Tue, Oct 31 2017 at  4:26:01 am GMT, Marc Zyngier <marc.zyngier@arm.com> wrote:
>> On Thu, Oct 19 2017 at  4:58:03 pm BST, James Morse <james.morse@arm.com> wrote:
>>> When we exit a guest due to an SError the vcpu fault info isn't updated
>>> with the ESR. Today this is only done for traps.
>>>
>>> The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
>>> fault_info with the ESR on SError so that handle_exit() can determine
>>> if this was a RAS SError and decode its severity.

>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>> index af37658223a0..cba6d8ac105c 100644
>>> --- a/arch/arm64/kvm/hyp/switch.c
>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>> @@ -230,13 +230,20 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
>>>  	return true;
>>>  }
>>>  
>>> +static void __hyp_text __populate_fault_info_esr(struct kvm_vcpu *vcpu)
>>> +{
>>> +	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
>>> +}
>>> +
>>>  static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
>>>  {
>>> -	u64 esr = read_sysreg_el2(esr);
>>> -	u8 ec = ESR_ELx_EC(esr);
>>> +	u8 ec;
>>> +	u64 esr;
>>>  	u64 hpfar, far;
>>>  
>>> -	vcpu->arch.fault.esr_el2 = esr;
>>> +	__populate_fault_info_esr(vcpu);
>>> +	esr = vcpu->arch.fault.esr_el2;
>>> +	ec = ESR_ELx_EC(esr);
>>>  
>>>  	if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
>>>  		return true;
>>> @@ -325,6 +332,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>>>  	 */
>>>  	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
>>>  		goto again;
>>> +	else if (ARM_EXCEPTION_CODE(exit_code) == ARM_EXCEPTION_EL1_SERROR)
>>> +		__populate_fault_info_esr(vcpu);
>>>  
>>>  	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
>>>  	    exit_code == ARM_EXCEPTION_TRAP) {
>>
>> With this patch, the only case were we don't save ESR_EL2 is when we
>> take an interrupt. I think we should bite the bullet and make it
>> slightly more streamlined, always saving ESR_EL2.

We always read it __guest_exit, just in case we take an SError and have to put
it back.


> Otherwise, an alternative would be to write something like:
> 
> 	if (ARM_EXCEPTION_CODE(exit_code) != ARM_EXCEPTION_IRQ)
>         	vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
> 
> which still avoids saving it, and is a lot more readable.

I'll switch to this in the next version.


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-01 15:23       ` James Morse
@ 2017-11-02  8:14         ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-02  8:14 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Wed, Nov 01, 2017 at 03:23:50PM +0000, James Morse wrote:
> Hi guys,
> 
> On 31/10/17 10:08, Will Deacon wrote:
> > On Tue, Oct 31, 2017 at 07:35:35AM +0100, Christoffer Dall wrote:
> >> On Thu, Oct 19, 2017 at 03:57:46PM +0100, James Morse wrote:
> >>> The aim of this series is to enable IESB and add ESB-instructions to let us
> >>> kick any pending RAS errors into firmware to be handled by firmware-first.
> >>>
> >>> Not all systems will have this firmware, so these RAS errors will become
> >>> pending SErrors. We should take these as quickly as possible and avoid
> >>> panic()ing for errors where we could have continued.
> >>>
> >>> This first part of this series reworks the DAIF masking so that SError is
> >>> unmasked unless we are handling a debug exception.
> >>>
> >>> The last part provides the same minimal handling for SError that interrupt
> >>> KVM. KVM is currently unable to handle SErrors during world-switch, unless
> >>> they occur during a magic single-instruction window, it hyp-panics. I suspect
> >>> this will be easier to fix once the VHE world-switch is further optimised.
> >>>
> >>> KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
> >>> and all-zeros has a RAS meaning.
> >>>
> >>> KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
> >>> These are errors where we don't know what they mean, they may not be
> >>> synchronised by ESB. Today we blame the guest.
> >>> My half-baked suggestion would be to make a virtual SError pending, but then
> >>> exit to user-space to give Qemu the change to quit (for virtual machines that
> >>> don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
> >>> continue and take KVMs default all-zeros impdef ESR.
> >>
> >> The KVM side of this series is looking pretty good.
> >>
> >> What are the merge plans for this?  I am fine if you will take this via
> >> the arm64 tree with our acks from the KVM side.  Alternatively, I
> >> suppose you can apply all the arm64 patches and provide us with a stable
> >> branch for that?
> > 
> > I'll take a look this afternoon, but we haven't had a linux next release
> > since the 18th so I'm starting to get nervous about conflicts if I end up
> > pulling in new trees now.
> 
> Will's 'what about mixed RAS support' comment will take me a while to get to
> fix, and I don't think I can test that before the end of the week.
> 
> Unless there is an rc8+linux-next I think this is too late, but I will split off
> and repost the SError_rework bits as that seems uncontentious...
> 
> 

It is indeed cutting it a bit close.  We'll have the same challenge of
either going via arm64 or using a stable branch we merge into the KVM
side for the next merge window as well.  I prefer the latter, since
there's going to be some conflicts with my optimization series which I
hope to get in for v4.16.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-02  8:14         ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-02  8:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 01, 2017 at 03:23:50PM +0000, James Morse wrote:
> Hi guys,
> 
> On 31/10/17 10:08, Will Deacon wrote:
> > On Tue, Oct 31, 2017 at 07:35:35AM +0100, Christoffer Dall wrote:
> >> On Thu, Oct 19, 2017 at 03:57:46PM +0100, James Morse wrote:
> >>> The aim of this series is to enable IESB and add ESB-instructions to let us
> >>> kick any pending RAS errors into firmware to be handled by firmware-first.
> >>>
> >>> Not all systems will have this firmware, so these RAS errors will become
> >>> pending SErrors. We should take these as quickly as possible and avoid
> >>> panic()ing for errors where we could have continued.
> >>>
> >>> This first part of this series reworks the DAIF masking so that SError is
> >>> unmasked unless we are handling a debug exception.
> >>>
> >>> The last part provides the same minimal handling for SError that interrupt
> >>> KVM. KVM is currently unable to handle SErrors during world-switch, unless
> >>> they occur during a magic single-instruction window, it hyp-panics. I suspect
> >>> this will be easier to fix once the VHE world-switch is further optimised.
> >>>
> >>> KVMs kvm_inject_vabt() needs updating for v8.2 as now we can specify an ESR,
> >>> and all-zeros has a RAS meaning.
> >>>
> >>> KVM's existing 'impdef SError to the guest' behaviour probably needs revisiting.
> >>> These are errors where we don't know what they mean, they may not be
> >>> synchronised by ESB. Today we blame the guest.
> >>> My half-baked suggestion would be to make a virtual SError pending, but then
> >>> exit to user-space to give Qemu the change to quit (for virtual machines that
> >>> don't generate SError), pend an SError with a new Qemu-specific ESR, or blindly
> >>> continue and take KVMs default all-zeros impdef ESR.
> >>
> >> The KVM side of this series is looking pretty good.
> >>
> >> What are the merge plans for this?  I am fine if you will take this via
> >> the arm64 tree with our acks from the KVM side.  Alternatively, I
> >> suppose you can apply all the arm64 patches and provide us with a stable
> >> branch for that?
> > 
> > I'll take a look this afternoon, but we haven't had a linux next release
> > since the 18th so I'm starting to get nervous about conflicts if I end up
> > pulling in new trees now.
> 
> Will's 'what about mixed RAS support' comment will take me a while to get to
> fix, and I don't think I can test that before the end of the week.
> 
> Unless there is an rc8+linux-next I think this is too late, but I will split off
> and repost the SError_rework bits as that seems uncontentious...
> 
> 

It is indeed cutting it a bit close.  We'll have the same challenge of
either going via arm64 or using a stable branch we merge into the KVM
side for the next merge window as well.  I prefer the latter, since
there's going to be some conflicts with my optimization series which I
hope to get in for v4.16.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
  2017-10-30  7:40     ` Christoffer Dall
@ 2017-11-02 12:14       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-02 12:14 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi Christoffer,

On 30/10/17 07:40, Christoffer Dall wrote:
> On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
>> Non-VHE systems take an exception to EL2 in order to world-switch into the
>> guest. When returning from the guest KVM implicitly restores the DAIF
>> flags when it returns to the kernel at EL1.
>>
>> With VHE none of this exception-level jumping happens, so KVMs
>> world-switch code is exposed to the host kernel's DAIF values, and KVM
>> spills the guest-exit DAIF values back into the host kernel.
>> On entry to a guest we have Debug and SError exceptions unmasked, KVM
>> has switched VBAR but isn't prepared to handle these. On guest exit
>> Debug exceptions are left disabled once we return to the host and will
>> stay this way until we enter user space.
>>
>> Add a helper to mask/unmask DAIF around VHE guests. The unmask can only
>> happen after the hosts VBAR value has been synchronised by the isb in
>> __vhe_hyp_call (via kvm_call_hyp()). Masking could be as late as
>> setting KVMs VBAR value, but is kept here for symmetry.

> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

Thanks!


>> ---
>> Give me a kick if you want this reworked as a fix (which will then
>> conflict with this series), or a backportable version.
> 
> I don't know of any real-world issues where some more graceful handling
> of SErrors would make sense on older kernels, so I'm fine with just
> merging this together with this series.

What about debug?
> On guest exit Debug exceptions are left disabled once we return to the host
> and will stay this way until we enter user space.

Today VHE:KVM causes the kernel to run with SError unmasked and debug disabled
until the next return to user-space, whereas previously the kernel expected
SError to be masked and debug enabled.


(Reposting just the SError rework without this patch changes the kernel to
expect SError to be unmasked, which isn't making this any worse.)


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
@ 2017-11-02 12:14       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-02 12:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 30/10/17 07:40, Christoffer Dall wrote:
> On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
>> Non-VHE systems take an exception to EL2 in order to world-switch into the
>> guest. When returning from the guest KVM implicitly restores the DAIF
>> flags when it returns to the kernel at EL1.
>>
>> With VHE none of this exception-level jumping happens, so KVMs
>> world-switch code is exposed to the host kernel's DAIF values, and KVM
>> spills the guest-exit DAIF values back into the host kernel.
>> On entry to a guest we have Debug and SError exceptions unmasked, KVM
>> has switched VBAR but isn't prepared to handle these. On guest exit
>> Debug exceptions are left disabled once we return to the host and will
>> stay this way until we enter user space.
>>
>> Add a helper to mask/unmask DAIF around VHE guests. The unmask can only
>> happen after the hosts VBAR value has been synchronised by the isb in
>> __vhe_hyp_call (via kvm_call_hyp()). Masking could be as late as
>> setting KVMs VBAR value, but is kept here for symmetry.

> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

Thanks!


>> ---
>> Give me a kick if you want this reworked as a fix (which will then
>> conflict with this series), or a backportable version.
> 
> I don't know of any real-world issues where some more graceful handling
> of SErrors would make sense on older kernels, so I'm fine with just
> merging this together with this series.

What about debug?
> On guest exit Debug exceptions are left disabled once we return to the host
> and will stay this way until we enter user space.

Today VHE:KVM causes the kernel to run with SError unmasked and debug disabled
until the next return to user-space, whereas previously the kernel expected
SError to be masked and debug enabled.


(Reposting just the SError rework without this patch changes the kernel to
expect SError to be unmasked, which isn't making this any worse.)


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 12/21] arm64: kernel: Survive corrected RAS errors notified by SError
  2017-10-31 13:50     ` Will Deacon
@ 2017-11-02 12:15       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-02 12:15 UTC (permalink / raw)
  To: Will Deacon
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

Hi Will,

On 31/10/17 13:50, Will Deacon wrote:
> On Thu, Oct 19, 2017 at 03:57:58PM +0100, James Morse wrote:
>> Prior to v8.2, SError is an uncontainable fatal exception. The v8.2 RAS
>> extensions use SError to notify software about RAS errors, these can be
>> contained by the ESB instruction.
>>
>> An ACPI system with firmware-first may use SError as its 'SEI'
>> notification. Future patches may add code to 'claim' this SError as a
>> notification.
>>
>> Other systems can distinguish these RAS errors from the SError ESR and
>> use the AET bits and additional data from RAS-Error registers to handle
>> the error. Future patches may add this kernel-first handling.
>>
>> Without support for either of these we will panic(), even if we received
>> a corrected error. Add code to decode the severity of RAS errors. We can
>> safely ignore contained errors where the CPU can continue to make
>> progress. For all other errors we continue to panic().

>> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
>> index 66ed8b6b9976..8ea52f15bf1c 100644
>> --- a/arch/arm64/include/asm/esr.h
>> +++ b/arch/arm64/include/asm/esr.h
>> @@ -85,6 +85,15 @@
>>  #define ESR_ELx_WNR_SHIFT	(6)
>>  #define ESR_ELx_WNR		(UL(1) << ESR_ELx_WNR_SHIFT)
>>  
>> +/* Asynchronous Error Type */
>> +#define ESR_ELx_AET		(UL(0x7) << 10)

> Can you add a #define for the AET shift in the Srror ISS, please? (we have
> other blocks in this file for different abort types). e.g.
> 
> /* ISS fields definitions for SError interrupts */
> #define ESR_ELx_AER_SHIFT	10
> 
> then use it below.

Yes,  I should have done that..


>> +#define ESR_ELx_AET_UC		(UL(0) << 10)	/* Uncontainable */
>> +#define ESR_ELx_AET_UEU		(UL(1) << 10)	/* Uncorrected Unrecoverable */
>> +#define ESR_ELx_AET_UEO		(UL(2) << 10)	/* Uncorrected Restartable */
>> +#define ESR_ELx_AET_UER		(UL(3) << 10)	/* Uncorrected Recoverable */
>> +#define ESR_ELx_AET_CE		(UL(6) << 10)	/* Corrected */
>> +
>>  /* Shared ISS field definitions for Data/Instruction aborts */
>>  #define ESR_ELx_SET_SHIFT	(11)
>>  #define ESR_ELx_SET_MASK	(UL(3) << ESR_ELx_SET_SHIFT)
>> @@ -99,6 +108,7 @@
>>  #define ESR_ELx_FSC		(0x3F)
>>  #define ESR_ELx_FSC_TYPE	(0x3C)
>>  #define ESR_ELx_FSC_EXTABT	(0x10)
>> +#define ESR_ELx_FSC_SERROR	(0x11)
>>  #define ESR_ELx_FSC_ACCESS	(0x08)
>>  #define ESR_ELx_FSC_FAULT	(0x04)

>>  #define ESR_ELx_FSC_PERM	(0x0C)
>> diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
>> index d131501c6222..8d2a1fff5c6b 100644
>> --- a/arch/arm64/include/asm/traps.h
>> +++ b/arch/arm64/include/asm/traps.h
>> @@ -19,6 +19,7 @@
>>  #define __ASM_TRAP_H
>>  
>>  #include <linux/list.h>
>> +#include <asm/esr.h>
>>  #include <asm/sections.h>
>>  
>>  struct pt_regs;
>> @@ -58,4 +59,39 @@ static inline int in_entry_text(unsigned long ptr)
>>  	return ptr >= (unsigned long)&__entry_text_start &&
>>  	       ptr < (unsigned long)&__entry_text_end;
>>  }
>> +
>> +static inline bool arm64_is_ras_serror(u32 esr)
>> +{
>> +	bool impdef = esr & ESR_ELx_ISV; /* aka IDS */
> 
> I think you should add an IDS field along with the AET one I suggested.

Sure,

>> +
>> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
>> +		return !impdef;
>> +
>> +	return false;
>> +}
>> +
>> +/* Return the AET bits of an SError ESR, or 0/uncontainable/uncategorized */
>> +static inline u32 arm64_ras_serror_get_severity(u32 esr)
>> +{
>> +	u32 aet = esr & ESR_ELx_AET;
>> +
>> +	if (!arm64_is_ras_serror(esr)) {
>> +		/* Not a RAS error, we can't interpret the ESR */
>> +		return 0;
>> +	}
>> +
>> +	/*
>> +	 * AET is RES0 if 'the value returned in the DFSC field is not
>> +	 * [ESR_ELx_FSC_SERROR]'
>> +	 */
>> +	if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
>> +		/* No severity information */
>> +		return 0;
>> +	}

> Hmm, this means we can't distinguish impdef or RES0 encodings from
> uncontainable errors. Is that desirable?

We panic for for both impdef and uncontainable ESR values, so the difference
doesn't matter. I'll remove the 'is_ras_serror()' in here and make it the
callers problem to check...


RES0 encodings?
If this is an imp-def 'all zeros', those should all be matched as impdef by
arm64_is_ras_serror().
Otherwise its a RAS encoding with {I,D}FSC bits that indicate we can't know the
severity.
The ARM-ARM calls these 'uncategorized'. Yes I'm treating them as uncontained,
(on aarch32 these share an encoding). I'll add a comment to call it out.


> Also, could we end up in a situation where some CPUs support RAS and some
> don't, 

Ooer, differing CPU support. I hadn't considered that... wouldn't cpufeature
declare such a system insane?


> so arm64_is_ras_serror returns false yet a correctable error is
> reported by one the CPUs and we treat it as uncontainable?

Makeing the HAS_RAS tests use this_cpu_has_cap() should cover this, but will
cause problems for KVM as it calls these from a pre-emptible context.


>> +
>> +	return aet;
>> +}
>> +
>> +bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr);
>> +void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
>>  #endif
>> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
>> index 773aae69c376..53aeb25158b0 100644
>> --- a/arch/arm64/kernel/traps.c
>> +++ b/arch/arm64/kernel/traps.c
>> @@ -709,17 +709,65 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)

>> +bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr)
>> +{

> Since you asked... what about "fatal" instead of "blocking"?

.. well that was obvious. Yes, I was looking too much at whether we could return
to the interrupted context instead of what we do next!


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 12/21] arm64: kernel: Survive corrected RAS errors notified by SError
@ 2017-11-02 12:15       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-02 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 31/10/17 13:50, Will Deacon wrote:
> On Thu, Oct 19, 2017 at 03:57:58PM +0100, James Morse wrote:
>> Prior to v8.2, SError is an uncontainable fatal exception. The v8.2 RAS
>> extensions use SError to notify software about RAS errors, these can be
>> contained by the ESB instruction.
>>
>> An ACPI system with firmware-first may use SError as its 'SEI'
>> notification. Future patches may add code to 'claim' this SError as a
>> notification.
>>
>> Other systems can distinguish these RAS errors from the SError ESR and
>> use the AET bits and additional data from RAS-Error registers to handle
>> the error. Future patches may add this kernel-first handling.
>>
>> Without support for either of these we will panic(), even if we received
>> a corrected error. Add code to decode the severity of RAS errors. We can
>> safely ignore contained errors where the CPU can continue to make
>> progress. For all other errors we continue to panic().

>> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
>> index 66ed8b6b9976..8ea52f15bf1c 100644
>> --- a/arch/arm64/include/asm/esr.h
>> +++ b/arch/arm64/include/asm/esr.h
>> @@ -85,6 +85,15 @@
>>  #define ESR_ELx_WNR_SHIFT	(6)
>>  #define ESR_ELx_WNR		(UL(1) << ESR_ELx_WNR_SHIFT)
>>  
>> +/* Asynchronous Error Type */
>> +#define ESR_ELx_AET		(UL(0x7) << 10)

> Can you add a #define for the AET shift in the Srror ISS, please? (we have
> other blocks in this file for different abort types). e.g.
> 
> /* ISS fields definitions for SError interrupts */
> #define ESR_ELx_AER_SHIFT	10
> 
> then use it below.

Yes,  I should have done that..


>> +#define ESR_ELx_AET_UC		(UL(0) << 10)	/* Uncontainable */
>> +#define ESR_ELx_AET_UEU		(UL(1) << 10)	/* Uncorrected Unrecoverable */
>> +#define ESR_ELx_AET_UEO		(UL(2) << 10)	/* Uncorrected Restartable */
>> +#define ESR_ELx_AET_UER		(UL(3) << 10)	/* Uncorrected Recoverable */
>> +#define ESR_ELx_AET_CE		(UL(6) << 10)	/* Corrected */
>> +
>>  /* Shared ISS field definitions for Data/Instruction aborts */
>>  #define ESR_ELx_SET_SHIFT	(11)
>>  #define ESR_ELx_SET_MASK	(UL(3) << ESR_ELx_SET_SHIFT)
>> @@ -99,6 +108,7 @@
>>  #define ESR_ELx_FSC		(0x3F)
>>  #define ESR_ELx_FSC_TYPE	(0x3C)
>>  #define ESR_ELx_FSC_EXTABT	(0x10)
>> +#define ESR_ELx_FSC_SERROR	(0x11)
>>  #define ESR_ELx_FSC_ACCESS	(0x08)
>>  #define ESR_ELx_FSC_FAULT	(0x04)

>>  #define ESR_ELx_FSC_PERM	(0x0C)
>> diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
>> index d131501c6222..8d2a1fff5c6b 100644
>> --- a/arch/arm64/include/asm/traps.h
>> +++ b/arch/arm64/include/asm/traps.h
>> @@ -19,6 +19,7 @@
>>  #define __ASM_TRAP_H
>>  
>>  #include <linux/list.h>
>> +#include <asm/esr.h>
>>  #include <asm/sections.h>
>>  
>>  struct pt_regs;
>> @@ -58,4 +59,39 @@ static inline int in_entry_text(unsigned long ptr)
>>  	return ptr >= (unsigned long)&__entry_text_start &&
>>  	       ptr < (unsigned long)&__entry_text_end;
>>  }
>> +
>> +static inline bool arm64_is_ras_serror(u32 esr)
>> +{
>> +	bool impdef = esr & ESR_ELx_ISV; /* aka IDS */
> 
> I think you should add an IDS field along with the AET one I suggested.

Sure,

>> +
>> +	if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
>> +		return !impdef;
>> +
>> +	return false;
>> +}
>> +
>> +/* Return the AET bits of an SError ESR, or 0/uncontainable/uncategorized */
>> +static inline u32 arm64_ras_serror_get_severity(u32 esr)
>> +{
>> +	u32 aet = esr & ESR_ELx_AET;
>> +
>> +	if (!arm64_is_ras_serror(esr)) {
>> +		/* Not a RAS error, we can't interpret the ESR */
>> +		return 0;
>> +	}
>> +
>> +	/*
>> +	 * AET is RES0 if 'the value returned in the DFSC field is not
>> +	 * [ESR_ELx_FSC_SERROR]'
>> +	 */
>> +	if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
>> +		/* No severity information */
>> +		return 0;
>> +	}

> Hmm, this means we can't distinguish impdef or RES0 encodings from
> uncontainable errors. Is that desirable?

We panic for for both impdef and uncontainable ESR values, so the difference
doesn't matter. I'll remove the 'is_ras_serror()' in here and make it the
callers problem to check...


RES0 encodings?
If this is an imp-def 'all zeros', those should all be matched as impdef by
arm64_is_ras_serror().
Otherwise its a RAS encoding with {I,D}FSC bits that indicate we can't know the
severity.
The ARM-ARM calls these 'uncategorized'. Yes I'm treating them as uncontained,
(on aarch32 these share an encoding). I'll add a comment to call it out.


> Also, could we end up in a situation where some CPUs support RAS and some
> don't, 

Ooer, differing CPU support. I hadn't considered that... wouldn't cpufeature
declare such a system insane?


> so arm64_is_ras_serror returns false yet a correctable error is
> reported by one the CPUs and we treat it as uncontainable?

Makeing the HAS_RAS tests use this_cpu_has_cap() should cover this, but will
cause problems for KVM as it calls these from a pre-emptible context.


>> +
>> +	return aet;
>> +}
>> +
>> +bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr);
>> +void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr);
>>  #endif
>> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
>> index 773aae69c376..53aeb25158b0 100644
>> --- a/arch/arm64/kernel/traps.c
>> +++ b/arch/arm64/kernel/traps.c
>> @@ -709,17 +709,65 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)

>> +bool arm64_blocking_ras_serror(struct pt_regs *regs, unsigned int esr)
>> +{

> Since you asked... what about "fatal" instead of "blocking"?

.. well that was obvious. Yes, I was looking too much at whether we could return
to the interrupted context instead of what we do next!


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 11/21] arm64: cpufeature: Detect CPU RAS Extentions
  2017-10-31 13:14     ` Will Deacon
@ 2017-11-02 12:15       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-02 12:15 UTC (permalink / raw)
  To: Will Deacon
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	wangxiongfeng2, linux-arm-kernel, Dongjiu Geng, kvmarm

Hi Will,

On 31/10/17 13:14, Will Deacon wrote:
> On Thu, Oct 19, 2017 at 03:57:57PM +0100, James Morse wrote:
>> From: Xie XiuQi <xiexiuqi@huawei.com>
>>
>> ARM's v8.2 Extentions add support for Reliability, Availability and
>> Serviceability (RAS). On CPUs with these extensions system software
>> can use additional barriers to isolate errors and determine if faults
>> are pending.
>>
>> Add cpufeature detection and a barrier in the context-switch code.
>> There is no need to use alternatives for this as CPUs that don't
>> support this feature will treat the instruction as a nop.
>>
>> Platform level RAS support may require additional firmware support.

>> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
>> index cd52d365d1f0..0fc017b55cb1 100644
>> --- a/arch/arm64/kernel/cpufeature.c
>> +++ b/arch/arm64/kernel/cpufeature.c
>> @@ -125,6 +125,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
>>  };
>>  
>>  static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64PFR0_RAS_SHIFT, 4, 0),

> We probably want FTR_LOWER_SAFE here now, right? (we changed the other
> fields in for-next/core).

Ah, yes.
(Looks like some copy-and-paste)


>> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
>> index 2dc0f8482210..5e5d2f0a1d0a 100644
>> --- a/arch/arm64/kernel/process.c
>> +++ b/arch/arm64/kernel/process.c
>> @@ -365,6 +365,9 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
>>  	 */
>>  	dsb(ish);
>>  
>> +	/* Deliver any pending SError from prev */
>> +	esb();

> I'm assuming this is going to be expensive.

I'm hoping not, but without numbers to prove otherwise...


> What if we moved it to switch_mm
> instead. Do we actually need thread granularity for error isolation?

(after a verbal discussion with Will:)

This would be needed to blame the correct thread, but until we have kernel-first
handling this is moot as do_serror() will panic() regardless.

So, lets drop the esb() here and decide what to do if/when we get kernel-first
handling. If that only acts on groups of threads, then switch_mm is a better
place for it.

In the meantime if we see RAS SError panic()s we should remember it may have
just switched task, which in practice will probably be obvious from the stack trace.

There is no firmware-first angle here as SError is unmasked either side of this,
unlike in the KVM example.

I'll apply the same logic to the KVM version in patch 20...



Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 11/21] arm64: cpufeature: Detect CPU RAS Extentions
@ 2017-11-02 12:15       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-02 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 31/10/17 13:14, Will Deacon wrote:
> On Thu, Oct 19, 2017 at 03:57:57PM +0100, James Morse wrote:
>> From: Xie XiuQi <xiexiuqi@huawei.com>
>>
>> ARM's v8.2 Extentions add support for Reliability, Availability and
>> Serviceability (RAS). On CPUs with these extensions system software
>> can use additional barriers to isolate errors and determine if faults
>> are pending.
>>
>> Add cpufeature detection and a barrier in the context-switch code.
>> There is no need to use alternatives for this as CPUs that don't
>> support this feature will treat the instruction as a nop.
>>
>> Platform level RAS support may require additional firmware support.

>> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
>> index cd52d365d1f0..0fc017b55cb1 100644
>> --- a/arch/arm64/kernel/cpufeature.c
>> +++ b/arch/arm64/kernel/cpufeature.c
>> @@ -125,6 +125,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
>>  };
>>  
>>  static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
>> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64PFR0_RAS_SHIFT, 4, 0),

> We probably want FTR_LOWER_SAFE here now, right? (we changed the other
> fields in for-next/core).

Ah, yes.
(Looks like some copy-and-paste)


>> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
>> index 2dc0f8482210..5e5d2f0a1d0a 100644
>> --- a/arch/arm64/kernel/process.c
>> +++ b/arch/arm64/kernel/process.c
>> @@ -365,6 +365,9 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
>>  	 */
>>  	dsb(ish);
>>  
>> +	/* Deliver any pending SError from prev */
>> +	esb();

> I'm assuming this is going to be expensive.

I'm hoping not, but without numbers to prove otherwise...


> What if we moved it to switch_mm
> instead. Do we actually need thread granularity for error isolation?

(after a verbal discussion with Will:)

This would be needed to blame the correct thread, but until we have kernel-first
handling this is moot as do_serror() will panic() regardless.

So, lets drop the esb() here and decide what to do if/when we get kernel-first
handling. If that only acts on groups of threads, then switch_mm is a better
place for it.

In the meantime if we see RAS SError panic()s we should remember it may have
just switched task, which in practice will probably be obvious from the stack trace.

There is no firmware-first angle here as SError is unmasked either side of this,
unlike in the KVM example.

I'll apply the same logic to the KVM version in patch 20...



Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
  2017-11-01  4:55         ` Christoffer Dall
@ 2017-11-02 12:18           ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-02 12:18 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi Christoffer,

On 01/11/17 04:55, Christoffer Dall wrote:
> On Tue, Oct 31, 2017 at 11:43:42AM +0000, James Morse wrote:
>> On 31/10/17 06:23, Christoffer Dall wrote:
>>> On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
>>>> On VHE systems KVM masks SError before switching the VBAR value. Any
>>>> host RAS error that the CPU knew about before world-switch may become
>>>> pending as an SError during world-switch, and only be taken once we enter
>>>> the guest.
>>>>
>>>> Until KVM can take RAS SErrors during world switch, add an ESB to
>>>> force any RAS errors to be synchronised and taken on the host before
>>>> we enter world switch.
>>>>
>>>> RAS errors that become pending during world switch are still taken
>>>> once we enter the guest.
>>
>>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>>>> index cf5d78ba14b5..5dc6f2877762 100644
>>>> --- a/arch/arm64/include/asm/kvm_host.h
>>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>>> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
>>>>  
>>>>  static inline void kvm_arm_vhe_guest_enter(void)
>>>>  {
>>>> +	esb();
>>
>>> I don't fully appreciate what the point of this is?
>>>
>>> As I understand it, our fundamental goal here is to try to distinguish
>>> between errors happening on the host or in the guest.
>>
>> Not just host/guest, but also those we can and can't handle.
>>
>> KVM can't currently take an SError during world switch, so a RAS error that the
>> CPU was hoping to defer may spread from the host into KVM's
>> no-SError:world-switch code. If this happens it will (almost certainly) have to
>> be re-classified as uncontainable.
>>
>> There is also a firmware-first angle here: NOTIFY_SEI can't be delivered if the
>> normal world has SError masked, so any error that spreads past this point
>> becomes a reboot-by-firmware instead of an OS notification and almost-helpful
>> error message.
>>
>>
>>> If that's correct, then why don't we do it at the last possible moment
>>> when we still have a scratch register left, in the world switch code
>>> itself, and in the case abort the guest entry and report back a "host
>>> SError" return code.
>>
>> We have IESB to run the error-barrier as we enter the guest. This would make any
>> host error pending as an SError, and we would exit the guest immediately. But if
>> there was an RAS error during world switch, by this point its likely to be
>> classified as uncontainable.
>>
>> This esb() is trying to keep this window of code as small as possible, to just
>> errors that occur during world switch.
>>
>> With your vcpu load/save this window becomes a lot smaller, it may be possible
>> to get a VHE-host's arch-code SError handler to take errors from EL2, in which
>> case this barrier can disappear.
>> (note to self: guest may still own the debug hardware)
>>
> 
> ok, thanks for your detailed explanation.  I didn't consider that the
> classification of a RAS error as containable vs. non-containable
> depended on where we take the exception.

Will makes the point over on patch 11 that until we have different handling for
these different classifications of error, there isn't much point doing this now.
(i.e. we treat an error generated here, or when we enter the guest in the same way).

I was trying to keep my eye on what we need for kernel-first support, so we
don't have to change the code twice, we just expand the error handling to do better.

I'll drop this patch for now, it will come back if/when we get kernel-first
support for RAS.


What about firmware-first? Firmware can always take these errors when the normal
world is running. Dropping the barrier means its up to the CPU when any error
gets reported, if firmware has to use NOTIFY_SEI it will have to do a reboot if
the error occurs during world-switch (as SError is masked). If an error spreads
over this boundary, that's just tough-luck, the kernel would have panic'd anyway.


Sorry for the noise,


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
@ 2017-11-02 12:18           ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-02 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 01/11/17 04:55, Christoffer Dall wrote:
> On Tue, Oct 31, 2017 at 11:43:42AM +0000, James Morse wrote:
>> On 31/10/17 06:23, Christoffer Dall wrote:
>>> On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
>>>> On VHE systems KVM masks SError before switching the VBAR value. Any
>>>> host RAS error that the CPU knew about before world-switch may become
>>>> pending as an SError during world-switch, and only be taken once we enter
>>>> the guest.
>>>>
>>>> Until KVM can take RAS SErrors during world switch, add an ESB to
>>>> force any RAS errors to be synchronised and taken on the host before
>>>> we enter world switch.
>>>>
>>>> RAS errors that become pending during world switch are still taken
>>>> once we enter the guest.
>>
>>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>>>> index cf5d78ba14b5..5dc6f2877762 100644
>>>> --- a/arch/arm64/include/asm/kvm_host.h
>>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>>> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
>>>>  
>>>>  static inline void kvm_arm_vhe_guest_enter(void)
>>>>  {
>>>> +	esb();
>>
>>> I don't fully appreciate what the point of this is?
>>>
>>> As I understand it, our fundamental goal here is to try to distinguish
>>> between errors happening on the host or in the guest.
>>
>> Not just host/guest, but also those we can and can't handle.
>>
>> KVM can't currently take an SError during world switch, so a RAS error that the
>> CPU was hoping to defer may spread from the host into KVM's
>> no-SError:world-switch code. If this happens it will (almost certainly) have to
>> be re-classified as uncontainable.
>>
>> There is also a firmware-first angle here: NOTIFY_SEI can't be delivered if the
>> normal world has SError masked, so any error that spreads past this point
>> becomes a reboot-by-firmware instead of an OS notification and almost-helpful
>> error message.
>>
>>
>>> If that's correct, then why don't we do it at the last possible moment
>>> when we still have a scratch register left, in the world switch code
>>> itself, and in the case abort the guest entry and report back a "host
>>> SError" return code.
>>
>> We have IESB to run the error-barrier as we enter the guest. This would make any
>> host error pending as an SError, and we would exit the guest immediately. But if
>> there was an RAS error during world switch, by this point its likely to be
>> classified as uncontainable.
>>
>> This esb() is trying to keep this window of code as small as possible, to just
>> errors that occur during world switch.
>>
>> With your vcpu load/save this window becomes a lot smaller, it may be possible
>> to get a VHE-host's arch-code SError handler to take errors from EL2, in which
>> case this barrier can disappear.
>> (note to self: guest may still own the debug hardware)
>>
> 
> ok, thanks for your detailed explanation.  I didn't consider that the
> classification of a RAS error as containable vs. non-containable
> depended on where we take the exception.

Will makes the point over on patch 11 that until we have different handling for
these different classifications of error, there isn't much point doing this now.
(i.e. we treat an error generated here, or when we enter the guest in the same way).

I was trying to keep my eye on what we need for kernel-first support, so we
don't have to change the code twice, we just expand the error handling to do better.

I'll drop this patch for now, it will come back if/when we get kernel-first
support for RAS.


What about firmware-first? Firmware can always take these errors when the normal
world is running. Dropping the barrier means its up to the CPU when any error
gets reported, if firmware has to use NOTIFY_SEI it will have to do a reboot if
the error occurs during world-switch (as SError is masked). If an error spreads
over this boundary, that's just tough-luck, the kernel would have panic'd anyway.


Sorry for the noise,


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
  2017-11-02 12:14       ` James Morse
@ 2017-11-03 12:45         ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-03 12:45 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Nov 02, 2017 at 12:14:28PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 30/10/17 07:40, Christoffer Dall wrote:
> > On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
> >> Non-VHE systems take an exception to EL2 in order to world-switch into the
> >> guest. When returning from the guest KVM implicitly restores the DAIF
> >> flags when it returns to the kernel at EL1.
> >>
> >> With VHE none of this exception-level jumping happens, so KVMs
> >> world-switch code is exposed to the host kernel's DAIF values, and KVM
> >> spills the guest-exit DAIF values back into the host kernel.
> >> On entry to a guest we have Debug and SError exceptions unmasked, KVM
> >> has switched VBAR but isn't prepared to handle these. On guest exit
> >> Debug exceptions are left disabled once we return to the host and will
> >> stay this way until we enter user space.
> >>
> >> Add a helper to mask/unmask DAIF around VHE guests. The unmask can only
> >> happen after the hosts VBAR value has been synchronised by the isb in
> >> __vhe_hyp_call (via kvm_call_hyp()). Masking could be as late as
> >> setting KVMs VBAR value, but is kept here for symmetry.
> 
> > Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
> 
> Thanks!
> 
> 
> >> ---
> >> Give me a kick if you want this reworked as a fix (which will then
> >> conflict with this series), or a backportable version.
> > 
> > I don't know of any real-world issues where some more graceful handling
> > of SErrors would make sense on older kernels, so I'm fine with just
> > merging this together with this series.
> 
> What about debug?

Are we unmasking debug exceptions as we should with this patch?

If so, I suppose that could be required for something like kgdb or when
running KVM as a guest hypervisor (nested).

In that case, we should probably provide a backport for stable, if we
think people are going to be running older kernels on VHE systems, which
they probably are.

> > On guest exit Debug exceptions are left disabled once we return to the host
> > and will stay this way until we enter user space.

[The indentation seems to indicate I wrote this, but I don't think I
did.  I'm confused.]

> 
> Today VHE:KVM causes the kernel to run with SError unmasked and debug disabled
> until the next return to user-space, whereas previously the kernel expected
> SError to be masked and debug enabled.
> 
> 
> (Reposting just the SError rework without this patch changes the kernel to
> expect SError to be unmasked, which isn't making this any worse.)
> 
I'm sorry, I don't understand this discussion.  What is today, and what
is previously, and are you suggesting we drop this patch, or that the
rest of this series is somehow going to be applied without this patch?

Reset: I think this patch is fine in the context of this series..  I now
have no idea what we need to do in terms of older kernels.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
@ 2017-11-03 12:45         ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-03 12:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 02, 2017 at 12:14:28PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 30/10/17 07:40, Christoffer Dall wrote:
> > On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
> >> Non-VHE systems take an exception to EL2 in order to world-switch into the
> >> guest. When returning from the guest KVM implicitly restores the DAIF
> >> flags when it returns to the kernel at EL1.
> >>
> >> With VHE none of this exception-level jumping happens, so KVMs
> >> world-switch code is exposed to the host kernel's DAIF values, and KVM
> >> spills the guest-exit DAIF values back into the host kernel.
> >> On entry to a guest we have Debug and SError exceptions unmasked, KVM
> >> has switched VBAR but isn't prepared to handle these. On guest exit
> >> Debug exceptions are left disabled once we return to the host and will
> >> stay this way until we enter user space.
> >>
> >> Add a helper to mask/unmask DAIF around VHE guests. The unmask can only
> >> happen after the hosts VBAR value has been synchronised by the isb in
> >> __vhe_hyp_call (via kvm_call_hyp()). Masking could be as late as
> >> setting KVMs VBAR value, but is kept here for symmetry.
> 
> > Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
> 
> Thanks!
> 
> 
> >> ---
> >> Give me a kick if you want this reworked as a fix (which will then
> >> conflict with this series), or a backportable version.
> > 
> > I don't know of any real-world issues where some more graceful handling
> > of SErrors would make sense on older kernels, so I'm fine with just
> > merging this together with this series.
> 
> What about debug?

Are we unmasking debug exceptions as we should with this patch?

If so, I suppose that could be required for something like kgdb or when
running KVM as a guest hypervisor (nested).

In that case, we should probably provide a backport for stable, if we
think people are going to be running older kernels on VHE systems, which
they probably are.

> > On guest exit Debug exceptions are left disabled once we return to the host
> > and will stay this way until we enter user space.

[The indentation seems to indicate I wrote this, but I don't think I
did.  I'm confused.]

> 
> Today VHE:KVM causes the kernel to run with SError unmasked and debug disabled
> until the next return to user-space, whereas previously the kernel expected
> SError to be masked and debug enabled.
> 
> 
> (Reposting just the SError rework without this patch changes the kernel to
> expect SError to be unmasked, which isn't making this any worse.)
> 
I'm sorry, I don't understand this discussion.  What is today, and what
is previously, and are you suggesting we drop this patch, or that the
rest of this series is somehow going to be applied without this patch?

Reset: I think this patch is fine in the context of this series..  I now
have no idea what we need to do in terms of older kernels.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
  2017-11-02 12:18           ` James Morse
@ 2017-11-03 12:49             ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-03 12:49 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Nov 02, 2017 at 12:18:20PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 01/11/17 04:55, Christoffer Dall wrote:
> > On Tue, Oct 31, 2017 at 11:43:42AM +0000, James Morse wrote:
> >> On 31/10/17 06:23, Christoffer Dall wrote:
> >>> On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
> >>>> On VHE systems KVM masks SError before switching the VBAR value. Any
> >>>> host RAS error that the CPU knew about before world-switch may become
> >>>> pending as an SError during world-switch, and only be taken once we enter
> >>>> the guest.
> >>>>
> >>>> Until KVM can take RAS SErrors during world switch, add an ESB to
> >>>> force any RAS errors to be synchronised and taken on the host before
> >>>> we enter world switch.
> >>>>
> >>>> RAS errors that become pending during world switch are still taken
> >>>> once we enter the guest.
> >>
> >>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> >>>> index cf5d78ba14b5..5dc6f2877762 100644
> >>>> --- a/arch/arm64/include/asm/kvm_host.h
> >>>> +++ b/arch/arm64/include/asm/kvm_host.h
> >>>> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
> >>>>  
> >>>>  static inline void kvm_arm_vhe_guest_enter(void)
> >>>>  {
> >>>> +	esb();
> >>
> >>> I don't fully appreciate what the point of this is?
> >>>
> >>> As I understand it, our fundamental goal here is to try to distinguish
> >>> between errors happening on the host or in the guest.
> >>
> >> Not just host/guest, but also those we can and can't handle.
> >>
> >> KVM can't currently take an SError during world switch, so a RAS error that the
> >> CPU was hoping to defer may spread from the host into KVM's
> >> no-SError:world-switch code. If this happens it will (almost certainly) have to
> >> be re-classified as uncontainable.
> >>
> >> There is also a firmware-first angle here: NOTIFY_SEI can't be delivered if the
> >> normal world has SError masked, so any error that spreads past this point
> >> becomes a reboot-by-firmware instead of an OS notification and almost-helpful
> >> error message.
> >>
> >>
> >>> If that's correct, then why don't we do it at the last possible moment
> >>> when we still have a scratch register left, in the world switch code
> >>> itself, and in the case abort the guest entry and report back a "host
> >>> SError" return code.
> >>
> >> We have IESB to run the error-barrier as we enter the guest. This would make any
> >> host error pending as an SError, and we would exit the guest immediately. But if
> >> there was an RAS error during world switch, by this point its likely to be
> >> classified as uncontainable.
> >>
> >> This esb() is trying to keep this window of code as small as possible, to just
> >> errors that occur during world switch.
> >>
> >> With your vcpu load/save this window becomes a lot smaller, it may be possible
> >> to get a VHE-host's arch-code SError handler to take errors from EL2, in which
> >> case this barrier can disappear.
> >> (note to self: guest may still own the debug hardware)
> >>
> > 
> > ok, thanks for your detailed explanation.  I didn't consider that the
> > classification of a RAS error as containable vs. non-containable
> > depended on where we take the exception.
> 
> Will makes the point over on patch 11 that until we have different handling for
> these different classifications of error, there isn't much point doing this now.
> (i.e. we treat an error generated here, or when we enter the guest in the same way).
> 
> I was trying to keep my eye on what we need for kernel-first support, so we
> don't have to change the code twice, we just expand the error handling to do better.

I figured as much...

> 
> I'll drop this patch for now, it will come back if/when we get kernel-first
> support for RAS.

Either way is fine from my point of view.
> 
> 
> What about firmware-first? Firmware can always take these errors when the normal
> world is running. Dropping the barrier means its up to the CPU when any error
> gets reported, if firmware has to use NOTIFY_SEI it will have to do a reboot if
> the error occurs during world-switch (as SError is masked). If an error spreads
> over this boundary, that's just tough-luck, the kernel would have panic'd anyway.
> 
> 

Does a non-secure esb() cause the error to be delivered to firmware on
the secure side if anything is pending?

I'm not sure I fully understand the interaction between issuing an
esb() in non-secure and firmware handling a RAS error; I thought there
would be none, and that this was only for kernel-first ?

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
@ 2017-11-03 12:49             ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-03 12:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 02, 2017 at 12:18:20PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 01/11/17 04:55, Christoffer Dall wrote:
> > On Tue, Oct 31, 2017 at 11:43:42AM +0000, James Morse wrote:
> >> On 31/10/17 06:23, Christoffer Dall wrote:
> >>> On Thu, Oct 19, 2017 at 03:58:06PM +0100, James Morse wrote:
> >>>> On VHE systems KVM masks SError before switching the VBAR value. Any
> >>>> host RAS error that the CPU knew about before world-switch may become
> >>>> pending as an SError during world-switch, and only be taken once we enter
> >>>> the guest.
> >>>>
> >>>> Until KVM can take RAS SErrors during world switch, add an ESB to
> >>>> force any RAS errors to be synchronised and taken on the host before
> >>>> we enter world switch.
> >>>>
> >>>> RAS errors that become pending during world switch are still taken
> >>>> once we enter the guest.
> >>
> >>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> >>>> index cf5d78ba14b5..5dc6f2877762 100644
> >>>> --- a/arch/arm64/include/asm/kvm_host.h
> >>>> +++ b/arch/arm64/include/asm/kvm_host.h
> >>>> @@ -392,6 +392,7 @@ static inline void __cpu_init_stage2(void)
> >>>>  
> >>>>  static inline void kvm_arm_vhe_guest_enter(void)
> >>>>  {
> >>>> +	esb();
> >>
> >>> I don't fully appreciate what the point of this is?
> >>>
> >>> As I understand it, our fundamental goal here is to try to distinguish
> >>> between errors happening on the host or in the guest.
> >>
> >> Not just host/guest, but also those we can and can't handle.
> >>
> >> KVM can't currently take an SError during world switch, so a RAS error that the
> >> CPU was hoping to defer may spread from the host into KVM's
> >> no-SError:world-switch code. If this happens it will (almost certainly) have to
> >> be re-classified as uncontainable.
> >>
> >> There is also a firmware-first angle here: NOTIFY_SEI can't be delivered if the
> >> normal world has SError masked, so any error that spreads past this point
> >> becomes a reboot-by-firmware instead of an OS notification and almost-helpful
> >> error message.
> >>
> >>
> >>> If that's correct, then why don't we do it at the last possible moment
> >>> when we still have a scratch register left, in the world switch code
> >>> itself, and in the case abort the guest entry and report back a "host
> >>> SError" return code.
> >>
> >> We have IESB to run the error-barrier as we enter the guest. This would make any
> >> host error pending as an SError, and we would exit the guest immediately. But if
> >> there was an RAS error during world switch, by this point its likely to be
> >> classified as uncontainable.
> >>
> >> This esb() is trying to keep this window of code as small as possible, to just
> >> errors that occur during world switch.
> >>
> >> With your vcpu load/save this window becomes a lot smaller, it may be possible
> >> to get a VHE-host's arch-code SError handler to take errors from EL2, in which
> >> case this barrier can disappear.
> >> (note to self: guest may still own the debug hardware)
> >>
> > 
> > ok, thanks for your detailed explanation.  I didn't consider that the
> > classification of a RAS error as containable vs. non-containable
> > depended on where we take the exception.
> 
> Will makes the point over on patch 11 that until we have different handling for
> these different classifications of error, there isn't much point doing this now.
> (i.e. we treat an error generated here, or when we enter the guest in the same way).
> 
> I was trying to keep my eye on what we need for kernel-first support, so we
> don't have to change the code twice, we just expand the error handling to do better.

I figured as much...

> 
> I'll drop this patch for now, it will come back if/when we get kernel-first
> support for RAS.

Either way is fine from my point of view.
> 
> 
> What about firmware-first? Firmware can always take these errors when the normal
> world is running. Dropping the barrier means its up to the CPU when any error
> gets reported, if firmware has to use NOTIFY_SEI it will have to do a reboot if
> the error occurs during world-switch (as SError is masked). If an error spreads
> over this boundary, that's just tough-luck, the kernel would have panic'd anyway.
> 
> 

Does a non-secure esb() cause the error to be delivered to firmware on
the secure side if anything is pending?

I'm not sure I fully understand the interaction between issuing an
esb() in non-secure and firmware handling a RAS error; I thought there
would be none, and that this was only for kernel-first ?

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
  2017-11-03 12:49             ` Christoffer Dall
@ 2017-11-03 16:14               ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-03 16:14 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi Christoffer,

On 03/11/17 12:49, Christoffer Dall wrote:
> Does a non-secure esb() cause the error to be delivered to firmware on
> the secure side if anything is pending?

Yes, the ESB-instruction causes 'synchronisable' errors to become pending as an
SError. They then follow the normal SError rules.


> I'm not sure I fully understand the interaction between issuing an
> esb() in non-secure and firmware handling a RAS error; I thought there
> would be none, and that this was only for kernel-first ?

To implement firmware-first, EL3 has to set SCR_EL3.EA to route external-aborts
and physical SError to EL3. So an ESB-instruction, even in a guest, may cause an
SError to be taken to EL3 for firmware-first handling.

This is why RAS is causing so much noise for KVM, any notification could also
interrupt a guest, so firmware has to emulate an exception taken to EL2
correctly and KVM will have to plumb the notification across to the host APEI code.


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
@ 2017-11-03 16:14               ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-03 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 03/11/17 12:49, Christoffer Dall wrote:
> Does a non-secure esb() cause the error to be delivered to firmware on
> the secure side if anything is pending?

Yes, the ESB-instruction causes 'synchronisable' errors to become pending as an
SError. They then follow the normal SError rules.


> I'm not sure I fully understand the interaction between issuing an
> esb() in non-secure and firmware handling a RAS error; I thought there
> would be none, and that this was only for kernel-first ?

To implement firmware-first, EL3 has to set SCR_EL3.EA to route external-aborts
and physical SError to EL3. So an ESB-instruction, even in a guest, may cause an
SError to be taken to EL3 for firmware-first handling.

This is why RAS is causing so much noise for KVM, any notification could also
interrupt a guest, so firmware has to emulate an exception taken to EL2
correctly and KVM will have to plumb the notification across to the host APEI code.


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
  2017-11-03 12:45         ` Christoffer Dall
@ 2017-11-03 17:19           ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-03 17:19 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi Christoffer,

On 03/11/17 12:45, Christoffer Dall wrote:
> On Thu, Nov 02, 2017 at 12:14:28PM +0000, James Morse wrote:
>> On 30/10/17 07:40, Christoffer Dall wrote:
>>> On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
>>>> Non-VHE systems take an exception to EL2 in order to world-switch into the
>>>> guest. When returning from the guest KVM implicitly restores the DAIF
>>>> flags when it returns to the kernel at EL1.
>>>>
>>>> With VHE none of this exception-level jumping happens, so KVMs
>>>> world-switch code is exposed to the host kernel's DAIF values, and KVM
>>>> spills the guest-exit DAIF values back into the host kernel.
>>>> On entry to a guest we have Debug and SError exceptions unmasked, KVM
>>>> has switched VBAR but isn't prepared to handle these. On guest exit
>>>> Debug exceptions are left disabled once we return to the host and will
>>>> stay this way until we enter user space.


>>>> Give me a kick if you want this reworked as a fix (which will then
>>>> conflict with this series), or a backportable version.
>>>
>>> I don't know of any real-world issues where some more graceful handling
>>> of SErrors would make sense on older kernels, so I'm fine with just
>>> merging this together with this series.
>>
>> What about debug?

> Are we unmasking debug exceptions as we should with this patch?

With this patch, yes, it directly restores the DAIF flags the arch code wants
for irq-masked process-context. Debug is re-enabled.


> If so, I suppose that could be required for something like kgdb or when
> running KVM as a guest hypervisor (nested).
> 
> In that case, we should probably provide a backport for stable, if we
> think people are going to be running older kernels on VHE systems, which
> they probably are.

Okay, I will produce a backport once this gets merged.


>>> On guest exit Debug exceptions are left disabled once we return to the host
>>> and will stay this way until we enter user space.

> [The indentation seems to indicate I wrote this, but I don't think I
> did.  I'm confused.]

I quoted it from the commit message, but evidently not from this depth-of-reply.
Sorry for the confusion.


>> Today VHE:KVM causes the kernel to run with SError unmasked and debug disabled
>> until the next return to user-space, whereas previously the kernel expected
>> SError to be masked and debug enabled.
>>
>>
>> (Reposting just the SError rework without this patch changes the kernel to
>> expect SError to be unmasked, which isn't making this any worse.)

> I'm sorry, I don't understand this discussion.  What is today, and what

English has failed me. I'll try again:

v4.14-rc7 with VHE causes the kernel to run after guest-exit with SError
unmasked and debug disabled until the next return to user-space.

The arch code expects SError masked and debug enabled.

In your kgdb example, if we switch-to a new task instead of returning to user
space, it won't hit any break/watchpoints.


> is previously, and are you suggesting we drop this patch, or that the
> rest of this series is somehow going to be applied without this patch?

I reposted just the SError rework, patches 1-10 without this patch.

If merged, this would change the arch code to expect SError to be unmasked from
process context, leaving just the debug disabled after VHE guest-exit.

I was (hurriedly) trying to work out if reposting the SError-rework without this
patch made the situation worse.


Sorry for the confusion!

James



> Reset: I think this patch is fine in the context of this series..  I now
> have no idea what we need to do in terms of older kernels.
> 
> Thanks,
> -Christoffer
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
@ 2017-11-03 17:19           ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-03 17:19 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 03/11/17 12:45, Christoffer Dall wrote:
> On Thu, Nov 02, 2017 at 12:14:28PM +0000, James Morse wrote:
>> On 30/10/17 07:40, Christoffer Dall wrote:
>>> On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
>>>> Non-VHE systems take an exception to EL2 in order to world-switch into the
>>>> guest. When returning from the guest KVM implicitly restores the DAIF
>>>> flags when it returns to the kernel at EL1.
>>>>
>>>> With VHE none of this exception-level jumping happens, so KVMs
>>>> world-switch code is exposed to the host kernel's DAIF values, and KVM
>>>> spills the guest-exit DAIF values back into the host kernel.
>>>> On entry to a guest we have Debug and SError exceptions unmasked, KVM
>>>> has switched VBAR but isn't prepared to handle these. On guest exit
>>>> Debug exceptions are left disabled once we return to the host and will
>>>> stay this way until we enter user space.


>>>> Give me a kick if you want this reworked as a fix (which will then
>>>> conflict with this series), or a backportable version.
>>>
>>> I don't know of any real-world issues where some more graceful handling
>>> of SErrors would make sense on older kernels, so I'm fine with just
>>> merging this together with this series.
>>
>> What about debug?

> Are we unmasking debug exceptions as we should with this patch?

With this patch, yes, it directly restores the DAIF flags the arch code wants
for irq-masked process-context. Debug is re-enabled.


> If so, I suppose that could be required for something like kgdb or when
> running KVM as a guest hypervisor (nested).
> 
> In that case, we should probably provide a backport for stable, if we
> think people are going to be running older kernels on VHE systems, which
> they probably are.

Okay, I will produce a backport once this gets merged.


>>> On guest exit Debug exceptions are left disabled once we return to the host
>>> and will stay this way until we enter user space.

> [The indentation seems to indicate I wrote this, but I don't think I
> did.  I'm confused.]

I quoted it from the commit message, but evidently not from this depth-of-reply.
Sorry for the confusion.


>> Today VHE:KVM causes the kernel to run with SError unmasked and debug disabled
>> until the next return to user-space, whereas previously the kernel expected
>> SError to be masked and debug enabled.
>>
>>
>> (Reposting just the SError rework without this patch changes the kernel to
>> expect SError to be unmasked, which isn't making this any worse.)

> I'm sorry, I don't understand this discussion.  What is today, and what

English has failed me. I'll try again:

v4.14-rc7 with VHE causes the kernel to run after guest-exit with SError
unmasked and debug disabled until the next return to user-space.

The arch code expects SError masked and debug enabled.

In your kgdb example, if we switch-to a new task instead of returning to user
space, it won't hit any break/watchpoints.


> is previously, and are you suggesting we drop this patch, or that the
> rest of this series is somehow going to be applied without this patch?

I reposted just the SError rework, patches 1-10 without this patch.

If merged, this would change the arch code to expect SError to be unmasked from
process context, leaving just the debug disabled after VHE guest-exit.

I was (hurriedly) trying to work out if reposting the SError-rework without this
patch made the situation worse.


Sorry for the confusion!

James



> Reset: I think this patch is fine in the context of this series..  I now
> have no idea what we need to do in terms of older kernels.
> 
> Thanks,
> -Christoffer
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
  2017-11-03 17:19           ` James Morse
@ 2017-11-06 12:42             ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-06 12:42 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Fri, Nov 03, 2017 at 05:19:40PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 03/11/17 12:45, Christoffer Dall wrote:
> > On Thu, Nov 02, 2017 at 12:14:28PM +0000, James Morse wrote:
> >> On 30/10/17 07:40, Christoffer Dall wrote:
> >>> On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
> >>>> Non-VHE systems take an exception to EL2 in order to world-switch into the
> >>>> guest. When returning from the guest KVM implicitly restores the DAIF
> >>>> flags when it returns to the kernel at EL1.
> >>>>
> >>>> With VHE none of this exception-level jumping happens, so KVMs
> >>>> world-switch code is exposed to the host kernel's DAIF values, and KVM
> >>>> spills the guest-exit DAIF values back into the host kernel.
> >>>> On entry to a guest we have Debug and SError exceptions unmasked, KVM
> >>>> has switched VBAR but isn't prepared to handle these. On guest exit
> >>>> Debug exceptions are left disabled once we return to the host and will
> >>>> stay this way until we enter user space.
> 
> 
> >>>> Give me a kick if you want this reworked as a fix (which will then
> >>>> conflict with this series), or a backportable version.
> >>>
> >>> I don't know of any real-world issues where some more graceful handling
> >>> of SErrors would make sense on older kernels, so I'm fine with just
> >>> merging this together with this series.
> >>
> >> What about debug?
> 
> > Are we unmasking debug exceptions as we should with this patch?
> 
> With this patch, yes, it directly restores the DAIF flags the arch code wants
> for irq-masked process-context. Debug is re-enabled.
> 
> 
> > If so, I suppose that could be required for something like kgdb or when
> > running KVM as a guest hypervisor (nested).
> > 
> > In that case, we should probably provide a backport for stable, if we
> > think people are going to be running older kernels on VHE systems, which
> > they probably are.
> 
> Okay, I will produce a backport once this gets merged.
> 
> 
> >>> On guest exit Debug exceptions are left disabled once we return to the host
> >>> and will stay this way until we enter user space.
> 
> > [The indentation seems to indicate I wrote this, but I don't think I
> > did.  I'm confused.]
> 
> I quoted it from the commit message, but evidently not from this depth-of-reply.
> Sorry for the confusion.
> 
> 
> >> Today VHE:KVM causes the kernel to run with SError unmasked and debug disabled
> >> until the next return to user-space, whereas previously the kernel expected
> >> SError to be masked and debug enabled.
> >>
> >>
> >> (Reposting just the SError rework without this patch changes the kernel to
> >> expect SError to be unmasked, which isn't making this any worse.)
> 
> > I'm sorry, I don't understand this discussion.  What is today, and what
> 
> English has failed me. I'll try again:
> 
> v4.14-rc7 with VHE causes the kernel to run after guest-exit with SError
> unmasked and debug disabled until the next return to user-space.
> 
> The arch code expects SError masked and debug enabled.
> 
> In your kgdb example, if we switch-to a new task instead of returning to user
> space, it won't hit any break/watchpoints.
> 
> 
> > is previously, and are you suggesting we drop this patch, or that the
> > rest of this series is somehow going to be applied without this patch?
> 
> I reposted just the SError rework, patches 1-10 without this patch.
> 
> If merged, this would change the arch code to expect SError to be unmasked from
> process context, leaving just the debug disabled after VHE guest-exit.
> 
> I was (hurriedly) trying to work out if reposting the SError-rework without this
> patch made the situation worse.
> 
> 
> Sorry for the confusion!
> 
No worries, and thanks for the explanation.
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests
@ 2017-11-06 12:42             ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-06 12:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 03, 2017 at 05:19:40PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 03/11/17 12:45, Christoffer Dall wrote:
> > On Thu, Nov 02, 2017 at 12:14:28PM +0000, James Morse wrote:
> >> On 30/10/17 07:40, Christoffer Dall wrote:
> >>> On Thu, Oct 19, 2017 at 03:57:55PM +0100, James Morse wrote:
> >>>> Non-VHE systems take an exception to EL2 in order to world-switch into the
> >>>> guest. When returning from the guest KVM implicitly restores the DAIF
> >>>> flags when it returns to the kernel at EL1.
> >>>>
> >>>> With VHE none of this exception-level jumping happens, so KVMs
> >>>> world-switch code is exposed to the host kernel's DAIF values, and KVM
> >>>> spills the guest-exit DAIF values back into the host kernel.
> >>>> On entry to a guest we have Debug and SError exceptions unmasked, KVM
> >>>> has switched VBAR but isn't prepared to handle these. On guest exit
> >>>> Debug exceptions are left disabled once we return to the host and will
> >>>> stay this way until we enter user space.
> 
> 
> >>>> Give me a kick if you want this reworked as a fix (which will then
> >>>> conflict with this series), or a backportable version.
> >>>
> >>> I don't know of any real-world issues where some more graceful handling
> >>> of SErrors would make sense on older kernels, so I'm fine with just
> >>> merging this together with this series.
> >>
> >> What about debug?
> 
> > Are we unmasking debug exceptions as we should with this patch?
> 
> With this patch, yes, it directly restores the DAIF flags the arch code wants
> for irq-masked process-context. Debug is re-enabled.
> 
> 
> > If so, I suppose that could be required for something like kgdb or when
> > running KVM as a guest hypervisor (nested).
> > 
> > In that case, we should probably provide a backport for stable, if we
> > think people are going to be running older kernels on VHE systems, which
> > they probably are.
> 
> Okay, I will produce a backport once this gets merged.
> 
> 
> >>> On guest exit Debug exceptions are left disabled once we return to the host
> >>> and will stay this way until we enter user space.
> 
> > [The indentation seems to indicate I wrote this, but I don't think I
> > did.  I'm confused.]
> 
> I quoted it from the commit message, but evidently not from this depth-of-reply.
> Sorry for the confusion.
> 
> 
> >> Today VHE:KVM causes the kernel to run with SError unmasked and debug disabled
> >> until the next return to user-space, whereas previously the kernel expected
> >> SError to be masked and debug enabled.
> >>
> >>
> >> (Reposting just the SError rework without this patch changes the kernel to
> >> expect SError to be unmasked, which isn't making this any worse.)
> 
> > I'm sorry, I don't understand this discussion.  What is today, and what
> 
> English has failed me. I'll try again:
> 
> v4.14-rc7 with VHE causes the kernel to run after guest-exit with SError
> unmasked and debug disabled until the next return to user-space.
> 
> The arch code expects SError masked and debug enabled.
> 
> In your kgdb example, if we switch-to a new task instead of returning to user
> space, it won't hit any break/watchpoints.
> 
> 
> > is previously, and are you suggesting we drop this patch, or that the
> > rest of this series is somehow going to be applied without this patch?
> 
> I reposted just the SError rework, patches 1-10 without this patch.
> 
> If merged, this would change the arch code to expect SError to be unmasked from
> process context, leaving just the debug disabled after VHE guest-exit.
> 
> I was (hurriedly) trying to work out if reposting the SError-rework without this
> patch made the situation worse.
> 
> 
> Sorry for the confusion!
> 
No worries, and thanks for the explanation.
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
  2017-11-03 16:14               ` James Morse
@ 2017-11-06 12:45                 ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-06 12:45 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Fri, Nov 03, 2017 at 04:14:04PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 03/11/17 12:49, Christoffer Dall wrote:
> > Does a non-secure esb() cause the error to be delivered to firmware on
> > the secure side if anything is pending?
> 
> Yes, the ESB-instruction causes 'synchronisable' errors to become pending as an
> SError. They then follow the normal SError rules.
> 
> 
> > I'm not sure I fully understand the interaction between issuing an
> > esb() in non-secure and firmware handling a RAS error; I thought there
> > would be none, and that this was only for kernel-first ?
> 
> To implement firmware-first, EL3 has to set SCR_EL3.EA to route external-aborts
> and physical SError to EL3. So an ESB-instruction, even in a guest, may cause an
> SError to be taken to EL3 for firmware-first handling.
> 
> This is why RAS is causing so much noise for KVM, any notification could also
> interrupt a guest, so firmware has to emulate an exception taken to EL2
> correctly and KVM will have to plumb the notification across to the host APEI code.
> 
> 

I see, but since the end result is that either we panic or firmware
reboots the machine, we don't care and can leave this patch out for now.
Makes sense.

Thanks for the explanation!
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest
@ 2017-11-06 12:45                 ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-06 12:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 03, 2017 at 04:14:04PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 03/11/17 12:49, Christoffer Dall wrote:
> > Does a non-secure esb() cause the error to be delivered to firmware on
> > the secure side if anything is pending?
> 
> Yes, the ESB-instruction causes 'synchronisable' errors to become pending as an
> SError. They then follow the normal SError rules.
> 
> 
> > I'm not sure I fully understand the interaction between issuing an
> > esb() in non-secure and firmware handling a RAS error; I thought there
> > would be none, and that this was only for kernel-first ?
> 
> To implement firmware-first, EL3 has to set SCR_EL3.EA to route external-aborts
> and physical SError to EL3. So an ESB-instruction, even in a guest, may cause an
> SError to be taken to EL3 for firmware-first handling.
> 
> This is why RAS is causing so much noise for KVM, any notification could also
> interrupt a guest, so firmware has to emulate an exception taken to EL2
> correctly and KVM will have to plumb the notification across to the host APEI code.
> 
> 

I see, but since the end result is that either we panic or firmware
reboots the machine, we don't care and can leave this patch out for now.
Makes sense.

Thanks for the explanation!
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-10-19 14:57 ` James Morse
@ 2017-11-09 18:14   ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-09 18:14 UTC (permalink / raw)
  To: kvmarm
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, Dongjiu Geng, linux-arm-kernel, wangxiongfeng2

Hi guys,

On 19/10/17 15:57, James Morse wrote:
> Known issues:
[...]
>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
>    hasn't taken it yet...?

I've been trying to work out how this pending-SError-migration could work.

If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
an attempt to kill the guest.

This will be more of a problem with GengDongjiu's SError CAP for triggering
guest SError from user-space, which will also allow the VSESR_EL2 to be
specified. (this register becomes the guest ESR_EL1 when the virtual SError is
taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
kernel-first RAS). These errors are likely to be handled by the guest.


We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.

To get out of this corner: why not declare pending-SError-migration an invalid
thing to do?

We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
would need to check this on each vcpu after migration, just before it throws the
switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
need migrating at all.

In the ideal world, Qemu could re-inject the last SError it triggered if there
is still one pending when it migrates... but because KVM injects errors too, it
would need to block migration until this flag is cleared.
KVM can promise this doesn't change unless you run the vcpu, so provided the
vcpu actually takes the SError at some point this thing can still be migrated.

This does make the VSE machinery hidden unmigratable state in KVM, which is nasty.

Can anyone suggest a better way?


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-09 18:14   ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-09 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi guys,

On 19/10/17 15:57, James Morse wrote:
> Known issues:
[...]
>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
>    hasn't taken it yet...?

I've been trying to work out how this pending-SError-migration could work.

If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
an attempt to kill the guest.

This will be more of a problem with GengDongjiu's SError CAP for triggering
guest SError from user-space, which will also allow the VSESR_EL2 to be
specified. (this register becomes the guest ESR_EL1 when the virtual SError is
taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
kernel-first RAS). These errors are likely to be handled by the guest.


We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.

To get out of this corner: why not declare pending-SError-migration an invalid
thing to do?

We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
would need to check this on each vcpu after migration, just before it throws the
switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
need migrating at all.

In the ideal world, Qemu could re-inject the last SError it triggered if there
is still one pending when it migrates... but because KVM injects errors too, it
would need to block migration until this flag is cleared.
KVM can promise this doesn't change unless you run the vcpu, so provided the
vcpu actually takes the SError at some point this thing can still be migrated.

This does make the VSE machinery hidden unmigratable state in KVM, which is nasty.

Can anyone suggest a better way?


Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-09 18:14   ` James Morse
@ 2017-11-10 12:03     ` gengdongjiu
  -1 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-11-10 12:03 UTC (permalink / raw)
  To: James Morse, kvmarm
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, linux-arm-kernel, wangxiongfeng2



On 2017/11/10 2:14, James Morse wrote:
> Hi guys,
> 
> On 19/10/17 15:57, James Morse wrote:
>> Known issues:
> [...]
>>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
>>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
>>    hasn't taken it yet...?
> 
> I've been trying to work out how this pending-SError-migration could work.


Hi James,
  I have finished the Qemu part development about RAS and sent the patches out, I think the solution followed your suggestion and other people's suggestion in the mail discussion.
For example, not pass KVM exception information to Qemu, according to the SIGBUS type(BUS_MCEERR_AR or BUS_MCEERR_A0)
to use different notification type,  create guest APEI table and record CPER in rumtime for guest, etc

how about you have a look at these implementation and then we discuss this migration again? thanks.



> 
> If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
> unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
> an attempt to kill the guest.
> 
> This will be more of a problem with GengDongjiu's SError CAP for triggering
> guest SError from user-space, which will also allow the VSESR_EL2 to be
> specified. (this register becomes the guest ESR_EL1 when the virtual SError is
> taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
> kernel-first RAS). These errors are likely to be handled by the guest.
> 
> 
> We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
> enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
> 
> To get out of this corner: why not declare pending-SError-migration an invalid
> thing to do?
> 
> We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
> would need to check this on each vcpu after migration, just before it throws the
> switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
> need migrating at all.
> 
> In the ideal world, Qemu could re-inject the last SError it triggered if there
> is still one pending when it migrates... but because KVM injects errors too, it
> would need to block migration until this flag is cleared.
> KVM can promise this doesn't change unless you run the vcpu, so provided the
> vcpu actually takes the SError at some point this thing can still be migrated.
> 
> This does make the VSE machinery hidden unmigratable state in KVM, which is nasty.
> 
> Can anyone suggest a better way?
> 
> 
> Thanks,
> 
> James
> 
> .
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-10 12:03     ` gengdongjiu
  0 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-11-10 12:03 UTC (permalink / raw)
  To: linux-arm-kernel



On 2017/11/10 2:14, James Morse wrote:
> Hi guys,
> 
> On 19/10/17 15:57, James Morse wrote:
>> Known issues:
> [...]
>>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
>>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
>>    hasn't taken it yet...?
> 
> I've been trying to work out how this pending-SError-migration could work.


Hi James,
  I have finished the Qemu part development about RAS and sent the patches out, I think the solution followed your suggestion and other people's suggestion in the mail discussion.
For example, not pass KVM exception information to Qemu, according to the SIGBUS type(BUS_MCEERR_AR or BUS_MCEERR_A0)
to use different notification type,  create guest APEI table and record CPER in rumtime for guest, etc

how about you have a look at these implementation and then we discuss this migration again? thanks.



> 
> If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
> unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
> an attempt to kill the guest.
> 
> This will be more of a problem with GengDongjiu's SError CAP for triggering
> guest SError from user-space, which will also allow the VSESR_EL2 to be
> specified. (this register becomes the guest ESR_EL1 when the virtual SError is
> taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
> kernel-first RAS). These errors are likely to be handled by the guest.
> 
> 
> We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
> enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
> 
> To get out of this corner: why not declare pending-SError-migration an invalid
> thing to do?
> 
> We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
> would need to check this on each vcpu after migration, just before it throws the
> switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
> need migrating at all.
> 
> In the ideal world, Qemu could re-inject the last SError it triggered if there
> is still one pending when it migrates... but because KVM injects errors too, it
> would need to block migration until this flag is cleared.
> KVM can promise this doesn't change unless you run the vcpu, so provided the
> vcpu actually takes the SError at some point this thing can still be migrated.
> 
> This does make the VSE machinery hidden unmigratable state in KVM, which is nasty.
> 
> Can anyone suggest a better way?
> 
> 
> Thanks,
> 
> James
> 
> .
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-09 18:14   ` James Morse
@ 2017-11-13 11:29     ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-13 11:29 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
> Hi guys,
> 
> On 19/10/17 15:57, James Morse wrote:
> > Known issues:
> [...]
> >  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
> >    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
> >    hasn't taken it yet...?
> 
> I've been trying to work out how this pending-SError-migration could work.
> 
> If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
> unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
> an attempt to kill the guest.
> 
> This will be more of a problem with GengDongjiu's SError CAP for triggering
> guest SError from user-space, which will also allow the VSESR_EL2 to be
> specified. (this register becomes the guest ESR_EL1 when the virtual SError is
> taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
> kernel-first RAS). These errors are likely to be handled by the guest.
> 
> 
> We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
> enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
> 
> To get out of this corner: why not declare pending-SError-migration an invalid
> thing to do?

To answer that question we'd have to know if that is generally a valid
thing to require.  How will higher level tools in the stack deal with
this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
"nope, can't migrate right now".  I'm thinking if you have a failing
host and want to signal some error to the guest, that's probably a
really good time to migrate your mission-critical VM away to a different
host, and being told, "sorry, cannot do this" would be painful.  I'm
cc'ing Drew for his insight into libvirt and how this is done on x86,
but I'm not really crazy about this idea.

> 
> We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
> would need to check this on each vcpu after migration, just before it throws the
> switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
> need migrating at all.
> 
> In the ideal world, Qemu could re-inject the last SError it triggered if there
> is still one pending when it migrates... but because KVM injects errors too, it
> would need to block migration until this flag is cleared.

I don't understand your conclusion here.

If QEMU can query the virtual SError pending state, it can also inject
that before running the VM after a restore, and we should have preserved
the same state.

> KVM can promise this doesn't change unless you run the vcpu, so provided the
> vcpu actually takes the SError at some point this thing can still be migrated.
> 
> This does make the VSE machinery hidden unmigratable state in KVM, which is nasty.

Yes, nasty.

> 
> Can anyone suggest a better way?
> 

I'm thinking this is analogous to migrating a VM that uses an irqchip in
userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
feeling is that this is also not supported today.

My suggestion would be to add some set of VCPU exception state,
potentially as flags, which can be migrated along with the VM, or at
least used by userspace to query the state of the VM, if there exists a
reliable mechanism to restore the state again without any side effects.

I think we have to comb through Documentation/virtual/kvm/api.txt to see
if we can reuse anything, and if not, add something.  We could also
consider adding something to Documentation/virtual/kvm/devices/vcpu.txt,
where I think we have a large number space to use from.

Hope this helps?

-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-13 11:29     ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-13 11:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
> Hi guys,
> 
> On 19/10/17 15:57, James Morse wrote:
> > Known issues:
> [...]
> >  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
> >    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
> >    hasn't taken it yet...?
> 
> I've been trying to work out how this pending-SError-migration could work.
> 
> If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
> unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
> an attempt to kill the guest.
> 
> This will be more of a problem with GengDongjiu's SError CAP for triggering
> guest SError from user-space, which will also allow the VSESR_EL2 to be
> specified. (this register becomes the guest ESR_EL1 when the virtual SError is
> taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
> kernel-first RAS). These errors are likely to be handled by the guest.
> 
> 
> We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
> enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
> 
> To get out of this corner: why not declare pending-SError-migration an invalid
> thing to do?

To answer that question we'd have to know if that is generally a valid
thing to require.  How will higher level tools in the stack deal with
this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
"nope, can't migrate right now".  I'm thinking if you have a failing
host and want to signal some error to the guest, that's probably a
really good time to migrate your mission-critical VM away to a different
host, and being told, "sorry, cannot do this" would be painful.  I'm
cc'ing Drew for his insight into libvirt and how this is done on x86,
but I'm not really crazy about this idea.

> 
> We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
> would need to check this on each vcpu after migration, just before it throws the
> switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
> need migrating at all.
> 
> In the ideal world, Qemu could re-inject the last SError it triggered if there
> is still one pending when it migrates... but because KVM injects errors too, it
> would need to block migration until this flag is cleared.

I don't understand your conclusion here.

If QEMU can query the virtual SError pending state, it can also inject
that before running the VM after a restore, and we should have preserved
the same state.

> KVM can promise this doesn't change unless you run the vcpu, so provided the
> vcpu actually takes the SError at some point this thing can still be migrated.
> 
> This does make the VSE machinery hidden unmigratable state in KVM, which is nasty.

Yes, nasty.

> 
> Can anyone suggest a better way?
> 

I'm thinking this is analogous to migrating a VM that uses an irqchip in
userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
feeling is that this is also not supported today.

My suggestion would be to add some set of VCPU exception state,
potentially as flags, which can be migrated along with the VM, or at
least used by userspace to query the state of the VM, if there exists a
reliable mechanism to restore the state again without any side effects.

I think we have to comb through Documentation/virtual/kvm/api.txt to see
if we can reuse anything, and if not, add something.  We could also
consider adding something to Documentation/virtual/kvm/devices/vcpu.txt,
where I think we have a large number space to use from.

Hope this helps?

-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-13 11:29     ` Christoffer Dall
@ 2017-11-13 13:05       ` Peter Maydell
  -1 siblings, 0 replies; 160+ messages in thread
From: Peter Maydell @ 2017-11-13 13:05 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, kvmarm, Julien Thierry, Marc Zyngier,
	Catalin Marinas, Will Deacon, Dongjiu Geng, wangxiongfeng2,
	arm-mail-list

On 13 November 2017 at 11:29, Christoffer Dall <cdall@linaro.org> wrote:
> I'm thinking this is analogous to migrating a VM that uses an irqchip in
> userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> feeling is that this is also not supported today.

Oops, yes, we completely forgot about migration when we added
that feature... I think you're right that we won't get that right.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-13 13:05       ` Peter Maydell
  0 siblings, 0 replies; 160+ messages in thread
From: Peter Maydell @ 2017-11-13 13:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 13 November 2017 at 11:29, Christoffer Dall <cdall@linaro.org> wrote:
> I'm thinking this is analogous to migrating a VM that uses an irqchip in
> userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> feeling is that this is also not supported today.

Oops, yes, we completely forgot about migration when we added
that feature... I think you're right that we won't get that right.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-13 11:29     ` Christoffer Dall
@ 2017-11-13 16:14       ` Andrew Jones
  -1 siblings, 0 replies; 160+ messages in thread
From: Andrew Jones @ 2017-11-13 16:14 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, Dongjiu Geng, kvmarm,
	linux-arm-kernel

On Mon, Nov 13, 2017 at 12:29:46PM +0100, Christoffer Dall wrote:
> On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
> > Hi guys,
> > 
> > On 19/10/17 15:57, James Morse wrote:
> > > Known issues:
> > [...]
> > >  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
> > >    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
> > >    hasn't taken it yet...?
> > 
> > I've been trying to work out how this pending-SError-migration could work.
> > 
> > If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
> > unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
> > an attempt to kill the guest.
> > 
> > This will be more of a problem with GengDongjiu's SError CAP for triggering
> > guest SError from user-space, which will also allow the VSESR_EL2 to be
> > specified. (this register becomes the guest ESR_EL1 when the virtual SError is
> > taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
> > kernel-first RAS). These errors are likely to be handled by the guest.
> > 
> > 
> > We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
> > enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
> > 
> > To get out of this corner: why not declare pending-SError-migration an invalid
> > thing to do?
> 
> To answer that question we'd have to know if that is generally a valid
> thing to require.  How will higher level tools in the stack deal with
> this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
> "nope, can't migrate right now".  I'm thinking if you have a failing
> host and want to signal some error to the guest, that's probably a
> really good time to migrate your mission-critical VM away to a different
> host, and being told, "sorry, cannot do this" would be painful.  I'm
> cc'ing Drew for his insight into libvirt and how this is done on x86,
> but I'm not really crazy about this idea.

Without actually confirming, I'm pretty sure it's handled with a best
effort to cancel the migration, continuing/restoring execution on the
source host (or there may be other policies that could be set as well).
Naturally, if the source host is going down and the migration is
cancelled, then the VM goes down too...

Anyway, I don't think we would generally want to introduce guest
controlled migration blockers. IIUC, this migration blocker would remain
until the guest handled the SError, which it may never unmask.

> 
> > 
> > We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
> > would need to check this on each vcpu after migration, just before it throws the
> > switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
> > need migrating at all.
> > 
> > In the ideal world, Qemu could re-inject the last SError it triggered if there
> > is still one pending when it migrates... but because KVM injects errors too, it
> > would need to block migration until this flag is cleared.
> 
> I don't understand your conclusion here.
> 
> If QEMU can query the virtual SError pending state, it can also inject
> that before running the VM after a restore, and we should have preserved
> the same state.
> 
> > KVM can promise this doesn't change unless you run the vcpu, so provided the
> > vcpu actually takes the SError at some point this thing can still be migrated.
> > 
> > This does make the VSE machinery hidden unmigratable state in KVM, which is nasty.
> 
> Yes, nasty.
> 
> > 
> > Can anyone suggest a better way?
> > 
> 
> I'm thinking this is analogous to migrating a VM that uses an irqchip in
> userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> feeling is that this is also not supported today.

Luckily userspace irqchip is mostly a debug feature, or just to support
oddball hardware. Or at least that's the way I see its usecases...

> 
> My suggestion would be to add some set of VCPU exception state,
> potentially as flags, which can be migrated along with the VM, or at
> least used by userspace to query the state of the VM, if there exists a
> reliable mechanism to restore the state again without any side effects.
> 
> I think we have to comb through Documentation/virtual/kvm/api.txt to see
> if we can reuse anything, and if not, add something.  We could also

Maybe KVM_GET/SET_VCPU_EVENTS? Looks like the doc mistakenly states it's
a VM ioctl, but it's a VCPU ioctl.

> consider adding something to Documentation/virtual/kvm/devices/vcpu.txt,
> where I think we have a large number space to use from.
> 
> Hope this helps?
> 
> -Christoffer

Thanks,
drew

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-13 16:14       ` Andrew Jones
  0 siblings, 0 replies; 160+ messages in thread
From: Andrew Jones @ 2017-11-13 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 13, 2017 at 12:29:46PM +0100, Christoffer Dall wrote:
> On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
> > Hi guys,
> > 
> > On 19/10/17 15:57, James Morse wrote:
> > > Known issues:
> > [...]
> > >  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
> > >    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
> > >    hasn't taken it yet...?
> > 
> > I've been trying to work out how this pending-SError-migration could work.
> > 
> > If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
> > unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
> > an attempt to kill the guest.
> > 
> > This will be more of a problem with GengDongjiu's SError CAP for triggering
> > guest SError from user-space, which will also allow the VSESR_EL2 to be
> > specified. (this register becomes the guest ESR_EL1 when the virtual SError is
> > taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
> > kernel-first RAS). These errors are likely to be handled by the guest.
> > 
> > 
> > We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
> > enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
> > 
> > To get out of this corner: why not declare pending-SError-migration an invalid
> > thing to do?
> 
> To answer that question we'd have to know if that is generally a valid
> thing to require.  How will higher level tools in the stack deal with
> this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
> "nope, can't migrate right now".  I'm thinking if you have a failing
> host and want to signal some error to the guest, that's probably a
> really good time to migrate your mission-critical VM away to a different
> host, and being told, "sorry, cannot do this" would be painful.  I'm
> cc'ing Drew for his insight into libvirt and how this is done on x86,
> but I'm not really crazy about this idea.

Without actually confirming, I'm pretty sure it's handled with a best
effort to cancel the migration, continuing/restoring execution on the
source host (or there may be other policies that could be set as well).
Naturally, if the source host is going down and the migration is
cancelled, then the VM goes down too...

Anyway, I don't think we would generally want to introduce guest
controlled migration blockers. IIUC, this migration blocker would remain
until the guest handled the SError, which it may never unmask.

> 
> > 
> > We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
> > would need to check this on each vcpu after migration, just before it throws the
> > switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
> > need migrating at all.
> > 
> > In the ideal world, Qemu could re-inject the last SError it triggered if there
> > is still one pending when it migrates... but because KVM injects errors too, it
> > would need to block migration until this flag is cleared.
> 
> I don't understand your conclusion here.
> 
> If QEMU can query the virtual SError pending state, it can also inject
> that before running the VM after a restore, and we should have preserved
> the same state.
> 
> > KVM can promise this doesn't change unless you run the vcpu, so provided the
> > vcpu actually takes the SError at some point this thing can still be migrated.
> > 
> > This does make the VSE machinery hidden unmigratable state in KVM, which is nasty.
> 
> Yes, nasty.
> 
> > 
> > Can anyone suggest a better way?
> > 
> 
> I'm thinking this is analogous to migrating a VM that uses an irqchip in
> userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> feeling is that this is also not supported today.

Luckily userspace irqchip is mostly a debug feature, or just to support
oddball hardware. Or at least that's the way I see its usecases...

> 
> My suggestion would be to add some set of VCPU exception state,
> potentially as flags, which can be migrated along with the VM, or at
> least used by userspace to query the state of the VM, if there exists a
> reliable mechanism to restore the state again without any side effects.
> 
> I think we have to comb through Documentation/virtual/kvm/api.txt to see
> if we can reuse anything, and if not, add something.  We could also

Maybe KVM_GET/SET_VCPU_EVENTS? Looks like the doc mistakenly states it's
a VM ioctl, but it's a VCPU ioctl.

> consider adding something to Documentation/virtual/kvm/devices/vcpu.txt,
> where I think we have a large number space to use from.
> 
> Hope this helps?
> 
> -Christoffer

Thanks,
drew

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-13 16:14       ` Andrew Jones
@ 2017-11-13 17:56         ` Peter Maydell
  -1 siblings, 0 replies; 160+ messages in thread
From: Peter Maydell @ 2017-11-13 17:56 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Jonathan.Zhang, Christoffer Dall, Julien Thierry, Marc Zyngier,
	Catalin Marinas, Will Deacon, Dongjiu Geng, kvmarm,
	wangxiongfeng2, arm-mail-list

On 13 November 2017 at 16:14, Andrew Jones <drjones@redhat.com> wrote:
> On Mon, Nov 13, 2017 at 12:29:46PM +0100, Christoffer Dall wrote:
>> I'm thinking this is analogous to migrating a VM that uses an irqchip in
>> userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
>> feeling is that this is also not supported today.
>
> Luckily userspace irqchip is mostly a debug feature, or just to support
> oddball hardware. Or at least that's the way I see its usecases...

True, but I think we should always insist on migration working
for new features, because it's just an easier line to define;
otherwise we end up with an annoying "feature mostly works,
unless you happened to be using [list of random things], in
which case it silently doesn't" effect.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-13 17:56         ` Peter Maydell
  0 siblings, 0 replies; 160+ messages in thread
From: Peter Maydell @ 2017-11-13 17:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 13 November 2017 at 16:14, Andrew Jones <drjones@redhat.com> wrote:
> On Mon, Nov 13, 2017 at 12:29:46PM +0100, Christoffer Dall wrote:
>> I'm thinking this is analogous to migrating a VM that uses an irqchip in
>> userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
>> feeling is that this is also not supported today.
>
> Luckily userspace irqchip is mostly a debug feature, or just to support
> oddball hardware. Or at least that's the way I see its usecases...

True, but I think we should always insist on migration working
for new features, because it's just an easier line to define;
otherwise we end up with an annoying "feature mostly works,
unless you happened to be using [list of random things], in
which case it silently doesn't" effect.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-13 11:29     ` Christoffer Dall
@ 2017-11-14 16:03       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-14 16:03 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

Hi Christoffer,

On 13/11/17 11:29, Christoffer Dall wrote:
> On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
>> On 19/10/17 15:57, James Morse wrote:
>>> Known issues:
>> [...]
>>>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
>>>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
>>>    hasn't taken it yet...?
>>
>> I've been trying to work out how this pending-SError-migration could work.
>>
>> If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
>> unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
>> an attempt to kill the guest.
>>
>> This will be more of a problem with GengDongjiu's SError CAP for triggering
>> guest SError from user-space, which will also allow the VSESR_EL2 to be
>> specified. (this register becomes the guest ESR_EL1 when the virtual SError is
>> taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
>> kernel-first RAS). These errors are likely to be handled by the guest.
>>
>>
>> We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
>> enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
>>
>> To get out of this corner: why not declare pending-SError-migration an invalid
>> thing to do?

> To answer that question we'd have to know if that is generally a valid
> thing to require.  How will higher level tools in the stack deal with
> this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
> "nope, can't migrate right now".  I'm thinking if you have a failing
> host and want to signal some error to the guest, that's probably a
> really good time to migrate your mission-critical VM away to a different
> host, and being told, "sorry, cannot do this" would be painful.  I'm
> cc'ing Drew for his insight into libvirt and how this is done on x86,

Thanks,


> but I'm not really crazy about this idea.

Excellent, so at the other extreme we could have an API to query all of this
state, and another to set it. On systems without the RAS extensions this just
moves the HCR_EL2.VSE bit. On systems with the RAS extensions it moves VSESR_EL2
too.

I was hoping to avoid exposing different information. I need to look into how
that works. (and this is all while avoiding adding an EL2 register to
vcpu_sysreg [0])


>> We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
>> would need to check this on each vcpu after migration, just before it throws the
>> switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
>> need migrating at all.
>>
>> In the ideal world, Qemu could re-inject the last SError it triggered if there
>> is still one pending when it migrates... but because KVM injects errors too, it
>> would need to block migration until this flag is cleared.

> I don't understand your conclusion here.

I was trying to reduce it to exposing just HCR_EL2.VSE as 'bool
serror_still_pending()', then let Qemu re-inject whatever SError it injected
last. This then behaves the same regardless of the RAS support.
But KVM's kvm_inject_vabt() breaks this, Qemu can't know whether this pending
SError was from Qemu, or from KVM.

... So we need VSESR_EL2 on systems which have that register ...

(or, get rid of kvm_inject_vabt(), but that would involve a new exit type, and
some trickery for existing user-space)

> If QEMU can query the virtual SError pending state, it can also inject
> that before running the VM after a restore, and we should have preserved
> the same state.

[..]

>> Can anyone suggest a better way?

> I'm thinking this is analogous to migrating a VM that uses an irqchip in
> userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> feeling is that this is also not supported today.

Does KVM change/update these values behind Qemu's back? It's kvm_inject_vabt()
that is making this tricky. (or at least confusing me)


> My suggestion would be to add some set of VCPU exception state,
> potentially as flags, which can be migrated along with the VM, or at
> least used by userspace to query the state of the VM, if there exists a
> reliable mechanism to restore the state again without any side effects.
> 
> I think we have to comb through Documentation/virtual/kvm/api.txt to see
> if we can reuse anything, and if not, add something.  We could also
> consider adding something to Documentation/virtual/kvm/devices/vcpu.txt,
> where I think we have a large number space to use from.
> 
> Hope this helps?

Yes, I'll go looking for a way to expose VSESR_EL2 to user-space.


Thanks!

James


[0] https://patchwork.kernel.org/patch/9886019/

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-14 16:03       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-14 16:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 13/11/17 11:29, Christoffer Dall wrote:
> On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
>> On 19/10/17 15:57, James Morse wrote:
>>> Known issues:
>> [...]
>>>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
>>>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
>>>    hasn't taken it yet...?
>>
>> I've been trying to work out how this pending-SError-migration could work.
>>
>> If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
>> unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
>> an attempt to kill the guest.
>>
>> This will be more of a problem with GengDongjiu's SError CAP for triggering
>> guest SError from user-space, which will also allow the VSESR_EL2 to be
>> specified. (this register becomes the guest ESR_EL1 when the virtual SError is
>> taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
>> kernel-first RAS). These errors are likely to be handled by the guest.
>>
>>
>> We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
>> enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
>>
>> To get out of this corner: why not declare pending-SError-migration an invalid
>> thing to do?

> To answer that question we'd have to know if that is generally a valid
> thing to require.  How will higher level tools in the stack deal with
> this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
> "nope, can't migrate right now".  I'm thinking if you have a failing
> host and want to signal some error to the guest, that's probably a
> really good time to migrate your mission-critical VM away to a different
> host, and being told, "sorry, cannot do this" would be painful.  I'm
> cc'ing Drew for his insight into libvirt and how this is done on x86,

Thanks,


> but I'm not really crazy about this idea.

Excellent, so at the other extreme we could have an API to query all of this
state, and another to set it. On systems without the RAS extensions this just
moves the HCR_EL2.VSE bit. On systems with the RAS extensions it moves VSESR_EL2
too.

I was hoping to avoid exposing different information. I need to look into how
that works. (and this is all while avoiding adding an EL2 register to
vcpu_sysreg [0])


>> We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
>> would need to check this on each vcpu after migration, just before it throws the
>> switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
>> need migrating at all.
>>
>> In the ideal world, Qemu could re-inject the last SError it triggered if there
>> is still one pending when it migrates... but because KVM injects errors too, it
>> would need to block migration until this flag is cleared.

> I don't understand your conclusion here.

I was trying to reduce it to exposing just HCR_EL2.VSE as 'bool
serror_still_pending()', then let Qemu re-inject whatever SError it injected
last. This then behaves the same regardless of the RAS support.
But KVM's kvm_inject_vabt() breaks this, Qemu can't know whether this pending
SError was from Qemu, or from KVM.

... So we need VSESR_EL2 on systems which have that register ...

(or, get rid of kvm_inject_vabt(), but that would involve a new exit type, and
some trickery for existing user-space)

> If QEMU can query the virtual SError pending state, it can also inject
> that before running the VM after a restore, and we should have preserved
> the same state.

[..]

>> Can anyone suggest a better way?

> I'm thinking this is analogous to migrating a VM that uses an irqchip in
> userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> feeling is that this is also not supported today.

Does KVM change/update these values behind Qemu's back? It's kvm_inject_vabt()
that is making this tricky. (or at least confusing me)


> My suggestion would be to add some set of VCPU exception state,
> potentially as flags, which can be migrated along with the VM, or at
> least used by userspace to query the state of the VM, if there exists a
> reliable mechanism to restore the state again without any side effects.
> 
> I think we have to comb through Documentation/virtual/kvm/api.txt to see
> if we can reuse anything, and if not, add something.  We could also
> consider adding something to Documentation/virtual/kvm/devices/vcpu.txt,
> where I think we have a large number space to use from.
> 
> Hope this helps?

Yes, I'll go looking for a way to expose VSESR_EL2 to user-space.


Thanks!

James


[0] https://patchwork.kernel.org/patch/9886019/

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-13 16:14       ` Andrew Jones
@ 2017-11-14 16:11         ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-14 16:11 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Jonathan.Zhang, Christoffer Dall, Marc Zyngier, Catalin Marinas,
	Julien Thierry, Will Deacon, wangxiongfeng2, Dongjiu Geng,
	kvmarm, linux-arm-kernel

Hi Drew,

On 13/11/17 16:14, Andrew Jones wrote:
> On Mon, Nov 13, 2017 at 12:29:46PM +0100, Christoffer Dall wrote:
>> On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
>>> On 19/10/17 15:57, James Morse wrote:
>>>> Known issues:
>>>>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
>>>>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
>>>>    hasn't taken it yet...?
>>>
>>> I've been trying to work out how this pending-SError-migration could work.

[..]

>>> To get out of this corner: why not declare pending-SError-migration an invalid
>>> thing to do?
>>
>> To answer that question we'd have to know if that is generally a valid
>> thing to require.  How will higher level tools in the stack deal with
>> this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
>> "nope, can't migrate right now".  I'm thinking if you have a failing
>> host and want to signal some error to the guest, that's probably a
>> really good time to migrate your mission-critical VM away to a different
>> host, and being told, "sorry, cannot do this" would be painful.  I'm
>> cc'ing Drew for his insight into libvirt and how this is done on x86,
>> but I'm not really crazy about this idea.

> Without actually confirming, I'm pretty sure it's handled with a best
> effort to cancel the migration, continuing/restoring execution on the
> source host (or there may be other policies that could be set as well).
> Naturally, if the source host is going down and the migration is
> cancelled, then the VM goes down too...

> Anyway, I don't think we would generally want to introduce guest
> controlled migration blockers. IIUC, this migration blocker would remain
> until the guest handled the SError, which it may never unmask.

Yes, given the guest can influence this it needs exposing so it can be migrated.


[...]

>> My suggestion would be to add some set of VCPU exception state,
>> potentially as flags, which can be migrated along with the VM, or at
>> least used by userspace to query the state of the VM, if there exists a
>> reliable mechanism to restore the state again without any side effects.
>>
>> I think we have to comb through Documentation/virtual/kvm/api.txt to see
>> if we can reuse anything, and if not, add something.  We could also
> 
> Maybe KVM_GET/SET_VCPU_EVENTS? Looks like the doc mistakenly states it's
> a VM ioctl, but it's a VCPU ioctl.

Hmm, if I suppress my register-size pedantry we can put the lower 32 bits of
VSESR_EL2 in exception.error_code and use has_error_code to mark it valid.
'exception' in this struct ends up meaning SError on arm64.

(While VSESR_EL2 is 64bit[0], the value gets written into the ESR, which is
32bit, so I doubt the top 32bits can be used, currently they are all reserved.)

I'll go dig into how x86 uses this...


Thanks!

James


[0]
https://static.docs.arm.com/ddi0587/a/RAS%20Extension-release%20candidate_march_29.pdf

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-14 16:11         ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-14 16:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Drew,

On 13/11/17 16:14, Andrew Jones wrote:
> On Mon, Nov 13, 2017 at 12:29:46PM +0100, Christoffer Dall wrote:
>> On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
>>> On 19/10/17 15:57, James Morse wrote:
>>>> Known issues:
>>>>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
>>>>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
>>>>    hasn't taken it yet...?
>>>
>>> I've been trying to work out how this pending-SError-migration could work.

[..]

>>> To get out of this corner: why not declare pending-SError-migration an invalid
>>> thing to do?
>>
>> To answer that question we'd have to know if that is generally a valid
>> thing to require.  How will higher level tools in the stack deal with
>> this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
>> "nope, can't migrate right now".  I'm thinking if you have a failing
>> host and want to signal some error to the guest, that's probably a
>> really good time to migrate your mission-critical VM away to a different
>> host, and being told, "sorry, cannot do this" would be painful.  I'm
>> cc'ing Drew for his insight into libvirt and how this is done on x86,
>> but I'm not really crazy about this idea.

> Without actually confirming, I'm pretty sure it's handled with a best
> effort to cancel the migration, continuing/restoring execution on the
> source host (or there may be other policies that could be set as well).
> Naturally, if the source host is going down and the migration is
> cancelled, then the VM goes down too...

> Anyway, I don't think we would generally want to introduce guest
> controlled migration blockers. IIUC, this migration blocker would remain
> until the guest handled the SError, which it may never unmask.

Yes, given the guest can influence this it needs exposing so it can be migrated.


[...]

>> My suggestion would be to add some set of VCPU exception state,
>> potentially as flags, which can be migrated along with the VM, or at
>> least used by userspace to query the state of the VM, if there exists a
>> reliable mechanism to restore the state again without any side effects.
>>
>> I think we have to comb through Documentation/virtual/kvm/api.txt to see
>> if we can reuse anything, and if not, add something.  We could also
> 
> Maybe KVM_GET/SET_VCPU_EVENTS? Looks like the doc mistakenly states it's
> a VM ioctl, but it's a VCPU ioctl.

Hmm, if I suppress my register-size pedantry we can put the lower 32 bits of
VSESR_EL2 in exception.error_code and use has_error_code to mark it valid.
'exception' in this struct ends up meaning SError on arm64.

(While VSESR_EL2 is 64bit[0], the value gets written into the ESR, which is
32bit, so I doubt the top 32bits can be used, currently they are all reserved.)

I'll go dig into how x86 uses this...


Thanks!

James


[0]
https://static.docs.arm.com/ddi0587/a/RAS%20Extension-release%20candidate_march_29.pdf

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-14 16:03       ` James Morse
@ 2017-11-15  9:15         ` gengdongjiu
  -1 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-11-15  9:15 UTC (permalink / raw)
  To: James Morse, Christoffer Dall
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, kvmarm

Hi james,

On 2017/11/15 0:03, James Morse wrote:
>> Hope this helps?
> Yes, I'll go looking for a way to expose VSESR_EL2 to user-space.

what is the purpose to expose VSESR_EL2?
do you mean set its value after migration?

May be we can use similar below Mechanism
https://www.spinics.net/lists/arm-kernel/msg603525.html

when user-space sync the register status, it will get these register value.
it will reuse the IOCTL KVM_GET_ONE_REG and no need to add extra API.

> 
> 
> Thanks!
> 
> James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-15  9:15         ` gengdongjiu
  0 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-11-15  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi james,

On 2017/11/15 0:03, James Morse wrote:
>> Hope this helps?
> Yes, I'll go looking for a way to expose VSESR_EL2 to user-space.

what is the purpose to expose VSESR_EL2?
do you mean set its value after migration?

May be we can use similar below Mechanism
https://www.spinics.net/lists/arm-kernel/msg603525.html

when user-space sync the register status, it will get these register value.
it will reuse the IOCTL KVM_GET_ONE_REG and no need to add extra API.

> 
> 
> Thanks!
> 
> James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-14 16:11         ` James Morse
@ 2017-11-15  9:59           ` gengdongjiu
  -1 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-11-15  9:59 UTC (permalink / raw)
  To: James Morse, Andrew Jones
  Cc: Jonathan.Zhang, Christoffer Dall, Marc Zyngier, Catalin Marinas,
	Julien Thierry, Will Deacon, wangxiongfeng2, kvmarm,
	linux-arm-kernel

> 
> (While VSESR_EL2 is 64bit[0], the value gets written into the ESR, which is
> 32bit, so I doubt the top 32bits can be used, currently they are all reserved.)

In fact the valid bits for vsesr_el2 is 25bit, which will set to ESR.ISS, bits [24:0].
ESR.IL and ESR.EC are not set by vsesr_el2.

> 
> I'll go dig into how x86 uses this...
> 
> 
> Thanks!
> 
> James
> 
> 
> [0]
> https://static.docs.arm.com/ddi0587/a/RAS%20Extension-release%20candidate_march_29.pdf
> 
> .
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-15  9:59           ` gengdongjiu
  0 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-11-15  9:59 UTC (permalink / raw)
  To: linux-arm-kernel

> 
> (While VSESR_EL2 is 64bit[0], the value gets written into the ESR, which is
> 32bit, so I doubt the top 32bits can be used, currently they are all reserved.)

In fact the valid bits for vsesr_el2 is 25bit, which will set to ESR.ISS, bits [24:0].
ESR.IL and ESR.EC are not set by vsesr_el2.

> 
> I'll go dig into how x86 uses this...
> 
> 
> Thanks!
> 
> James
> 
> 
> [0]
> https://static.docs.arm.com/ddi0587/a/RAS%20Extension-release%20candidate_march_29.pdf
> 
> .
> 

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-15  9:15         ` gengdongjiu
@ 2017-11-15 18:25           ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-15 18:25 UTC (permalink / raw)
  To: gengdongjiu
  Cc: Jonathan.Zhang, Christoffer Dall, Marc Zyngier, Catalin Marinas,
	Julien Thierry, Will Deacon, wangxiongfeng2, kvmarm,
	linux-arm-kernel

Hi gengdongjiu,

On 15/11/17 09:15, gengdongjiu wrote:
> On 2017/11/15 0:03, James Morse wrote:
>>> Hope this helps?
>> Yes, I'll go looking for a way to expose VSESR_EL2 to user-space.
> 
> what is the purpose to expose VSESR_EL2?
> do you mean set its value after migration?

Yes. Ideally Qemu would know the value it supplied last, and we just need to
tell it if 'the' inject SError has been delivered. But kvm_inject_vabt() makes
this impossible as Qemu can't know whose injected error this is.


> May be we can use similar below Mechanism
> https://www.spinics.net/lists/arm-kernel/msg603525.html

> when user-space sync the register status, it will get these register value.
> it will reuse the IOCTL KVM_GET_ONE_REG and no need to add extra API.

The maintainer NAKed "any patch that will expose _EL2 registers outside of
nested virtualization": https://patchwork.kernel.org/patch/9886019/

Why? If we 'spend' VSESR_EL2's name and encoding on 'the register we will give
to the guest when it can next take an SError', we will need a new name (and
encoding!) for systems with nested virtualization as now the guest has an
VSESR_EL2 too. The sys_reg/get_one_reg stuff is for guest registers. This thing
is part of the hypervisor's state.

Exposing VSESR_EL2 directly wouldn't be enough: A value of all-zeroes doesn't
tell us if an SError is pending, we need HCR_EL2.VSE too.


Your 'give me register' is a very raw interface, it makes it difficult to change
in the future: What if we get a new way to inject SError? We may not be able to
use it if user-space is poking CPU registers directly.
What happens if all those RES0 bits (and there are a lot of them) mean something
on future CPUs? Should we expose them? Should user-space be allowed to set them?
What if we need an errata workaround, based on something user-space can't know?

What about 32bit? The register names and sizes are different. User-space would
need a separate implementation to drive this. This is easier for the kernel to do.

We should have an API specific to the feature we are offering user-space. We are
offering a way to trigger an SError, with a specified ESR if the system supports
that. To be migrated it needs to be able to read this information back.

This way we can change the implementation without changing the API.



Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-15 18:25           ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2017-11-15 18:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi gengdongjiu,

On 15/11/17 09:15, gengdongjiu wrote:
> On 2017/11/15 0:03, James Morse wrote:
>>> Hope this helps?
>> Yes, I'll go looking for a way to expose VSESR_EL2 to user-space.
> 
> what is the purpose to expose VSESR_EL2?
> do you mean set its value after migration?

Yes. Ideally Qemu would know the value it supplied last, and we just need to
tell it if 'the' inject SError has been delivered. But kvm_inject_vabt() makes
this impossible as Qemu can't know whose injected error this is.


> May be we can use similar below Mechanism
> https://www.spinics.net/lists/arm-kernel/msg603525.html

> when user-space sync the register status, it will get these register value.
> it will reuse the IOCTL KVM_GET_ONE_REG and no need to add extra API.

The maintainer NAKed "any patch that will expose _EL2 registers outside of
nested virtualization": https://patchwork.kernel.org/patch/9886019/

Why? If we 'spend' VSESR_EL2's name and encoding on 'the register we will give
to the guest when it can next take an SError', we will need a new name (and
encoding!) for systems with nested virtualization as now the guest has an
VSESR_EL2 too. The sys_reg/get_one_reg stuff is for guest registers. This thing
is part of the hypervisor's state.

Exposing VSESR_EL2 directly wouldn't be enough: A value of all-zeroes doesn't
tell us if an SError is pending, we need HCR_EL2.VSE too.


Your 'give me register' is a very raw interface, it makes it difficult to change
in the future: What if we get a new way to inject SError? We may not be able to
use it if user-space is poking CPU registers directly.
What happens if all those RES0 bits (and there are a lot of them) mean something
on future CPUs? Should we expose them? Should user-space be allowed to set them?
What if we need an errata workaround, based on something user-space can't know?

What about 32bit? The register names and sizes are different. User-space would
need a separate implementation to drive this. This is easier for the kernel to do.

We should have an API specific to the feature we are offering user-space. We are
offering a way to trigger an SError, with a specified ESR if the system supports
that. To be migrated it needs to be able to read this information back.

This way we can change the implementation without changing the API.



Thanks,

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-13 13:05       ` Peter Maydell
@ 2017-11-20  8:53         ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-20  8:53 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Jonathan.Zhang, kvmarm, Julien Thierry, Marc Zyngier,
	Catalin Marinas, Will Deacon, Dongjiu Geng, wangxiongfeng2,
	arm-mail-list

On Mon, Nov 13, 2017 at 01:05:19PM +0000, Peter Maydell wrote:
> On 13 November 2017 at 11:29, Christoffer Dall <cdall@linaro.org> wrote:
> > I'm thinking this is analogous to migrating a VM that uses an irqchip in
> > userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> > feeling is that this is also not supported today.
> 
> Oops, yes, we completely forgot about migration when we added
> that feature... I think you're right that we won't get that right.

So I think it might actually work for the timer, because we migrate the
timer state, and I think QEMU migrates the timer-to-GIC line state, and
if we're licky the IRQ line from the userspace GIC to the KVM VCPU would
get updated after restore.

But in general, KVM_IRQ_LINE values don't get migrated, and I think
that's a problem we've probably had from the initial implementation, and
not introduced with userspace timers support.

IIRC, QEMU is really happy to continously call KVM_IRQ_LINE with the
same value (which could potentially be further optimized), and that
currently may hide this problem.

Still, it's something we should look at and ensure is correct,
especially when adding a new similar state that needs migration.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-20  8:53         ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-20  8:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 13, 2017 at 01:05:19PM +0000, Peter Maydell wrote:
> On 13 November 2017 at 11:29, Christoffer Dall <cdall@linaro.org> wrote:
> > I'm thinking this is analogous to migrating a VM that uses an irqchip in
> > userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> > feeling is that this is also not supported today.
> 
> Oops, yes, we completely forgot about migration when we added
> that feature... I think you're right that we won't get that right.

So I think it might actually work for the timer, because we migrate the
timer state, and I think QEMU migrates the timer-to-GIC line state, and
if we're licky the IRQ line from the userspace GIC to the KVM VCPU would
get updated after restore.

But in general, KVM_IRQ_LINE values don't get migrated, and I think
that's a problem we've probably had from the initial implementation, and
not introduced with userspace timers support.

IIRC, QEMU is really happy to continously call KVM_IRQ_LINE with the
same value (which could potentially be further optimized), and that
currently may hide this problem.

Still, it's something we should look at and ensure is correct,
especially when adding a new similar state that needs migration.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-14 16:03       ` James Morse
@ 2017-11-20  8:55         ` Christoffer Dall
  -1 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-20  8:55 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Marc Zyngier, Catalin Marinas, Julien Thierry,
	Will Deacon, wangxiongfeng2, linux-arm-kernel, Dongjiu Geng,
	kvmarm

On Tue, Nov 14, 2017 at 04:03:01PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 13/11/17 11:29, Christoffer Dall wrote:
> > On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
> >> On 19/10/17 15:57, James Morse wrote:
> >>> Known issues:
> >> [...]
> >>>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
> >>>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
> >>>    hasn't taken it yet...?
> >>
> >> I've been trying to work out how this pending-SError-migration could work.
> >>
> >> If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
> >> unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
> >> an attempt to kill the guest.
> >>
> >> This will be more of a problem with GengDongjiu's SError CAP for triggering
> >> guest SError from user-space, which will also allow the VSESR_EL2 to be
> >> specified. (this register becomes the guest ESR_EL1 when the virtual SError is
> >> taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
> >> kernel-first RAS). These errors are likely to be handled by the guest.
> >>
> >>
> >> We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
> >> enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
> >>
> >> To get out of this corner: why not declare pending-SError-migration an invalid
> >> thing to do?
> 
> > To answer that question we'd have to know if that is generally a valid
> > thing to require.  How will higher level tools in the stack deal with
> > this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
> > "nope, can't migrate right now".  I'm thinking if you have a failing
> > host and want to signal some error to the guest, that's probably a
> > really good time to migrate your mission-critical VM away to a different
> > host, and being told, "sorry, cannot do this" would be painful.  I'm
> > cc'ing Drew for his insight into libvirt and how this is done on x86,
> 
> Thanks,
> 
> 
> > but I'm not really crazy about this idea.
> 
> Excellent, so at the other extreme we could have an API to query all of this
> state, and another to set it. On systems without the RAS extensions this just
> moves the HCR_EL2.VSE bit. On systems with the RAS extensions it moves VSESR_EL2
> too.
> 
> I was hoping to avoid exposing different information. I need to look into how
> that works. (and this is all while avoiding adding an EL2 register to
> vcpu_sysreg [0])
> 
> 
> >> We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
> >> would need to check this on each vcpu after migration, just before it throws the
> >> switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
> >> need migrating at all.
> >>
> >> In the ideal world, Qemu could re-inject the last SError it triggered if there
> >> is still one pending when it migrates... but because KVM injects errors too, it
> >> would need to block migration until this flag is cleared.
> 
> > I don't understand your conclusion here.
> 
> I was trying to reduce it to exposing just HCR_EL2.VSE as 'bool
> serror_still_pending()', then let Qemu re-inject whatever SError it injected
> last. This then behaves the same regardless of the RAS support.
> But KVM's kvm_inject_vabt() breaks this, Qemu can't know whether this pending
> SError was from Qemu, or from KVM.
> 
> ... So we need VSESR_EL2 on systems which have that register ...
> 
> (or, get rid of kvm_inject_vabt(), but that would involve a new exit type, and
> some trickery for existing user-space)
> 
> > If QEMU can query the virtual SError pending state, it can also inject
> > that before running the VM after a restore, and we should have preserved
> > the same state.
> 
> [..]
> 
> >> Can anyone suggest a better way?
> 
> > I'm thinking this is analogous to migrating a VM that uses an irqchip in
> > userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> > feeling is that this is also not supported today.
> 
> Does KVM change/update these values behind Qemu's back? It's kvm_inject_vabt()
> that is making this tricky. (or at least confusing me)
> 

Yes, the IRQ line can be set to high from userspace, and then KVM can
lower this value when the guest has taken the virtual IRQ/FIQ.  I think
it's completely similar to your problem.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-20  8:55         ` Christoffer Dall
  0 siblings, 0 replies; 160+ messages in thread
From: Christoffer Dall @ 2017-11-20  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 14, 2017 at 04:03:01PM +0000, James Morse wrote:
> Hi Christoffer,
> 
> On 13/11/17 11:29, Christoffer Dall wrote:
> > On Thu, Nov 09, 2017 at 06:14:56PM +0000, James Morse wrote:
> >> On 19/10/17 15:57, James Morse wrote:
> >>> Known issues:
> >> [...]
> >>>  * KVM-Migration: VDISR_EL2 is exposed to userspace as DISR_EL1, but how should
> >>>    HCR_EL2.VSE or VSESR_EL2 be migrated when the guest has an SError pending but
> >>>    hasn't taken it yet...?
> >>
> >> I've been trying to work out how this pending-SError-migration could work.
> >>
> >> If HCR_EL2.VSE is set then the guest will take a virtual SError when it next
> >> unmasks SError. Today this doesn't get migrated, but only KVM sets this bit as
> >> an attempt to kill the guest.
> >>
> >> This will be more of a problem with GengDongjiu's SError CAP for triggering
> >> guest SError from user-space, which will also allow the VSESR_EL2 to be
> >> specified. (this register becomes the guest ESR_EL1 when the virtual SError is
> >> taken and is used to emulate firmware-first's NOTIFY_SEI and eventually
> >> kernel-first RAS). These errors are likely to be handled by the guest.
> >>
> >>
> >> We don't want to expose VSESR_EL2 to user-space, and for migration it isn't
> >> enough as a value of '0' doesn't tell us if HCR_EL2.VSE is set.
> >>
> >> To get out of this corner: why not declare pending-SError-migration an invalid
> >> thing to do?
> 
> > To answer that question we'd have to know if that is generally a valid
> > thing to require.  How will higher level tools in the stack deal with
> > this (e.g. libvirt, and OpenStack).  Is it really valid to tell them
> > "nope, can't migrate right now".  I'm thinking if you have a failing
> > host and want to signal some error to the guest, that's probably a
> > really good time to migrate your mission-critical VM away to a different
> > host, and being told, "sorry, cannot do this" would be painful.  I'm
> > cc'ing Drew for his insight into libvirt and how this is done on x86,
> 
> Thanks,
> 
> 
> > but I'm not really crazy about this idea.
> 
> Excellent, so at the other extreme we could have an API to query all of this
> state, and another to set it. On systems without the RAS extensions this just
> moves the HCR_EL2.VSE bit. On systems with the RAS extensions it moves VSESR_EL2
> too.
> 
> I was hoping to avoid exposing different information. I need to look into how
> that works. (and this is all while avoiding adding an EL2 register to
> vcpu_sysreg [0])
> 
> 
> >> We can give Qemu a way to query if a virtual SError is (still) pending. Qemu
> >> would need to check this on each vcpu after migration, just before it throws the
> >> switch and the guest runs on the new host. This way the VSESR_EL2 value doesn't
> >> need migrating at all.
> >>
> >> In the ideal world, Qemu could re-inject the last SError it triggered if there
> >> is still one pending when it migrates... but because KVM injects errors too, it
> >> would need to block migration until this flag is cleared.
> 
> > I don't understand your conclusion here.
> 
> I was trying to reduce it to exposing just HCR_EL2.VSE as 'bool
> serror_still_pending()', then let Qemu re-inject whatever SError it injected
> last. This then behaves the same regardless of the RAS support.
> But KVM's kvm_inject_vabt() breaks this, Qemu can't know whether this pending
> SError was from Qemu, or from KVM.
> 
> ... So we need VSESR_EL2 on systems which have that register ...
> 
> (or, get rid of kvm_inject_vabt(), but that would involve a new exit type, and
> some trickery for existing user-space)
> 
> > If QEMU can query the virtual SError pending state, it can also inject
> > that before running the VM after a restore, and we should have preserved
> > the same state.
> 
> [..]
> 
> >> Can anyone suggest a better way?
> 
> > I'm thinking this is analogous to migrating a VM that uses an irqchip in
> > userspace and has set the IRQ or FIQ lines using KVM_IRQ_LINE.  My
> > feeling is that this is also not supported today.
> 
> Does KVM change/update these values behind Qemu's back? It's kvm_inject_vabt()
> that is making this tricky. (or at least confusing me)
> 

Yes, the IRQ line can be set to high from userspace, and then KVM can
lower this value when the guest has taken the virtual IRQ/FIQ.  I think
it's completely similar to your problem.

Thanks,
-Christoffer

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
  2017-11-15 18:25           ` James Morse
@ 2017-11-21 11:31             ` gengdongjiu
  -1 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-11-21 11:31 UTC (permalink / raw)
  To: James Morse
  Cc: Jonathan.Zhang, Christoffer Dall, Marc Zyngier, Catalin Marinas,
	Julien Thierry, Will Deacon, wangxiongfeng2, kvmarm,
	linux-arm-kernel

Hi james,

On 2017/11/16 2:25, James Morse wrote:
> What about 32bit? The register names and sizes are different. User-space would
> need a separate implementation to drive this. This is easier for the kernel to do
I agree with you that using different register names and sizes, such as 32 bit.
For the hcr_el2.VSE/hcr_el2.VF/hcr_el2.IF(KVM_IRQ_LINE needs hcr_el2.VF/hcr_el2.IF),  we can only export
the necessary bits that user space need.

Then add the renamed registers to the sys_reg_desc sys_reg_descs[], user space will save these registers in sys_reg_desc sys_reg_descs[]
before migration, and load these saved value after finish migration, which should be current user space logic, this way will avoid do much change.
Not sure whether other people have better idea.

static const struct sys_reg_desc sys_reg_descs[] = {
	..................................
        { SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
        { SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
        { SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
	.................................
}

> 
> We should have an API specific to the feature we are offering user-space. We are
> offering a way to trigger an SError, with a specified ESR if the system supports
> that. To be migrated it needs to be able to read this information back.
> 
> This way we can change the implementation without changing the API.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support
@ 2017-11-21 11:31             ` gengdongjiu
  0 siblings, 0 replies; 160+ messages in thread
From: gengdongjiu @ 2017-11-21 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi james,

On 2017/11/16 2:25, James Morse wrote:
> What about 32bit? The register names and sizes are different. User-space would
> need a separate implementation to drive this. This is easier for the kernel to do
I agree with you that using different register names and sizes, such as 32 bit.
For the hcr_el2.VSE/hcr_el2.VF/hcr_el2.IF(KVM_IRQ_LINE needs hcr_el2.VF/hcr_el2.IF),  we can only export
the necessary bits that user space need.

Then add the renamed registers to the sys_reg_desc sys_reg_descs[], user space will save these registers in sys_reg_desc sys_reg_descs[]
before migration, and load these saved value after finish migration, which should be current user space logic, this way will avoid do much change.
Not sure whether other people have better idea.

static const struct sys_reg_desc sys_reg_descs[] = {
	..................................
        { SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
        { SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
        { SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
	.................................
}

> 
> We should have an API specific to the feature we are offering user-space. We are
> offering a way to trigger an SError, with a specified ESR if the system supports
> that. To be migrated it needs to be able to read this information back.
> 
> This way we can change the implementation without changing the API.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 10/21] arm64: entry.S: move SError handling into a C function for future expansion
  2017-10-19 14:57   ` James Morse
@ 2018-01-02 21:07     ` Adam Wallis
  -1 siblings, 0 replies; 160+ messages in thread
From: Adam Wallis @ 2018-01-02 21:07 UTC (permalink / raw)
  To: James Morse, linux-arm-kernel
  Cc: Jonathan.Zhang, Julien Thierry, Marc Zyngier, Catalin Marinas,
	Will Deacon, Dongjiu Geng, kvmarm, Wang Xiongfeng,
	wangxiongfeng2

James

On 10/19/2017 10:57 AM, James Morse wrote:
[..]
>  	kernel_ventry	el1_fiq_invalid			// FIQ EL1h
> -	kernel_ventry	el1_error_invalid		// Error EL1h
> +	kernel_ventry	el1_error			// Error EL1h
>  
>  	kernel_ventry	el0_sync			// Synchronous 64-bit EL0
>  	kernel_ventry	el0_irq				// IRQ 64-bit EL0
>  	kernel_ventry	el0_fiq_invalid			// FIQ 64-bit EL0
> -	kernel_ventry	el0_error_invalid		// Error 64-bit EL0
> +	kernel_ventry	el0_error			// Error 64-bit EL0
>  
>  #ifdef CONFIG_COMPAT
>  	kernel_ventry	el0_sync_compat			// Synchronous 32-bit EL0
>  	kernel_ventry	el0_irq_compat			// IRQ 32-bit EL0
>  	kernel_ventry	el0_fiq_invalid_compat		// FIQ 32-bit EL0
> -	kernel_ventry	el0_error_invalid_compat	// Error 32-bit EL0
> +	kernel_ventry	el0_error_compat		// Error 32-bit EL0
>  #else
>  	kernel_ventry	el0_sync_invalid		// Synchronous 32-bit EL0
>  	kernel_ventry	el0_irq_invalid			// IRQ 32-bit EL0
> @@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid)
>  el0_fiq_invalid_compat:
>  	inv_entry 0, BAD_FIQ, 32
>  ENDPROC(el0_fiq_invalid_compat)
> -
> -el0_error_invalid_compat:
> -	inv_entry 0, BAD_ERROR, 32
> -ENDPROC(el0_error_invalid_compat)
>  #endif

Perhaps I missed something quite obvious, but is there any reason to not also
remove el1_error_invalid, since SError handling now jumps to el1_error?

>  el1_sync_invalid:
> @@ -663,6 +659,10 @@ el0_svc_compat:
>  el0_irq_compat:
>  	kernel_entry 0, 32
>  	b	el0_irq_naked
> +
> +el0_error_compat:
> +	kernel_entry 0, 32
> +	b	el0_error_naked
>  #endif
>  
>  el0_da:
> @@ -780,6 +780,28 @@ el0_irq_naked:
>  	b	ret_to_user
>  ENDPROC(el0_irq)
>  
> +el1_error:
> +	kernel_entry 1
> +	mrs	x1, esr_el1
> +	enable_dbg
> +	mov	x0, sp
> +	bl	do_serror
> +	kernel_exit 1
> +ENDPROC(el1_error)
> +
> +el0_error:
> +	kernel_entry 0
> +el0_error_naked:
> +	mrs	x1, esr_el1
> +	enable_dbg
> +	mov	x0, sp
> +	bl	do_serror
> +	enable_daif
> +	ct_user_exit
> +	b	ret_to_user
> +ENDPROC(el0_error)
[..]
Thanks

Adam

-- 
Adam Wallis
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 10/21] arm64: entry.S: move SError handling into a C function for future expansion
@ 2018-01-02 21:07     ` Adam Wallis
  0 siblings, 0 replies; 160+ messages in thread
From: Adam Wallis @ 2018-01-02 21:07 UTC (permalink / raw)
  To: linux-arm-kernel

James

On 10/19/2017 10:57 AM, James Morse wrote:
[..]
>  	kernel_ventry	el1_fiq_invalid			// FIQ EL1h
> -	kernel_ventry	el1_error_invalid		// Error EL1h
> +	kernel_ventry	el1_error			// Error EL1h
>  
>  	kernel_ventry	el0_sync			// Synchronous 64-bit EL0
>  	kernel_ventry	el0_irq				// IRQ 64-bit EL0
>  	kernel_ventry	el0_fiq_invalid			// FIQ 64-bit EL0
> -	kernel_ventry	el0_error_invalid		// Error 64-bit EL0
> +	kernel_ventry	el0_error			// Error 64-bit EL0
>  
>  #ifdef CONFIG_COMPAT
>  	kernel_ventry	el0_sync_compat			// Synchronous 32-bit EL0
>  	kernel_ventry	el0_irq_compat			// IRQ 32-bit EL0
>  	kernel_ventry	el0_fiq_invalid_compat		// FIQ 32-bit EL0
> -	kernel_ventry	el0_error_invalid_compat	// Error 32-bit EL0
> +	kernel_ventry	el0_error_compat		// Error 32-bit EL0
>  #else
>  	kernel_ventry	el0_sync_invalid		// Synchronous 32-bit EL0
>  	kernel_ventry	el0_irq_invalid			// IRQ 32-bit EL0
> @@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid)
>  el0_fiq_invalid_compat:
>  	inv_entry 0, BAD_FIQ, 32
>  ENDPROC(el0_fiq_invalid_compat)
> -
> -el0_error_invalid_compat:
> -	inv_entry 0, BAD_ERROR, 32
> -ENDPROC(el0_error_invalid_compat)
>  #endif

Perhaps I missed something quite obvious, but is there any reason to not also
remove el1_error_invalid, since SError handling now jumps to el1_error?

>  el1_sync_invalid:
> @@ -663,6 +659,10 @@ el0_svc_compat:
>  el0_irq_compat:
>  	kernel_entry 0, 32
>  	b	el0_irq_naked
> +
> +el0_error_compat:
> +	kernel_entry 0, 32
> +	b	el0_error_naked
>  #endif
>  
>  el0_da:
> @@ -780,6 +780,28 @@ el0_irq_naked:
>  	b	ret_to_user
>  ENDPROC(el0_irq)
>  
> +el1_error:
> +	kernel_entry 1
> +	mrs	x1, esr_el1
> +	enable_dbg
> +	mov	x0, sp
> +	bl	do_serror
> +	kernel_exit 1
> +ENDPROC(el1_error)
> +
> +el0_error:
> +	kernel_entry 0
> +el0_error_naked:
> +	mrs	x1, esr_el1
> +	enable_dbg
> +	mov	x0, sp
> +	bl	do_serror
> +	enable_daif
> +	ct_user_exit
> +	b	ret_to_user
> +ENDPROC(el0_error)
[..]
Thanks

Adam

-- 
Adam Wallis
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 160+ messages in thread

* Re: [PATCH v4 10/21] arm64: entry.S: move SError handling into a C function for future expansion
  2018-01-02 21:07     ` Adam Wallis
@ 2018-01-03 16:00       ` James Morse
  -1 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2018-01-03 16:00 UTC (permalink / raw)
  To: Adam Wallis
  Cc: Jonathan.Zhang, Julien Thierry, Marc Zyngier, Catalin Marinas,
	Will Deacon, Dongjiu Geng, kvmarm, Wang Xiongfeng,
	wangxiongfeng2, linux-arm-kernel

Hi Adam,

On 02/01/18 21:07, Adam Wallis wrote:
> On 10/19/2017 10:57 AM, James Morse wrote:
> [..]
>>  	kernel_ventry	el1_fiq_invalid			// FIQ EL1h
>> -	kernel_ventry	el1_error_invalid		// Error EL1h
>> +	kernel_ventry	el1_error			// Error EL1h

>>  	kernel_ventry	el0_sync			// Synchronous 64-bit EL0
>>  	kernel_ventry	el0_irq				// IRQ 64-bit EL0
>>  	kernel_ventry	el0_fiq_invalid			// FIQ 64-bit EL0
>> -	kernel_ventry	el0_error_invalid		// Error 64-bit EL0
>> +	kernel_ventry	el0_error			// Error 64-bit EL0
>>  
>>  #ifdef CONFIG_COMPAT
>>  	kernel_ventry	el0_sync_compat			// Synchronous 32-bit EL0
>>  	kernel_ventry	el0_irq_compat			// IRQ 32-bit EL0
>>  	kernel_ventry	el0_fiq_invalid_compat		// FIQ 32-bit EL0
>> -	kernel_ventry	el0_error_invalid_compat	// Error 32-bit EL0
>> +	kernel_ventry	el0_error_compat		// Error 32-bit EL0
>>  #else
>>  	kernel_ventry	el0_sync_invalid		// Synchronous 32-bit EL0
>>  	kernel_ventry	el0_irq_invalid			// IRQ 32-bit EL0
>> @@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid)
>>  el0_fiq_invalid_compat:
>>  	inv_entry 0, BAD_FIQ, 32
>>  ENDPROC(el0_fiq_invalid_compat)
>> -
>> -el0_error_invalid_compat:
>> -	inv_entry 0, BAD_ERROR, 32
>> -ENDPROC(el0_error_invalid_compat)
>>  #endif

> Perhaps I missed something quite obvious, but is there any reason to not also
> remove el1_error_invalid, since SError handling now jumps to el1_error?

There is still a caller for el1_error_invalid: depending on SPSel we are in
thread or handler mode, which causes exceptions to use a different entry in the
vectors. The kernel always uses handler mode, all the thread mode entries point
at their '_invalid' versions.

If we take an SError from EL1t, SPsel==0 then it uses vectors+0x180. (just cut
off the top of this diff). The el1_error change above is for EL1h, SPsel==1,
which uses vectors+0x380.


Thanks for taking a look!

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

* [PATCH v4 10/21] arm64: entry.S: move SError handling into a C function for future expansion
@ 2018-01-03 16:00       ` James Morse
  0 siblings, 0 replies; 160+ messages in thread
From: James Morse @ 2018-01-03 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Adam,

On 02/01/18 21:07, Adam Wallis wrote:
> On 10/19/2017 10:57 AM, James Morse wrote:
> [..]
>>  	kernel_ventry	el1_fiq_invalid			// FIQ EL1h
>> -	kernel_ventry	el1_error_invalid		// Error EL1h
>> +	kernel_ventry	el1_error			// Error EL1h

>>  	kernel_ventry	el0_sync			// Synchronous 64-bit EL0
>>  	kernel_ventry	el0_irq				// IRQ 64-bit EL0
>>  	kernel_ventry	el0_fiq_invalid			// FIQ 64-bit EL0
>> -	kernel_ventry	el0_error_invalid		// Error 64-bit EL0
>> +	kernel_ventry	el0_error			// Error 64-bit EL0
>>  
>>  #ifdef CONFIG_COMPAT
>>  	kernel_ventry	el0_sync_compat			// Synchronous 32-bit EL0
>>  	kernel_ventry	el0_irq_compat			// IRQ 32-bit EL0
>>  	kernel_ventry	el0_fiq_invalid_compat		// FIQ 32-bit EL0
>> -	kernel_ventry	el0_error_invalid_compat	// Error 32-bit EL0
>> +	kernel_ventry	el0_error_compat		// Error 32-bit EL0
>>  #else
>>  	kernel_ventry	el0_sync_invalid		// Synchronous 32-bit EL0
>>  	kernel_ventry	el0_irq_invalid			// IRQ 32-bit EL0
>> @@ -455,10 +455,6 @@ ENDPROC(el0_error_invalid)
>>  el0_fiq_invalid_compat:
>>  	inv_entry 0, BAD_FIQ, 32
>>  ENDPROC(el0_fiq_invalid_compat)
>> -
>> -el0_error_invalid_compat:
>> -	inv_entry 0, BAD_ERROR, 32
>> -ENDPROC(el0_error_invalid_compat)
>>  #endif

> Perhaps I missed something quite obvious, but is there any reason to not also
> remove el1_error_invalid, since SError handling now jumps to el1_error?

There is still a caller for el1_error_invalid: depending on SPSel we are in
thread or handler mode, which causes exceptions to use a different entry in the
vectors. The kernel always uses handler mode, all the thread mode entries point
at their '_invalid' versions.

If we take an SError from EL1t, SPsel==0 then it uses vectors+0x180. (just cut
off the top of this diff). The el1_error change above is for EL1h, SPsel==1,
which uses vectors+0x380.


Thanks for taking a look!

James

^ permalink raw reply	[flat|nested] 160+ messages in thread

end of thread, other threads:[~2018-01-03 16:00 UTC | newest]

Thread overview: 160+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-19 14:57 [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support James Morse
2017-10-19 14:57 ` James Morse
2017-10-19 14:57 ` [PATCH v4 01/21] arm64: explicitly mask all exceptions James Morse
2017-10-19 14:57   ` James Morse
2017-10-19 14:57 ` [PATCH v4 02/21] arm64: introduce an order for exceptions James Morse
2017-10-19 14:57   ` James Morse
2017-10-19 14:57 ` [PATCH v4 03/21] arm64: Move the async/fiq helpers to explicitly set process context flags James Morse
2017-10-19 14:57   ` James Morse
2017-10-19 14:57 ` [PATCH v4 04/21] arm64: Mask all exceptions during kernel_exit James Morse
2017-10-19 14:57   ` James Morse
2017-10-19 14:57 ` [PATCH v4 05/21] arm64: entry.S: Remove disable_dbg James Morse
2017-10-19 14:57   ` James Morse
2017-10-19 14:57 ` [PATCH v4 06/21] arm64: entry.S: convert el1_sync James Morse
2017-10-19 14:57   ` James Morse
2017-10-19 14:57 ` [PATCH v4 07/21] arm64: entry.S convert el0_sync James Morse
2017-10-19 14:57   ` James Morse
2017-10-19 14:57 ` [PATCH v4 08/21] arm64: entry.S: convert elX_irq James Morse
2017-10-19 14:57   ` James Morse
2017-10-19 14:57 ` [PATCH v4 09/21] KVM: arm/arm64: mask/unmask daif around VHE guests James Morse
2017-10-19 14:57   ` James Morse
2017-10-30  7:40   ` Christoffer Dall
2017-10-30  7:40     ` Christoffer Dall
2017-11-02 12:14     ` James Morse
2017-11-02 12:14       ` James Morse
2017-11-03 12:45       ` Christoffer Dall
2017-11-03 12:45         ` Christoffer Dall
2017-11-03 17:19         ` James Morse
2017-11-03 17:19           ` James Morse
2017-11-06 12:42           ` Christoffer Dall
2017-11-06 12:42             ` Christoffer Dall
2017-10-19 14:57 ` [PATCH v4 10/21] arm64: entry.S: move SError handling into a C function for future expansion James Morse
2017-10-19 14:57   ` James Morse
2018-01-02 21:07   ` Adam Wallis
2018-01-02 21:07     ` Adam Wallis
2018-01-03 16:00     ` James Morse
2018-01-03 16:00       ` James Morse
2017-10-19 14:57 ` [PATCH v4 11/21] arm64: cpufeature: Detect CPU RAS Extentions James Morse
2017-10-19 14:57   ` James Morse
2017-10-31 13:14   ` Will Deacon
2017-10-31 13:14     ` Will Deacon
2017-11-02 12:15     ` James Morse
2017-11-02 12:15       ` James Morse
2017-10-19 14:57 ` [PATCH v4 12/21] arm64: kernel: Survive corrected RAS errors notified by SError James Morse
2017-10-19 14:57   ` James Morse
2017-10-31 13:50   ` Will Deacon
2017-10-31 13:50     ` Will Deacon
2017-11-02 12:15     ` James Morse
2017-11-02 12:15       ` James Morse
2017-10-19 14:57 ` [PATCH v4 13/21] arm64: cpufeature: Enable IESB on exception entry/return for firmware-first James Morse
2017-10-19 14:57   ` James Morse
2017-10-31 13:56   ` Will Deacon
2017-10-31 13:56     ` Will Deacon
2017-10-19 14:58 ` [PATCH v4 14/21] arm64: kernel: Prepare for a DISR user James Morse
2017-10-19 14:58   ` James Morse
2017-10-19 14:58 ` [PATCH v4 15/21] KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2 James Morse
2017-10-19 14:58   ` James Morse
2017-10-20 16:44   ` gengdongjiu
2017-10-20 16:44     ` gengdongjiu
2017-10-23 15:26     ` James Morse
2017-10-23 15:26       ` James Morse
2017-10-24  9:53       ` gengdongjiu
2017-10-24  9:53         ` gengdongjiu
2017-10-30  7:59   ` Christoffer Dall
2017-10-30  7:59     ` Christoffer Dall
2017-10-30 10:51     ` Christoffer Dall
2017-10-30 10:51       ` Christoffer Dall
2017-10-30 15:44       ` James Morse
2017-10-30 15:44         ` James Morse
2017-10-31  5:48         ` Christoffer Dall
2017-10-31  5:48           ` Christoffer Dall
2017-10-31  6:34   ` Marc Zyngier
2017-10-31  6:34     ` Marc Zyngier
2017-10-19 14:58 ` [PATCH v4 16/21] KVM: arm64: Save/Restore guest DISR_EL1 James Morse
2017-10-19 14:58   ` James Morse
2017-10-31  4:27   ` Marc Zyngier
2017-10-31  4:27     ` Marc Zyngier
2017-10-31  5:27   ` Christoffer Dall
2017-10-31  5:27     ` Christoffer Dall
2017-10-19 14:58 ` [PATCH v4 17/21] KVM: arm64: Save ESR_EL2 on guest SError James Morse
2017-10-19 14:58   ` James Morse
2017-10-31  4:26   ` Marc Zyngier
2017-10-31  4:26     ` Marc Zyngier
2017-10-31  5:47     ` Marc Zyngier
2017-10-31  5:47       ` Marc Zyngier
2017-11-01 17:42       ` James Morse
2017-11-01 17:42         ` James Morse
2017-10-19 14:58 ` [PATCH v4 18/21] KVM: arm64: Handle RAS SErrors from EL1 on guest exit James Morse
2017-10-19 14:58   ` James Morse
2017-10-31  5:55   ` Marc Zyngier
2017-10-31  5:55     ` Marc Zyngier
2017-10-31  5:56   ` Christoffer Dall
2017-10-31  5:56     ` Christoffer Dall
2017-10-19 14:58 ` [PATCH v4 19/21] KVM: arm64: Handle RAS SErrors from EL2 " James Morse
2017-10-19 14:58   ` James Morse
2017-10-27  6:26   ` gengdongjiu
2017-10-27  6:26     ` gengdongjiu
2017-10-27 17:38     ` James Morse
2017-10-27 17:38       ` James Morse
2017-10-31  6:13   ` Marc Zyngier
2017-10-31  6:13     ` Marc Zyngier
2017-10-31  6:13   ` Christoffer Dall
2017-10-31  6:13     ` Christoffer Dall
2017-10-19 14:58 ` [PATCH v4 20/21] KVM: arm64: Take any host SError before entering the guest James Morse
2017-10-19 14:58   ` James Morse
2017-10-31  6:23   ` Christoffer Dall
2017-10-31  6:23     ` Christoffer Dall
2017-10-31 11:43     ` James Morse
2017-10-31 11:43       ` James Morse
2017-11-01  4:55       ` Christoffer Dall
2017-11-01  4:55         ` Christoffer Dall
2017-11-02 12:18         ` James Morse
2017-11-02 12:18           ` James Morse
2017-11-03 12:49           ` Christoffer Dall
2017-11-03 12:49             ` Christoffer Dall
2017-11-03 16:14             ` James Morse
2017-11-03 16:14               ` James Morse
2017-11-06 12:45               ` Christoffer Dall
2017-11-06 12:45                 ` Christoffer Dall
2017-10-19 14:58 ` [PATCH v4 21/21] KVM: arm64: Trap RAS error registers and set HCR_EL2's TERR & TEA James Morse
2017-10-19 14:58   ` James Morse
2017-10-31  6:32   ` Christoffer Dall
2017-10-31  6:32     ` Christoffer Dall
2017-10-31  6:32   ` Marc Zyngier
2017-10-31  6:32     ` Marc Zyngier
2017-10-31  6:35 ` [PATCH v4 00/21] SError rework + RAS&IESB for firmware first support Christoffer Dall
2017-10-31  6:35   ` Christoffer Dall
2017-10-31 10:08   ` Will Deacon
2017-10-31 10:08     ` Will Deacon
2017-11-01 15:23     ` James Morse
2017-11-01 15:23       ` James Morse
2017-11-02  8:14       ` Christoffer Dall
2017-11-02  8:14         ` Christoffer Dall
2017-11-09 18:14 ` James Morse
2017-11-09 18:14   ` James Morse
2017-11-10 12:03   ` gengdongjiu
2017-11-10 12:03     ` gengdongjiu
2017-11-13 11:29   ` Christoffer Dall
2017-11-13 11:29     ` Christoffer Dall
2017-11-13 13:05     ` Peter Maydell
2017-11-13 13:05       ` Peter Maydell
2017-11-20  8:53       ` Christoffer Dall
2017-11-20  8:53         ` Christoffer Dall
2017-11-13 16:14     ` Andrew Jones
2017-11-13 16:14       ` Andrew Jones
2017-11-13 17:56       ` Peter Maydell
2017-11-13 17:56         ` Peter Maydell
2017-11-14 16:11       ` James Morse
2017-11-14 16:11         ` James Morse
2017-11-15  9:59         ` gengdongjiu
2017-11-15  9:59           ` gengdongjiu
2017-11-14 16:03     ` James Morse
2017-11-14 16:03       ` James Morse
2017-11-15  9:15       ` gengdongjiu
2017-11-15  9:15         ` gengdongjiu
2017-11-15 18:25         ` James Morse
2017-11-15 18:25           ` James Morse
2017-11-21 11:31           ` gengdongjiu
2017-11-21 11:31             ` gengdongjiu
2017-11-20  8:55       ` Christoffer Dall
2017-11-20  8:55         ` Christoffer Dall

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.