All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features
@ 2022-02-10  4:04 Richard Henderson
  2022-02-10  4:04 ` [PATCH v2 01/15] hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N> Richard Henderson
                   ` (16 more replies)
  0 siblings, 17 replies; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

Changes for v2:
  * Introduce FIELD_SEX64, instead of open-coding w/ sextract64.
  * Set TCR_EL1 more completely for user-only.
  * Continue to bound tsz within aa64_va_parameters;
    provide an out-of-bound indicator for raising AddressSize fault.
  * Split IPS patch.
  * Fix debug registers for LVA.
  * Fix long-format fsc for LPA2.
  * Fix TLBI page shift.
  * Validate TLBI granule vs TCR granule.

Not done:
  * Validate translation levels which accept blocks.

There is still no upstream kernel support for FEAT_LPA2,
so that is essentially untested.


r~


Richard Henderson (15):
  hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N>
  target/arm: Set TCR_EL1.TSZ for user-only
  target/arm: Fault on invalid TCR_ELx.TxSZ
  target/arm: Move arm_pamax out of line
  target/arm: Pass outputsize down to check_s2_mmu_setup
  target/arm: Use MAKE_64BIT_MASK to compute indexmask
  target/arm: Honor TCR_ELx.{I}PS
  target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA
  target/arm: Implement FEAT_LVA
  target/arm: Implement FEAT_LPA
  target/arm: Extend arm_fi_to_lfsc to level -1
  target/arm: Introduce tlbi_aa64_get_range
  target/arm: Fix TLBIRange.base for 16k and 64k pages
  target/arm: Validate tlbi TG matches translation granule in use
  target/arm: Implement FEAT_LPA2

 include/hw/registerfields.h |  48 +++++-
 target/arm/cpu-param.h      |   4 +-
 target/arm/cpu.h            |  27 +++
 target/arm/internals.h      |  58 ++++---
 target/arm/cpu.c            |   3 +-
 target/arm/cpu64.c          |   7 +-
 target/arm/helper.c         | 332 ++++++++++++++++++++++++++++--------
 7 files changed, 378 insertions(+), 101 deletions(-)

-- 
2.25.1



^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 01/15] hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N>
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-10 11:15   ` Philippe Mathieu-Daudé via
  2022-02-10  4:04 ` [PATCH v2 02/15] target/arm: Set TCR_EL1.TSZ for user-only Richard Henderson
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

