mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
target/arm: Introduce ARMSecuritySpace
Introduce both the enumeration and functions to retrieve the current state, and state outside of EL3. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230620124418.805717-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
ef1febe758
commit
5d28ac0cf7
2 changed files with 127 additions and 22 deletions
|
@ -2414,25 +2414,53 @@ static inline int arm_feature(CPUARMState *env, int feature)
|
||||||
|
|
||||||
void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
|
void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
/*
|
/*
|
||||||
|
* ARM v9 security states.
|
||||||
|
* The ordering of the enumeration corresponds to the low 2 bits
|
||||||
|
* of the GPI value, and (except for Root) the concat of NSE:NS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum ARMSecuritySpace {
|
||||||
|
ARMSS_Secure = 0,
|
||||||
|
ARMSS_NonSecure = 1,
|
||||||
|
ARMSS_Root = 2,
|
||||||
|
ARMSS_Realm = 3,
|
||||||
|
} ARMSecuritySpace;
|
||||||
|
|
||||||
|
/* Return true if @space is secure, in the pre-v9 sense. */
|
||||||
|
static inline bool arm_space_is_secure(ARMSecuritySpace space)
|
||||||
|
{
|
||||||
|
return space == ARMSS_Secure || space == ARMSS_Root;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the ARMSecuritySpace for @secure, assuming !RME or EL[0-2]. */
|
||||||
|
static inline ARMSecuritySpace arm_secure_to_space(bool secure)
|
||||||
|
{
|
||||||
|
return secure ? ARMSS_Secure : ARMSS_NonSecure;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
/**
|
||||||
|
* arm_security_space_below_el3:
|
||||||
|
* @env: cpu context
|
||||||
|
*
|
||||||
|
* Return the security space of exception levels below EL3, following
|
||||||
|
* an exception return to those levels. Unlike arm_security_space,
|
||||||
|
* this doesn't care about the current EL.
|
||||||
|
*/
|
||||||
|
ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* arm_is_secure_below_el3:
|
||||||
|
* @env: cpu context
|
||||||
|
*
|
||||||
* Return true if exception levels below EL3 are in secure state,
|
* Return true if exception levels below EL3 are in secure state,
|
||||||
* or would be following an exception return to that level.
|
* or would be following an exception return to those levels.
|
||||||
* Unlike arm_is_secure() (which is always a question about the
|
|
||||||
* _current_ state of the CPU) this doesn't care about the current
|
|
||||||
* EL or mode.
|
|
||||||
*/
|
*/
|
||||||
static inline bool arm_is_secure_below_el3(CPUARMState *env)
|
static inline bool arm_is_secure_below_el3(CPUARMState *env)
|
||||||
{
|
{
|
||||||
assert(!arm_feature(env, ARM_FEATURE_M));
|
ARMSecuritySpace ss = arm_security_space_below_el3(env);
|
||||||
if (arm_feature(env, ARM_FEATURE_EL3)) {
|
return ss == ARMSS_Secure;
|
||||||
return !(env->cp15.scr_el3 & SCR_NS);
|
|
||||||
} else {
|
|
||||||
/* If EL3 is not supported then the secure state is implementation
|
|
||||||
* defined, in which case QEMU defaults to non-secure.
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if the CPU is AArch64 EL3 or AArch32 Mon */
|
/* Return true if the CPU is AArch64 EL3 or AArch32 Mon */
|
||||||
|
@ -2452,16 +2480,23 @@ static inline bool arm_is_el3_or_mon(CPUARMState *env)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if the processor is in secure state */
|
/**
|
||||||
|
* arm_security_space:
|
||||||
|
* @env: cpu context
|
||||||
|
*
|
||||||
|
* Return the current security space of the cpu.
|
||||||
|
*/
|
||||||
|
ARMSecuritySpace arm_security_space(CPUARMState *env);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* arm_is_secure:
|
||||||
|
* @env: cpu context
|
||||||
|
*
|
||||||
|
* Return true if the processor is in secure state.
|
||||||
|
*/
|
||||||
static inline bool arm_is_secure(CPUARMState *env)
|
static inline bool arm_is_secure(CPUARMState *env)
|
||||||
{
|
{
|
||||||
if (arm_feature(env, ARM_FEATURE_M)) {
|
return arm_space_is_secure(arm_security_space(env));
|
||||||
return env->v7m.secure;
|
|
||||||
}
|
|
||||||
if (arm_is_el3_or_mon(env)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return arm_is_secure_below_el3(env);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2480,11 +2515,21 @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
static inline ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
|
||||||
|
{
|
||||||
|
return ARMSS_NonSecure;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool arm_is_secure_below_el3(CPUARMState *env)
|
static inline bool arm_is_secure_below_el3(CPUARMState *env)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ARMSecuritySpace arm_security_space(CPUARMState *env)
|
||||||
|
{
|
||||||
|
return ARMSS_NonSecure;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool arm_is_secure(CPUARMState *env)
|
static inline bool arm_is_secure(CPUARMState *env)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -12136,3 +12136,63 @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
ARMSecuritySpace arm_security_space(CPUARMState *env)
|
||||||
|
{
|
||||||
|
if (arm_feature(env, ARM_FEATURE_M)) {
|
||||||
|
return arm_secure_to_space(env->v7m.secure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If EL3 is not supported then the secure state is implementation
|
||||||
|
* defined, in which case QEMU defaults to non-secure.
|
||||||
|
*/
|
||||||
|
if (!arm_feature(env, ARM_FEATURE_EL3)) {
|
||||||
|
return ARMSS_NonSecure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for AArch64 EL3 or AArch32 Mon. */
|
||||||
|
if (is_a64(env)) {
|
||||||
|
if (extract32(env->pstate, 2, 2) == 3) {
|
||||||
|
if (cpu_isar_feature(aa64_rme, env_archcpu(env))) {
|
||||||
|
return ARMSS_Root;
|
||||||
|
} else {
|
||||||
|
return ARMSS_Secure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
|
||||||
|
return ARMSS_Secure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return arm_security_space_below_el3(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
|
||||||
|
{
|
||||||
|
assert(!arm_feature(env, ARM_FEATURE_M));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If EL3 is not supported then the secure state is implementation
|
||||||
|
* defined, in which case QEMU defaults to non-secure.
|
||||||
|
*/
|
||||||
|
if (!arm_feature(env, ARM_FEATURE_EL3)) {
|
||||||
|
return ARMSS_NonSecure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note NSE cannot be set without RME, and NSE & !NS is Reserved.
|
||||||
|
* Ignoring NSE when !NS retains consistency without having to
|
||||||
|
* modify other predicates.
|
||||||
|
*/
|
||||||
|
if (!(env->cp15.scr_el3 & SCR_NS)) {
|
||||||
|
return ARMSS_Secure;
|
||||||
|
} else if (env->cp15.scr_el3 & SCR_NSE) {
|
||||||
|
return ARMSS_Realm;
|
||||||
|
} else {
|
||||||
|
return ARMSS_NonSecure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_USER_ONLY */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue