]> xenbits.xensource.com Git - people/dariof/xen.git/commitdiff
xen/arm32: Invalidate BTB on guest exit for Cortex A17 and 12
authorJulien Grall <julien.grall@linaro.org>
Fri, 2 Feb 2018 14:19:23 +0000 (14:19 +0000)
committerStefano Stabellini <sstabellini@kernel.org>
Fri, 2 Feb 2018 19:35:00 +0000 (11:35 -0800)
In order to avoid aliasing attackes agains the branch predictor, let's
invalidate the BTB on guest exist. This is made complicated by the fact
that we cannot take a branch invalidating the BTB.

This is based on the fourth version posted by Marc Zyngier on Linux-arm
mailing list (see [1]).

This is part of XSA-254.

[1] https://www.spinics.net/lists/arm-kernel/msg632062.html

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Julien Grall <julien.grall@linaro.org>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/arm32/entry.S
xen/arch/arm/cpuerrata.c

index 828e52c25c2553b4e903feb0eefab6405517656f..1ebbe4b06556932d1433bb64cadd27c1e33b77be 100644 (file)
@@ -160,6 +160,44 @@ GLOBAL(hyp_traps_vector)
         b trap_irq                      /* 0x18 - IRQ */
         b trap_fiq                      /* 0x1c - FIQ */
 
+#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
+
+        .align 5
+GLOBAL(hyp_traps_vector_bp_inv)
+        /*
+         * We encode the exception entry in the bottom 3 bits of
+         * SP, and we have to guarantee to be 8 bytes aligned.
+         */
+        add sp, sp, #1                  /* Reset            7 */
+        add sp, sp, #1                  /* Undef            6 */
+        add sp, sp, #1                  /* Hypervisor Call  5 */
+        add sp, sp, #1                  /* Prefetch abort   4 */
+        add sp, sp, #1                  /* Data abort       3 */
+        add sp, sp, #1                  /* Hypervisor       2 */
+        add sp, sp, #1                  /* IRQ              1 */
+        nop                             /* FIQ              0 */
+
+        mcr    p15, 0, r0, c7, c5, 6       /* BPIALL */
+        isb
+
+.macro vect_br val, targ
+        eor     sp, sp, #\val
+        tst     sp, #7
+        eorne   sp, sp, #\val
+        beq     \targ
+.endm
+
+        vect_br 0, trap_fiq
+        vect_br 1, trap_irq
+        vect_br 2, trap_guest_sync
+        vect_br 3, trap_data_abort
+        vect_br 4, trap_prefetch_abort
+        vect_br 5, trap_hypervisor_call
+        vect_br 6, trap_undefined_instruction
+        vect_br 7, trap_reset
+
+#endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */
+
 DEFINE_TRAP_ENTRY(reset)
 DEFINE_TRAP_ENTRY(undefined_instruction)
 DEFINE_TRAP_ENTRY(hypervisor_call)
index 0a138fa73581bb771a14edddc3083c17b1b02291..c79e6d65d397b5c239a45562ea59d47f5e8c66e9 100644 (file)
@@ -198,6 +198,13 @@ install_bp_hardening_vecs(const struct arm_cpu_capabilities *entry,
     this_cpu(bp_harden_vecs) = hyp_vecs;
 }
 
+static int enable_bp_inv_hardening(void *data)
+{
+    install_bp_hardening_vecs(data, hyp_traps_vector_bp_inv,
+                              "execute BPIALL");
+    return 0;
+}
+
 #endif
 
 #define MIDR_RANGE(model, min, max)     \
@@ -283,6 +290,18 @@ static const struct arm_cpu_capabilities arm_errata[] = {
         MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
         .enable = enable_psci_bp_hardening,
     },
+#endif
+#ifdef CONFIG_ARM32_HARDEN_BRANCH_PREDICTOR
+    {
+        .capability = ARM_HARDEN_BRANCH_PREDICTOR,
+        MIDR_ALL_VERSIONS(MIDR_CORTEX_A12),
+        .enable = enable_bp_inv_hardening,
+    },
+    {
+        .capability = ARM_HARDEN_BRANCH_PREDICTOR,
+        MIDR_ALL_VERSIONS(MIDR_CORTEX_A17),
+        .enable = enable_bp_inv_hardening,
+    },
 #endif
     {},
 };