Add new macros to manipulate signed fields within the register.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/registerfields.h | 48 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
index f2a3c9c41f..3a88e135d0 100644
--- a/include/hw/registerfields.h
+++ b/include/hw/registerfields.h
@@ -59,6 +59,19 @@
     extract64((storage), R_ ## reg ## _ ## field ## _SHIFT,               \
               R_ ## reg ## _ ## field ## _LENGTH)
 
+#define FIELD_SEX8(storage, reg, field)                                   \
+    sextract8((storage), R_ ## reg ## _ ## field ## _SHIFT,               \
+              R_ ## reg ## _ ## field ## _LENGTH)
+#define FIELD_SEX16(storage, reg, field)                                  \
+    sextract16((storage), R_ ## reg ## _ ## field ## _SHIFT,              \
+               R_ ## reg ## _ ## field ## _LENGTH)
+#define FIELD_SEX32(storage, reg, field)                                  \
+    sextract32((storage), R_ ## reg ## _ ## field ## _SHIFT,              \
+               R_ ## reg ## _ ## field ## _LENGTH)
+#define FIELD_SEX64(storage, reg, field)                                  \
+    sextract64((storage), R_ ## reg ## _ ## field ## _SHIFT,              \
+               R_ ## reg ## _ ## field ## _LENGTH)
+
 /* Extract a field from an array of registers */
 #define ARRAY_FIELD_EX32(regs, reg, field)                                \
     FIELD_EX32((regs)[R_ ## reg], reg, field)
@@ -95,7 +108,40 @@
     _d; })
 #define FIELD_DP64(storage, reg, field, val) ({                           \
     struct {                                                              \
-        uint64_t v:R_ ## reg ## _ ## field ## _LENGTH;                \
+        uint64_t v:R_ ## reg ## _ ## field ## _LENGTH;                    \
+    } _v = { .v = val };                                                  \
+    uint64_t _d;                                                          \
+    _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
+                  R_ ## reg ## _ ## field ## _LENGTH, _v.v);              \
+    _d; })
+
+#define FIELD_SDP8(storage, reg, field, val) ({                           \
+    struct {                                                              \
+        signed int v:R_ ## reg ## _ ## field ## _LENGTH;                  \
+    } _v = { .v = val };                                                  \
+    uint8_t _d;                                                           \
+    _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
+                  R_ ## reg ## _ ## field ## _LENGTH, _v.v);              \
+    _d; })
+#define FIELD_SDP16(storage, reg, field, val) ({                          \
+    struct {                                                              \
+        signed int v:R_ ## reg ## _ ## field ## _LENGTH;                  \
+    } _v = { .v = val };                                                  \
+    uint16_t _d;                                                          \
+    _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
+                  R_ ## reg ## _ ## field ## _LENGTH, _v.v);              \
+    _d; })
+#define FIELD_SDP32(storage, reg, field, val) ({                          \
+    struct {                                                              \
+        signed int v:R_ ## reg ## _ ## field ## _LENGTH;                  \
+    } _v = { .v = val };                                                  \
+    uint32_t _d;                                                          \
+    _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
+                  R_ ## reg ## _ ## field ## _LENGTH, _v.v);              \
+    _d; })
+#define FIELD_SDP64(storage, reg, field, val) ({                          \
+    struct {                                                              \
+        int64_t v:R_ ## reg ## _ ## field ## _LENGTH;                     \
     } _v = { .v = val };                                                  \
     uint64_t _d;                                                          \
     _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 02/15] target/arm: Set TCR_EL1.TSZ for user-only
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
  2022-02-10  4:04 ` [PATCH v2 01/15] hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N> Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 21:50   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 03/15] target/arm: Fault on invalid TCR_ELx.TxSZ Richard Henderson
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

Set this as the kernel would, to 48 bits, to keep the computation
of the address space correct for PAuth.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 5a9c02a256..92f19f919a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -206,10 +206,11 @@ static void arm_cpu_reset(DeviceState *dev)
                 aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
         }
         /*
+         * Enable 48-bit address space (TODO: take reserved_va into account).
          * Enable TBI0 but not TBI1.
          * Note that this must match useronly_clean_ptr.
          */
-        env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
+        env->cp15.tcr_el[1].raw_tcr = 5 | (1ULL << 37);
 
         /* Enable MTE */
         if (cpu_isar_feature(aa64_mte, cpu)) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 03/15] target/arm: Fault on invalid TCR_ELx.TxSZ
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
  2022-02-10  4:04 ` [PATCH v2 01/15] hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N> Richard Henderson
  2022-02-10  4:04 ` [PATCH v2 02/15] target/arm: Set TCR_EL1.TSZ for user-only Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 21:51   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 04/15] target/arm: Move arm_pamax out of line Richard Henderson
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

Without FEAT_LVA, the behaviour of programming an invalid value
is IMPLEMENTATION DEFINED.  With FEAT_LVA, programming an invalid
minimum value requires a Translation fault.

It is most self-consistent to choose to generate the fault always.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v2: Continue to bound in aa64_va_parameters, so that PAuth gets
    something it can use, but provide a flag for get_phys_addr_lpae
    to raise a fault.
---
 target/arm/internals.h |  1 +
 target/arm/helper.c    | 32 ++++++++++++++++++++++++++++----
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 3f05748ea4..ef6c25d8cb 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1055,6 +1055,7 @@ typedef struct ARMVAParameters {
     bool hpd        : 1;
     bool using16k   : 1;
     bool using64k   : 1;
+    bool tsz_oob    : 1;  /* tsz has been clamped to legal range */
 } ARMVAParameters;
 
 ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b5f80988c9..14cc866d8d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11188,8 +11188,8 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
                                    ARMMMUIdx mmu_idx, bool data)
 {
     uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
-    bool epd, hpd, using16k, using64k;
-    int select, tsz, tbi, max_tsz;
+    bool epd, hpd, using16k, using64k, tsz_oob;
+    int select, tsz, tbi, max_tsz, min_tsz;
 
     if (!regime_has_2_ranges(mmu_idx)) {
         select = 0;
@@ -11230,9 +11230,17 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
     } else {
         max_tsz = 39;
     }
+    min_tsz = 16;  /* TODO: ARMv8.2-LVA  */
 
-    tsz = MIN(tsz, max_tsz);
-    tsz = MAX(tsz, 16);  /* TODO: ARMv8.2-LVA  */
+    if (tsz > max_tsz) {
+        tsz = max_tsz;
+        tsz_oob = true;
+    } else if (tsz < min_tsz) {
+        tsz = min_tsz;
+        tsz_oob = true;
+    } else {
+        tsz_oob = false;
+    }
 
     /* Present TBI as a composite with TBID.  */
     tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
@@ -11249,6 +11257,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
         .hpd = hpd,
         .using16k = using16k,
         .using64k = using64k,
+        .tsz_oob = tsz_oob,
     };
 }
 
@@ -11372,6 +11381,21 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
         param = aa64_va_parameters(env, address, mmu_idx,
                                    access_type != MMU_INST_FETCH);
         level = 0;
+
+        /*
+         * If TxSZ is programmed to a value larger than the maximum,
+         * or smaller than the effective minimum, it is IMPLEMENTATION
+         * DEFINED whether we behave as if the field were programmed
+         * within bounds, or if a level 0 Translation fault is generated.
+         *
+         * With FEAT_LVA, fault on less than minimum becomes required,
+         * so our choice is to always raise the fault.
+         */
+        if (param.tsz_oob) {
+            fault_type = ARMFault_Translation;
+            goto do_fault;
+        }
+
         addrsize = 64 - 8 * param.tbi;
         inputsize = 64 - param.tsz;
     } else {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 04/15] target/arm: Move arm_pamax out of line
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (2 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 03/15] target/arm: Fault on invalid TCR_ELx.TxSZ Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 21:51   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 05/15] target/arm: Pass outputsize down to check_s2_mmu_setup Richard Henderson
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, qemu-arm, alex.bennee, Philippe Mathieu-Daudé

We will shortly share parts of this function with other portions
of address translation.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/internals.h | 19 +------------------
 target/arm/helper.c    | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index ef6c25d8cb..fefd1fb8d8 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -243,24 +243,7 @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
  * Returns the implementation defined bit-width of physical addresses.
  * The ARMv8 reference manuals refer to this as PAMax().
  */
-static inline unsigned int arm_pamax(ARMCPU *cpu)
-{
-    static const unsigned int pamax_map[] = {
-        [0] = 32,
-        [1] = 36,
-        [2] = 40,
-        [3] = 42,
-        [4] = 44,
-        [5] = 48,
-    };
-    unsigned int parange =
-        FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
-
-    /* id_aa64mmfr0 is a read-only register so values outside of the
-     * supported mappings can be considered an implementation error.  */
-    assert(parange < ARRAY_SIZE(pamax_map));
-    return pamax_map[parange];
-}
+unsigned int arm_pamax(ARMCPU *cpu);
 
 /* Return true if extended addresses are enabled.
  * This is always the case if our translation regime is 64 bit,
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 14cc866d8d..fa0824e12c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11150,6 +11150,28 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
 }
 #endif /* !CONFIG_USER_ONLY */
 
+/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
+unsigned int arm_pamax(ARMCPU *cpu)
+{
+    static const unsigned int pamax_map[] = {
+        [0] = 32,
+        [1] = 36,
+        [2] = 40,
+        [3] = 42,
+        [4] = 44,
+        [5] = 48,
+    };
+    unsigned int parange =
+        FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
+
+    /*
+     * id_aa64mmfr0 is a read-only register so values outside of the
+     * supported mappings can be considered an implementation error.
+     */
+    assert(parange < ARRAY_SIZE(pamax_map));
+    return pamax_map[parange];
+}
+
 static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
 {
     if (regime_has_2_ranges(mmu_idx)) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 05/15] target/arm: Pass outputsize down to check_s2_mmu_setup
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (3 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 04/15] target/arm: Move arm_pamax out of line Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 21:57   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 06/15] target/arm: Use MAKE_64BIT_MASK to compute indexmask Richard Henderson
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

Pass down the width of the output address from translation.
For now this is still just PAMax, but a subsequent patch will
compute the correct value from TCR_ELx.{I}PS.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index fa0824e12c..cf38ebd816 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11063,7 +11063,7 @@ do_fault:
  * false otherwise.
  */
 static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
-                               int inputsize, int stride)
+                               int inputsize, int stride, int outputsize)
 {
     const int grainsize = stride + 3;
     int startsizecheck;
@@ -11079,22 +11079,19 @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
     }
 
     if (is_aa64) {
-        CPUARMState *env = &cpu->env;
-        unsigned int pamax = arm_pamax(cpu);
-
         switch (stride) {
         case 13: /* 64KB Pages.  */
-            if (level == 0 || (level == 1 && pamax <= 42)) {
+            if (level == 0 || (level == 1 && outputsize <= 42)) {
                 return false;
             }
             break;
         case 11: /* 16KB Pages.  */
-            if (level == 0 || (level == 1 && pamax <= 40)) {
+            if (level == 0 || (level == 1 && outputsize <= 40)) {
                 return false;
             }
             break;
         case 9: /* 4KB Pages.  */
-            if (level == 0 && pamax <= 42) {
+            if (level == 0 && outputsize <= 42) {
                 return false;
             }
             break;
@@ -11103,8 +11100,8 @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
         }
 
         /* Inputsize checks.  */
-        if (inputsize > pamax &&
-            (arm_el_is_aa64(env, 1) || inputsize > 40)) {
+        if (inputsize > outputsize &&
+            (arm_el_is_aa64(&cpu->env, 1) || inputsize > 40)) {
             /* This is CONSTRAINED UNPREDICTABLE and we choose to fault.  */
             return false;
         }
@@ -11390,7 +11387,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
     target_ulong page_size;
     uint32_t attrs;
     int32_t stride;
-    int addrsize, inputsize;
+    int addrsize, inputsize, outputsize;
     TCR *tcr = regime_tcr(env, mmu_idx);
     int ap, ns, xn, pxn;
     uint32_t el = regime_el(env, mmu_idx);
@@ -11420,11 +11417,13 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
 
         addrsize = 64 - 8 * param.tbi;
         inputsize = 64 - param.tsz;
+        outputsize = arm_pamax(cpu);
     } else {
         param = aa32_va_parameters(env, address, mmu_idx);
         level = 1;
         addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
         inputsize = addrsize - param.tsz;
+        outputsize = 40;
     }
 
     /*
@@ -11509,7 +11508,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
 
         /* Check that the starting level is valid. */
         ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
-                                inputsize, stride);
+                                inputsize, stride, outputsize);
         if (!ok) {
             fault_type = ARMFault_Translation;
             goto do_fault;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 06/15] target/arm: Use MAKE_64BIT_MASK to compute indexmask
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (4 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 05/15] target/arm: Pass outputsize down to check_s2_mmu_setup Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-10 11:15   ` Philippe Mathieu-Daudé via
  2022-02-10  4:04 ` [PATCH v2 07/15] target/arm: Honor TCR_ELx.{I}PS Richard Henderson
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

The macro is a bit more readable than the inlined computation.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index cf38ebd816..94304804cb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11516,8 +11516,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
         level = startlevel;
     }
 
-    indexmask_grainsize = (1ULL << (stride + 3)) - 1;
-    indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
+    indexmask_grainsize = MAKE_64BIT_MASK(0, stride + 3);
+    indexmask = MAKE_64BIT_MASK(0, inputsize - (stride * (4 - level)));
 
     /* Now we can extract the actual base address from the TTBR */
     descaddr = extract64(ttbr, 0, 48);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 07/15] target/arm: Honor TCR_ELx.{I}PS
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (5 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 06/15] target/arm: Use MAKE_64BIT_MASK to compute indexmask Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 22:01   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 08/15] target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA Richard Henderson
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

This field controls the output (intermediate) physical address size
of the translation process.  V8 requires to raise an AddressSize
fault if the page tables are programmed incorrectly, such that any
intermediate descriptor address, or the final translated address,
is out of range.

Add a PS field to ARMVAParameters, and properly compute outputsize
in get_phys_addr_lpae.  Test the descaddr as extracted from TTBR
and from page table entries.

Restrict descaddrmask so that we won't raise the fault for v7.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/internals.h |  1 +
 target/arm/helper.c    | 72 ++++++++++++++++++++++++++++++++----------
 2 files changed, 57 insertions(+), 16 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index fefd1fb8d8..3d3d41ba2b 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1032,6 +1032,7 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
  */
 typedef struct ARMVAParameters {
     unsigned tsz    : 8;
+    unsigned ps     : 3;
     unsigned select : 1;
     bool tbi        : 1;
     bool epd        : 1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 94304804cb..015f992f02 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11147,17 +11147,19 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
 }
 #endif /* !CONFIG_USER_ONLY */
 
+/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
+static const uint8_t pamax_map[] = {
+    [0] = 32,
+    [1] = 36,
+    [2] = 40,
+    [3] = 42,
+    [4] = 44,
+    [5] = 48,
+};
+
 /* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
 unsigned int arm_pamax(ARMCPU *cpu)
 {
-    static const unsigned int pamax_map[] = {
-        [0] = 32,
-        [1] = 36,
-        [2] = 40,
-        [3] = 42,
-        [4] = 44,
-        [5] = 48,
-    };
     unsigned int parange =
         FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
 
@@ -11208,7 +11210,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
 {
     uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
     bool epd, hpd, using16k, using64k, tsz_oob;
-    int select, tsz, tbi, max_tsz, min_tsz;
+    int select, tsz, tbi, max_tsz, min_tsz, ps;
 
     if (!regime_has_2_ranges(mmu_idx)) {
         select = 0;
@@ -11222,6 +11224,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
             hpd = extract32(tcr, 24, 1);
         }
         epd = false;
+        ps = extract32(tcr, 16, 3);
     } else {
         /*
          * Bit 55 is always between the two regions, and is canonical for
@@ -11242,6 +11245,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
             epd = extract32(tcr, 23, 1);
             hpd = extract64(tcr, 42, 1);
         }
+        ps = extract64(tcr, 32, 3);
     }
 
     if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
@@ -11270,6 +11274,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
 
     return (ARMVAParameters) {
         .tsz = tsz,
+        .ps = ps,
         .select = select,
         .tbi = tbi,
         .epd = epd,
@@ -11397,6 +11402,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
 
     /* TODO: This code does not support shareability levels. */
     if (aarch64) {
+        int ps;
+
         param = aa64_va_parameters(env, address, mmu_idx,
                                    access_type != MMU_INST_FETCH);
         level = 0;
@@ -11417,7 +11424,16 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
 
         addrsize = 64 - 8 * param.tbi;
         inputsize = 64 - param.tsz;
-        outputsize = arm_pamax(cpu);
+
+        /*
+         * Bound PS by PARANGE to find the effective output address size.
+         * ID_AA64MMFR0 is a read-only register so values outside of the
+         * supported mappings can be considered an implementation error.
+         */
+        ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
+        ps = MIN(ps, param.ps);
+        assert(ps < ARRAY_SIZE(pamax_map));
+        outputsize = pamax_map[ps];
     } else {
         param = aa32_va_parameters(env, address, mmu_idx);
         level = 1;
@@ -11521,19 +11537,38 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
 
     /* Now we can extract the actual base address from the TTBR */
     descaddr = extract64(ttbr, 0, 48);
+
+    /*
+     * If the base address is out of range, raise AddressSizeFault.
+     * In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
+     * but we've just cleared the bits above 47, so simplify the test.
+     */
+    if (descaddr >> outputsize) {
+        level = 0;
+        fault_type = ARMFault_AddressSize;
+        goto do_fault;
+    }
+
     /*
      * We rely on this masking to clear the RES0 bits at the bottom of the TTBR
      * and also to mask out CnP (bit 0) which could validly be non-zero.
      */
     descaddr &= ~indexmask;
 
-    /* The address field in the descriptor goes up to bit 39 for ARMv7
-     * but up to bit 47 for ARMv8, but we use the descaddrmask
-     * up to bit 39 for AArch32, because we don't need other bits in that case
-     * to construct next descriptor address (anyway they should be all zeroes).
+    /*
+     * For AArch32, the address field in the descriptor goes up to bit 39
+     * for both v7 and v8.  However, for v8 the SBZ bits [47:40] must be 0
+     * or an AddressSize fault is raised.  So for v8 we extract those SBZ
+     * bits as part of the address, which will be checked via outputsize.
+     * For AArch64, the address field always goes up to bit 47 (with extra
+     * bits for FEAT_LPA placed elsewhere).  AArch64 implies v8.
      */
-    descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
-                   ~indexmask_grainsize;
+    if (arm_feature(env, ARM_FEATURE_V8)) {
+        descaddrmask = MAKE_64BIT_MASK(0, 48);
+    } else {
+        descaddrmask = MAKE_64BIT_MASK(0, 40);
+    }
+    descaddrmask &= ~indexmask_grainsize;
 
     /* Secure accesses start with the page table in secure memory and
      * can be downgraded to non-secure at any step. Non-secure accesses
@@ -11558,7 +11593,12 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
             /* Invalid, or the Reserved level 3 encoding */
             goto do_fault;
         }
+
         descaddr = descriptor & descaddrmask;
+        if (descaddr >> outputsize) {
+            fault_type = ARMFault_AddressSize;
+            goto do_fault;
+        }
 
         if ((descriptor & 2) && (level < 3)) {
             /* Table entry. The top five bits are attributes which may
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 08/15] target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (6 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 07/15] target/arm: Honor TCR_ELx.{I}PS Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 22:03   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 09/15] target/arm: Implement FEAT_LVA Richard Henderson
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

The original A.a revision of the AArch64 ARM required that we
force-extend the addresses in these registers from 49 bits.
This language has been loosened via a combination of IMPLEMENTATION
DEFINED and CONSTRAINTED UNPREDICTABLE to allow consideration of
the entire aligned address.

This means that we do not have to consider whether or not FEAT_LVA
is enabled, and decide from which bit an address might need to be
extended.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 015f992f02..e5050816cf 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6421,11 +6421,18 @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     ARMCPU *cpu = env_archcpu(env);
     int i = ri->crm;
 
-    /* Bits [63:49] are hardwired to the value of bit [48]; that is, the
-     * register reads and behaves as if values written are sign extended.
+    /*
      * Bits [1:0] are RES0.
+     *
+     * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
+     * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
+     * they contain the value written.  It is CONSTRAINED UNPREDICTABLE
+     * whether the RESS bits are ignored when comparing an address.
+     *
+     * Therefore we are allowed to compare the entire register, which lets
+     * us avoid considering whether or not FEAT_LVA is actually enabled.
      */
-    value = sextract64(value, 0, 49) & ~3ULL;
+    value &= ~3ULL;
 
     raw_write(env, ri, value);
     hw_watchpoint_update(cpu, i);
@@ -6471,10 +6478,19 @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
     case 0: /* unlinked address match */
     case 1: /* linked address match */
     {
-        /* Bits [63:49] are hardwired to the value of bit [48]; that is,
-         * we behave as if the register was sign extended. Bits [1:0] are
-         * RES0. The BAS field is used to allow setting breakpoints on 16
-         * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether
+        /*
+         * Bits [1:0] are RES0.
+         *
+         * It is IMPLEMENTATION DEFINED whether bits [63:49]
+         * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
+         * of the VA field ([48] or [52] for FEAT_LVA), or whether the
+         * value is read as written.  It is CONSTRAINED UNPREDICTABLE
+         * whether the RESS bits are ignored when comparing an address.
+         * Therefore we are allowed to compare the entire register, which
+         * lets us avoid considering whether FEAT_LVA is actually enabled.
+         *
+         * The BAS field is used to allow setting breakpoints on 16-bit
+         * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
          * a bp will fire if the addresses covered by the bp and the addresses
          * covered by the insn overlap but the insn doesn't start at the
          * start of the bp address range. We choose to require the insn and
@@ -6487,7 +6503,7 @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
          * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
          */
         int bas = extract64(bcr, 5, 4);
-        addr = sextract64(bvr, 0, 49) & ~3ULL;
+        addr = bvr & ~3ULL;
         if (bas == 0) {
             return;
         }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 09/15] target/arm: Implement FEAT_LVA
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (7 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 08/15] target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 22:05   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 10/15] target/arm: Implement FEAT_LPA Richard Henderson
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

This feature is relatively small, as it applies only to
64k pages and thus requires no additional changes to the
table descriptor walking algorithm, only a change to the
minimum TSZ (which is the inverse of the maximum virtual
address space size).

Note that this feature widens VBAR_ELx, but we already
treat the register as being 64 bits wide.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu-param.h | 2 +-
 target/arm/cpu.h       | 5 +++++
 target/arm/cpu64.c     | 1 +
 target/arm/helper.c    | 9 ++++++++-
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index 7f38d33b8e..5f9c288b1a 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -11,7 +11,7 @@
 #ifdef TARGET_AARCH64
 # define TARGET_LONG_BITS             64
 # define TARGET_PHYS_ADDR_SPACE_BITS  48
-# define TARGET_VIRT_ADDR_SPACE_BITS  48
+# define TARGET_VIRT_ADDR_SPACE_BITS  52
 #else
 # define TARGET_LONG_BITS             32
 # define TARGET_PHYS_ADDR_SPACE_BITS  40
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c6a4d50e82..c52d56f669 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -4289,6 +4289,11 @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
 }
 
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
+{
+    return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
+}
+
 static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
 {
     return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 8786be7783..d80a7eafac 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -781,6 +781,7 @@ static void aarch64_max_initfn(Object *obj)
         t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
         t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
         t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
+        t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LPA */
         cpu->isar.id_aa64mmfr2 = t;
 
         t = cpu->isar.id_aa64zfr0;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index e5050816cf..62935b06d0 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11269,7 +11269,14 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
     } else {
         max_tsz = 39;
     }
-    min_tsz = 16;  /* TODO: ARMv8.2-LVA  */
+
+    min_tsz = 16;
+    if (using64k) {
+        if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
+            min_tsz = 12;
+        }
+    }
+    /* TODO: FEAT_LPA2 */
 
     if (tsz > max_tsz) {
         tsz = max_tsz;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 10/15] target/arm: Implement FEAT_LPA
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (8 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 09/15] target/arm: Implement FEAT_LVA Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 22:06   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 11/15] target/arm: Extend arm_fi_to_lfsc to level -1 Richard Henderson
                   ` (6 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

This feature widens physical addresses (and intermediate physical
addresses for 2-stage translation) from 48 to 52 bits, when using
64k pages.  The only thing left at this point is to handle the
extra bits in the TTBR and in the table descriptors.

Note that PAR_EL1 and HPFAR_EL2 are nominally extended, but we don't
mask out the high bits when writing to those registers, so no changes
are required there.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu-param.h |  2 +-
 target/arm/cpu64.c     |  2 +-
 target/arm/helper.c    | 19 ++++++++++++++++---
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index 5f9c288b1a..b59d505761 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -10,7 +10,7 @@
 
 #ifdef TARGET_AARCH64
 # define TARGET_LONG_BITS             64
-# define TARGET_PHYS_ADDR_SPACE_BITS  48
+# define TARGET_PHYS_ADDR_SPACE_BITS  52
 # define TARGET_VIRT_ADDR_SPACE_BITS  52
 #else
 # define TARGET_LONG_BITS             32
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index d80a7eafac..707ae7767f 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -765,7 +765,7 @@ static void aarch64_max_initfn(Object *obj)
         cpu->isar.id_aa64pfr1 = t;
 
         t = cpu->isar.id_aa64mmfr0;
-        t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */
+        t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
         cpu->isar.id_aa64mmfr0 = t;
 
         t = cpu->isar.id_aa64mmfr1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 62935b06d0..9b1b1b2611 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11171,6 +11171,7 @@ static const uint8_t pamax_map[] = {
     [3] = 42,
     [4] = 44,
     [5] = 48,
+    [6] = 52,
 };
 
 /* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
@@ -11562,11 +11563,15 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
     descaddr = extract64(ttbr, 0, 48);
 
     /*
-     * If the base address is out of range, raise AddressSizeFault.
+     * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [5:2] of TTBR.
+     *
+     * Otherwise, if the base address is out of range, raise AddressSizeFault.
      * In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
      * but we've just cleared the bits above 47, so simplify the test.
      */
-    if (descaddr >> outputsize) {
+    if (outputsize > 48) {
+        descaddr |= extract64(ttbr, 2, 4) << 48;
+    } else if (descaddr >> outputsize) {
         level = 0;
         fault_type = ARMFault_AddressSize;
         goto do_fault;
@@ -11618,7 +11623,15 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
         }
 
         descaddr = descriptor & descaddrmask;
-        if (descaddr >> outputsize) {
+
+        /*
+         * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
+         * of descriptor.  Otherwise, if descaddr is out of range, raise
+         * AddressSizeFault.
+         */
+        if (outputsize > 48) {
+            descaddr |= extract64(descriptor, 12, 4) << 48;
+        } else if (descaddr >> outputsize) {
             fault_type = ARMFault_AddressSize;
             goto do_fault;
         }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 11/15] target/arm: Extend arm_fi_to_lfsc to level -1
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (9 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 10/15] target/arm: Implement FEAT_LPA Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 22:11   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 12/15] target/arm: Introduce tlbi_aa64_get_range Richard Henderson
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

With FEAT_LPA2, rather than introducing translation level 4,
we introduce level -1, below the current level 0.  Extend
arm_fi_to_lfsc to handle these faults.

Assert that this new translation level does not leak into
faults types for which it is not defined, which allows some
masking of fi->level to be removed.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/internals.h | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 3d3d41ba2b..00af41d792 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -462,28 +462,51 @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
     case ARMFault_None:
         return 0;
     case ARMFault_AddressSize:
-        fsc = fi->level & 3;
+        assert(fi->level >= -1 && fi->level <= 3);
+        if (fi->level < 0) {
+            fsc = 0b101001;
+        } else {
+            fsc = fi->level;
+        }
         break;
     case ARMFault_AccessFlag:
-        fsc = (fi->level & 3) | (0x2 << 2);
+        assert(fi->level >= 0 && fi->level <= 3);
+        fsc = 0b001000 | fi->level;
         break;
     case ARMFault_Permission:
-        fsc = (fi->level & 3) | (0x3 << 2);
+        assert(fi->level >= 0 && fi->level <= 3);
+        fsc = 0b001100 | fi->level;
         break;
     case ARMFault_Translation:
-        fsc = (fi->level & 3) | (0x1 << 2);
+        assert(fi->level >= -1 && fi->level <= 3);
+        if (fi->level < 0) {
+            fsc = 0b101011;
+        } else {
+            fsc = 0b000100 | fi->level;
+        }
         break;
     case ARMFault_SyncExternal:
         fsc = 0x10 | (fi->ea << 12);
         break;
     case ARMFault_SyncExternalOnWalk:
-        fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
+        assert(fi->level >= -1 && fi->level <= 3);
+        if (fi->level < 0) {
+            fsc = 0b010011;
+        } else {
+            fsc = 0b010100 | fi->level;
+        }
+        fsc |= fi->ea << 12;
         break;
     case ARMFault_SyncParity:
         fsc = 0x18;
         break;
     case ARMFault_SyncParityOnWalk:
-        fsc = (fi->level & 3) | (0x7 << 2);
+        assert(fi->level >= -1 && fi->level <= 3);
+        if (fi->level < 0) {
+            fsc = 0b011011;
+        } else {
+            fsc = 0b011100 | fi->level;
+        }
         break;
     case ARMFault_AsyncParity:
         fsc = 0x19;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 12/15] target/arm: Introduce tlbi_aa64_get_range
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (10 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 11/15] target/arm: Extend arm_fi_to_lfsc to level -1 Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 22:14   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 13/15] target/arm: Fix TLBIRange.base for 16k and 64k pages Richard Henderson
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

Merge tlbi_aa64_range_get_length and tlbi_aa64_range_get_base,
returning a structure containing both results.  Pass in the
ARMMMUIdx, rather than the digested two_ranges boolean.

This is in preparation for FEAT_LPA2, where the interpretation
of 'value' depends on the effective value of DS for the regime.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 58 +++++++++++++++++++--------------------------
 1 file changed, 24 insertions(+), 34 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 9b1b1b2611..8b1899ceef 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4509,70 +4509,60 @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
 }
 
 #ifdef TARGET_AARCH64
-static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
-                                           uint64_t value)
-{
-    unsigned int page_shift;
-    unsigned int page_size_granule;
-    uint64_t num;
-    uint64_t scale;
-    uint64_t exponent;
+typedef struct {
+    uint64_t base;
     uint64_t length;
+} TLBIRange;
+
+static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
+                                     uint64_t value)
+{
+    unsigned int page_size_granule, page_shift, num, scale, exponent;
+    TLBIRange ret = { };
 
-    num = extract64(value, 39, 5);
-    scale = extract64(value, 44, 2);
     page_size_granule = extract64(value, 46, 2);
 
     if (page_size_granule == 0) {
         qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
                       page_size_granule);
-        return 0;
+        return ret;
     }
 
     page_shift = (page_size_granule - 1) * 2 + 12;
