arm-trusted-firmware/include/bl31/sync_handle.h
Manish Pandey 3c789bfccc feat(el3-runtime): introduce UNDEF injection to lower EL
For a feature to be used at lower ELs, EL3 generally needs to disable
the trap so that lower ELs can access the system registers associated
with the feature. Lower ELs generally check ID registers to dynamically
detect if a feature is present (in HW) or not while EL3 Firmware relies
statically on feature build macros to enable a feature.

If a lower EL accesses a system register for a feature that EL3 FW is
unaware of, EL3 traps the access and panics. This happens mostly with
EL2 but sometimes VMs can also cause EL3 panic.

To provide platforms with capability to mitigate this problem, UNDEF
injection support has been introduced which injects a synchronous
exception into the lower EL which is supposed to handle the
synchronous exception.

The current support is only provided for aarch64.

The implementation does the following on encountering sys reg trap

 - Get the target EL, which can be either EL2 or EL1
 - Update ELR_ELx with ELR_EL3, so that after UNDEF handling in lower EL
   control returns to original location.
 - ESR_ELx with EC_UNKNOWN
 - Update ELR_EL3 with vector address of sync exception handler with
   following possible causes
     - Current EL with SP0
     - Current EL with SPx
     - Lower EL using AArch64
 - Re-create SPSR_EL3 which will be used to generate PSTATE at ERET

Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
Change-Id: I1b7bf6c043ce7aec1ee4fc1121c389b490b7bfb7
2024-02-28 12:47:29 +00:00

67 lines
2.2 KiB
C

/*
* Copyright (c) 2022, ARM Limited. All rights reserved.
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef TRAP_HANDLE_H
#define TRAP_HANDLE_H
#include <stdbool.h>
#include <context.h>
#define ISS_SYSREG_OPCODE_MASK 0x3ffc1eUL
#define ISS_SYSREG_REG_MASK 0x0003e0UL
#define ISS_SYSREG_REG_SHIFT 5U
#define ISS_SYSREG_DIRECTION_MASK 0x000001UL
#define ISS_SYSREG_OPCODE_RNDR 0x30c808U
#define ISS_SYSREG_OPCODE_IMPDEF 0x303c00U
#define ISS_SYSREG_OPCODE_RNDRRS 0x32c808U
#define TRAP_RET_UNHANDLED -1
#define TRAP_RET_REPEAT 0
#define TRAP_RET_CONTINUE 1
#ifndef __ASSEMBLER__
static inline unsigned int get_sysreg_iss_rt(uint64_t esr)
{
return (esr & ISS_SYSREG_REG_MASK) >> ISS_SYSREG_REG_SHIFT;
}
static inline bool is_sysreg_iss_write(uint64_t esr)
{
return !(esr & ISS_SYSREG_DIRECTION_MASK);
}
/**
* handle_sysreg_trap() - Handle AArch64 system register traps from lower ELs
* @esr_el3: The content of ESR_EL3, containing the trap syndrome information
* @ctx: Pointer to the lower EL context, containing saved registers
*
* Called by the exception handler when a synchronous trap identifies as a
* system register trap (EC=0x18). ESR contains the encoding of the op[x] and
* CRm/CRn fields, to identify the system register, and the target/source
* GPR plus the direction (MRS/MSR). The lower EL's context can be altered
* by the function, to inject back the result of the emulation.
*
* Return: indication how to proceed with the trap:
* TRAP_RET_UNHANDLED(-1): trap is unhandled, trigger panic
* TRAP_RET_REPEAT(0): trap was handled, return to the trapping instruction
* (repeating it)
* TRAP_RET_CONTINUE(1): trap was handled, return to the next instruction
* (continuing after it)
*/
int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx);
/* Handler for injecting UNDEF exception to lower EL */
void inject_undef64(cpu_context_t *ctx);
/* Prototypes for system register emulation handlers provided by platforms. */
int plat_handle_impdef_trap(uint64_t esr_el3, cpu_context_t *ctx);
int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
#endif /* __ASSEMBLER__ */
#endif