* [PATCHv5 00/19] ARMv8.4-A Secure EL2
@ 2021-01-12 10:44 Rémi Denis-Courmont
2021-01-12 10:44 ` [PATCH 01/19] target/arm: remove redundant tests remi.denis.courmont
` (19 more replies)
0 siblings, 20 replies; 26+ messages in thread
From: Rémi Denis-Courmont @ 2021-01-12 10:44 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
Hi,
This adds Secure EL2.
Changes since version 4:
- Fix NS unitialised in secure state stage 2 translation.
- Remove EEL2 translation block flag in 32-bit mode.
- Clarify comments on arm_is_el2_enabled().
----------------------------------------------------------------
Rémi Denis-Courmont (19):
target/arm: remove redundant tests
target/arm: add arm_is_el2_enabled() helper
target/arm: use arm_is_el2_enabled() where applicable
target/arm: use arm_hcr_el2_eff() where applicable
target/arm: factor MDCR_EL2 common handling
target/arm: declare new AA64PFR0 bit-fields
target/arm: add 64-bit S-EL2 to EL exception table
target/arm: add MMU stage 1 for Secure EL2
target/arm: add ARMv8.4-SEL2 system registers
target/arm: handle VMID change in secure state
target/arm: do S1_ptw_translate() before address space lookup
target/arm: translate NS bit in page-walks
target/arm: generalize 2-stage page-walk condition
target/arm: secure stage 2 translation regime
target/arm: set HPFAR_EL2.NS on secure stage 2 faults
target/arm: revector to run-time pick target EL
target/arm: add ARMv8.4-SEL2 extension
target/arm: enable Secure EL2 in max CPU
target/arm: refactor vae1_tlbmask()
target/arm/cpu-param.h | 2 +-
target/arm/cpu.c | 10 +-
target/arm/cpu.h | 90 ++++++++--
target/arm/cpu64.c | 1 +
target/arm/helper-a64.c | 8 +-
target/arm/helper.c | 414 ++++++++++++++++++++++++++++++---------------
target/arm/internals.h | 36 ++++
target/arm/op_helper.c | 4 +-
target/arm/tlb_helper.c | 3 +
target/arm/translate-a64.c | 4 +
target/arm/translate.c | 35 +++-
11 files changed, 430 insertions(+), 177 deletions(-)
--
雷米‧德尼-库尔蒙
http://www.remlab.net/
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 01/19] target/arm: remove redundant tests
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
@ 2021-01-12 10:44 ` remi.denis.courmont
2021-01-12 10:44 ` [PATCH 02/19] target/arm: add arm_is_el2_enabled() helper remi.denis.courmont
` (18 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:44 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
In this context, the HCR value is the effective value, and thus is
zero in secure mode. The tests for HCR.{F,I}MO are sufficient.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.c | 8 ++++----
target/arm/helper.c | 10 ++++------
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 8387e94b94..5530874686 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -451,14 +451,14 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
break;
case EXCP_VFIQ:
- if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
- /* VFIQs are only taken when hypervized and non-secure. */
+ if (!(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
+ /* VFIQs are only taken when hypervized. */
return false;
}
return !(env->daif & PSTATE_F);
case EXCP_VIRQ:
- if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
- /* VIRQs are only taken when hypervized and non-secure. */
+ if (!(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
+ /* VIRQs are only taken when hypervized. */
return false;
}
return !(env->daif & PSTATE_I);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5ab3f5ace3..dabe1b32bb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2083,13 +2083,11 @@ static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
CPUState *cs = env_cpu(env);
- uint64_t hcr_el2 = arm_hcr_el2_eff(env);
+ bool el1 = arm_current_el(env) == 1;
+ uint64_t hcr_el2 = el1 ? arm_hcr_el2_eff(env) : 0;
uint64_t ret = 0;
- bool allow_virt = (arm_current_el(env) == 1 &&
- (!arm_is_secure_below_el3(env) ||
- (env->cp15.scr_el3 & SCR_EEL2)));
- if (allow_virt && (hcr_el2 & HCR_IMO)) {
+ if (hcr_el2 & HCR_IMO) {
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
ret |= CPSR_I;
}
@@ -2099,7 +2097,7 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
}
}
- if (allow_virt && (hcr_el2 & HCR_FMO)) {
+ if (hcr_el2 & HCR_FMO) {
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
ret |= CPSR_F;
}
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 02/19] target/arm: add arm_is_el2_enabled() helper
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
2021-01-12 10:44 ` [PATCH 01/19] target/arm: remove redundant tests remi.denis.courmont
@ 2021-01-12 10:44 ` remi.denis.courmont
2021-01-12 10:44 ` [PATCH 03/19] target/arm: use arm_is_el2_enabled() where applicable remi.denis.courmont
` (17 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:44 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
This checks if EL2 is enabled (meaning EL2 registers take effects) in
the current security context.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ad37ff61c6..0881e0157d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2072,6 +2072,18 @@ static inline bool arm_is_secure(CPUARMState *env)
return arm_is_secure_below_el3(env);
}
+/*
+ * Return true if the current security state has AArch64 EL2 or AArch32 Hyp.
+ * This corresponds to the pseudocode EL2Enabled()
+ */
+static inline bool arm_is_el2_enabled(CPUARMState *env)
+{
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
+ return !arm_is_secure_below_el3(env);
+ }
+ return false;
+}
+
#else
static inline bool arm_is_secure_below_el3(CPUARMState *env)
{
@@ -2082,6 +2094,11 @@ static inline bool arm_is_secure(CPUARMState *env)
{
return false;
}
+
+static inline bool arm_is_el2_enabled(CPUARMState *env)
+{
+ return false;
+}
#endif
/**
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 03/19] target/arm: use arm_is_el2_enabled() where applicable
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
2021-01-12 10:44 ` [PATCH 01/19] target/arm: remove redundant tests remi.denis.courmont
2021-01-12 10:44 ` [PATCH 02/19] target/arm: add arm_is_el2_enabled() helper remi.denis.courmont
@ 2021-01-12 10:44 ` remi.denis.courmont
2021-01-12 10:44 ` [PATCH 04/19] target/arm: use arm_hcr_el2_eff() " remi.denis.courmont
` (16 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:44 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Do not assume that EL2 is available in and only in non-secure context.
That equivalence is broken by ARMv8.4-SEL2.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 4 ++--
target/arm/helper-a64.c | 8 +-------
target/arm/helper.c | 33 +++++++++++++--------------------
3 files changed, 16 insertions(+), 29 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 0881e0157d..7afa26e08a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2134,7 +2134,7 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
return aa64;
}
- if (arm_feature(env, ARM_FEATURE_EL2) && !arm_is_secure_below_el3(env)) {
+ if (arm_is_el2_enabled(env)) {
aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
}
@@ -3078,7 +3078,7 @@ static inline int arm_debug_target_el(CPUARMState *env)
bool secure = arm_is_secure(env);
bool route_to_el2 = false;
- if (arm_feature(env, ARM_FEATURE_EL2) && !secure) {
+ if (arm_is_el2_enabled(env)) {
route_to_el2 = env->cp15.hcr_el2 & HCR_TGE ||
env->cp15.mdcr_el2 & MDCR_TDE;
}
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
index 30b2ad119f..c426c23d2c 100644
--- a/target/arm/helper-a64.c
+++ b/target/arm/helper-a64.c
@@ -972,8 +972,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
if (new_el == -1) {
goto illegal_return;
}
- if (new_el > cur_el
- || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
+ if (new_el > cur_el || (new_el == 2 && !arm_is_el2_enabled(env))) {
/* Disallow return to an EL which is unimplemented or higher
* than the current one.
*/
@@ -985,11 +984,6 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
goto illegal_return;
}
- if (new_el == 2 && arm_is_secure_below_el3(env)) {
- /* Return to the non-existent secure-EL2 */
- goto illegal_return;
- }
-
if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
goto illegal_return;
}
diff --git a/target/arm/helper.c b/target/arm/helper.c
index dabe1b32bb..26dcafbee1 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1048,8 +1048,8 @@ static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
{
if (arm_feature(env, ARM_FEATURE_V8)) {
/* Check if CPACR accesses are to be trapped to EL2 */
- if (arm_current_el(env) == 1 &&
- (env->cp15.cptr_el[2] & CPTR_TCPAC) && !arm_is_secure(env)) {
+ if (arm_current_el(env) == 1 && arm_is_el2_enabled(env) &&
+ (env->cp15.cptr_el[2] & CPTR_TCPAC)) {
return CP_ACCESS_TRAP_EL2;
/* Check if CPACR accesses are to be trapped to EL3 */
} else if (arm_current_el(env) < 3 &&
@@ -2519,7 +2519,7 @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
bool isread)
{
unsigned int cur_el = arm_current_el(env);
- bool secure = arm_is_secure(env);
+ bool has_el2 = arm_is_el2_enabled(env);
uint64_t hcr = arm_hcr_el2_eff(env);
switch (cur_el) {
@@ -2543,8 +2543,7 @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
}
} else {
/* If HCR_EL2.<E2H> == 0: check CNTHCTL_EL2.EL1PCEN. */
- if (arm_feature(env, ARM_FEATURE_EL2) &&
- timeridx == GTIMER_PHYS && !secure &&
+ if (has_el2 && timeridx == GTIMER_PHYS &&
!extract32(env->cp15.cnthctl_el2, 1, 1)) {
return CP_ACCESS_TRAP_EL2;
}
@@ -2553,8 +2552,7 @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
case 1:
/* Check CNTHCTL_EL2.EL1PCTEN, which changes location based on E2H. */
- if (arm_feature(env, ARM_FEATURE_EL2) &&
- timeridx == GTIMER_PHYS && !secure &&
+ if (has_el2 && timeridx == GTIMER_PHYS &&
(hcr & HCR_E2H
? !extract32(env->cp15.cnthctl_el2, 10, 1)
: !extract32(env->cp15.cnthctl_el2, 0, 1))) {
@@ -2569,7 +2567,7 @@ static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx,
bool isread)
{
unsigned int cur_el = arm_current_el(env);
- bool secure = arm_is_secure(env);
+ bool has_el2 = arm_is_el2_enabled(env);
uint64_t hcr = arm_hcr_el2_eff(env);
switch (cur_el) {
@@ -2590,8 +2588,7 @@ static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx,
/* fall through */
case 1:
- if (arm_feature(env, ARM_FEATURE_EL2) &&
- timeridx == GTIMER_PHYS && !secure) {
+ if (has_el2 && timeridx == GTIMER_PHYS) {
if (hcr & HCR_E2H) {
/* If HCR_EL2.<E2H,TGE> == '10': check CNTHCTL_EL2.EL1PTEN. */
if (!extract32(env->cp15.cnthctl_el2, 11, 1)) {
@@ -4247,11 +4244,9 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- ARMCPU *cpu = env_archcpu(env);
unsigned int cur_el = arm_current_el(env);
- bool secure = arm_is_secure(env);
- if (arm_feature(&cpu->env, ARM_FEATURE_EL2) && !secure && cur_el == 1) {
+ if (arm_is_el2_enabled(env) && cur_el == 1) {
return env->cp15.vpidr_el2;
}
return raw_read(env, ri);
@@ -4278,9 +4273,8 @@ static uint64_t mpidr_read_val(CPUARMState *env)
static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
unsigned int cur_el = arm_current_el(env);
- bool secure = arm_is_secure(env);
- if (arm_feature(env, ARM_FEATURE_EL2) && !secure && cur_el == 1) {
+ if (arm_is_el2_enabled(env) && cur_el == 1) {
return env->cp15.vmpidr_el2;
}
return mpidr_read_val(env);
@@ -5347,7 +5341,7 @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
{
uint64_t ret = env->cp15.hcr_el2;
- if (arm_is_secure_below_el3(env)) {
+ if (!arm_is_el2_enabled(env)) {
/*
* "This register has no effect if EL2 is not enabled in the
* current Security state". This is ARMv8.4-SecEL2 speak for
@@ -6144,7 +6138,7 @@ int sve_exception_el(CPUARMState *env, int el)
/* CPTR_EL2. Since TZ and TFP are positive,
* they will be zero when EL2 is not present.
*/
- if (el <= 2 && !arm_is_secure_below_el3(env)) {
+ if (el <= 2 && arm_is_el2_enabled(env)) {
if (env->cp15.cptr_el[2] & CPTR_TZ) {
return 2;
}
@@ -8719,8 +8713,7 @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
}
return 0;
case ARM_CPU_MODE_HYP:
- return !arm_feature(env, ARM_FEATURE_EL2)
- || arm_current_el(env) < 2 || arm_is_secure_below_el3(env);
+ return !arm_is_el2_enabled(env) || arm_current_el(env) < 2;
case ARM_CPU_MODE_MON:
return arm_current_el(env) < 3;
default:
@@ -12646,7 +12639,7 @@ int fp_exception_el(CPUARMState *env, int cur_el)
/* CPTR_EL2 : present in v7VE or v8 */
if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
- && !arm_is_secure_below_el3(env)) {
+ && arm_is_el2_enabled(env)) {
/* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */
return 2;
}
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 04/19] target/arm: use arm_hcr_el2_eff() where applicable
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (2 preceding siblings ...)
2021-01-12 10:44 ` [PATCH 03/19] target/arm: use arm_is_el2_enabled() where applicable remi.denis.courmont
@ 2021-01-12 10:44 ` remi.denis.courmont
2021-01-12 10:44 ` [PATCH 05/19] target/arm: factor MDCR_EL2 common handling remi.denis.courmont
` (15 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:44 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
This will simplify accessing HCR conditionally in secure state.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 26dcafbee1..2676d227bb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4432,16 +4432,16 @@ static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env,
static int vae1_tlbmask(CPUARMState *env)
{
- /* Since we exclude secure first, we may read HCR_EL2 directly. */
- if (arm_is_secure_below_el3(env)) {
- return ARMMMUIdxBit_SE10_1 |
- ARMMMUIdxBit_SE10_1_PAN |
- ARMMMUIdxBit_SE10_0;
- } else if ((env->cp15.hcr_el2 & (HCR_E2H | HCR_TGE))
- == (HCR_E2H | HCR_TGE)) {
+ uint64_t hcr = arm_hcr_el2_eff(env);
+
+ if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
return ARMMMUIdxBit_E20_2 |
ARMMMUIdxBit_E20_2_PAN |
ARMMMUIdxBit_E20_0;
+ } else if (arm_is_secure_below_el3(env)) {
+ return ARMMMUIdxBit_SE10_1 |
+ ARMMMUIdxBit_SE10_1_PAN |
+ ARMMMUIdxBit_SE10_0;
} else {
return ARMMMUIdxBit_E10_1 |
ARMMMUIdxBit_E10_1_PAN |
@@ -9964,6 +9964,8 @@ static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
static inline bool regime_translation_disabled(CPUARMState *env,
ARMMMUIdx mmu_idx)
{
+ uint64_t hcr_el2;
+
if (arm_feature(env, ARM_FEATURE_M)) {
switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
@@ -9982,19 +9984,21 @@ static inline bool regime_translation_disabled(CPUARMState *env,
}
}
+ hcr_el2 = arm_hcr_el2_eff(env);
+
if (mmu_idx == ARMMMUIdx_Stage2) {
/* HCR.DC means HCR.VM behaves as 1 */
- return (env->cp15.hcr_el2 & (HCR_DC | HCR_VM)) == 0;
+ return (hcr_el2 & (HCR_DC | HCR_VM)) == 0;
}
- if (env->cp15.hcr_el2 & HCR_TGE) {
+ if (hcr_el2 & HCR_TGE) {
/* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
if (!regime_is_secure(env, mmu_idx) && regime_el(env, mmu_idx) == 1) {
return true;
}
}
- if ((env->cp15.hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
+ if ((hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
/* HCR.DC means SCTLR_EL1.M behaves as 0 */
return true;
}
@@ -10345,7 +10349,8 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
fi->s1ptw = true;
return ~0;
}
- if ((env->cp15.hcr_el2 & HCR_PTW) && (cacheattrs.attrs & 0xf0) == 0) {
+ if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
+ (cacheattrs.attrs & 0xf0) == 0) {
/*
* PTW set and S1 walk touched S2 Device memory:
* generate Permission fault.
@@ -10778,7 +10783,7 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
uint8_t hihint = 0, lohint = 0;
if (hiattr != 0) { /* normal memory */
- if ((env->cp15.hcr_el2 & HCR_CD) != 0) { /* cache disabled */
+ if (arm_hcr_el2_eff(env) & HCR_CD) { /* cache disabled */
hiattr = loattr = 1; /* non-cacheable */
} else {
if (hiattr != 1) { /* Write-through or write-back */
@@ -12111,7 +12116,7 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
}
/* Combine the S1 and S2 cache attributes. */
- if (env->cp15.hcr_el2 & HCR_DC) {
+ if (arm_hcr_el2_eff(env) & HCR_DC) {
/*
* HCR.DC forces the first stage attributes to
* Normal Non-Shareable,
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 05/19] target/arm: factor MDCR_EL2 common handling
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (3 preceding siblings ...)
2021-01-12 10:44 ` [PATCH 04/19] target/arm: use arm_hcr_el2_eff() " remi.denis.courmont
@ 2021-01-12 10:44 ` remi.denis.courmont
2021-01-12 10:44 ` [PATCH 06/19] target/arm: declare new AA64PFR0 bit-fields remi.denis.courmont
` (14 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:44 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
This adds a common helper to compute the effective value of MDCR_EL2.
That is the actual value if EL2 is enabled in the current security
context, or 0 elsewise.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 38 ++++++++++++++++++++++----------------
1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2676d227bb..7860ccd7ae 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -538,6 +538,11 @@ static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
return CP_ACCESS_TRAP_UNCATEGORIZED;
}
+static uint64_t arm_mdcr_el2_eff(CPUARMState *env)
+{
+ return arm_is_el2_enabled(env) ? env->cp15.mdcr_el2 : 0;
+}
+
/* Check for traps to "powerdown debug" registers, which are controlled
* by MDCR.TDOSA
*/
@@ -545,11 +550,11 @@ static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
int el = arm_current_el(env);
- bool mdcr_el2_tdosa = (env->cp15.mdcr_el2 & MDCR_TDOSA) ||
- (env->cp15.mdcr_el2 & MDCR_TDE) ||
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
+ bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) ||
(arm_hcr_el2_eff(env) & HCR_TGE);
- if (el < 2 && mdcr_el2_tdosa && !arm_is_secure_below_el3(env)) {
+ if (el < 2 && mdcr_el2_tdosa) {
return CP_ACCESS_TRAP_EL2;
}
if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) {
@@ -565,11 +570,11 @@ static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
int el = arm_current_el(env);
- bool mdcr_el2_tdra = (env->cp15.mdcr_el2 & MDCR_TDRA) ||
- (env->cp15.mdcr_el2 & MDCR_TDE) ||
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
+ bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) ||
(arm_hcr_el2_eff(env) & HCR_TGE);
- if (el < 2 && mdcr_el2_tdra && !arm_is_secure_below_el3(env)) {
+ if (el < 2 && mdcr_el2_tdra) {
return CP_ACCESS_TRAP_EL2;
}
if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
@@ -585,11 +590,11 @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
int el = arm_current_el(env);
- bool mdcr_el2_tda = (env->cp15.mdcr_el2 & MDCR_TDA) ||
- (env->cp15.mdcr_el2 & MDCR_TDE) ||
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
+ bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
(arm_hcr_el2_eff(env) & HCR_TGE);
- if (el < 2 && mdcr_el2_tda && !arm_is_secure_below_el3(env)) {
+ if (el < 2 && mdcr_el2_tda) {
return CP_ACCESS_TRAP_EL2;
}
if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
@@ -605,9 +610,9 @@ static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
int el = arm_current_el(env);
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
- if (el < 2 && (env->cp15.mdcr_el2 & MDCR_TPM)
- && !arm_is_secure_below_el3(env)) {
+ if (el < 2 && (mdcr_el2 & MDCR_TPM)) {
return CP_ACCESS_TRAP_EL2;
}
if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
@@ -1347,12 +1352,12 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
* trapping to EL2 or EL3 for other accesses.
*/
int el = arm_current_el(env);
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
if (el == 0 && !(env->cp15.c9_pmuserenr & 1)) {
return CP_ACCESS_TRAP;
}
- if (el < 2 && (env->cp15.mdcr_el2 & MDCR_TPM)
- && !arm_is_secure_below_el3(env)) {
+ if (el < 2 && (mdcr_el2 & MDCR_TPM)) {
return CP_ACCESS_TRAP_EL2;
}
if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
@@ -1431,7 +1436,8 @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
bool enabled, prohibited, filtered;
bool secure = arm_is_secure(env);
int el = arm_current_el(env);
- uint8_t hpmn = env->cp15.mdcr_el2 & MDCR_HPMN;
+ uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
+ uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
if (!arm_feature(env, ARM_FEATURE_PMU)) {
return false;
@@ -1441,13 +1447,13 @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
(counter < hpmn || counter == 31)) {
e = env->cp15.c9_pmcr & PMCRE;
} else {
- e = env->cp15.mdcr_el2 & MDCR_HPME;
+ e = mdcr_el2 & MDCR_HPME;
}
enabled = e && (env->cp15.c9_pmcnten & (1 << counter));
if (!secure) {
if (el == 2 && (counter < hpmn || counter == 31)) {
- prohibited = env->cp15.mdcr_el2 & MDCR_HPMD;
+ prohibited = mdcr_el2 & MDCR_HPMD;
} else {
prohibited = false;
}
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 06/19] target/arm: declare new AA64PFR0 bit-fields
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (4 preceding siblings ...)
2021-01-12 10:44 ` [PATCH 05/19] target/arm: factor MDCR_EL2 common handling remi.denis.courmont
@ 2021-01-12 10:44 ` remi.denis.courmont
2021-01-12 10:44 ` [PATCH 07/19] target/arm: add 64-bit S-EL2 to EL exception table remi.denis.courmont
` (13 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:44 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 7afa26e08a..fecdd642c9 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1881,6 +1881,12 @@ FIELD(ID_AA64PFR0, ADVSIMD, 20, 4)
FIELD(ID_AA64PFR0, GIC, 24, 4)
FIELD(ID_AA64PFR0, RAS, 28, 4)
FIELD(ID_AA64PFR0, SVE, 32, 4)
+FIELD(ID_AA64PFR0, SEL2, 36, 4)
+FIELD(ID_AA64PFR0, MPAM, 40, 4)
+FIELD(ID_AA64PFR0, AMU, 44, 4)
+FIELD(ID_AA64PFR0, DIT, 48, 4)
+FIELD(ID_AA64PFR0, CSV2, 56, 4)
+FIELD(ID_AA64PFR0, CSV3, 60, 4)
FIELD(ID_AA64PFR1, BT, 0, 4)
FIELD(ID_AA64PFR1, SBSS, 4, 4)
@@ -3928,6 +3934,11 @@ static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
}
+static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
+}
+
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 07/19] target/arm: add 64-bit S-EL2 to EL exception table
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (5 preceding siblings ...)
2021-01-12 10:44 ` [PATCH 06/19] target/arm: declare new AA64PFR0 bit-fields remi.denis.courmont
@ 2021-01-12 10:44 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 08/19] target/arm: add MMU stage 1 for Secure EL2 remi.denis.courmont
` (12 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:44 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
With the ARMv8.4-SEL2 extension, EL2 is a legal exception level in
secure mode, though it can only be AArch64.
This patch adds the target EL for exceptions from 64-bit S-EL2.
It also fixes the target EL to EL2 when HCR.{A,F,I}MO are set in secure
mode. Those values were never used in practice as the effective value of
HCR was always 0 in secure mode.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 10 +++++-----
target/arm/op_helper.c | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7860ccd7ae..bc228e070f 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9001,13 +9001,13 @@ static const int8_t target_el_table[2][2][2][2][2][4] = {
{{/* 0 1 1 0 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
{/* 0 1 1 1 */{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},},},
{{{{/* 1 0 0 0 */{ 1, 1, 2, -1 },{ 1, 1, -1, 1 },},
- {/* 1 0 0 1 */{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},},
- {{/* 1 0 1 0 */{ 1, 1, 1, -1 },{ 1, 1, -1, 1 },},
- {/* 1 0 1 1 */{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},},},
+ {/* 1 0 0 1 */{ 2, 2, 2, -1 },{ 2, 2, -1, 1 },},},
+ {{/* 1 0 1 0 */{ 1, 1, 1, -1 },{ 1, 1, 1, 1 },},
+ {/* 1 0 1 1 */{ 2, 2, 2, -1 },{ 2, 2, 2, 1 },},},},
{{{/* 1 1 0 0 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},
{/* 1 1 0 1 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},
- {{/* 1 1 1 0 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},
- {/* 1 1 1 1 */{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},},},
+ {{/* 1 1 1 0 */{ 3, 3, 3, -1 },{ 3, 3, 3, 3 },},
+ {/* 1 1 1 1 */{ 3, 3, 3, -1 },{ 3, 3, 3, 3 },},},},},
};
/*
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index ff91fe6121..5e0f123043 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -652,10 +652,10 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
target_el = exception_target_el(env);
break;
case CP_ACCESS_TRAP_EL2:
- /* Requesting a trap to EL2 when we're in EL3 or S-EL0/1 is
+ /* Requesting a trap to EL2 when we're in EL3 is
* a bug in the access function.
*/
- assert(!arm_is_secure(env) && arm_current_el(env) != 3);
+ assert(arm_current_el(env) != 3);
target_el = 2;
break;
case CP_ACCESS_TRAP_EL3:
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 08/19] target/arm: add MMU stage 1 for Secure EL2
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (6 preceding siblings ...)
2021-01-12 10:44 ` [PATCH 07/19] target/arm: add 64-bit S-EL2 to EL exception table remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 09/19] target/arm: add ARMv8.4-SEL2 system registers remi.denis.courmont
` (11 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
This adds the MMU indices for EL2 stage 1 in secure state.
To keep code contained, which is largelly identical between secure and
non-secure modes, the MMU indices are reassigned. The new assignments
provide a systematic pattern with a non-secure bit.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu-param.h | 2 +-
target/arm/cpu.h | 37 +++++++----
target/arm/helper.c | 127 ++++++++++++++++++++++++-------------
target/arm/internals.h | 12 ++++
target/arm/translate-a64.c | 4 ++
5 files changed, 124 insertions(+), 58 deletions(-)
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index 6321385b46..00e7d9e937 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -29,6 +29,6 @@
# define TARGET_PAGE_BITS_MIN 10
#endif
-#define NB_MMU_MODES 11
+#define NB_MMU_MODES 15
#endif
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index fecdd642c9..085dc9cc54 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2979,6 +2979,9 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
#define ARM_MMU_IDX_M 0x40 /* M profile */
+/* Meanings of the bits for A profile mmu idx values */
+#define ARM_MMU_IDX_A_NS 0x8
+
/* Meanings of the bits for M profile mmu idx values */
#define ARM_MMU_IDX_M_PRIV 0x1
#define ARM_MMU_IDX_M_NEGPRI 0x2
@@ -2992,20 +2995,22 @@ typedef enum ARMMMUIdx {
/*
* A-profile.
*/
- ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A,
- ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A,
-
- ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A,
- ARMMMUIdx_E10_1_PAN = 3 | ARM_MMU_IDX_A,
-
- ARMMMUIdx_E2 = 4 | ARM_MMU_IDX_A,
- ARMMMUIdx_E20_2 = 5 | ARM_MMU_IDX_A,
- ARMMMUIdx_E20_2_PAN = 6 | ARM_MMU_IDX_A,
-
- ARMMMUIdx_SE10_0 = 7 | ARM_MMU_IDX_A,
- ARMMMUIdx_SE10_1 = 8 | ARM_MMU_IDX_A,
- ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
- ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
+ ARMMMUIdx_SE10_0 = 0 | ARM_MMU_IDX_A,
+ ARMMMUIdx_SE20_0 = 1 | ARM_MMU_IDX_A,
+ ARMMMUIdx_SE10_1 = 2 | ARM_MMU_IDX_A,
+ ARMMMUIdx_SE20_2 = 3 | ARM_MMU_IDX_A,
+ ARMMMUIdx_SE10_1_PAN = 4 | ARM_MMU_IDX_A,
+ ARMMMUIdx_SE20_2_PAN = 5 | ARM_MMU_IDX_A,
+ ARMMMUIdx_SE2 = 6 | ARM_MMU_IDX_A,
+ ARMMMUIdx_SE3 = 7 | ARM_MMU_IDX_A,
+
+ ARMMMUIdx_E10_0 = ARMMMUIdx_SE10_0 | ARM_MMU_IDX_A_NS,
+ ARMMMUIdx_E20_0 = ARMMMUIdx_SE20_0 | ARM_MMU_IDX_A_NS,
+ ARMMMUIdx_E10_1 = ARMMMUIdx_SE10_1 | ARM_MMU_IDX_A_NS,
+ ARMMMUIdx_E20_2 = ARMMMUIdx_SE20_2 | ARM_MMU_IDX_A_NS,
+ ARMMMUIdx_E10_1_PAN = ARMMMUIdx_SE10_1_PAN | ARM_MMU_IDX_A_NS,
+ ARMMMUIdx_E20_2_PAN = ARMMMUIdx_SE20_2_PAN | ARM_MMU_IDX_A_NS,
+ ARMMMUIdx_E2 = ARMMMUIdx_SE2 | ARM_MMU_IDX_A_NS,
/*
* These are not allocated TLBs and are used only for AT system
@@ -3052,8 +3057,12 @@ typedef enum ARMMMUIdxBit {
TO_CORE_BIT(E20_2),
TO_CORE_BIT(E20_2_PAN),
TO_CORE_BIT(SE10_0),
+ TO_CORE_BIT(SE20_0),
TO_CORE_BIT(SE10_1),
+ TO_CORE_BIT(SE20_2),
TO_CORE_BIT(SE10_1_PAN),
+ TO_CORE_BIT(SE20_2_PAN),
+ TO_CORE_BIT(SE2),
TO_CORE_BIT(SE3),
TO_CORE_BIT(MUser),
diff --git a/target/arm/helper.c b/target/arm/helper.c
index bc228e070f..fde95cb97e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2861,6 +2861,9 @@ static int gt_phys_redir_timeridx(CPUARMState *env)
case ARMMMUIdx_E20_0:
case ARMMMUIdx_E20_2:
case ARMMMUIdx_E20_2_PAN:
+ case ARMMMUIdx_SE20_0:
+ case ARMMMUIdx_SE20_2:
+ case ARMMMUIdx_SE20_2_PAN:
return GTIMER_HYP;
default:
return GTIMER_PHYS;
@@ -2873,6 +2876,9 @@ static int gt_virt_redir_timeridx(CPUARMState *env)
case ARMMMUIdx_E20_0:
case ARMMMUIdx_E20_2:
case ARMMMUIdx_E20_2_PAN:
+ case ARMMMUIdx_SE20_0:
+ case ARMMMUIdx_SE20_2:
+ case ARMMMUIdx_SE20_2_PAN:
return GTIMER_HYPVIRT;
default:
return GTIMER_VIRT;
@@ -3576,7 +3582,7 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
mmu_idx = ARMMMUIdx_SE3;
break;
case 2:
- g_assert(!secure); /* TODO: ARMv8.4-SecEL2 */
+ g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
/* fall through */
case 1:
if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
@@ -3672,7 +3678,7 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
}
break;
case 4: /* AT S1E2R, AT S1E2W */
- mmu_idx = ARMMMUIdx_E2;
+ mmu_idx = secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2;
break;
case 6: /* AT S1E3R, AT S1E3W */
mmu_idx = ARMMMUIdx_SE3;
@@ -3987,10 +3993,15 @@ static void vmsa_tcr_ttbr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
*/
if (extract64(raw_read(env, ri) ^ value, 48, 16) &&
(arm_hcr_el2_eff(env) & HCR_E2H)) {
- tlb_flush_by_mmuidx(env_cpu(env),
- ARMMMUIdxBit_E20_2 |
- ARMMMUIdxBit_E20_2_PAN |
- ARMMMUIdxBit_E20_0);
+ uint16_t mask = ARMMMUIdxBit_E20_2 |
+ ARMMMUIdxBit_E20_2_PAN |
+ ARMMMUIdxBit_E20_0;
+
+ if (arm_is_secure_below_el3(env)) {
+ mask >>= ARM_MMU_IDX_A_NS;
+ }
+
+ tlb_flush_by_mmuidx(env_cpu(env), mask);
}
raw_write(env, ri, value);
}
@@ -4441,9 +4452,15 @@ static int vae1_tlbmask(CPUARMState *env)
uint64_t hcr = arm_hcr_el2_eff(env);
if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
- return ARMMMUIdxBit_E20_2 |
- ARMMMUIdxBit_E20_2_PAN |
- ARMMMUIdxBit_E20_0;
+ uint16_t mask = ARMMMUIdxBit_E20_2 |
+ ARMMMUIdxBit_E20_2_PAN |
+ ARMMMUIdxBit_E20_0;
+
+ if (arm_is_secure_below_el3(env)) {
+ mask >>= ARM_MMU_IDX_A_NS;
+ }
+
+ return mask;
} else if (arm_is_secure_below_el3(env)) {
return ARMMMUIdxBit_SE10_1 |
ARMMMUIdxBit_SE10_1_PAN |
@@ -4468,17 +4485,20 @@ static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
{
+ uint64_t hcr = arm_hcr_el2_eff(env);
ARMMMUIdx mmu_idx;
/* Only the regime of the mmu_idx below is significant. */
- if (arm_is_secure_below_el3(env)) {
- mmu_idx = ARMMMUIdx_SE10_0;
- } else if ((env->cp15.hcr_el2 & (HCR_E2H | HCR_TGE))
- == (HCR_E2H | HCR_TGE)) {
+ if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
mmu_idx = ARMMMUIdx_E20_0;
} else {
mmu_idx = ARMMMUIdx_E10_0;
}
+
+ if (arm_is_secure_below_el3(env)) {
+ mmu_idx &= ~ARM_MMU_IDX_A_NS;
+ }
+
return tlbbits_for_regime(env, mmu_idx, addr);
}
@@ -4524,11 +4544,17 @@ static int alle1_tlbmask(CPUARMState *env)
static int e2_tlbmask(CPUARMState *env)
{
- /* TODO: ARMv8.4-SecEL2 */
- return ARMMMUIdxBit_E20_0 |
- ARMMMUIdxBit_E20_2 |
- ARMMMUIdxBit_E20_2_PAN |
- ARMMMUIdxBit_E2;
+ if (arm_is_secure_below_el3(env)) {
+ return ARMMMUIdxBit_SE20_0 |
+ ARMMMUIdxBit_SE20_2 |
+ ARMMMUIdxBit_SE20_2_PAN |
+ ARMMMUIdxBit_SE2;
+ } else {
+ return ARMMMUIdxBit_E20_0 |
+ ARMMMUIdxBit_E20_2 |
+ ARMMMUIdxBit_E20_2_PAN |
+ ARMMMUIdxBit_E2;
+ }
}
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -4648,10 +4674,12 @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
{
CPUState *cs = env_cpu(env);
uint64_t pageaddr = sextract64(value << 12, 0, 56);
- int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
+ bool secure = arm_is_secure_below_el3(env);
+ int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
+ int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
+ pageaddr);
- tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
- ARMMMUIdxBit_E2, bits);
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
}
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -9953,7 +9981,8 @@ uint64_t arm_sctlr(CPUARMState *env, int el)
/* Only EL0 needs to be adjusted for EL1&0 or EL2&0. */
if (el == 0) {
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
- el = (mmu_idx == ARMMMUIdx_E20_0 ? 2 : 1);
+ el = (mmu_idx == ARMMMUIdx_E20_0 || mmu_idx == ARMMMUIdx_SE20_0)
+ ? 2 : 1;
}
return env->cp15.sctlr_el[el];
}
@@ -10082,6 +10111,7 @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
switch (mmu_idx) {
case ARMMMUIdx_SE10_0:
case ARMMMUIdx_E20_0:
+ case ARMMMUIdx_SE20_0:
case ARMMMUIdx_Stage1_E0:
case ARMMMUIdx_MUser:
case ARMMMUIdx_MSUser:
@@ -12675,6 +12705,7 @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
case ARMMMUIdx_E10_0:
case ARMMMUIdx_E20_0:
case ARMMMUIdx_SE10_0:
+ case ARMMMUIdx_SE20_0:
return 0;
case ARMMMUIdx_E10_1:
case ARMMMUIdx_E10_1_PAN:
@@ -12684,6 +12715,9 @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
case ARMMMUIdx_E2:
case ARMMMUIdx_E20_2:
case ARMMMUIdx_E20_2_PAN:
+ case ARMMMUIdx_SE2:
+ case ARMMMUIdx_SE20_2:
+ case ARMMMUIdx_SE20_2_PAN:
return 2;
case ARMMMUIdx_SE3:
return 3;
@@ -12701,6 +12735,9 @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
{
+ ARMMMUIdx idx;
+ uint64_t hcr;
+
if (arm_feature(env, ARM_FEATURE_M)) {
return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
}
@@ -12708,40 +12745,43 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
/* See ARM pseudo-function ELIsInHost. */
switch (el) {
case 0:
- if (arm_is_secure_below_el3(env)) {
- return ARMMMUIdx_SE10_0;
- }
- if ((env->cp15.hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)
- && arm_el_is_aa64(env, 2)) {
- return ARMMMUIdx_E20_0;
+ hcr = arm_hcr_el2_eff(env);
+ if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
+ idx = ARMMMUIdx_E20_0;
+ } else {
+ idx = ARMMMUIdx_E10_0;
}
- return ARMMMUIdx_E10_0;
+ break;
case 1:
- if (arm_is_secure_below_el3(env)) {
- if (env->pstate & PSTATE_PAN) {
- return ARMMMUIdx_SE10_1_PAN;
- }
- return ARMMMUIdx_SE10_1;
- }
if (env->pstate & PSTATE_PAN) {
- return ARMMMUIdx_E10_1_PAN;
+ idx = ARMMMUIdx_E10_1_PAN;
+ } else {
+ idx = ARMMMUIdx_E10_1;
}
- return ARMMMUIdx_E10_1;
+ break;
case 2:
- /* TODO: ARMv8.4-SecEL2 */
/* Note that TGE does not apply at EL2. */
- if ((env->cp15.hcr_el2 & HCR_E2H) && arm_el_is_aa64(env, 2)) {
+ if (arm_hcr_el2_eff(env) & HCR_E2H) {
if (env->pstate & PSTATE_PAN) {
- return ARMMMUIdx_E20_2_PAN;
+ idx = ARMMMUIdx_E20_2_PAN;
+ } else {
+ idx = ARMMMUIdx_E20_2;
}
- return ARMMMUIdx_E20_2;
+ } else {
+ idx = ARMMMUIdx_E2;
}
- return ARMMMUIdx_E2;
+ break;
case 3:
return ARMMMUIdx_SE3;
default:
g_assert_not_reached();
}
+
+ if (arm_is_secure_below_el3(env)) {
+ idx &= ~ARM_MMU_IDX_A_NS;
+ }
+
+ return idx;
}
ARMMMUIdx arm_mmu_idx(CPUARMState *env)
@@ -12906,7 +12946,8 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
break;
case ARMMMUIdx_E20_2:
case ARMMMUIdx_E20_2_PAN:
- /* TODO: ARMv8.4-SecEL2 */
+ case ARMMMUIdx_SE20_2:
+ case ARMMMUIdx_SE20_2_PAN:
/*
* Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
* gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 5460678756..e4e6afef19 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -860,6 +860,9 @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
case ARMMMUIdx_SE10_0:
case ARMMMUIdx_SE10_1:
case ARMMMUIdx_SE10_1_PAN:
+ case ARMMMUIdx_SE20_0:
+ case ARMMMUIdx_SE20_2:
+ case ARMMMUIdx_SE20_2_PAN:
return true;
default:
return false;
@@ -890,6 +893,10 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
case ARMMMUIdx_SE10_0:
case ARMMMUIdx_SE10_1:
case ARMMMUIdx_SE10_1_PAN:
+ case ARMMMUIdx_SE20_0:
+ case ARMMMUIdx_SE20_2:
+ case ARMMMUIdx_SE20_2_PAN:
+ case ARMMMUIdx_SE2:
case ARMMMUIdx_MSPrivNegPri:
case ARMMMUIdx_MSUserNegPri:
case ARMMMUIdx_MSPriv:
@@ -907,6 +914,7 @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
case ARMMMUIdx_E10_1_PAN:
case ARMMMUIdx_E20_2_PAN:
case ARMMMUIdx_SE10_1_PAN:
+ case ARMMMUIdx_SE20_2_PAN:
return true;
default:
return false;
@@ -917,10 +925,14 @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
{
switch (mmu_idx) {
+ case ARMMMUIdx_SE20_0:
+ case ARMMMUIdx_SE20_2:
+ case ARMMMUIdx_SE20_2_PAN:
case ARMMMUIdx_E20_0:
case ARMMMUIdx_E20_2:
case ARMMMUIdx_E20_2_PAN:
case ARMMMUIdx_Stage2:
+ case ARMMMUIdx_SE2:
case ARMMMUIdx_E2:
return 2;
case ARMMMUIdx_SE3:
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index ef63edfc68..ffc060e5d7 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -118,6 +118,10 @@ static int get_a64_user_mem_index(DisasContext *s)
case ARMMMUIdx_SE10_1_PAN:
useridx = ARMMMUIdx_SE10_0;
break;
+ case ARMMMUIdx_SE20_2:
+ case ARMMMUIdx_SE20_2_PAN:
+ useridx = ARMMMUIdx_SE20_0;
+ break;
default:
g_assert_not_reached();
}
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 09/19] target/arm: add ARMv8.4-SEL2 system registers
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (7 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 08/19] target/arm: add MMU stage 1 for Secure EL2 remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 10/19] target/arm: handle VMID change in secure state remi.denis.courmont
` (10 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 7 +++++++
target/arm/helper.c | 24 ++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 085dc9cc54..b6685f3746 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -168,6 +168,11 @@ typedef struct {
uint32_t base_mask;
} TCR;
+#define VTCR_NSW (1u << 29)
+#define VTCR_NSA (1u << 30)
+#define VSTCR_SW VTCR_NSW
+#define VSTCR_SA VTCR_NSA
+
/* Define a maximum sized vector register.
* For 32-bit, this is a 128-bit NEON/AdvSIMD register.
* For 64-bit, this is a 2048-bit SVE register.
@@ -323,9 +328,11 @@ typedef struct CPUARMState {
uint64_t ttbr1_el[4];
};
uint64_t vttbr_el2; /* Virtualization Translation Table Base. */
+ uint64_t vsttbr_el2; /* Secure Virtualization Translation Table. */
/* MMU translation table base control. */
TCR tcr_el[4];
TCR vtcr_el2; /* Virtualization Translation Control. */
+ TCR vstcr_el2; /* Secure Virtualization Translation Control. */
uint32_t c2_data; /* MPU data cacheable bits. */
uint32_t c2_insn; /* MPU instruction cacheable bits. */
union { /* MMU domain access control register
diff --git a/target/arm/helper.c b/target/arm/helper.c
index fde95cb97e..7f84662dfa 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5721,6 +5721,27 @@ static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
REGINFO_SENTINEL
};
+static CPAccessResult sel2_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ if (arm_current_el(env) == 3 || arm_is_secure_below_el3(env)) {
+ return CP_ACCESS_OK;
+ }
+ return CP_ACCESS_TRAP_UNCATEGORIZED;
+}
+
+static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
+ { .name = "VSTTBR_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 0,
+ .access = PL2_RW, .accessfn = sel2_access,
+ .fieldoffset = offsetof(CPUARMState, cp15.vsttbr_el2) },
+ { .name = "VSTCR_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 2,
+ .access = PL2_RW, .accessfn = sel2_access,
+ .fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
+ REGINFO_SENTINEL
+};
+
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
@@ -7733,6 +7754,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
if (arm_feature(env, ARM_FEATURE_V8)) {
define_arm_cp_regs(cpu, el2_v8_cp_reginfo);
}
+ if (cpu_isar_feature(aa64_sel2, cpu)) {
+ define_arm_cp_regs(cpu, el2_sec_cp_reginfo);
+ }
/* RVBAR_EL2 is only implemented if EL2 is the highest EL */
if (!arm_feature(env, ARM_FEATURE_EL3)) {
ARMCPRegInfo rvbar = {
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 10/19] target/arm: handle VMID change in secure state
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (8 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 09/19] target/arm: add ARMv8.4-SEL2 system registers remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 11/19] target/arm: do S1_ptw_translate() before address space lookup remi.denis.courmont
` (9 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
The VTTBR write callback so far assumes that the underlying VM lies in
non-secure state. This handles the secure state scenario.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7f84662dfa..3e6b1c548b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4017,10 +4017,15 @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
* the combined stage 1&2 tlbs (EL10_1 and EL10_0).
*/
if (raw_read(env, ri) != value) {
- tlb_flush_by_mmuidx(cs,
- ARMMMUIdxBit_E10_1 |
- ARMMMUIdxBit_E10_1_PAN |
- ARMMMUIdxBit_E10_0);
+ uint16_t mask = ARMMMUIdxBit_E10_1 |
+ ARMMMUIdxBit_E10_1_PAN |
+ ARMMMUIdxBit_E10_0;
+
+ if (arm_is_secure_below_el3(env)) {
+ mask >>= ARM_MMU_IDX_A_NS;
+ }
+
+ tlb_flush_by_mmuidx(cs, mask);
raw_write(env, ri, value);
}
}
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 11/19] target/arm: do S1_ptw_translate() before address space lookup
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (9 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 10/19] target/arm: handle VMID change in secure state remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 12/19] target/arm: translate NS bit in page-walks remi.denis.courmont
` (8 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
In the secure stage 2 translation regime, the VSTCR.SW and VTCR.NSW
bits can invert the secure flag for pagetable walks. This patchset
allows S1_ptw_translate() to change the non-secure bit.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3e6b1c548b..7d96897f9a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10392,7 +10392,7 @@ static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
/* Translate a S1 pagetable walk through S2 if needed. */
static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
- hwaddr addr, MemTxAttrs txattrs,
+ hwaddr addr, bool *is_secure,
ARMMMUFaultInfo *fi)
{
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
@@ -10402,6 +10402,9 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
int s2prot;
int ret;
ARMCacheAttrs cacheattrs = {};
+ MemTxAttrs txattrs = {};
+
+ assert(!*is_secure); /* TODO: S-EL2 */
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
false,
@@ -10442,9 +10445,9 @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
AddressSpace *as;
uint32_t data;
+ addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi);
attrs.secure = is_secure;
as = arm_addressspace(cs, attrs);
- addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);
if (fi->s1ptw) {
return 0;
}
@@ -10471,9 +10474,9 @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
AddressSpace *as;
uint64_t data;
+ addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi);
attrs.secure = is_secure;
as = arm_addressspace(cs, attrs);
- addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);
if (fi->s1ptw) {
return 0;
}
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 12/19] target/arm: translate NS bit in page-walks
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (10 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 11/19] target/arm: do S1_ptw_translate() before address space lookup remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 13/19] target/arm: generalize 2-stage page-walk condition remi.denis.courmont
` (7 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7d96897f9a..fe95c2965d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10429,6 +10429,18 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
fi->s1ptw = true;
return ~0;
}
+
+ if (arm_is_secure_below_el3(env)) {
+ /* Check if page table walk is to secure or non-secure PA space. */
+ if (*is_secure) {
+ *is_secure = !(env->cp15.vstcr_el2.raw_tcr & VSTCR_SW);
+ } else {
+ *is_secure = !(env->cp15.vtcr_el2.raw_tcr & VTCR_NSW);
+ }
+ } else {
+ assert(!*is_secure);
+ }
+
addr = s2pa;
}
return addr;
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 13/19] target/arm: generalize 2-stage page-walk condition
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (11 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 12/19] target/arm: translate NS bit in page-walks remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 14/19] target/arm: secure stage 2 translation regime remi.denis.courmont
` (6 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
The stage_1_mmu_idx() already effectively keeps track of which
translation regimes have two stages. Don't hard-code another test.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index fe95c2965d..d889a6cd17 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12159,11 +12159,11 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
target_ulong *page_size,
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
{
- if (mmu_idx == ARMMMUIdx_E10_0 ||
- mmu_idx == ARMMMUIdx_E10_1 ||
- mmu_idx == ARMMMUIdx_E10_1_PAN) {
+ ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
+
+ if (mmu_idx != s1_mmu_idx) {
/* Call ourselves recursively to do the stage 1 and then stage 2
- * translations.
+ * translations if mmu_idx is a two-stage regime.
*/
if (arm_feature(env, ARM_FEATURE_EL2)) {
hwaddr ipa;
@@ -12171,9 +12171,8 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
int ret;
ARMCacheAttrs cacheattrs2 = {};
- ret = get_phys_addr(env, address, access_type,
- stage_1_mmu_idx(mmu_idx), &ipa, attrs,
- prot, page_size, fi, cacheattrs);
+ ret = get_phys_addr(env, address, access_type, s1_mmu_idx, &ipa,
+ attrs, prot, page_size, fi, cacheattrs);
/* If S1 fails or S2 is disabled, return early. */
if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 14/19] target/arm: secure stage 2 translation regime
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (12 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 13/19] target/arm: generalize 2-stage page-walk condition remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 21:02 ` Richard Henderson
2021-01-12 10:45 ` [PATCH 15/19] target/arm: set HPFAR_EL2.NS on secure stage 2 faults remi.denis.courmont
` (5 subsequent siblings)
19 siblings, 1 reply; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
---
target/arm/cpu.h | 6 +++-
target/arm/helper.c | 78 +++++++++++++++++++++++++++++-------------
target/arm/internals.h | 22 ++++++++++++
3 files changed, 81 insertions(+), 25 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index b6685f3746..0f90c772d7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3026,6 +3026,9 @@ typedef enum ARMMMUIdx {
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
+ ARMMMUIdx_Stage1_SE0 = 3 | ARM_MMU_IDX_NOTLB,
+ ARMMMUIdx_Stage1_SE1 = 4 | ARM_MMU_IDX_NOTLB,
+ ARMMMUIdx_Stage1_SE1_PAN = 5 | ARM_MMU_IDX_NOTLB,
/*
* Not allocated a TLB: used only for second stage of an S12 page
* table walk, or for descriptor loads during first stage of an S1
@@ -3033,7 +3036,8 @@ typedef enum ARMMMUIdx {
* then various TLB flush insns which currently are no-ops or flush
* only stage 1 MMU indexes will need to change to flush stage 2.
*/
- ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
+ ARMMMUIdx_Stage2 = 6 | ARM_MMU_IDX_NOTLB,
+ ARMMMUIdx_Stage2_S = 7 | ARM_MMU_IDX_NOTLB,
/*
* M-profile.
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d889a6cd17..f451f281f6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3429,7 +3429,7 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
uint32_t syn, fsr, fsc;
bool take_exc = false;
- if (fi.s1ptw && current_el == 1 && !arm_is_secure(env)
+ if (fi.s1ptw && current_el == 1
&& arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
/*
* Synchronous stage 2 fault on an access made as part of the
@@ -3586,10 +3586,10 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
/* fall through */
case 1:
if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
- mmu_idx = (secure ? ARMMMUIdx_SE10_1_PAN
+ mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
: ARMMMUIdx_Stage1_E1_PAN);
} else {
- mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1;
+ mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
}
break;
default:
@@ -3603,10 +3603,11 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
mmu_idx = ARMMMUIdx_SE10_0;
break;
case 2:
+ g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
mmu_idx = ARMMMUIdx_Stage1_E0;
break;
case 1:
- mmu_idx = secure ? ARMMMUIdx_SE10_0 : ARMMMUIdx_Stage1_E0;
+ mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
break;
default:
g_assert_not_reached();
@@ -3671,10 +3672,10 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
switch (ri->opc1) {
case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
- mmu_idx = (secure ? ARMMMUIdx_SE10_1_PAN
+ mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
: ARMMMUIdx_Stage1_E1_PAN);
} else {
- mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1;
+ mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
}
break;
case 4: /* AT S1E2R, AT S1E2W */
@@ -3688,7 +3689,7 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
}
break;
case 2: /* AT S1E0R, AT S1E0W */
- mmu_idx = secure ? ARMMMUIdx_SE10_0 : ARMMMUIdx_Stage1_E0;
+ mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
break;
case 4: /* AT S12E1R, AT S12E1W */
mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_E10_1;
@@ -10050,7 +10051,7 @@ static inline bool regime_translation_disabled(CPUARMState *env,
hcr_el2 = arm_hcr_el2_eff(env);
- if (mmu_idx == ARMMMUIdx_Stage2) {
+ if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
/* HCR.DC means HCR.VM behaves as 1 */
return (hcr_el2 & (HCR_DC | HCR_VM)) == 0;
}
@@ -10083,6 +10084,9 @@ static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
if (mmu_idx == ARMMMUIdx_Stage2) {
return env->cp15.vttbr_el2;
}
+ if (mmu_idx == ARMMMUIdx_Stage2_S) {
+ return env->cp15.vsttbr_el2;
+ }
if (ttbrn == 0) {
return env->cp15.ttbr0_el[regime_el(env, mmu_idx)];
} else {
@@ -10098,6 +10102,12 @@ static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
{
switch (mmu_idx) {
+ case ARMMMUIdx_SE10_0:
+ return ARMMMUIdx_Stage1_SE0;
+ case ARMMMUIdx_SE10_1:
+ return ARMMMUIdx_Stage1_SE1;
+ case ARMMMUIdx_SE10_1_PAN:
+ return ARMMMUIdx_Stage1_SE1_PAN;
case ARMMMUIdx_E10_0:
return ARMMMUIdx_Stage1_E0;
case ARMMMUIdx_E10_1:
@@ -10142,6 +10152,7 @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
case ARMMMUIdx_E20_0:
case ARMMMUIdx_SE20_0:
case ARMMMUIdx_Stage1_E0:
+ case ARMMMUIdx_Stage1_SE0:
case ARMMMUIdx_MUser:
case ARMMMUIdx_MSUser:
case ARMMMUIdx_MUserNegPri:
@@ -10307,6 +10318,7 @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
int wxn = 0;
assert(mmu_idx != ARMMMUIdx_Stage2);
+ assert(mmu_idx != ARMMMUIdx_Stage2_S);
user_rw = simple_ap_to_rw_prot_is_user(ap, true);
if (is_user) {
@@ -10401,13 +10413,12 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
hwaddr s2pa;
int s2prot;
int ret;
+ ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S
+ : ARMMMUIdx_Stage2;
ARMCacheAttrs cacheattrs = {};
MemTxAttrs txattrs = {};
- assert(!*is_secure); /* TODO: S-EL2 */
-
- ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
- false,
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
&s2pa, &txattrs, &s2prot, &s2size, fi,
&cacheattrs);
if (ret) {
@@ -10883,7 +10894,7 @@ static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
{
if (regime_has_2_ranges(mmu_idx)) {
return extract64(tcr, 37, 2);
- } else if (mmu_idx == ARMMMUIdx_Stage2) {
+ } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
return 0; /* VTCR_EL2 */
} else {
/* Replicate the single TBI bit so we always have 2 bits. */
@@ -10895,7 +10906,7 @@ static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
{
if (regime_has_2_ranges(mmu_idx)) {
return extract64(tcr, 51, 2);
- } else if (mmu_idx == ARMMMUIdx_Stage2) {
+ } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
return 0; /* VTCR_EL2 */
} else {
/* Replicate the single TBID bit so we always have 2 bits. */
@@ -10925,7 +10936,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
tsz = extract32(tcr, 0, 6);
using64k = extract32(tcr, 14, 1);
using16k = extract32(tcr, 15, 1);
- if (mmu_idx == ARMMMUIdx_Stage2) {
+ if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
/* VTCR_EL2 */
hpd = false;
} else {
@@ -10990,6 +11001,8 @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
int select, tsz;
bool epd, hpd;
+ assert(mmu_idx != ARMMMUIdx_Stage2_S);
+
if (mmu_idx == ARMMMUIdx_Stage2) {
/* VTCR */
bool sext = extract32(tcr, 4, 1);
@@ -11155,7 +11168,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
goto do_fault;
}
- if (mmu_idx != ARMMMUIdx_Stage2) {
+ if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
/* The starting level depends on the virtual address size (which can
* be up to 48 bits) and the translation granule size. It indicates
* the number of strides (stride bits at a time) needed to
@@ -11263,7 +11276,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
attrs = extract64(descriptor, 2, 10)
| (extract64(descriptor, 52, 12) << 10);
- if (mmu_idx == ARMMMUIdx_Stage2) {
+ if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
/* Stage 2 table descriptors do not include any attribute fields */
break;
}
@@ -11293,8 +11306,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
ap = extract32(attrs, 4, 2);
- if (mmu_idx == ARMMMUIdx_Stage2) {
- ns = true;
+ if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
+ ns = mmu_idx == ARMMMUIdx_Stage2;
xn = extract32(attrs, 11, 2);
*prot = get_S2prot(env, ap, xn, s1_is_el0);
} else {
@@ -11321,7 +11334,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
arm_tlb_bti_gp(txattrs) = true;
}
- if (mmu_idx == ARMMMUIdx_Stage2) {
+ if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
cacheattrs->attrs = convert_stage2_attrs(env, extract32(attrs, 0, 4));
} else {
/* Index into MAIR registers for cache attributes */
@@ -11340,7 +11353,8 @@ do_fault:
fi->type = fault_type;
fi->level = level;
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
- fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2);
+ fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 ||
+ mmu_idx == ARMMMUIdx_Stage2_S);
return true;
}
@@ -12170,6 +12184,8 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
int s2_prot;
int ret;
ARMCacheAttrs cacheattrs2 = {};
+ ARMMMUIdx s2_mmu_idx;
+ bool is_el0;
ret = get_phys_addr(env, address, access_type, s1_mmu_idx, &ipa,
attrs, prot, page_size, fi, cacheattrs);
@@ -12180,9 +12196,11 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
return ret;
}
+ s2_mmu_idx = attrs->secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
+ is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
+
/* S1 is done. Now do S2 translation. */
- ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
- mmu_idx == ARMMMUIdx_E10_0,
+ ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx, is_el0,
phys_ptr, attrs, &s2_prot,
page_size, fi, &cacheattrs2);
fi->s2addr = ipa;
@@ -12209,6 +12227,18 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
cacheattrs->shareability = 0;
}
*cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
+
+ /* Check if IPA translates to secure or non-secure PA space. */
+ if (arm_is_secure_below_el3(env)) {
+ if (attrs->secure) {
+ attrs->secure =
+ !(env->cp15.vstcr_el2.raw_tcr & (VSTCR_SA | VSTCR_SW));
+ } else {
+ attrs->secure =
+ !((env->cp15.vtcr_el2.raw_tcr & (VTCR_NSA | VTCR_NSW))
+ || (env->cp15.vstcr_el2.raw_tcr & VSTCR_SA));
+ }
+ }
return 0;
} else {
/*
@@ -12277,7 +12307,7 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
* MMU disabled. S1 addresses within aa64 translation regimes are
* still checked for bounds -- see AArch64.TranslateAddressS1Off.
*/
- if (mmu_idx != ARMMMUIdx_Stage2) {
+ if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
int r_el = regime_el(env, mmu_idx);
if (arm_el_is_aa64(env, r_el)) {
int pamax = arm_pamax(env_archcpu(env));
diff --git a/target/arm/internals.h b/target/arm/internals.h
index e4e6afef19..3aec10263e 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -851,6 +851,9 @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
case ARMMMUIdx_Stage1_E0:
case ARMMMUIdx_Stage1_E1:
case ARMMMUIdx_Stage1_E1_PAN:
+ case ARMMMUIdx_Stage1_SE0:
+ case ARMMMUIdx_Stage1_SE1:
+ case ARMMMUIdx_Stage1_SE1_PAN:
case ARMMMUIdx_E10_0:
case ARMMMUIdx_E10_1:
case ARMMMUIdx_E10_1_PAN:
@@ -896,7 +899,11 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
case ARMMMUIdx_SE20_0:
case ARMMMUIdx_SE20_2:
case ARMMMUIdx_SE20_2_PAN:
+ case ARMMMUIdx_Stage1_SE0:
+ case ARMMMUIdx_Stage1_SE1:
+ case ARMMMUIdx_Stage1_SE1_PAN:
case ARMMMUIdx_SE2:
+ case ARMMMUIdx_Stage2_S:
case ARMMMUIdx_MSPrivNegPri:
case ARMMMUIdx_MSUserNegPri:
case ARMMMUIdx_MSPriv:
@@ -911,6 +918,7 @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
{
switch (mmu_idx) {
case ARMMMUIdx_Stage1_E1_PAN:
+ case ARMMMUIdx_Stage1_SE1_PAN:
case ARMMMUIdx_E10_1_PAN:
case ARMMMUIdx_E20_2_PAN:
case ARMMMUIdx_SE10_1_PAN:
@@ -932,18 +940,22 @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
case ARMMMUIdx_E20_2:
case ARMMMUIdx_E20_2_PAN:
case ARMMMUIdx_Stage2:
+ case ARMMMUIdx_Stage2_S:
case ARMMMUIdx_SE2:
case ARMMMUIdx_E2:
return 2;
case ARMMMUIdx_SE3:
return 3;
case ARMMMUIdx_SE10_0:
+ case ARMMMUIdx_Stage1_SE0:
return arm_el_is_aa64(env, 3) ? 1 : 3;
case ARMMMUIdx_SE10_1:
case ARMMMUIdx_SE10_1_PAN:
case ARMMMUIdx_Stage1_E0:
case ARMMMUIdx_Stage1_E1:
case ARMMMUIdx_Stage1_E1_PAN:
+ case ARMMMUIdx_Stage1_SE1:
+ case ARMMMUIdx_Stage1_SE1_PAN:
case ARMMMUIdx_E10_0:
case ARMMMUIdx_E10_1:
case ARMMMUIdx_E10_1_PAN:
@@ -967,6 +979,13 @@ static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
if (mmu_idx == ARMMMUIdx_Stage2) {
return &env->cp15.vtcr_el2;
}
+ if (mmu_idx == ARMMMUIdx_Stage2_S) {
+ /*
+ * Note: Secure stage 2 nominally shares fields from VTCR_EL2, but
+ * those are not currently used by QEMU, so just return VSTCR_EL2.
+ */
+ return &env->cp15.vstcr_el2;
+ }
return &env->cp15.tcr_el[regime_el(env, mmu_idx)];
}
@@ -1169,6 +1188,9 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
case ARMMMUIdx_Stage1_E0:
case ARMMMUIdx_Stage1_E1:
case ARMMMUIdx_Stage1_E1_PAN:
+ case ARMMMUIdx_Stage1_SE0:
+ case ARMMMUIdx_Stage1_SE1:
+ case ARMMMUIdx_Stage1_SE1_PAN:
return true;
default:
return false;
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 15/19] target/arm: set HPFAR_EL2.NS on secure stage 2 faults
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (13 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 14/19] target/arm: secure stage 2 translation regime remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 16/19] target/arm: revector to run-time pick target EL remi.denis.courmont
` (4 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 2 ++
target/arm/helper.c | 6 ++++++
target/arm/internals.h | 2 ++
target/arm/tlb_helper.c | 3 +++
4 files changed, 13 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 0f90c772d7..e605791e47 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1482,6 +1482,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
#define HCR_TWEDEN (1ULL << 59)
#define HCR_TWEDEL MAKE_64BIT_MASK(60, 4)
+#define HPFAR_NS (1ULL << 63)
+
#define SCR_NS (1U << 0)
#define SCR_IRQ (1U << 1)
#define SCR_FIQ (1U << 2)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index f451f281f6..7648f6fb97 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3444,6 +3444,9 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
target_el = 3;
} else {
env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
+ if (arm_is_secure_below_el3(env) && fi.s1ns) {
+ env->cp15.hpfar_el2 |= HPFAR_NS;
+ }
target_el = 2;
}
take_exc = true;
@@ -10426,6 +10429,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
fi->s2addr = addr;
fi->stage2 = true;
fi->s1ptw = true;
+ fi->s1ns = !*is_secure;
return ~0;
}
if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
@@ -10438,6 +10442,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
fi->s2addr = addr;
fi->stage2 = true;
fi->s1ptw = true;
+ fi->s1ns = !*is_secure;
return ~0;
}
@@ -11355,6 +11360,7 @@ do_fault:
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 ||
mmu_idx == ARMMMUIdx_Stage2_S);
+ fi->s1ns = mmu_idx == ARMMMUIdx_Stage2;
return true;
}
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 3aec10263e..27cc93f15a 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -593,6 +593,7 @@ typedef enum ARMFaultType {
* @s2addr: Address that caused a fault at stage 2
* @stage2: True if we faulted at stage 2
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
+ * @s1ns: True if we faulted on a non-secure IPA while in secure state
* @ea: True if we should set the EA (external abort type) bit in syndrome
*/
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
@@ -603,6 +604,7 @@ struct ARMMMUFaultInfo {
int domain;
bool stage2;
bool s1ptw;
+ bool s1ns;
bool ea;
};
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
index b35dc8a011..df85079d9f 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tlb_helper.c
@@ -63,6 +63,9 @@ static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
if (fi->stage2) {
target_el = 2;
env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
+ if (arm_is_secure_below_el3(env) && fi->s1ns) {
+ env->cp15.hpfar_el2 |= HPFAR_NS;
+ }
}
same_el = (arm_current_el(env) == target_el);
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 16/19] target/arm: revector to run-time pick target EL
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (14 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 15/19] target/arm: set HPFAR_EL2.NS on secure stage 2 faults remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 21:04 ` Richard Henderson
2021-01-12 10:45 ` [PATCH 17/19] target/arm: add ARMv8.4-SEL2 extension remi.denis.courmont
` (3 subsequent siblings)
19 siblings, 1 reply; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
On ARMv8-A, accesses by 32-bit secure EL1 to monitor registers trap to
the upper (64-bit) EL. With Secure EL2 support, we can no longer assume
that that is always EL3, so make room for the value to be computed at
run-time.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
---
target/arm/translate.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index f5acd32e76..8b6b7355c9 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1094,6 +1094,22 @@ static void unallocated_encoding(DisasContext *s)
default_exception_el(s));
}
+static void gen_exception_el(DisasContext *s, int excp, uint32_t syn,
+ TCGv_i32 tcg_el)
+{
+ TCGv_i32 tcg_excp;
+ TCGv_i32 tcg_syn;
+
+ gen_set_condexec(s);
+ gen_set_pc_im(s, s->pc_curr);
+ tcg_excp = tcg_const_i32(excp);
+ tcg_syn = tcg_const_i32(syn);
+ gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn, tcg_el);
+ tcg_temp_free_i32(tcg_syn);
+ tcg_temp_free_i32(tcg_excp);
+ s->base.is_jmp = DISAS_NORETURN;
+}
+
/* Force a TB lookup after an instruction that changes the CPU state. */
static inline void gen_lookup_tb(DisasContext *s)
{
@@ -2818,8 +2834,11 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
/* If we're in Secure EL1 (which implies that EL3 is AArch64)
* then accesses to Mon registers trap to EL3
*/
- exc_target = 3;
- goto undef;
+ TCGv_i32 tcg_el = tcg_const_i32(3);
+
+ gen_exception_el(s, EXCP_UDEF, syn_uncategorized(), tcg_el);
+ tcg_temp_free_i32(tcg_el);
+ return false;
}
break;
case ARM_CPU_MODE_HYP:
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 17/19] target/arm: add ARMv8.4-SEL2 extension
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (15 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 16/19] target/arm: revector to run-time pick target EL remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 21:30 ` Richard Henderson
2021-01-12 10:45 ` [PATCH 18/19] target/arm: enable Secure EL2 in max CPU remi.denis.courmont
` (2 subsequent siblings)
19 siblings, 1 reply; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
This adds handling for the SCR_EL3.EEL2 bit.
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
---
target/arm/cpu.c | 2 +-
target/arm/cpu.h | 8 ++++++--
target/arm/helper.c | 19 ++++++++++++++++---
target/arm/translate.c | 14 ++++++++++++--
4 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 5530874686..b85b644941 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -480,7 +480,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
* masked from Secure state. The HCR and SCR settings
* don't affect the masking logic, only the interrupt routing.
*/
- if (target_el == 3 || !secure) {
+ if (target_el == 3 || !secure || (env->cp15.scr_el3 & SCR_EEL2)) {
unmasked = true;
}
} else {
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e605791e47..df510114f6 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2094,7 +2094,10 @@ static inline bool arm_is_secure(CPUARMState *env)
static inline bool arm_is_el2_enabled(CPUARMState *env)
{
if (arm_feature(env, ARM_FEATURE_EL2)) {
- return !arm_is_secure_below_el3(env);
+ if (arm_is_secure_below_el3(env)) {
+ return (env->cp15.scr_el3 & SCR_EEL2) != 0;
+ }
+ return true;
}
return false;
}
@@ -2141,7 +2144,8 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
return aa64;
}
- if (arm_feature(env, ARM_FEATURE_EL3)) {
+ if (arm_feature(env, ARM_FEATURE_EL3) &&
+ ((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) {
aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
}
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7648f6fb97..32fc72d9ed 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -532,6 +532,9 @@ static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
return CP_ACCESS_OK;
}
if (arm_is_secure_below_el3(env)) {
+ if (env->cp15.scr_el3 & SCR_EEL2) {
+ return CP_ACCESS_TRAP_EL2;
+ }
return CP_ACCESS_TRAP_EL3;
}
/* This will be EL1 NS and EL2 NS, which just UNDEF */
@@ -2029,6 +2032,9 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
if (cpu_isar_feature(aa64_pauth, cpu)) {
valid_mask |= SCR_API | SCR_APK;
}
+ if (cpu_isar_feature(aa64_sel2, cpu)) {
+ valid_mask |= SCR_EEL2;
+ }
if (cpu_isar_feature(aa64_mte, cpu)) {
valid_mask |= SCR_ATA;
}
@@ -3387,13 +3393,16 @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
if (ri->opc2 & 4) {
- /* The ATS12NSO* operations must trap to EL3 if executed in
+ /* The ATS12NSO* operations must trap to EL3 or EL2 if executed in
* Secure EL1 (which can only happen if EL3 is AArch64).
* They are simply UNDEF if executed from NS EL1.
* They function normally from EL2 or EL3.
*/
if (arm_current_el(env) == 1) {
if (arm_is_secure_below_el3(env)) {
+ if (env->cp15.scr_el3 & SCR_EEL2) {
+ return CP_ACCESS_TRAP_UNCATEGORIZED_EL2;
+ }
return CP_ACCESS_TRAP_UNCATEGORIZED_EL3;
}
return CP_ACCESS_TRAP_UNCATEGORIZED;
@@ -3656,7 +3665,8 @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
- if (arm_current_el(env) == 3 && !(env->cp15.scr_el3 & SCR_NS)) {
+ if (arm_current_el(env) == 3 &&
+ !(env->cp15.scr_el3 & (SCR_NS | SCR_EEL2))) {
return CP_ACCESS_TRAP;
}
return CP_ACCESS_OK;
@@ -5755,12 +5765,15 @@ static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
/* The NSACR is RW at EL3, and RO for NS EL1 and NS EL2.
- * At Secure EL1 it traps to EL3.
+ * At Secure EL1 it traps to EL3 or EL2.
*/
if (arm_current_el(env) == 3) {
return CP_ACCESS_OK;
}
if (arm_is_secure_below_el3(env)) {
+ if (env->cp15.scr_el3 & SCR_EEL2) {
+ return CP_ACCESS_TRAP_EL2;
+ }
return CP_ACCESS_TRAP_EL3;
}
/* Accesses from EL1 NS and EL2 NS are UNDEF for write but allow reads. */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 8b6b7355c9..688cd41684 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -2832,9 +2832,19 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
}
if (s->current_el == 1) {
/* If we're in Secure EL1 (which implies that EL3 is AArch64)
- * then accesses to Mon registers trap to EL3
+ * then accesses to Mon registers trap to Secure EL2, if it exists,
+ * otherwise EL3.
*/
- TCGv_i32 tcg_el = tcg_const_i32(3);
+ TCGv_i32 tcg_el;
+
+ if (dc_isar_feature(aa64_sel2, s)) {
+ /* Target EL is EL<3 minus SCR_EL3.EEL2> */
+ tcg_el = load_cpu_field(cp15.scr_el3);
+ tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
+ tcg_gen_addi_i32(tcg_el, tcg_el, 3);
+ } else {
+ tcg_el = tcg_const_i32(3);
+ }
gen_exception_el(s, EXCP_UDEF, syn_uncategorized(), tcg_el);
tcg_temp_free_i32(tcg_el);
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 18/19] target/arm: enable Secure EL2 in max CPU
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (16 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 17/19] target/arm: add ARMv8.4-SEL2 extension remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-12 10:45 ` [PATCH 19/19] target/arm: refactor vae1_tlbmask() remi.denis.courmont
2021-01-19 11:13 ` [PATCHv5 00/19] ARMv8.4-A Secure EL2 Peter Maydell
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu64.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index da24f94baa..8d3473db3e 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -641,6 +641,7 @@ static void aarch64_max_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
+ t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1);
cpu->isar.id_aa64pfr0 = t;
t = cpu->isar.id_aa64pfr1;
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 19/19] target/arm: refactor vae1_tlbmask()
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (17 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 18/19] target/arm: enable Secure EL2 in max CPU remi.denis.courmont
@ 2021-01-12 10:45 ` remi.denis.courmont
2021-01-19 11:13 ` [PATCHv5 00/19] ARMv8.4-A Secure EL2 Peter Maydell
19 siblings, 0 replies; 26+ messages in thread
From: remi.denis.courmont @ 2021-01-12 10:45 UTC (permalink / raw)
To: qemu-arm; +Cc: qemu-devel
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/helper.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 32fc72d9ed..c07850c7ca 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4469,26 +4469,23 @@ static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env,
static int vae1_tlbmask(CPUARMState *env)
{
uint64_t hcr = arm_hcr_el2_eff(env);
+ uint16_t mask;
if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
- uint16_t mask = ARMMMUIdxBit_E20_2 |
- ARMMMUIdxBit_E20_2_PAN |
- ARMMMUIdxBit_E20_0;
-
- if (arm_is_secure_below_el3(env)) {
- mask >>= ARM_MMU_IDX_A_NS;
- }
-
- return mask;
- } else if (arm_is_secure_below_el3(env)) {
- return ARMMMUIdxBit_SE10_1 |
- ARMMMUIdxBit_SE10_1_PAN |
- ARMMMUIdxBit_SE10_0;
+ mask = ARMMMUIdxBit_E20_2 |
+ ARMMMUIdxBit_E20_2_PAN |
+ ARMMMUIdxBit_E20_0;
} else {
- return ARMMMUIdxBit_E10_1 |
+ mask = ARMMMUIdxBit_E10_1 |
ARMMMUIdxBit_E10_1_PAN |
ARMMMUIdxBit_E10_0;
}
+
+ if (arm_is_secure_below_el3(env)) {
+ mask >>= ARM_MMU_IDX_A_NS;
+ }
+
+ return mask;
}
/* Return 56 if TBI is enabled, 64 otherwise. */
--
2.30.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 14/19] target/arm: secure stage 2 translation regime
2021-01-12 10:45 ` [PATCH 14/19] target/arm: secure stage 2 translation regime remi.denis.courmont
@ 2021-01-12 21:02 ` Richard Henderson
0 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2021-01-12 21:02 UTC (permalink / raw)
To: remi.denis.courmont, qemu-arm; +Cc: qemu-devel
On 1/12/21 12:45 AM, remi.denis.courmont@huawei.com wrote:
> From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
>
> Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 16/19] target/arm: revector to run-time pick target EL
2021-01-12 10:45 ` [PATCH 16/19] target/arm: revector to run-time pick target EL remi.denis.courmont
@ 2021-01-12 21:04 ` Richard Henderson
0 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2021-01-12 21:04 UTC (permalink / raw)
To: remi.denis.courmont, qemu-arm; +Cc: qemu-devel
On 1/12/21 12:45 AM, remi.denis.courmont@huawei.com wrote:
> From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
>
> On ARMv8-A, accesses by 32-bit secure EL1 to monitor registers trap to
> the upper (64-bit) EL. With Secure EL2 support, we can no longer assume
> that that is always EL3, so make room for the value to be computed at
> run-time.
>
> Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
> ---
> target/arm/translate.c | 23 +++++++++++++++++++++--
> 1 file changed, 21 insertions(+), 2 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 17/19] target/arm: add ARMv8.4-SEL2 extension
2021-01-12 10:45 ` [PATCH 17/19] target/arm: add ARMv8.4-SEL2 extension remi.denis.courmont
@ 2021-01-12 21:30 ` Richard Henderson
2021-01-13 13:12 ` Rémi Denis-Courmont
0 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2021-01-12 21:30 UTC (permalink / raw)
To: remi.denis.courmont, qemu-arm; +Cc: qemu-devel
On 1/12/21 12:45 AM, remi.denis.courmont@huawei.com wrote:
> From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
>
> This adds handling for the SCR_EL3.EEL2 bit.
>
> Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
The patch title seems to have gone awry.
> @@ -2832,9 +2832,19 @@ static bool msr_banked_access_decode
> }
> if (s->current_el == 1) {
> /* If we're in Secure EL1 (which implies that EL3 is AArch64)
> - * then accesses to Mon registers trap to EL3
> + * then accesses to Mon registers trap to Secure EL2, if it exists,
> + * otherwise EL3.
> */
> - TCGv_i32 tcg_el = tcg_const_i32(3);
> + TCGv_i32 tcg_el;
> +
> + if (dc_isar_feature(aa64_sel2, s)) {
> + /* Target EL is EL<3 minus SCR_EL3.EEL2> */
> + tcg_el = load_cpu_field(cp15.scr_el3);
> + tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
> + tcg_gen_addi_i32(tcg_el, tcg_el, 3);
> + } else {
> + tcg_el = tcg_const_i32(3);
> + }
You can't test an aa64 feature without verifying that the cpu has aa64 support
(if the cpu is strictly aa32, the aa64 registers are undefined/uninitialized). So:
if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
dc_isar_feature(aa64_sel2, s)) {
...
With those things changed,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 17/19] target/arm: add ARMv8.4-SEL2 extension
2021-01-12 21:30 ` Richard Henderson
@ 2021-01-13 13:12 ` Rémi Denis-Courmont
2021-01-13 17:35 ` Richard Henderson
0 siblings, 1 reply; 26+ messages in thread
From: Rémi Denis-Courmont @ 2021-01-13 13:12 UTC (permalink / raw)
To: qemu-arm; +Cc: Richard Henderson, qemu-devel
Le tiistaina 12. tammikuuta 2021, 23.30.39 EET Richard Henderson a écrit :
> On 1/12/21 12:45 AM, remi.denis.courmont@huawei.com wrote:
> > From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
> >
> > This adds handling for the SCR_EL3.EEL2 bit.
> >
> > Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
>
> The patch title seems to have gone awry.
>
> > @@ -2832,9 +2832,19 @@ static bool msr_banked_access_decode
> >
> > }
> > if (s->current_el == 1) {
> >
> > /* If we're in Secure EL1 (which implies that EL3 is AArch64)
> >
> > - * then accesses to Mon registers trap to EL3
> > + * then accesses to Mon registers trap to Secure EL2, if it
> > exists, + * otherwise EL3.
> >
> > */
> >
> > - TCGv_i32 tcg_el = tcg_const_i32(3);
> > + TCGv_i32 tcg_el;
> > +
> > + if (dc_isar_feature(aa64_sel2, s)) {
> > + /* Target EL is EL<3 minus SCR_EL3.EEL2> */
> > + tcg_el = load_cpu_field(cp15.scr_el3);
> > + tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
> > + tcg_gen_addi_i32(tcg_el, tcg_el, 3);
> > + } else {
> > + tcg_el = tcg_const_i32(3);
> > + }
>
> You can't test an aa64 feature without verifying that the cpu has aa64
> support (if the cpu is strictly aa32, the aa64 registers are
> undefined/uninitialized). So:
>
> if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
> dc_isar_feature(aa64_sel2, s)) {
> ...
>
Hmm, yeah. Should this be an ifdef on TARGET_AARCH64 instead?
Also do we need to revector the exception code, or leave it mostly duplicated
as is?
> With those things changed,
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
>
> r~
--
Rémi Denis-Courmont
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 17/19] target/arm: add ARMv8.4-SEL2 extension
2021-01-13 13:12 ` Rémi Denis-Courmont
@ 2021-01-13 17:35 ` Richard Henderson
0 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2021-01-13 17:35 UTC (permalink / raw)
To: Rémi Denis-Courmont, qemu-arm; +Cc: qemu-devel
On 1/13/21 3:12 AM, Rémi Denis-Courmont wrote:
>> if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
>> dc_isar_feature(aa64_sel2, s)) {
>> ...
>>
>
> Hmm, yeah. Should this be an ifdef on TARGET_AARCH64 instead?
No, I don't think so. It's not performance critical that we avoid a single bit
test.
> Also do we need to revector the exception code, or leave it mostly duplicated
> as is?
If you see a way to tidy that, great, please. But I don't think it's required
for this patch set.
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCHv5 00/19] ARMv8.4-A Secure EL2
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
` (18 preceding siblings ...)
2021-01-12 10:45 ` [PATCH 19/19] target/arm: refactor vae1_tlbmask() remi.denis.courmont
@ 2021-01-19 11:13 ` Peter Maydell
19 siblings, 0 replies; 26+ messages in thread
From: Peter Maydell @ 2021-01-19 11:13 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: qemu-arm, QEMU Developers
On Tue, 12 Jan 2021 at 10:59, Rémi Denis-Courmont
<remi.denis.courmont@huawei.com> wrote:
>
> Hi,
>
> This adds Secure EL2.
>
> Changes since version 4:
> - Fix NS unitialised in secure state stage 2 translation.
> - Remove EEL2 translation block flag in 32-bit mode.
> - Clarify comments on arm_is_el2_enabled().
Looking through this patchset, it's practically ready and only
needs a couple of very tiny tweaks, so rather than asking you to
roll a v6, I'm just going to apply it to target-arm.next and
make the tweaks in the process:
* patch 6 needed adjustment on rebase as commit 00a92832f4532
has already added definitions of the ID_AA64PFR0 fields;
I dropped the now-duplicate part of the patch and adjusted
the commit message to match
* patch 17: added the change requested by RTH:
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -2837,7 +2837,8 @@ static bool
msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
*/
TCGv_i32 tcg_el;
- if (dc_isar_feature(aa64_sel2, s)) {
+ if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
+ dc_isar_feature(aa64_sel2, s)) {
/* Target EL is EL<3 minus SCR_EL3.EEL2> */
tcg_el = load_cpu_field(cp15.scr_el3);
tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
and corrected the patch subject line to
"target/arm: Implement SCR_EL2.EEL2"
thanks
-- PMM
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2021-01-19 11:14 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-12 10:44 [PATCHv5 00/19] ARMv8.4-A Secure EL2 Rémi Denis-Courmont
2021-01-12 10:44 ` [PATCH 01/19] target/arm: remove redundant tests remi.denis.courmont
2021-01-12 10:44 ` [PATCH 02/19] target/arm: add arm_is_el2_enabled() helper remi.denis.courmont
2021-01-12 10:44 ` [PATCH 03/19] target/arm: use arm_is_el2_enabled() where applicable remi.denis.courmont
2021-01-12 10:44 ` [PATCH 04/19] target/arm: use arm_hcr_el2_eff() " remi.denis.courmont
2021-01-12 10:44 ` [PATCH 05/19] target/arm: factor MDCR_EL2 common handling remi.denis.courmont
2021-01-12 10:44 ` [PATCH 06/19] target/arm: declare new AA64PFR0 bit-fields remi.denis.courmont
2021-01-12 10:44 ` [PATCH 07/19] target/arm: add 64-bit S-EL2 to EL exception table remi.denis.courmont
2021-01-12 10:45 ` [PATCH 08/19] target/arm: add MMU stage 1 for Secure EL2 remi.denis.courmont
2021-01-12 10:45 ` [PATCH 09/19] target/arm: add ARMv8.4-SEL2 system registers remi.denis.courmont
2021-01-12 10:45 ` [PATCH 10/19] target/arm: handle VMID change in secure state remi.denis.courmont
2021-01-12 10:45 ` [PATCH 11/19] target/arm: do S1_ptw_translate() before address space lookup remi.denis.courmont
2021-01-12 10:45 ` [PATCH 12/19] target/arm: translate NS bit in page-walks remi.denis.courmont
2021-01-12 10:45 ` [PATCH 13/19] target/arm: generalize 2-stage page-walk condition remi.denis.courmont
2021-01-12 10:45 ` [PATCH 14/19] target/arm: secure stage 2 translation regime remi.denis.courmont
2021-01-12 21:02 ` Richard Henderson
2021-01-12 10:45 ` [PATCH 15/19] target/arm: set HPFAR_EL2.NS on secure stage 2 faults remi.denis.courmont
2021-01-12 10:45 ` [PATCH 16/19] target/arm: revector to run-time pick target EL remi.denis.courmont
2021-01-12 21:04 ` Richard Henderson
2021-01-12 10:45 ` [PATCH 17/19] target/arm: add ARMv8.4-SEL2 extension remi.denis.courmont
2021-01-12 21:30 ` Richard Henderson
2021-01-13 13:12 ` Rémi Denis-Courmont
2021-01-13 17:35 ` Richard Henderson
2021-01-12 10:45 ` [PATCH 18/19] target/arm: enable Secure EL2 in max CPU remi.denis.courmont
2021-01-12 10:45 ` [PATCH 19/19] target/arm: refactor vae1_tlbmask() remi.denis.courmont
2021-01-19 11:13 ` [PATCHv5 00/19] ARMv8.4-A Secure EL2 Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).