-
+    num = extract64(value, 39, 5);
+    scale = extract64(value, 44, 2);
     exponent = (5 * scale) + 1;
-    length = (num + 1) << (exponent + page_shift);
 
-    return length;
-}
+    ret.length = (num + 1) << (exponent + page_shift);
 
-static uint64_t tlbi_aa64_range_get_base(CPUARMState *env, uint64_t value,
-                                        bool two_ranges)
-{
-    /* TODO: ARMv8.7 FEAT_LPA2 */
-    uint64_t pageaddr;
-
-    if (two_ranges) {
-        pageaddr = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
+    if (regime_has_2_ranges(mmuidx)) {
+        ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
     } else {
-        pageaddr = extract64(value, 0, 37) << TARGET_PAGE_BITS;
+        ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
     }
 
-    return pageaddr;
+    return ret;
 }
 
 static void do_rvae_write(CPUARMState *env, uint64_t value,
                           int idxmap, bool synced)
 {
     ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
-    bool two_ranges = regime_has_2_ranges(one_idx);
-    uint64_t baseaddr, length;
+    TLBIRange range;
     int bits;
 
-    baseaddr = tlbi_aa64_range_get_base(env, value, two_ranges);
-    length = tlbi_aa64_range_get_length(env, value);
-    bits = tlbbits_for_regime(env, one_idx, baseaddr);
+    range = tlbi_aa64_get_range(env, one_idx, value);
+    bits = tlbbits_for_regime(env, one_idx, range.base);
 
     if (synced) {
         tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
-                                                  baseaddr,
-                                                  length,
+                                                  range.base,
+                                                  range.length,
                                                   idxmap,
                                                   bits);
     } else {
-        tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr,
-                                  length, idxmap, bits);
+        tlb_flush_range_by_mmuidx(env_cpu(env), range.base,
+                                  range.length, idxmap, bits);
     }
 }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 13/15] target/arm: Fix TLBIRange.base for 16k and 64k pages
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (11 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 12/15] target/arm: Introduce tlbi_aa64_get_range Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 22:18   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 14/15] target/arm: Validate tlbi TG matches translation granule in use Richard Henderson
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

The shift of the BaseADDR field depends on the translation
granule in use.

