]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
xen/arm: Isolate the SError between the context switch of 2 vCPUs
authorWei Chen <Wei.Chen@arm.com>
Wed, 5 Apr 2017 09:09:19 +0000 (17:09 +0800)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 5 Apr 2017 19:14:56 +0000 (12:14 -0700)
If there is a pending SError while we are doing context switch, if the
SError handle option is "FORWARD", We have to guarantee this SError to
be caught by current vCPU, otherwise it will be caught by next vCPU and
be forwarded to this wrong vCPU.

So we have to synchronize SError before switch to next vCPU. But this is
only required by "FORWARD" option. In this case we added a new flag
SKIP_CTXT_SWITCH_SERROR_SYNC in cpu_hwcaps to skip synchronizing SError
in context switch for other options. In the meantime, we don't need to
export serror_op accessing to other source files.

Because we have umasked the Abort/SError bit in previous patch, we have
to disable Abort/SError before doing context switch as we have done for
IRQ.

Signed-off-by: Wei Chen <Wei.Chen@arm.com>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/domain.c
xen/arch/arm/traps.c
xen/include/asm-arm/cpufeature.h

index 69c28544ca96a906fdf3116650de448205dc4d4e..76310ed41d41a327cba41ad24fca2aa667df8243 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/cpufeature.h>
 #include <asm/vfp.h>
 #include <asm/procinfo.h>
+#include <asm/alternative.h>
 
 #include <asm/gic.h>
 #include <asm/vgic.h>
@@ -312,6 +313,17 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
 
     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);
index 21cf922e15865c1058a628cb8e73154e88c27117..c092e662c0888ac216b4e165927dd07442ac8dfc 100644 (file)
@@ -167,6 +167,9 @@ static int __init update_serrors_cpu_caps(void)
     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);
index 9eb72e1522928dfe34edd223154272ac58c96d2b..b3cf706332dc2d38d0dc97fa4997caec521fcbe6 100644 (file)
@@ -41,8 +41,9 @@
 #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_NCAPS           6
+#define ARM_NCAPS           7
 
 #ifndef __ASSEMBLY__