ARM: KVM: invalidate icache on guest exit for Cortex-A15
authorMarc Zyngier <marc.zyngier@arm.com>
Wed, 7 Nov 2018 16:43:50 +0000 (11:43 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Nov 2018 07:20:38 +0000 (08:20 +0100)
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 625edef2a54f46aa5daa477c72ae25bdcb858370..3ad2c44f4137f1159c568609691194ee32d6b0eb 100644 (file)
@@ -257,6 +257,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 58ec002721a1845ab858b9c2f72bbc5372487b14..1bdd03014138506adfdbd4f0c9a7ee571624b415 100644 (file)
@@ -72,6 +72,28 @@ __kvm_hyp_vector:
        W(b)    hyp_fiq
 
 #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.