Fixes: 84940ed8255 ("target/arm: Add support for FEAT_TLBIRANGE")
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8b1899ceef..e2551e693b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4536,10 +4536,11 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
     ret.length = (num + 1) << (exponent + page_shift);
 
     if (regime_has_2_ranges(mmuidx)) {
-        ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
+        ret.base = sextract64(value, 0, 37);
     } else {
-        ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
+        ret.base = extract64(value, 0, 37);
     }
+    ret.base <<= page_shift;
 
     return ret;
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 14/15] target/arm: Validate tlbi TG matches translation granule in use
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (12 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 13/15] target/arm: Fix TLBIRange.base for 16k and 64k pages Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-15 22:24   ` Peter Maydell
  2022-02-10  4:04 ` [PATCH v2 15/15] target/arm: Implement FEAT_LPA2 Richard Henderson
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

For FEAT_LPA2, we will need other ARMVAParameters, which themselves
depend on the translation granule in use.  We might as well validate
that the given TG matches; the architecture "does not require that
the instruction invalidates any entries" if this is not true.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index e2551e693b..771de959dd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4518,12 +4518,16 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
                                      uint64_t value)
 {
     unsigned int page_size_granule, page_shift, num, scale, exponent;
+    /* Extract one bit to represent the va selector in use. */
+    uint64_t select = sextract64(value, 36, 1);
+    ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
     TLBIRange ret = { };
 
     page_size_granule = extract64(value, 46, 2);
 
-    if (page_size_granule == 0) {
-        qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
+    /* The granule encoded in value must match the granule in use. */
+    if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
+        qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
                       page_size_granule);
         return ret;
     }
@@ -4535,7 +4539,7 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
 
     ret.length = (num + 1) << (exponent + page_shift);
 
-    if (regime_has_2_ranges(mmuidx)) {
+    if (param.select) {
         ret.base = sextract64(value, 0, 37);
     } else {
         ret.base = extract64(value, 0, 37);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 15/15] target/arm: Implement FEAT_LPA2
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (13 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 14/15] target/arm: Validate tlbi TG matches translation granule in use Richard Henderson
@ 2022-02-10  4:04 ` Richard Henderson
  2022-02-16 17:50   ` Peter Maydell
  2022-02-16 17:51 ` [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Peter Maydell
  2022-02-17 14:07 ` Peter Maydell
  16 siblings, 1 reply; 36+ messages in thread
From: Richard Henderson @ 2022-02-10  4:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

This feature widens physical addresses (and intermediate physical
addresses for 2-stage translation) from 48 to 52 bits, when using
4k or 16k pages.

This introduces the DS bit to TCR_ELx, which is RES0 unless the
page size is enabled and supports LPA2, resulting in the effective
value of DS for a given table walk.  The DS bit changes the format
of the page table descriptor slightly, moving the PS field out to
TCR so that all pages have the same sharability and repurposing
those bits of the page table descriptor for the highest bits of
the output address.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v2: Check DS in tlbi_aa64_get_range.
    Check TGRAN4_2 and TGRAN16_2.
---
 target/arm/cpu.h       |  22 +++++++++
 target/arm/internals.h |   2 +
 target/arm/cpu64.c     |   4 ++
 target/arm/helper.c    | 102 +++++++++++++++++++++++++++++++++++------
 4 files changed, 115 insertions(+), 15 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c52d56f669..24d9fff170 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -4284,6 +4284,28 @@ static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
 }
 
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
+{
+    return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
+}
+
+static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
+{
+    unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
+    return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
+}
+
+static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
+{
+    return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
+}
+
+static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
+{
+    unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
+    return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
+}
+
 static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
 {
     return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 00af41d792..a34be2e459 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1056,6 +1056,7 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
 typedef struct ARMVAParameters {
     unsigned tsz    : 8;
     unsigned ps     : 3;
+    unsigned sh     : 2;
     unsigned select : 1;
     bool tbi        : 1;
     bool epd        : 1;
@@ -1063,6 +1064,7 @@ typedef struct ARMVAParameters {
     bool using16k   : 1;
     bool using64k   : 1;
     bool tsz_oob    : 1;  /* tsz has been clamped to legal range */
+    bool ds         : 1;
 } ARMVAParameters;
 
 ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 707ae7767f..9382c19e54 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -766,6 +766,10 @@ static void aarch64_max_initfn(Object *obj)
 
         t = cpu->isar.id_aa64mmfr0;
         t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
+        t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* FEAT_LPA2: 52 bits */
+        t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1);  /* FEAT_LPA2: 52 bits */
+        t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* FEAT_LPA2: 52 bits */
+        t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3);  /* FEAT_LPA2: 52 bits */
         cpu->isar.id_aa64mmfr0 = t;
 
         t = cpu->isar.id_aa64mmfr1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 771de959dd..bf694d8324 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4544,6 +4544,14 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
     } else {
         ret.base = extract64(value, 0, 37);
     }
+    if (param.ds) {
+        /*
+         * With DS=1, BaseADDR is always shifted 16 so that it is able
+         * to address all 52 va bits.  The input address is perforce
+         * aligned on a 64k boundary regardless of translation granule.
+         */
+        page_shift = 16;
+    }
     ret.base <<= page_shift;
 
     return ret;
@@ -11079,8 +11087,13 @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
     const int grainsize = stride + 3;
     int startsizecheck;
 
