arm64: Make BP hardening slot counter available
authorMarc Zyngier <marc.zyngier@arm.com>
Tue, 13 Mar 2018 12:40:39 +0000 (12:40 +0000)
committerMarc Zyngier <marc.zyngier@arm.com>
Mon, 19 Mar 2018 13:06:39 +0000 (13:06 +0000)
We're about to need to allocate hardening slots from other parts
of the kernel (in order to support ARM64_HARDEN_EL2_VECTORS).

Turn the counter into an atomic_t and make it available to the
rest of the kernel. Also add BP_HARDEN_EL2_SLOTS as the number of
slots instead of the hardcoded 4...

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
arch/arm64/include/asm/mmu.h
arch/arm64/kernel/bpi.S
arch/arm64/kernel/cpu_errata.c

index a050d4f..3baf010 100644 (file)
@@ -21,6 +21,8 @@
 #define USER_ASID_FLAG (UL(1) << USER_ASID_BIT)
 #define TTBR_ASID_MASK (UL(0xffff) << 48)
 
+#define BP_HARDEN_EL2_SLOTS 4
+
 #ifndef __ASSEMBLY__
 
 typedef struct {
@@ -51,6 +53,7 @@ struct bp_hardening_data {
 
 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
 extern char __bp_harden_hyp_vecs_start[], __bp_harden_hyp_vecs_end[];
+extern atomic_t arm64_el2_vector_last_slot;
 
 DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
 
index dc51ef2..bb0b677 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/arm-smccc.h>
 
 #include <asm/alternative.h>
+#include <asm/mmu.h>
 
 .macro hyp_ventry
        .align 7
@@ -66,7 +67,7 @@ alternative_cb_end
 
        .align  11
 ENTRY(__bp_harden_hyp_vecs_start)
-       .rept 4
+       .rept BP_HARDEN_EL2_SLOTS
        generate_vectors
        .endr
 ENTRY(__bp_harden_hyp_vecs_end)
index 52f15cd..8cf6b60 100644 (file)
@@ -60,6 +60,8 @@ static int cpu_enable_trap_ctr_access(void *__unused)
        return 0;
 }
 
+atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1);
+
 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
@@ -90,7 +92,6 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
                                      const char *hyp_vecs_start,
                                      const char *hyp_vecs_end)
 {
-       static int last_slot = -1;
        static DEFINE_SPINLOCK(bp_lock);
        int cpu, slot = -1;
 
@@ -103,10 +104,8 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
        }
 
        if (slot == -1) {
-               last_slot++;
-               BUG_ON(((__bp_harden_hyp_vecs_end - __bp_harden_hyp_vecs_start)
-                       / SZ_2K) <= last_slot);
-               slot = last_slot;
+               slot = atomic_inc_return(&arm64_el2_vector_last_slot);
+               BUG_ON(slot >= BP_HARDEN_EL2_SLOTS);
                __copy_hyp_vect_bpi(slot, hyp_vecs_start, hyp_vecs_end);
        }