Message ID | 20211208231154.392029-6-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | target/arm: Implement LVA, LPA, LPA2 features | expand |
On Wed, 8 Dec 2021 at 23:15, Richard Henderson <richard.henderson@linaro.org> wrote: > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Could you put some content in the commit message, please? A brief description of what FEAT_LPA is would be helpful, for instance. While I was rereading the Arm ARM to review this I noticed an related check that I think we're missing. In section D5.2.7 the text describes which levels of translation tables support Block descriptors. (This varies depending on whether FEAT_LPA/FEAT_LPA2 are supported, which is why I ran into it.) e.g for 64KB granule size Block descriptors are OK in level 2, and if (FEAT_LPA && 52 bit PA size supported) also in level 1. Finding a block descriptor at a level it should not be is supposed to cause a level 1 Translation fault. As far as I can tell we don't check for this, unless it falls out in the wash in some super-subtle way... That seems like an unrelated bug to be fixed in a separate patch (though it does entangle with the LPA stuff because that will change the conditions for the check). Side note that might be worth mentioning in the commit message: FEAT_LPA also extends the nominal field size of addresses held in the fault registers HPFAR_EL2 and PAR_EL1. Our implementation doesn't explicitly mask out the high bits of addresses when filling out those fields, so it doesn't need changes to handle them expanding to hold bits [51:48] of PAs and IPAs. For the code: Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM
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 f44ee643ef..3bb79ca744 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -739,7 +739,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 6a59975028..e39c1f5b3a 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11095,6 +11095,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. */ @@ -11472,11 +11473,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; @@ -11526,7 +11531,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; }
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(-)