-    /* Negative levels are never allowed.  */
-    if (level < 0) {
+    /*
+     * Negative levels are usually not allowed...
+     * Except for FEAT_LPA2, 4k page table, 52-bit address space, which
+     * begins with level -1.  Note that previous feature tests will have
+     * eliminated this combination if it is not enabled.
+     */
+    if (level < (inputsize == 52 && stride == 9 ? -1 : 0)) {
         return false;
     }
 
@@ -11221,8 +11234,9 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
                                    ARMMMUIdx mmu_idx, bool data)
 {
     uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
-    bool epd, hpd, using16k, using64k, tsz_oob;
-    int select, tsz, tbi, max_tsz, min_tsz, ps;
+    bool epd, hpd, using16k, using64k, tsz_oob, ds;
+    int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
+    ARMCPU *cpu = env_archcpu(env);
 
     if (!regime_has_2_ranges(mmu_idx)) {
         select = 0;
@@ -11236,7 +11250,9 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
             hpd = extract32(tcr, 24, 1);
         }
         epd = false;
+        sh = extract32(tcr, 12, 2);
         ps = extract32(tcr, 16, 3);
+        ds = extract64(tcr, 32, 1);
     } else {
         /*
          * Bit 55 is always between the two regions, and is canonical for
@@ -11246,6 +11262,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
         if (!select) {
             tsz = extract32(tcr, 0, 6);
             epd = extract32(tcr, 7, 1);
+            sh = extract32(tcr, 12, 2);
             using64k = extract32(tcr, 14, 1);
             using16k = extract32(tcr, 15, 1);
             hpd = extract64(tcr, 41, 1);
@@ -11255,24 +11272,51 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
             using64k = tg == 3;
             tsz = extract32(tcr, 16, 6);
             epd = extract32(tcr, 23, 1);
+            sh = extract32(tcr, 28, 2);
             hpd = extract64(tcr, 42, 1);
         }
         ps = extract64(tcr, 32, 3);
+        ds = extract64(tcr, 59, 1);
     }
 
-    if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
+    if (cpu_isar_feature(aa64_st, cpu)) {
         max_tsz = 48 - using64k;
     } else {
         max_tsz = 39;
     }
 
+    /*
+     * DS is RES0 unless FEAT_LPA2 is supported for the given page size;
+     * adjust the effective value of DS, as documented.
+     */
     min_tsz = 16;
     if (using64k) {
-        if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
+        if (cpu_isar_feature(aa64_lva, cpu)) {
+            min_tsz = 12;
+        }
+        ds = false;
+    } else if (ds) {
+        switch (mmu_idx) {
+        case ARMMMUIdx_Stage2:
+        case ARMMMUIdx_Stage2_S:
+            if (using16k) {
+                ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
+            } else {
+                ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
+            }
+            break;
+        default:
+            if (using16k) {
+                ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
+            } else {
+                ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
+            }
+            break;
+        }
+        if (ds) {
             min_tsz = 12;
         }
     }
-    /* TODO: FEAT_LPA2 */
 
     if (tsz > max_tsz) {
         tsz = max_tsz;
@@ -11294,6 +11338,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
     return (ARMVAParameters) {
         .tsz = tsz,
         .ps = ps,
+        .sh = sh,
         .select = select,
         .tbi = tbi,
         .epd = epd,
@@ -11301,6 +11346,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
         .using16k = using16k,
         .using64k = using64k,
         .tsz_oob = tsz_oob,
+        .ds = ds,
     };
 }
 
@@ -11526,10 +11572,19 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
          * VTCR_EL2.SL0 field (whose interpretation depends on the page size)
          */
         uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
+        uint32_t sl2 = extract64(tcr->raw_tcr, 33, 1);
         uint32_t startlevel;
         bool ok;
 
-        if (!aarch64 || stride == 9) {
+        /* SL2 is RES0 unless DS=1 & 4kb granule. */
+        if (param.ds && stride == 9 && sl2) {
+            if (sl0 != 0) {
+                level = 0;
+                fault_type = ARMFault_Translation;
+                goto do_fault;
+            }
+            startlevel = -1;
+        } else if (!aarch64 || stride == 9) {
             /* AArch32 or 4KB pages */
             startlevel = 2 - sl0;
 
@@ -11583,10 +11638,12 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
      * for both v7 and v8.  However, for v8 the SBZ bits [47:40] must be 0
      * or an AddressSize fault is raised.  So for v8 we extract those SBZ
      * bits as part of the address, which will be checked via outputsize.
-     * For AArch64, the address field always goes up to bit 47 (with extra
-     * bits for FEAT_LPA placed elsewhere).  AArch64 implies v8.
+     * For AArch64, the address field goes up to bit 47, or 49 with FEAT_LPA2;
+     * the highest bits of a 52-bit output are placed elsewhere.
      */
-    if (arm_feature(env, ARM_FEATURE_V8)) {
+    if (param.ds) {
+        descaddrmask = MAKE_64BIT_MASK(0, 50);
+    } else if (arm_feature(env, ARM_FEATURE_V8)) {
         descaddrmask = MAKE_64BIT_MASK(0, 48);
     } else {
         descaddrmask = MAKE_64BIT_MASK(0, 40);
@@ -11621,11 +11678,16 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
 
         /*
          * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
-         * of descriptor.  Otherwise, if descaddr is out of range, raise
-         * AddressSizeFault.
+         * of descriptor.  For FEAT_LPA2 and effective DS, bits [51:50] of
+         * descaddr are in [9:8].  Otherwise, if descaddr is out of range,
+         * raise AddressSizeFault.
          */
         if (outputsize > 48) {
-            descaddr |= extract64(descriptor, 12, 4) << 48;
+            if (param.ds) {
+                descaddr |= extract64(descriptor, 8, 2) << 50;
+            } else {
+                descaddr |= extract64(descriptor, 12, 4) << 48;
+            }
         } else if (descaddr >> outputsize) {
             fault_type = ARMFault_AddressSize;
             goto do_fault;
@@ -11719,7 +11781,17 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
         assert(attrindx <= 7);
         cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
     }
-    cacheattrs->shareability = extract32(attrs, 6, 2);
+
+    /*
+     * For FEAT_LPA2 and effective DS, the SH field in the attributes
+     * was re-purposed for output address bits.  The SH attribute in
+     * that case comes from TCR_ELx, which we extracted earlier.
+     */
+    if (param.ds) {
+        cacheattrs->shareability = param.sh;
+    } else {
+        cacheattrs->shareability = extract32(attrs, 6, 2);
+    }
 
     *phys_ptr = descaddr;
     *page_size_ptr = page_size;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 01/15] hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N>
  2022-02-10  4:04 ` [PATCH v2 01/15] hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N> Richard Henderson
@ 2022-02-10 11:15   ` Philippe Mathieu-Daudé via
  0 siblings, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-02-10 11:15 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, qemu-arm, alex.bennee

On 10/2/22 05:04, Richard Henderson wrote:
> Add new macros to manipulate signed fields within the register.
> 
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   include/hw/registerfields.h | 48 ++++++++++++++++++++++++++++++++++++-
>   1 file changed, 47 insertions(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 06/15] target/arm: Use MAKE_64BIT_MASK to compute indexmask
  2022-02-10  4:04 ` [PATCH v2 06/15] target/arm: Use MAKE_64BIT_MASK to compute indexmask Richard Henderson
@ 2022-02-10 11:15   ` Philippe Mathieu-Daudé via
  0 siblings, 0 replies; 36+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-02-10 11:15 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, qemu-arm

On 10/2/22 05:04, Richard Henderson wrote:
> The macro is a bit more readable than the inlined computation.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/arm/helper.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 02/15] target/arm: Set TCR_EL1.TSZ for user-only
  2022-02-10  4:04 ` [PATCH v2 02/15] target/arm: Set TCR_EL1.TSZ for user-only Richard Henderson
@ 2022-02-15 21:50   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 21:50 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Set this as the kernel would, to 48 bits, to keep the computation
> of the address space correct for PAuth.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 5a9c02a256..92f19f919a 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -206,10 +206,11 @@ static void arm_cpu_reset(DeviceState *dev)
>                  aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
>          }
>          /*
> +         * Enable 48-bit address space (TODO: take reserved_va into account).
>           * Enable TBI0 but not TBI1.
>           * Note that this must match useronly_clean_ptr.
>           */
> -        env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
> +        env->cp15.tcr_el[1].raw_tcr = 5 | (1ULL << 37);

I think the kernel defaults to 39 bits if it's built for 4K pages
(probably the usual setup), but OTOH we've been effectively
using 48 bits previously so not changing that seems the best
option.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 03/15] target/arm: Fault on invalid TCR_ELx.TxSZ
  2022-02-10  4:04 ` [PATCH v2 03/15] target/arm: Fault on invalid TCR_ELx.TxSZ Richard Henderson
@ 2022-02-15 21:51   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 21:51 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Without FEAT_LVA, the behaviour of programming an invalid value
> is IMPLEMENTATION DEFINED.  With FEAT_LVA, programming an invalid
> minimum value requires a Translation fault.
>
> It is most self-consistent to choose to generate the fault always.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> v2: Continue to bound in aa64_va_parameters, so that PAuth gets
>     something it can use, but provide a flag for get_phys_addr_lpae
>     to raise a fault.
> ---

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 04/15] target/arm: Move arm_pamax out of line
  2022-02-10  4:04 ` [PATCH v2 04/15] target/arm: Move arm_pamax out of line Richard Henderson
@ 2022-02-15 21:51   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 21:51 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-arm, alex.bennee, qemu-devel, Philippe Mathieu-Daudé

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> We will shortly share parts of this function with other portions
> of address translation.
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/internals.h | 19 +------------------
>  target/arm/helper.c    | 22 ++++++++++++++++++++++
>  2 files changed, 23 insertions(+), 18 deletions(-)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 05/15] target/arm: Pass outputsize down to check_s2_mmu_setup
  2022-02-10  4:04 ` [PATCH v2 05/15] target/arm: Pass outputsize down to check_s2_mmu_setup Richard Henderson
@ 2022-02-15 21:57   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 21:57 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Pass down the width of the output address from translation.
> For now this is still just PAMax, but a subsequent patch will
> compute the correct value from TCR_ELx.{I}PS.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 07/15] target/arm: Honor TCR_ELx.{I}PS
  2022-02-10  4:04 ` [PATCH v2 07/15] target/arm: Honor TCR_ELx.{I}PS Richard Henderson
@ 2022-02-15 22:01   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 22:01 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This field controls the output (intermediate) physical address size
> of the translation process.  V8 requires to raise an AddressSize
> fault if the page tables are programmed incorrectly, such that any
> intermediate descriptor address, or the final translated address,
> is out of range.
>
> Add a PS field to ARMVAParameters, and properly compute outputsize
> in get_phys_addr_lpae.  Test the descaddr as extracted from TTBR
> and from page table entries.
>
> Restrict descaddrmask so that we won't raise the fault for v7.
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---


Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 08/15] target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA
  2022-02-10  4:04 ` [PATCH v2 08/15] target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA Richard Henderson
@ 2022-02-15 22:03   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 22:03 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The original A.a revision of the AArch64 ARM required that we
> force-extend the addresses in these registers from 49 bits.
> This language has been loosened via a combination of IMPLEMENTATION
> DEFINED and CONSTRAINTED UNPREDICTABLE to allow consideration of
> the entire aligned address.
>
> This means that we do not have to consider whether or not FEAT_LVA
> is enabled, and decide from which bit an address might need to be
> extended.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 09/15] target/arm: Implement FEAT_LVA
  2022-02-10  4:04 ` [PATCH v2 09/15] target/arm: Implement FEAT_LVA Richard Henderson
@ 2022-02-15 22:05   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 22:05 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This feature is relatively small, as it applies only to
> 64k pages and thus requires no additional changes to the
> table descriptor walking algorithm, only a change to the
> minimum TSZ (which is the inverse of the maximum virtual
> address space size).
>
> Note that this feature widens VBAR_ELx, but we already
> treat the register as being 64 bits wide.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu-param.h | 2 +-
>  target/arm/cpu.h       | 5 +++++
>  target/arm/cpu64.c     | 1 +
>  target/arm/helper.c    | 9 ++++++++-
>  4 files changed, 15 insertions(+), 2 deletions(-)

Need to add FEAT_LVA to the list of emulated features in
docs/system/arm/emulation.rst.

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 10/15] target/arm: Implement FEAT_LPA
  2022-02-10  4:04 ` [PATCH v2 10/15] target/arm: Implement FEAT_LPA Richard Henderson
