* [RFC PATCH] target/arm: fix user-mode emulation of ID_AA64MMFR0_EL1
@ 2026-09-21 14:29 Alex Bennée
2026-09-28 14:02 ` Peter Maydell
2026-09-28 17:57 ` Peter Maydell
0 siblings, 2 replies; 4+ messages in thread
From: Alex Bennée @ 2026-09-21 14:29 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée, Peter Maydell, open list:ARM TCG CPUs
Since kernel commit b130a8f70cbbf9 (KVM: arm64: Check advertised
Stage-2 page size capability) the relevant Stage 2 have been pegged at
1 f(4KB granule not supported at stage 2) by the kernel. As a result
the behaviour of the test differs when run on real HW compared to
under emulation:
id_aa64mmfr0_el1 : 0x00000111ff000000
!!extra bits!! : 0x0000011100000000
Update the test with a new helper to explicitly test for fixed bits
and update v8_user_idregs to match real systems.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4566
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
target/arm/helper.c | 7 +++++--
tests/tcg/aarch64/sysregs.c | 31 ++++++++++++++++++++++++++++---
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index c3f607e6d6b..7e65f072a4a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6902,8 +6902,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
R_ID_AA64FPFR0_F8CVT_MASK },
{ .name = "ID_AA64MMFR0_EL1",
.exported_bits = R_ID_AA64MMFR0_ECV_MASK,
- .fixed_bits = (0xfu << R_ID_AA64MMFR0_TGRAN64_SHIFT) |
- (0xfu << R_ID_AA64MMFR0_TGRAN4_SHIFT) },
+ .fixed_bits = (0xfULL << R_ID_AA64MMFR0_TGRAN64_SHIFT) |
+ (0xfULL << R_ID_AA64MMFR0_TGRAN4_SHIFT) |
+ (0x1ULL << R_ID_AA64MMFR0_TGRAN4_2_SHIFT) |
+ (0x1ULL << R_ID_AA64MMFR0_TGRAN64_2_SHIFT) |
+ (0x1ULL << R_ID_AA64MMFR0_TGRAN16_2_SHIFT) },
{ .name = "ID_AA64MMFR1_EL1",
.exported_bits = R_ID_AA64MMFR1_AFP_MASK },
{ .name = "ID_AA64MMFR2_EL1",
diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
index 301e61d0dd4..8f7c5303f77 100644
--- a/tests/tcg/aarch64/sysregs.c
+++ b/tests/tcg/aarch64/sysregs.c
@@ -54,6 +54,23 @@ int failed_bit_count;
} \
})
+/* As above but also check that required fixed bits have expected values */
+#define get_cpu_reg_check_fixed(id, allowed_mask, fixed_mask, expected_val) ({ \
+ unsigned long __cval = get_cpu_reg(id); \
+ unsigned long __extra = __cval & ~(allowed_mask); \
+ if (__extra) { \
+ printf("%-20s: 0x%016lx\n", " !!extra bits!!", __extra); \
+ failed_bit_count++; \
+ } \
+ if ((__cval & (fixed_mask)) != (expected_val)) { \
+ printf("%-20s: 0x%016llx (expected fixed 0x%016llx)\n", \
+ " !!fixed mismatch!!", \
+ (unsigned long long)(__cval & (fixed_mask)), \
+ (unsigned long long)(expected_val)); \
+ failed_bit_count++; \
+ } \
+})
+
/* As above but check RAZ */
#define get_cpu_reg_check_zero(id) ({ \
unsigned long __val = 0xdeadbeef; \
@@ -127,8 +144,16 @@ int main(void)
get_cpu_reg_check_mask(id_aa64isar0_el1, _m(f0ff,ffff,f0ff,fff0));
get_cpu_reg_check_mask(id_aa64isar1_el1, _m(00ff,f0ff,ffff,ffff));
get_cpu_reg_check_mask(SYS_ID_AA64ISAR2_EL1, _m(00ff,0000,00ff,ffff));
- /* TGran4 & TGran64 as pegged to -1 */
- get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(f000,0000,ff00,0000));
+ /*
+ * TGran4 & TGran64 are pegged to -1 (0xf).
+ * Stage 2 translation granule support (TGran4_2, TGran64_2, TGran16_2)
+ * are pegged to safe value 1 as exposed by Linux kernel since
+ * b130a8f70cbbf9 (KVM: arm64: Check advertised Stage-2 page size capability).
+ */
+ get_cpu_reg_check_fixed(id_aa64mmfr0_el1,
+ _m(f000, 0111, ff00, 0000),
+ _m(0000, 0111, ff00, 0000),
+ _m(0000, 0111, ff00, 0000));
get_cpu_reg_check_mask(id_aa64mmfr1_el1, _m(0000,f000,0000,0000));
get_cpu_reg_check_mask(SYS_ID_AA64MMFR2_EL1, _m(0000,000f,0000,0000));
/* EL1/EL0 reported as AA64 only */
@@ -179,7 +204,7 @@ int main(void)
}
if (failed_bit_count > 0) {
- printf("Extra information leaked to user-space!\n");
+ printf("Bit check failure or extra info leaked to user-space!\n");
return 1;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [RFC PATCH] target/arm: fix user-mode emulation of ID_AA64MMFR0_EL1
2026-09-21 14:29 [RFC PATCH] target/arm: fix user-mode emulation of ID_AA64MMFR0_EL1 Alex Bennée
@ 2026-09-28 14:02 ` Peter Maydell
2026-09-28 14:27 ` Alex Bennée
2026-09-28 17:57 ` Peter Maydell
1 sibling, 1 reply; 4+ messages in thread
From: Peter Maydell @ 2026-09-28 14:02 UTC (permalink / raw)
To: Alex Bennée; +Cc: qemu-devel, open list:ARM TCG CPUs
On Mon, 21 Sept 2026 at 15:29, Alex Bennée <alex.bennee@linaro.org> wrote:
>
> Since kernel commit b130a8f70cbbf9 (KVM: arm64: Check advertised
> Stage-2 page size capability) the relevant Stage 2 have been pegged at
> 1 f(4KB granule not supported at stage 2) by the kernel. As a result
> the behaviour of the test differs when run on real HW compared to
> under emulation:
>
> id_aa64mmfr0_el1 : 0x00000111ff000000
> !!extra bits!! : 0x0000011100000000
>
> Update the test with a new helper to explicitly test for fixed bits
> and update v8_user_idregs to match real systems.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4566
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Why is this only an RFC? What would you like comments on? :-)
thanks
-- PMM
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC PATCH] target/arm: fix user-mode emulation of ID_AA64MMFR0_EL1
2026-09-28 14:02 ` Peter Maydell
@ 2026-09-28 14:27 ` Alex Bennée
0 siblings, 0 replies; 4+ messages in thread
From: Alex Bennée @ 2026-09-28 14:27 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, open list:ARM TCG CPUs
Peter Maydell <peter.maydell@linaro.org> writes:
> On Mon, 21 Sept 2026 at 15:29, Alex Bennée <alex.bennee@linaro.org> wrote:
>>
>> Since kernel commit b130a8f70cbbf9 (KVM: arm64: Check advertised
>> Stage-2 page size capability) the relevant Stage 2 have been pegged at
>> 1 f(4KB granule not supported at stage 2) by the kernel. As a result
>> the behaviour of the test differs when run on real HW compared to
>> under emulation:
>>
>> id_aa64mmfr0_el1 : 0x00000111ff000000
>> !!extra bits!! : 0x0000011100000000
>>
>> Update the test with a new helper to explicitly test for fixed bits
>> and update v8_user_idregs to match real systems.
>>
>> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4566
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>
> Why is this only an RFC? What would you like comments on? :-)
skill issue (or possibly my shell history). If your happy to take it
please do ;-)
>
> thanks
> -- PMM
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC PATCH] target/arm: fix user-mode emulation of ID_AA64MMFR0_EL1
2026-09-21 14:29 [RFC PATCH] target/arm: fix user-mode emulation of ID_AA64MMFR0_EL1 Alex Bennée
2026-09-28 14:02 ` Peter Maydell
@ 2026-09-28 17:57 ` Peter Maydell
1 sibling, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2026-09-28 17:57 UTC (permalink / raw)
To: Alex Bennée; +Cc: qemu-devel, open list:ARM TCG CPUs
On Mon, 21 Sept 2026 at 15:29, Alex Bennée <alex.bennee@linaro.org> wrote:
>
> Since kernel commit b130a8f70cbbf9 (KVM: arm64: Check advertised
> Stage-2 page size capability) the relevant Stage 2 have been pegged at
> 1 f(4KB granule not supported at stage 2) by the kernel. As a result
> the behaviour of the test differs when run on real HW compared to
> under emulation:
>
> id_aa64mmfr0_el1 : 0x00000111ff000000
> !!extra bits!! : 0x0000011100000000
>
> Update the test with a new helper to explicitly test for fixed bits
> and update v8_user_idregs to match real systems.
Huh, 2020; that's not a recent change at all...
I don't understand what the above output is intended to tell me,
though. What are "extra bits"? In the actual implementation code
in helper.c all we define is exported bits and fixed bits. I think
we could stand to be a bit more verbose in the test program output
in saying what the test thinks the problem is.
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4566
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
> target/arm/helper.c | 7 +++++--
> tests/tcg/aarch64/sysregs.c | 31 ++++++++++++++++++++++++++++---
> 2 files changed, 33 insertions(+), 5 deletions(-)
>
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index c3f607e6d6b..7e65f072a4a 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -6902,8 +6902,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
> R_ID_AA64FPFR0_F8CVT_MASK },
> { .name = "ID_AA64MMFR0_EL1",
> .exported_bits = R_ID_AA64MMFR0_ECV_MASK,
> - .fixed_bits = (0xfu << R_ID_AA64MMFR0_TGRAN64_SHIFT) |
> - (0xfu << R_ID_AA64MMFR0_TGRAN4_SHIFT) },
> + .fixed_bits = (0xfULL << R_ID_AA64MMFR0_TGRAN64_SHIFT) |
> + (0xfULL << R_ID_AA64MMFR0_TGRAN4_SHIFT) |
> + (0x1ULL << R_ID_AA64MMFR0_TGRAN4_2_SHIFT) |
> + (0x1ULL << R_ID_AA64MMFR0_TGRAN64_2_SHIFT) |
> + (0x1ULL << R_ID_AA64MMFR0_TGRAN16_2_SHIFT) },
This change looks OK: the rule for the ID registers at EL0
(per https://docs.kernel.org/arch/arm64/cpu-feature-registers.html )
is that fields not visible to userspace should have the value
indicating "feature is missing". That is:
* for TGran16: 0
* for TGran64 and TGran4: 0b1111
* for TGran16_2, TGran64_2, TGran4_2: 0b0001
and that's what we now define for the fixed_bits value. I think
we could reasonably add a brief comment, though:
/*
* Linux does not expose the TGRAN* fields to userspace and so they
* must read as the "this is not implemented" value for those fields
* (which is 0, 0b0001 or 0b1111 depending on the field)
*/
thanks
-- PMM
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-28 17:57 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-21 14:29 [RFC PATCH] target/arm: fix user-mode emulation of ID_AA64MMFR0_EL1 Alex Bennée
2026-09-28 14:02 ` Peter Maydell
2026-09-28 14:27 ` Alex Bennée
2026-09-28 17:57 ` Peter Maydell
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.