arm64: efi: Fix stub cache maintenance
[firefly-linux-kernel-4.4.55.git] / arch / arm64 / kernel / efi-entry.S
index 619b1dd7bcdea70e184daacbfb5dd7797c8460c0..d18a449409683cb8f87e7998259ea4141d3d0eca 100644 (file)
@@ -54,18 +54,17 @@ ENTRY(efi_stub_entry)
        b.eq    efi_load_fail
 
        /*
-        * efi_entry() will have relocated the kernel image if necessary
-        * and we return here with device tree address in x0 and the kernel
-        * entry point stored at *image_addr. Save those values in registers
-        * which are callee preserved.
+        * efi_entry() will have copied the kernel image if necessary and we
+        * return here with device tree address in x0 and the kernel entry
+        * point stored at *image_addr. Save those values in registers which
+        * are callee preserved.
         */
        mov     x20, x0         // DTB address
        ldr     x0, [sp, #16]   // relocated _text address
        mov     x21, x0
 
        /*
-        * Flush dcache covering current runtime addresses
-        * of kernel text/data. Then flush all of icache.
+        * Calculate size of the kernel Image (same for original and copy).
         */
        adrp    x1, _text
        add     x1, x1, #:lo12:_text
@@ -73,9 +72,24 @@ ENTRY(efi_stub_entry)
        add     x2, x2, #:lo12:_edata
        sub     x1, x2, x1
 
+       /*
+        * Flush the copied Image to the PoC, and ensure it is not shadowed by
+        * stale icache entries from before relocation.
+        */
        bl      __flush_dcache_area
        ic      ialluis
 
+       /*
+        * Ensure that the rest of this function (in the original Image) is
+        * visible when the caches are disabled. The I-cache can't have stale
+        * entries for the VA range of the current image, so no maintenance is
+        * necessary.
+        */
+       adr     x0, efi_stub_entry
+       adr     x1, efi_stub_entry_end
+       sub     x1, x1, x0
+       bl      __flush_dcache_area
+
        /* Turn off Dcache and MMU */
        mrs     x0, CurrentEL
        cmp     x0, #CurrentEL_EL2
@@ -105,4 +119,5 @@ efi_load_fail:
        ldp     x29, x30, [sp], #32
        ret
 
+efi_stub_entry_end:
 ENDPROC(efi_stub_entry)