• Alexei Fedorov's avatar
    Refactor ARMv8.3 Pointer Authentication support code · ed108b56
    Alexei Fedorov authored
    
    This patch provides the following features and makes modifications
    listed below:
    - Individual APIAKey key generation for each CPU.
    - New key generation on every BL31 warm boot and TSP CPU On event.
    - Per-CPU storage of APIAKey added in percpu_data[]
      of cpu_data structure.
    - `plat_init_apiakey()` function replaced with `plat_init_apkey()`
      which returns 128-bit value and uses Generic timer physical counter
      value to increase the randomness of the generated key.
      The new function can be used for generation of all ARMv8.3-PAuth keys
    - ARMv8.3-PAuth specific code placed in `lib\extensions\pauth`.
    - New `pauth_init_enable_el1()` and `pauth_init_enable_el3()` functions
      generate, program and enable APIAKey_EL1 for EL1 and EL3 respectively;
      pauth_disable_el1()` and `pauth_disable_el3()` functions disable
      PAuth for EL1 and EL3 respectively;
      `pauth_load_bl31_apiakey()` loads saved per-CPU APIAKey_EL1 from
      cpu-data structure.
    - Combined `save_gp_pauth_registers()` function replaces calls to
      `save_gp_registers()` and `pauth_context_save()`;
      `restore_gp_pauth_registers()` replaces `pauth_context_restore()`
      and `restore_gp_registers()` calls.
    - `restore_gp_registers_eret()` function removed with corresponding
      code placed in `el3_exit()`.
    - Fixed the issue when `pauth_t pauth_ctx` structure allocated space
      for 12 uint64_t PAuth registers instead of 10 by removal of macro
      CTX_PACGAKEY_END from `include/lib/el3_runtime/aarch64/context.h`
      and assigning its value to CTX_PAUTH_REGS_END.
    - Use of MODE_SP_ELX and MODE_SP_EL0 macro definitions
      in `msr	spsel`  instruction instead of hard-coded values.
    - Changes in documentation related to ARMv8.3-PAuth and ARMv8.5-BTI.
    
    Change-Id: Id18b81cc46f52a783a7e6a09b9f149b6ce803211
    Signed-off-by: default avatarAlexei Fedorov <Alexei.Fedorov@arm.com>
    ed108b56
bl2_main.c 3.8 KB
/*
 * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>

#include <arch_helpers.h>
#include <arch_features.h>
#include <bl1/bl1.h>
#include <bl2/bl2.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/auth/auth_mod.h>
#include <drivers/console.h>
#include <lib/extensions/pauth.h>
#include <plat/common/platform.h>

#include "bl2_private.h"

#ifdef __aarch64__
#define NEXT_IMAGE	"BL31"
#else
#define NEXT_IMAGE	"BL32"
#endif

#if !BL2_AT_EL3
/*******************************************************************************
 * Setup function for BL2.
 ******************************************************************************/
void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
	       u_register_t arg3)
{
	/* Perform early platform-specific setup */
	bl2_early_platform_setup2(arg0, arg1, arg2, arg3);

	/* Perform late platform-specific setup */
	bl2_plat_arch_setup();

#if CTX_INCLUDE_PAUTH_REGS
	/*
	 * Assert that the ARMv8.3-PAuth registers are present or an access
	 * fault will be triggered when they are being saved or restored.
	 */
	assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
}

#else /* if BL2_AT_EL3 */
/*******************************************************************************
 * Setup function for BL2 when BL2_AT_EL3=1.
 ******************************************************************************/
void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
		   u_register_t arg3)
{
	/* Perform early platform-specific setup */
	bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3);

	/* Perform late platform-specific setup */
	bl2_el3_plat_arch_setup();

#if CTX_INCLUDE_PAUTH_REGS
	/*
	 * Assert that the ARMv8.3-PAuth registers are present or an access
	 * fault will be triggered when they are being saved or restored.
	 */
	assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
}
#endif /* BL2_AT_EL3 */

/*******************************************************************************
 * The only thing to do in BL2 is to load further images and pass control to
 * next BL. The memory occupied by BL2 will be reclaimed by BL3x stages. BL2
 * runs entirely in S-EL1.
 ******************************************************************************/
void bl2_main(void)
{
	entry_point_info_t *next_bl_ep_info;

	NOTICE("BL2: %s\n", version_string);
	NOTICE("BL2: %s\n", build_message);

	/* Perform remaining generic architectural setup in S-EL1 */
	bl2_arch_setup();

#if TRUSTED_BOARD_BOOT
	/* Initialize authentication module */
	auth_mod_init();
#endif /* TRUSTED_BOARD_BOOT */

	/* initialize boot source */
	bl2_plat_preload_setup();

	/* Load the subsequent bootloader images. */
	next_bl_ep_info = bl2_load_images();

#if !BL2_AT_EL3
#ifndef __aarch64__
	/*
	 * For AArch32 state BL1 and BL2 share the MMU setup.
	 * Given that BL2 does not map BL1 regions, MMU needs
	 * to be disabled in order to go back to BL1.
	 */
	disable_mmu_icache_secure();
#endif /* !__aarch64__ */

	console_flush();

#if ENABLE_PAUTH
	/*
	 * Disable pointer authentication before running next boot image
	 */
	pauth_disable_el1();
#endif /* ENABLE_PAUTH */

	/*
	 * Run next BL image via an SMC to BL1. Information on how to pass
	 * control to the BL32 (if present) and BL33 software images will
	 * be passed to next BL image as an argument.
	 */
	smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0);
#else /* if BL2_AT_EL3 */
	NOTICE("BL2: Booting " NEXT_IMAGE "\n");
	print_entry_point_info(next_bl_ep_info);
	console_flush();

#if ENABLE_PAUTH
	/*
	 * Disable pointer authentication before running next boot image
	 */
	pauth_disable_el3();
#endif /* ENABLE_PAUTH */

	bl2_run_next_image(next_bl_ep_info);
#endif /* BL2_AT_EL3 */
}