Per the Arm ARM (D4.5 in ARM DDI 0487E.a), SError may be precise or
imprecise.
Imprecise means the state presented to the exception handler is not
guaranteed to be consistent with any point in the excution stream from
which the exception was taken. In other words, they are likely to be
fatal as you can't return safely from them.
Without the RAS extension, the Arm architecture does not provide a way
to differentiate between imprecise and precise SError. Furthermore Xen
has no support for RAS yet. So from a software POV, there is not much
we can do.
More generally, forwarding blindly SErrors to the guest is likely to be
the wrong thing to do. Indeed, Xen is not able to know what is the
content of the SError. This may be a critical device used by the
hypervisor that is about to fail.
In a nutshell, the option serrors=forward is not safe to use in any
environment with the current state of Xen. Therefore the option and any
code related to it are completely removed.
Take the opportunity to rework the comment in do_trap_data_abort() as
all SErrors/External Abort generated by the hypervisor will result in
a crash of the system no matter what the user passed on the command
line.
Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Release-acked-by: Juergen Gross <jgross@suse.com>
(cherry picked from commit
abb234b5acc5380fc85388c7d98e79533b4eef95)
Set the serial transmit buffer size.
### serrors (ARM)
-> `= diverse | forward | panic`
+> `= diverse | panic`
> Default: `diverse`
use this parameter to skip categorizing SErrors and reduce the overhead of
dsb/isb.
-We provided the following 3 options to administrators to determine how the
+We provided the following 2 options to administrators to determine how the
hypervisors handle SErrors:
* `diverse`:
2. dsb/isb on EL2 -> EL1 return paths to prevent slipping hypervisor
SErrors to guests.
-* `forward`:
- The hypervisor will not distinguish guest SErrors from hypervisor SErrors.
- All SErrors will be forwarded to guests, except the SErrors generated when
- the idle vCPU is running. The idle domain doesn't have the ability to handle
- SErrors, so we have to crash the whole system when we get SErros with the
- idle vCPU. This option will avoid most overhead of the dsb/isb, except the
- dsb/isb in context switch which is used to isolate the SErrors between 2
- vCPUs.
-
* `panic`:
The hypervisor will not distinguish guest SErrors from hypervisor SErrors.
All SErrors will crash the whole system. This option will avoid all overhead
void do_trap_data_abort(struct cpu_user_regs *regs)
{
/*
- * We cannot distinguish Xen SErrors from synchronous data aborts. We
- * want to avoid treating any Xen synchronous aborts as SErrors and
- * forwarding them to the guest. Instead, crash the system in all
- * cases when the abort comes from Xen. Even if they are Xen SErrors
- * it would be a reasonable thing to do, and the default behavior with
- * serror_op == DIVERSE.
+ * We cannot distinguish between Asynchronous External Abort and
+ * Synchronous Data Abort.
+ *
+ * As asynchronous abort (aka SError) generated by the hypervisor will
+ * result in a crash of the system (see __do_trap_serror()), it is fine to
+ * do it here.
*/
if ( VABORT_GEN_BY_GUEST(regs) )
do_trap_guest_serror(regs);
local_irq_disable();
- /*
- * If the serrors_op is "FORWARD", we have to prevent forwarding
- * SError to wrong vCPU. So before context switch, we have to use
- * the SYNCRONIZE_SERROR to guarantee that the pending SError would
- * be caught by current vCPU.
- *
- * The SKIP_CTXT_SWITCH_SERROR_SYNC will be set to cpu_hwcaps when the
- * serrors_op is NOT "FORWARD".
- */
- SYNCHRONIZE_SERROR(SKIP_CTXT_SWITCH_SERROR_SYNC);
-
set_current(next);
prev = __context_switch(prev, next);
static enum {
SERRORS_DIVERSE,
- SERRORS_FORWARD,
SERRORS_PANIC,
} serrors_op;
static int __init parse_serrors_behavior(const char *str)
{
- if ( !strcmp(str, "forward") )
- serrors_op = SERRORS_FORWARD;
- else if ( !strcmp(str, "panic") )
+ if ( !strcmp(str, "panic") )
serrors_op = SERRORS_PANIC;
else
serrors_op = SERRORS_DIVERSE;
if ( serrors_op != SERRORS_DIVERSE )
cpus_set_cap(SKIP_SYNCHRONIZE_SERROR_ENTRY_EXIT);
- if ( serrors_op != SERRORS_FORWARD )
- cpus_set_cap(SKIP_CTXT_SWITCH_SERROR_SYNC);
-
return 0;
}
__initcall(update_serrors_cpu_caps);
* 3) Hypervisor generated native SError, that would be a bug.
*
* A true parameter "guest" means that the SError is type#1 or type#2.
+ *
+ * Note that Arm32 asynchronous external abort generated by the
+ * hypervisor will be handled in do_trap_data_abort().
*/
static void __do_trap_serror(struct cpu_user_regs *regs, bool guest)
{
goto crash_system;
}
- /*
- * The "FORWARD" option will forward all SErrors to the guests, except
- * idle domain generated SErrors.
- */
- if ( serrors_op == SERRORS_FORWARD )
- {
- /*
- * Because the idle domain doesn't have the ability to handle the
- * SErrors, we have to crash the whole system while we get a SError
- * generated by idle domain.
- */
- if ( is_idle_vcpu(current) )
- goto crash_system;
-
- return inject_vabt_exception(regs);
- }
-
crash_system:
- /* Three possibilities to crash the whole system:
+ /*
+ * Two possibilities to crash the whole system:
* 1) "DIVERSE" option with Hypervisor generated SErrors.
- * 2) "FORWARD" option with Idle Domain generated SErrors.
- * 3) "PANIC" option with all SErrors.
+ * 2) "PANIC" option with all SErrors.
*/
do_unexpected_trap("SError", regs);
}
#define ARM64_WORKAROUND_834220 3
#define LIVEPATCH_FEATURE 4
#define SKIP_SYNCHRONIZE_SERROR_ENTRY_EXIT 5
-#define SKIP_CTXT_SWITCH_SERROR_SYNC 6
-#define ARM_HARDEN_BRANCH_PREDICTOR 7
-#define ARM_SSBD 8
-#define ARM_SMCCC_1_1 9
-#define ARM64_WORKAROUND_AT_SPECULATE 10
+#define ARM_HARDEN_BRANCH_PREDICTOR 6
+#define ARM_SSBD 7
+#define ARM_SMCCC_1_1 8
+#define ARM64_WORKAROUND_AT_SPECULATE 9
-#define ARM_NCAPS 11
+#define ARM_NCAPS 10
#ifndef __ASSEMBLY__