[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 12/19] target/arm: Implement fine-grained-trap handling for FEAT_X
From: |
Peter Maydell |
Subject: |
[PULL 12/19] target/arm: Implement fine-grained-trap handling for FEAT_XS |
Date: |
Tue, 17 Dec 2024 17:19:30 +0000 |
FEAT_XS introduces a set of new TLBI maintenance instructions with an
"nXS" qualifier. These behave like the stardard ones except that
they do not wait for memory accesses with the XS attribute to
complete. They have an interaction with the fine-grained-trap
handling: the FGT bits that a hypervisor can use to trap TLBI
maintenance instructions normally trap also the nXS variants, but the
hypervisor can elect to not trap the nXS variants by setting
HCRX_EL2.FGTnXS to 1.
Add support to our FGT mechanism for these TLBI bits. For each
TLBI-trapping FGT bit we define, for example:
* FGT_TLBIVAE1 -- the same value we do at present for the
normal variant of the insn
* FGT_TLBIVAE1NXS -- for the nXS qualified insn; the value of
this enum has an NXS bit ORed into it
In access_check_cp_reg() we can then ignore the trap bit for an
access where ri->fgt has the NXS bit set and HCRX_EL2.FGTnXS is 1.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241211144440.2700268-2-peter.maydell@linaro.org
---
target/arm/cpregs.h | 72 ++++++++++++++++++++++----------------
target/arm/cpu-features.h | 5 +++
target/arm/helper.c | 5 ++-
target/arm/tcg/op_helper.c | 11 +++++-
4 files changed, 61 insertions(+), 32 deletions(-)
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
index cc7c54378f4..87704762ef9 100644
--- a/target/arm/cpregs.h
+++ b/target/arm/cpregs.h
@@ -621,6 +621,7 @@ FIELD(HDFGWTR_EL2, NBRBCTL, 60, 1)
FIELD(HDFGWTR_EL2, NBRBDATA, 61, 1)
FIELD(HDFGWTR_EL2, NPMSNEVFR_EL1, 62, 1)
+FIELD(FGT, NXS, 13, 1) /* Honour HCR_EL2.FGTnXS to suppress FGT */
/* Which fine-grained trap bit register to check, if any */
FIELD(FGT, TYPE, 10, 3)
FIELD(FGT, REV, 9, 1) /* Is bit sense reversed? */
@@ -639,6 +640,17 @@ FIELD(FGT, BITPOS, 0, 6) /* Bit position within the
uint64_t */
#define DO_REV_BIT(REG, BITNAME) \
FGT_##BITNAME = FGT_##REG | FGT_REV | R_##REG##_EL2_##BITNAME##_SHIFT
+/*
+ * The FGT bits for TLBI maintenance instructions accessible at EL1 always
+ * affect the "normal" TLBI insns; they affect the corresponding TLBI insns
+ * with the nXS qualifier only if HCRX_EL2.FGTnXS is 0. We define e.g.
+ * FGT_TLBIVAE1 to use for the normal insn, and FGT_TLBIVAE1NXS to use
+ * for the nXS qualified insn.
+ */
+#define DO_TLBINXS_BIT(REG, BITNAME) \
+ FGT_##BITNAME = FGT_##REG | R_##REG##_EL2_##BITNAME##_SHIFT, \
+ FGT_##BITNAME##NXS = FGT_##BITNAME | R_FGT_NXS_MASK
+
typedef enum FGTBit {
/*
* These bits tell us which register arrays to use:
@@ -772,36 +784,36 @@ typedef enum FGTBit {
DO_BIT(HFGITR, ATS1E0W),
DO_BIT(HFGITR, ATS1E1RP),
DO_BIT(HFGITR, ATS1E1WP),
- DO_BIT(HFGITR, TLBIVMALLE1OS),
- DO_BIT(HFGITR, TLBIVAE1OS),
- DO_BIT(HFGITR, TLBIASIDE1OS),
- DO_BIT(HFGITR, TLBIVAAE1OS),
- DO_BIT(HFGITR, TLBIVALE1OS),
- DO_BIT(HFGITR, TLBIVAALE1OS),
- DO_BIT(HFGITR, TLBIRVAE1OS),
- DO_BIT(HFGITR, TLBIRVAAE1OS),
- DO_BIT(HFGITR, TLBIRVALE1OS),
- DO_BIT(HFGITR, TLBIRVAALE1OS),
- DO_BIT(HFGITR, TLBIVMALLE1IS),
- DO_BIT(HFGITR, TLBIVAE1IS),
- DO_BIT(HFGITR, TLBIASIDE1IS),
- DO_BIT(HFGITR, TLBIVAAE1IS),
- DO_BIT(HFGITR, TLBIVALE1IS),
- DO_BIT(HFGITR, TLBIVAALE1IS),
- DO_BIT(HFGITR, TLBIRVAE1IS),
- DO_BIT(HFGITR, TLBIRVAAE1IS),
- DO_BIT(HFGITR, TLBIRVALE1IS),
- DO_BIT(HFGITR, TLBIRVAALE1IS),
- DO_BIT(HFGITR, TLBIRVAE1),
- DO_BIT(HFGITR, TLBIRVAAE1),
- DO_BIT(HFGITR, TLBIRVALE1),
- DO_BIT(HFGITR, TLBIRVAALE1),
- DO_BIT(HFGITR, TLBIVMALLE1),
- DO_BIT(HFGITR, TLBIVAE1),
- DO_BIT(HFGITR, TLBIASIDE1),
- DO_BIT(HFGITR, TLBIVAAE1),
- DO_BIT(HFGITR, TLBIVALE1),
- DO_BIT(HFGITR, TLBIVAALE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIVMALLE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIASIDE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAAE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVALE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAALE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAAE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVALE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAALE1OS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVMALLE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIASIDE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAAE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVALE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAALE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAAE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVALE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAALE1IS),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAAE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVALE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIRVAALE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIVMALLE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIASIDE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAAE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIVALE1),
+ DO_TLBINXS_BIT(HFGITR, TLBIVAALE1),
DO_BIT(HFGITR, CFPRCTX),
DO_BIT(HFGITR, DVPRCTX),
DO_BIT(HFGITR, CPPRCTX),
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index e806f138b8f..30302d6c5b4 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -474,6 +474,11 @@ static inline bool isar_feature_aa64_fcma(const
ARMISARegisters *id)
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
}
+static inline bool isar_feature_aa64_xs(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, XS) != 0;
+}
+
/*
* These are the values from APA/API/APA3.
* In general these must be compared '>=', per the normal Arm ARM
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 910ae62c476..8e62769ec0d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5346,10 +5346,13 @@ static void hcrx_write(CPUARMState *env, const
ARMCPRegInfo *ri,
valid_mask |= HCRX_TALLINT | HCRX_VINMI | HCRX_VFNMI;
}
/* FEAT_CMOW adds CMOW */
-
if (cpu_isar_feature(aa64_cmow, cpu)) {
valid_mask |= HCRX_CMOW;
}
+ /* FEAT_XS adds FGTnXS, FnXS */
+ if (cpu_isar_feature(aa64_xs, cpu)) {
+ valid_mask |= HCRX_FGTNXS | HCRX_FNXS;
+ }
/* Clear RES0 bits. */
env->cp15.hcrx_el2 = value & valid_mask;
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index 1ecb4659889..1161d301b71 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -817,6 +817,7 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env,
uint32_t key,
unsigned int idx = FIELD_EX32(ri->fgt, FGT, IDX);
unsigned int bitpos = FIELD_EX32(ri->fgt, FGT, BITPOS);
bool rev = FIELD_EX32(ri->fgt, FGT, REV);
+ bool nxs = FIELD_EX32(ri->fgt, FGT, NXS);
bool trapbit;
if (ri->fgt & FGT_EXEC) {
@@ -830,7 +831,15 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env,
uint32_t key,
trapword = env->cp15.fgt_write[idx];
}
- trapbit = extract64(trapword, bitpos, 1);
+ if (nxs && (arm_hcrx_el2_eff(env) & HCRX_FGTNXS)) {
+ /*
+ * If HCRX_EL2.FGTnXS is 1 then the fine-grained trap for
+ * TLBI maintenance insns does *not* apply to the nXS variant.
+ */
+ trapbit = 0;
+ } else {
+ trapbit = extract64(trapword, bitpos, 1);
+ }
if (trapbit != rev) {
res = CP_ACCESS_TRAP_EL2;
goto fail;
--
2.34.1
- [PULL 09/19] target/arm: Convert neon_helper.c to use env alias, (continued)
- [PULL 09/19] target/arm: Convert neon_helper.c to use env alias, Peter Maydell, 2024/12/17
- [PULL 10/19] target/arm: Use float_status in helper_fcvtx_f64_to_f32, Peter Maydell, 2024/12/17
- [PULL 08/19] target/arm: Convert vec_helper.c to use env alias, Peter Maydell, 2024/12/17
- [PULL 11/19] target/arm: Use float_status in helper_vfp_fcvt{ds,sd}, Peter Maydell, 2024/12/17
- [PULL 15/19] target/arm: Add decodetree entry for DSB nXS variant, Peter Maydell, 2024/12/17
- [PULL 18/19] hw/intc/arm_gicv3_its: Zero initialize local DTEntry etc structs, Peter Maydell, 2024/12/17
- [PULL 13/19] target/arm: Add ARM_CP_ADD_TLBI_NXS type flag for NXS insns, Peter Maydell, 2024/12/17
- [PULL 19/19] tests/functional: update sbsa-ref firmware used in test, Peter Maydell, 2024/12/17
- [PULL 14/19] target/arm: Add ARM_CP_ADD_TLBI_NXS type flag to TLBI insns, Peter Maydell, 2024/12/17
- [PULL 16/19] target/arm: Enable FEAT_XS for the max cpu, Peter Maydell, 2024/12/17
- [PULL 12/19] target/arm: Implement fine-grained-trap handling for FEAT_XS,
Peter Maydell <=
- [PULL 17/19] tests/tcg/aarch64: add system test for FEAT_XS, Peter Maydell, 2024/12/17
- Re: [PULL 00/19] target-arm queue, Stefan Hajnoczi, 2024/12/19