@ 2022-02-15 22:06   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 22:06 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This feature widens physical addresses (and intermediate physical
> addresses for 2-stage translation) from 48 to 52 bits, when using
> 64k pages.  The only thing left at this point is to handle the
> extra bits in the TTBR and in the table descriptors.
>
> Note that PAR_EL1 and HPFAR_EL2 are nominally extended, but we don't
> mask out the high bits when writing to those registers, so no changes
> are required there.
>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu-param.h |  2 +-
>  target/arm/cpu64.c     |  2 +-
>  target/arm/helper.c    | 19 ++++++++++++++++---
>  3 files changed, 18 insertions(+), 5 deletions(-)

Need to update docs/system/arm/emulation.rst

-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 11/15] target/arm: Extend arm_fi_to_lfsc to level -1
  2022-02-10  4:04 ` [PATCH v2 11/15] target/arm: Extend arm_fi_to_lfsc to level -1 Richard Henderson
@ 2022-02-15 22:11   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 22:11 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> With FEAT_LPA2, rather than introducing translation level 4,
> we introduce level -1, below the current level 0.  Extend
> arm_fi_to_lfsc to handle these faults.
>
> Assert that this new translation level does not leak into
> faults types for which it is not defined, which allows some
> masking of fi->level to be removed.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 12/15] target/arm: Introduce tlbi_aa64_get_range
  2022-02-10  4:04 ` [PATCH v2 12/15] target/arm: Introduce tlbi_aa64_get_range Richard Henderson
@ 2022-02-15 22:14   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 22:14 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Merge tlbi_aa64_range_get_length and tlbi_aa64_range_get_base,
> returning a structure containing both results.  Pass in the
> ARMMMUIdx, rather than the digested two_ranges boolean.
>
> This is in preparation for FEAT_LPA2, where the interpretation
> of 'value' depends on the effective value of DS for the regime.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 13/15] target/arm: Fix TLBIRange.base for 16k and 64k pages
  2022-02-10  4:04 ` [PATCH v2 13/15] target/arm: Fix TLBIRange.base for 16k and 64k pages Richard Henderson
@ 2022-02-15 22:18   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 22:18 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The shift of the BaseADDR field depends on the translation
> granule in use.
>
> Fixes: 84940ed8255 ("target/arm: Add support for FEAT_TLBIRANGE")
> Reported-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/helper.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 14/15] target/arm: Validate tlbi TG matches translation granule in use
  2022-02-10  4:04 ` [PATCH v2 14/15] target/arm: Validate tlbi TG matches translation granule in use Richard Henderson
@ 2022-02-15 22:24   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-15 22:24 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> For FEAT_LPA2, we will need other ARMVAParameters, which themselves
> depend on the translation granule in use.  We might as well validate
> that the given TG matches; the architecture "does not require that
> the instruction invalidates any entries" if this is not true.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 15/15] target/arm: Implement FEAT_LPA2
  2022-02-10  4:04 ` [PATCH v2 15/15] target/arm: Implement FEAT_LPA2 Richard Henderson
@ 2022-02-16 17:50   ` Peter Maydell
  0 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-16 17:50 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This feature widens physical addresses (and intermediate physical
> addresses for 2-stage translation) from 48 to 52 bits, when using
> 4k or 16k pages.
>
> This introduces the DS bit to TCR_ELx, which is RES0 unless the
> page size is enabled and supports LPA2, resulting in the effective
> value of DS for a given table walk.  The DS bit changes the format
> of the page table descriptor slightly, moving the PS field out to
> TCR so that all pages have the same sharability and repurposing
> those bits of the page table descriptor for the highest bits of
> the output address.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (14 preceding siblings ...)
  2022-02-10  4:04 ` [PATCH v2 15/15] target/arm: Implement FEAT_LPA2 Richard Henderson
@ 2022-02-16 17:51 ` Peter Maydell
  2022-02-17 14:07 ` Peter Maydell
  16 siblings, 0 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-16 17:51 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Changes for v2:
>   * Introduce FIELD_SEX64, instead of open-coding w/ sextract64.
>   * Set TCR_EL1 more completely for user-only.
>   * Continue to bound tsz within aa64_va_parameters;
>     provide an out-of-bound indicator for raising AddressSize fault.
>   * Split IPS patch.
>   * Fix debug registers for LVA.
>   * Fix long-format fsc for LPA2.
>   * Fix TLBI page shift.
>   * Validate TLBI granule vs TCR granule.
>
> Not done:
>   * Validate translation levels which accept blocks.
>
> There is still no upstream kernel support for FEAT_LPA2,
> so that is essentially untested.

Is this ready to go into the tree, from your point of view ?
(If it is, I can add the docs changes when I put it into target-arm.)

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features
  2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
                   ` (15 preceding siblings ...)
  2022-02-16 17:51 ` [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Peter Maydell
@ 2022-02-17 14:07 ` Peter Maydell
  2022-02-17 17:37   ` Alex Bennée
  2022-02-23 21:08   ` Richard Henderson
  16 siblings, 2 replies; 36+ messages in thread
From: Peter Maydell @ 2022-02-17 14:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, alex.bennee, qemu-devel

On Thu, 10 Feb 2022 at 04:04, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Changes for v2:
>   * Introduce FIELD_SEX64, instead of open-coding w/ sextract64.
>   * Set TCR_EL1 more completely for user-only.
>   * Continue to bound tsz within aa64_va_parameters;
>     provide an out-of-bound indicator for raising AddressSize fault.
>   * Split IPS patch.
>   * Fix debug registers for LVA.
>   * Fix long-format fsc for LPA2.
>   * Fix TLBI page shift.
>   * Validate TLBI granule vs TCR granule.
>
> Not done:
>   * Validate translation levels which accept blocks.
>
> There is still no upstream kernel support for FEAT_LPA2,
> so that is essentially untested.

This series seems to break 'make check-acceptance':

 (01/59) tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv2:
INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred:
Timeout reached\nOriginal status: ERROR\n{'name':
'01-tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv2',
'logdir': '/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-clang/tests/results/j...
(900.74 s)
 (02/59) tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv3:
INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred:
Timeout reached\nOriginal status: ERROR\n{'name':
'02-tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv3',
'logdir': '/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-clang/tests/results/j...
(900.71 s)

UEFI runs in the guest and seems to launch the kernel, but there's
no output from the kernel itself in the logfile. Last thing it
prints is:

EFI stub: Booting Linux Kernel...
EFI stub: EFI_RNG_PROTOCOL unavailable, no randomness supplied
EFI stub: Using DTB from configuration table
EFI stub: Exiting boot services and installing virtual address map...
SetUefiImageMemoryAttributes - 0x000000007F500000 - 0x0000000000040000
(0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000007C190000 - 0x0000000000040000
(0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000007C140000 - 0x0000000000040000
(0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000007F4C0000 - 0x0000000000030000
(0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000007C0F0000 - 0x0000000000040000
(0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000007BFB0000 - 0x0000000000040000
(0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000007BE00000 - 0x0000000000030000
(0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000007BDC0000 - 0x0000000000030000
(0x0000000000000008)

This ought to be followed by the usual kernel boot log
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x000f0510]
etc but it isn't. Probably the kernel is crashing in early bootup
before it gets round to printing anything.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features
  2022-02-17 14:07 ` Peter Maydell
@ 2022-02-17 17:37   ` Alex Bennée
  2022-02-18  3:47     ` Richard Henderson
  2022-02-23 21:08   ` Richard Henderson
  1 sibling, 1 reply; 36+ messages in thread
From: Alex Bennée @ 2022-02-17 17:37 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-arm, Richard Henderson, qemu-devel


Peter Maydell <peter.maydell@linaro.org> writes:

> On Thu, 10 Feb 2022 at 04:04, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> Changes for v2:
>>   * Introduce FIELD_SEX64, instead of open-coding w/ sextract64.
>>   * Set TCR_EL1 more completely for user-only.
>>   * Continue to bound tsz within aa64_va_parameters;
>>     provide an out-of-bound indicator for raising AddressSize fault.
>>   * Split IPS patch.
>>   * Fix debug registers for LVA.
>>   * Fix long-format fsc for LPA2.
>>   * Fix TLBI page shift.
>>   * Validate TLBI granule vs TCR granule.
>>
>> Not done:
>>   * Validate translation levels which accept blocks.
>>
>> There is still no upstream kernel support for FEAT_LPA2,
>> so that is essentially untested.
>
> This series seems to break 'make check-acceptance':
>
>  (01/59) tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv2:
> INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred:
> Timeout reached\nOriginal status: ERROR\n{'name':
> '01-tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv2',
> 'logdir': '/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-clang/tests/results/j...
> (900.74 s)
>  (02/59) tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv3:
> INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred:
> Timeout reached\nOriginal status: ERROR\n{'name':
> '02-tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv3',
> 'logdir': '/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-clang/tests/results/j...
> (900.71 s)
>
> UEFI runs in the guest and seems to launch the kernel, but there's
> no output from the kernel itself in the logfile. Last thing it
> prints is:
>
> EFI stub: Booting Linux Kernel...
> EFI stub: EFI_RNG_PROTOCOL unavailable, no randomness supplied
> EFI stub: Using DTB from configuration table
> EFI stub: Exiting boot services and installing virtual address map...
> SetUefiImageMemoryAttributes - 0x000000007F500000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007C190000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007C140000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007F4C0000 - 0x0000000000030000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007C0F0000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007BFB0000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007BE00000 - 0x0000000000030000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007BDC0000 - 0x0000000000030000
> (0x0000000000000008)
>
> This ought to be followed by the usual kernel boot log
> [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x000f0510]
> etc but it isn't. Probably the kernel is crashing in early bootup
> before it gets round to printing anything.

As this test runs under -cpu max it is likely exercising the new
features (and failing).

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features
  2022-02-17 17:37   ` Alex Bennée
@ 2022-02-18  3:47     ` Richard Henderson
  0 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2022-02-18  3:47 UTC (permalink / raw)
  To: Alex Bennée, Peter Maydell; +Cc: qemu-arm, qemu-devel

On 2/18/22 04:37, Alex Bennée wrote:
> 
> Peter Maydell <peter.maydell@linaro.org> writes:
> 
>> On Thu, 10 Feb 2022 at 04:04, Richard Henderson
>> <richard.henderson@linaro.org> wrote:
>>>
>>> Changes for v2:
>>>    * Introduce FIELD_SEX64, instead of open-coding w/ sextract64.
>>>    * Set TCR_EL1 more completely for user-only.
>>>    * Continue to bound tsz within aa64_va_parameters;
>>>      provide an out-of-bound indicator for raising AddressSize fault.
>>>    * Split IPS patch.
>>>    * Fix debug registers for LVA.
>>>    * Fix long-format fsc for LPA2.
>>>    * Fix TLBI page shift.
>>>    * Validate TLBI granule vs TCR granule.
>>>
>>> Not done:
>>>    * Validate translation levels which accept blocks.
>>>
>>> There is still no upstream kernel support for FEAT_LPA2,
>>> so that is essentially untested.
>>
>> This series seems to break 'make check-acceptance':
>>
>>   (01/59) tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv2:
>> INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred:
>> Timeout reached\nOriginal status: ERROR\n{'name':
>> '01-tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv2',
>> 'logdir': '/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-clang/tests/results/j...
>> (900.74 s)
>>   (02/59) tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv3:
>> INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred:
>> Timeout reached\nOriginal status: ERROR\n{'name':
>> '02-tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv3',
>> 'logdir': '/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-clang/tests/results/j...
>> (900.71 s)
>>
>> UEFI runs in the guest and seems to launch the kernel, but there's
>> no output from the kernel itself in the logfile. Last thing it
>> prints is:
>>
>> EFI stub: Booting Linux Kernel...
>> EFI stub: EFI_RNG_PROTOCOL unavailable, no randomness supplied
>> EFI stub: Using DTB from configuration table
>> EFI stub: Exiting boot services and installing virtual address map...
>> SetUefiImageMemoryAttributes - 0x000000007F500000 - 0x0000000000040000
>> (0x0000000000000008)
>> SetUefiImageMemoryAttributes - 0x000000007C190000 - 0x0000000000040000
>> (0x0000000000000008)
>> SetUefiImageMemoryAttributes - 0x000000007C140000 - 0x0000000000040000
>> (0x0000000000000008)
>> SetUefiImageMemoryAttributes - 0x000000007F4C0000 - 0x0000000000030000
>> (0x0000000000000008)
>> SetUefiImageMemoryAttributes - 0x000000007C0F0000 - 0x0000000000040000
>> (0x0000000000000008)
>> SetUefiImageMemoryAttributes - 0x000000007BFB0000 - 0x0000000000040000
>> (0x0000000000000008)
>> SetUefiImageMemoryAttributes - 0x000000007BE00000 - 0x0000000000030000
>> (0x0000000000000008)
>> SetUefiImageMemoryAttributes - 0x000000007BDC0000 - 0x0000000000030000
>> (0x0000000000000008)
>>
>> This ought to be followed by the usual kernel boot log
>> [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x000f0510]
>> etc but it isn't. Probably the kernel is crashing in early bootup
>> before it gets round to printing anything.
> 
> As this test runs under -cpu max it is likely exercising the new
> features (and failing).

I would have thought so too.  However...

I've bisected this to the final LPA2 patch.  I have not tracked down what exactly is going 
on with this, but it's definitely not the guest exercising the new feature -- there is no 
upstream support for LPA2.

I'll keep looking.


r~



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features
  2022-02-17 14:07 ` Peter Maydell
  2022-02-17 17:37   ` Alex Bennée
@ 2022-02-23 21:08   ` Richard Henderson
  1 sibling, 0 replies; 36+ messages in thread
From: Richard Henderson @ 2022-02-23 21:08 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-arm, alex.bennee, qemu-devel

On 2/17/22 04:07, Peter Maydell wrote:
> This series seems to break 'make check-acceptance':
> 
>   (01/59) tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv2:
> INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred:
> Timeout reached\nOriginal status: ERROR\n{'name':
> '01-tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv2',
> 'logdir': '/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-clang/tests/results/j...
> (900.74 s)
>   (02/59) tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv3:
> INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred:
> Timeout reached\nOriginal status: ERROR\n{'name':
> '02-tests/avocado/boot_linux.py:BootLinuxAarch64.test_virt_tcg_gicv3',
> 'logdir': '/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-clang/tests/results/j...
> (900.71 s)
> 
> UEFI runs in the guest and seems to launch the kernel, but there's
> no output from the kernel itself in the logfile. Last thing it
> prints is:
> 
> EFI stub: Booting Linux Kernel...
> EFI stub: EFI_RNG_PROTOCOL unavailable, no randomness supplied
> EFI stub: Using DTB from configuration table
> EFI stub: Exiting boot services and installing virtual address map...
> SetUefiImageMemoryAttributes - 0x000000007F500000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007C190000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007C140000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007F4C0000 - 0x0000000000030000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007C0F0000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007BFB0000 - 0x0000000000040000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007BE00000 - 0x0000000000030000
> (0x0000000000000008)
> SetUefiImageMemoryAttributes - 0x000000007BDC0000 - 0x0000000000030000
> (0x0000000000000008)
> 
> This ought to be followed by the usual kernel boot log
> [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x000f0510]
> etc but it isn't. Probably the kernel is crashing in early bootup
> before it gets round to printing anything.

Ug.  The v5.3.7 kernel we're trying to boot is actively broken wrt LPA2:

ENTRY(__enable_mmu)
         mrs     x2, ID_AA64MMFR0_EL1
         ubfx    x2, x2, #ID_AA64MMFR0_TGRAN_SHIFT, 4
         cmp     x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
         b.ne    __no_granule_support

That's an exact match for TGRAN4 == 0, so the LPA2 value sends the cpu into a sleep loop.

This is fixed in 26f55386f964c, included in v5.12.

So... we're going to need to update avocado, or something.


r~


^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2022-02-23 21:09 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-10  4:04 [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Richard Henderson
2022-02-10  4:04 ` [PATCH v2 01/15] hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N> Richard Henderson
2022-02-10 11:15   ` Philippe Mathieu-Daudé via
2022-02-10  4:04 ` [PATCH v2 02/15] target/arm: Set TCR_EL1.TSZ for user-only Richard Henderson
2022-02-15 21:50   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 03/15] target/arm: Fault on invalid TCR_ELx.TxSZ Richard Henderson
2022-02-15 21:51   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 04/15] target/arm: Move arm_pamax out of line Richard Henderson
2022-02-15 21:51   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 05/15] target/arm: Pass outputsize down to check_s2_mmu_setup Richard Henderson
2022-02-15 21:57   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 06/15] target/arm: Use MAKE_64BIT_MASK to compute indexmask Richard Henderson
2022-02-10 11:15   ` Philippe Mathieu-Daudé via
2022-02-10  4:04 ` [PATCH v2 07/15] target/arm: Honor TCR_ELx.{I}PS Richard Henderson
2022-02-15 22:01   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 08/15] target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA Richard Henderson
2022-02-15 22:03   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 09/15] target/arm: Implement FEAT_LVA Richard Henderson
2022-02-15 22:05   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 10/15] target/arm: Implement FEAT_LPA Richard Henderson
2022-02-15 22:06   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 11/15] target/arm: Extend arm_fi_to_lfsc to level -1 Richard Henderson
2022-02-15 22:11   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 12/15] target/arm: Introduce tlbi_aa64_get_range Richard Henderson
2022-02-15 22:14   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 13/15] target/arm: Fix TLBIRange.base for 16k and 64k pages Richard Henderson
2022-02-15 22:18   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 14/15] target/arm: Validate tlbi TG matches translation granule in use Richard Henderson
2022-02-15 22:24   ` Peter Maydell
2022-02-10  4:04 ` [PATCH v2 15/15] target/arm: Implement FEAT_LPA2 Richard Henderson
2022-02-16 17:50   ` Peter Maydell
2022-02-16 17:51 ` [PATCH v2 00/15] target/arm: Implement LVA, LPA, LPA2 features Peter Maydell
2022-02-17 14:07 ` Peter Maydell
2022-02-17 17:37   ` Alex Bennée
2022-02-18  3:47     ` Richard Henderson
2022-02-23 21:08   ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.