Re: [PATCH] powerpc/prom_init: Undo relocation before entering secure mode

From: Ram Pai
Date: Fri Oct 18 2019 - 11:05:30 EST


On Wed, Sep 11, 2019 at 01:34:33PM -0300, Thiago Jung Bauermann wrote:
> The ultravisor will do an integrity check of the kernel image but we
> relocated it so the check will fail. Restore the original image by
> relocating it back to the kernel virtual base address.
>
> This works because during build vmlinux is linked with an expected virtual
> runtime address of KERNELBASE.
>
> Fixes: 6a9c930bd775 ("powerpc/prom_init: Add the ESM call to prom_init")
> Signed-off-by: Thiago Jung Bauermann <bauerman@xxxxxxxxxxxxx>

Tested-by: Ram Pai <linuxram@xxxxxxxxxx>


> ---
> arch/powerpc/include/asm/elf.h | 3 +++
> arch/powerpc/kernel/prom_init.c | 11 +++++++++++
> arch/powerpc/kernel/prom_init_check.sh | 3 ++-
> 3 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index 409c9bfb43d9..57c229a86f08 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -175,4 +175,7 @@ do { \
> ARCH_DLINFO_CACHE_GEOMETRY; \
> } while (0)
>
> +/* Relocate the kernel image to @final_address */
> +void relocate(unsigned long final_address);
> +
> #endif /* _ASM_POWERPC_ELF_H */
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 74f70f90eff0..44b1d404250e 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -3249,7 +3249,18 @@ static void setup_secure_guest(unsigned long kbase, unsigned long fdt)
> /* Switch to secure mode. */
> prom_printf("Switching to secure mode.\n");
>
> + /*
> + * The ultravisor will do an integrity check of the kernel image but we
> + * relocated it so the check will fail. Restore the original image by
> + * relocating it back to the kernel virtual base address.
> + */
> + relocate(KERNELBASE);
> +
> ret = enter_secure_mode(kbase, fdt);
> +
> + /* Relocate the kernel again. */
> + relocate(kbase);
> +
> if (ret != U_SUCCESS) {
> prom_printf("Returned %d from switching to secure mode.\n", ret);
> prom_rtas_os_term("Switch to secure mode failed.\n");
> diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
> index 160bef0d553d..16535ccc0fa0 100644
> --- a/arch/powerpc/kernel/prom_init_check.sh
> +++ b/arch/powerpc/kernel/prom_init_check.sh
> @@ -26,7 +26,8 @@ _end enter_prom $MEM_FUNCS reloc_offset __secondary_hold
> __secondary_hold_acknowledge __secondary_hold_spinloop __start
> logo_linux_clut224 btext_prepare_BAT
> reloc_got2 kernstart_addr memstart_addr linux_banner _stext
> -__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC."
> +__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC.
> +relocate"
>
> NM="$1"
> OBJ="$2"

--
Ram Pai