]> xenbits.xensource.com Git - 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>
Wed, 7 Feb 2018 19:52:29 +0000 (11:52 -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>
(cherry picked from commit 05e0690d03dc6177e614e060ae78001d4f2abde2)

Renamed trap_hypervisor_call to trap_supervisor_call

xen/arch/arm/arm32/entry.S
xen/arch/arm/cpuerrata.c

index 97cfa4cd274e155c9460798c8c2ff8a12cf398b6..2ffa42248ae62ca9d6517b7100746649422640c6 100644 (file)
@@ -148,6 +148,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_supervisor_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(supervisor_call)
index 97d36a26438efa478e2e994adfe25eeb50908cc3..2e37fea865c1998dea463e0c5d296e046eb7fae8 100644 (file)
@@ -194,6 +194,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)     \
@@ -238,6 +245,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
     {},
 };