Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b0b2658 authored by Mark Rutland's avatar Mark Rutland Committed by Catalin Marinas
Browse files

arm64: efi: Fix stub cache maintenance



While efi-entry.S mentions that efi_entry() will have relocated the
kernel image, it actually means that efi_entry will have placed a copy
of the kernel in the appropriate location, and until this is branched to
at the end of efi_entry.S, all instructions are executed from the
original image.

Thus while the flush in efi_entry.S does ensure that the copy is visible
to noncacheable accesses, it does not guarantee that this is true for
the image instructions are being executed from. This could have
disasterous effects when the MMU and caches are disabled if the image
has not been naturally evicted to the PoC.

Additionally, due to a missing dsb following the ic ialluis, the new
kernel image is not necessarily clean in the I-cache when it is branched
to, with similar potentially disasterous effects.

This patch adds additional flushing to ensure that the currently
executing stub text is flushed to the PoC and is thus visible to
noncacheable accesses. As it is placed after the instructions cache
maintenance for the new image and __flush_dcache_area already contains a
dsb, we do not need to add a separate barrier to ensure completion of
the icache maintenance.

Comments are updated to clarify the situation with regard to the two
images and the maintenance required for both.

Fixes: 3c7f2550
Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Acked-by: default avatarJoel Schopp <joel.schopp@amd.com>
Reviewed-by: default avatarRoy Franz <roy.franz@linaro.org>
Tested-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Ian Campbell <ijc@hellion.org.uk>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Mark Salter <msalter@redhat.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 206c5f60
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -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)