ARM: KVM: invalidate icache on guest exit for Cortex-A15
authorMarc Zyngier <marc.zyngier@arm.com>
Mon, 15 Oct 2018 15:32:06 +0000 (11:32 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Oct 2018 07:16:27 +0000 (09:16 +0200)
Commit 0c47ac8cd157727e7a532d665d6fb1b5fd333977 upstream.

In order to avoid aliasing attacks against the branch predictor
on Cortex-A15, let's invalidate the BTB on guest exit, which can
only be done by invalidating the icache (with ACTLR[0] being set).

We use the same hack as for A12/A17 to perform the vector decoding.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Boot-tested-by: Tony Lindgren <tony@atomide.com>
Reviewed-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: David A. Long <dave.long@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm/include/asm/kvm_mmu.h
arch/arm/kvm/hyp/hyp-entry.S

index 85d48c9..082b286 100644 (file)
@@ -255,6 +255,11 @@ static inline void *kvm_get_hyp_vector(void)
                return kvm_ksym_ref(__kvm_hyp_vector_bp_inv);
        }
 
+       case ARM_CPU_PART_CORTEX_A15:
+       {
+               extern char __kvm_hyp_vector_ic_inv[];
+               return kvm_ksym_ref(__kvm_hyp_vector_ic_inv);
+       }
 #endif
        default:
        {
index e789f52..918a05d 100644 (file)
@@ -73,6 +73,28 @@ __kvm_hyp_vector:
 
 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
        .align 5
+__kvm_hyp_vector_ic_inv:
+       .global __kvm_hyp_vector_ic_inv
+
+       /*
+        * We encode the exception entry in the bottom 3 bits of
+        * SP, and we have to guarantee to be 8 bytes aligned.
+        */
+       W(add)  sp, sp, #1      /* Reset          7 */
+       W(add)  sp, sp, #1      /* Undef          6 */
+       W(add)  sp, sp, #1      /* Syscall        5 */
+       W(add)  sp, sp, #1      /* Prefetch abort 4 */
+       W(add)  sp, sp, #1      /* Data abort     3 */
+       W(add)  sp, sp, #1      /* HVC            2 */
+       W(add)  sp, sp, #1      /* IRQ            1 */
+       W(nop)                  /* FIQ            0 */
+
+       mcr     p15, 0, r0, c7, c5, 0   /* ICIALLU */
+       isb
+
+       b       decode_vectors
+
+       .align 5
 __kvm_hyp_vector_bp_inv:
        .global __kvm_hyp_vector_bp_inv
 
@@ -92,6 +114,8 @@ __kvm_hyp_vector_bp_inv:
        mcr     p15, 0, r0, c7, c5, 6   /* BPIALL */
        isb
 
+decode_vectors:
+
 #ifdef CONFIG_THUMB2_KERNEL
        /*
         * Yet another silly hack: Use VPIDR as a temp register.