Message ID | 20250504205714.3432096-5-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | accel/tcg: Fix cross-page pointer wrapping issue | expand |
+Gustavo On 4/5/25 22:57, Richard Henderson wrote: > For a-profile, check A32 vs A64 state. > For m-profile, use cpu_pointer_wrap_uint32. > > Cc: qemu-arm@nongnu.org > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/arm/cpu.c | 24 ++++++++++++++++++++++++ > target/arm/tcg/cpu-v7m.c | 1 + > 2 files changed, 25 insertions(+) > > diff --git a/target/arm/cpu.c b/target/arm/cpu.c > index 45cb6fd7ee..18edcf49c6 100644 > --- a/target/arm/cpu.c > +++ b/target/arm/cpu.c > @@ -2710,6 +2710,29 @@ static const struct SysemuCPUOps arm_sysemu_ops = { > #endif > > #ifdef CONFIG_TCG > +#ifndef CONFIG_USER_ONLY > +static vaddr aprofile_pointer_wrap(CPUState *cs, int mmu_idx, > + vaddr result, vaddr base) > +{ > + /* > + * The Stage2 and Phys indexes are only used for ptw on arm32, > + * and all pte's are aligned, so we never produce a wrap for these. > + * Double check that we're not truncating a 40-bit physical address. > + */ > + assert((unsigned)mmu_idx < (ARMMMUIdx_Stage2_S & ARM_MMU_IDX_COREIDX_MASK)); > + > + if (!is_a64(cpu_env(cs))) { > + return (uint32_t)result; > + } > + > + /* > + * TODO: For FEAT_CPA2, decide how to we want to resolve > + * Unpredictable_CPACHECK in AddressIncrement. > + */ > + return result; > +} > +#endif /* !CONFIG_USER_ONLY */ > + > static const TCGCPUOps arm_tcg_ops = { > .mttcg_supported = true, > /* ARM processors have a weak memory model */ > @@ -2729,6 +2752,7 @@ static const TCGCPUOps arm_tcg_ops = { > .untagged_addr = aarch64_untagged_addr, > #else > .tlb_fill_align = arm_cpu_tlb_fill_align, > + .pointer_wrap = aprofile_pointer_wrap, IIUC this is also used by non A-profiles (R-profiles and non Cortex cores). Patch LGTM but I'd rather someone else to look at it. > .cpu_exec_interrupt = arm_cpu_exec_interrupt, > .cpu_exec_halt = arm_cpu_exec_halt, > .cpu_exec_reset = cpu_reset, > diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c > index 95b23d9b55..8e1a083b91 100644 > --- a/target/arm/tcg/cpu-v7m.c > +++ b/target/arm/tcg/cpu-v7m.c > @@ -249,6 +249,7 @@ static const TCGCPUOps arm_v7m_tcg_ops = { > .record_sigbus = arm_cpu_record_sigbus, > #else > .tlb_fill_align = arm_cpu_tlb_fill_align, > + .pointer_wrap = cpu_pointer_wrap_uint32, > .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt, > .cpu_exec_halt = arm_cpu_exec_halt, > .cpu_exec_reset = cpu_reset,
On 5/26/25 19:21, Philippe Mathieu-Daudé wrote: > +Gustavo > > On 4/5/25 22:57, Richard Henderson wrote: >> For a-profile, check A32 vs A64 state. >> For m-profile, use cpu_pointer_wrap_uint32. >> >> Cc: qemu-arm@nongnu.org >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >> --- >> target/arm/cpu.c | 24 ++++++++++++++++++++++++ >> target/arm/tcg/cpu-v7m.c | 1 + >> 2 files changed, 25 insertions(+) >> >> diff --git a/target/arm/cpu.c b/target/arm/cpu.c >> index 45cb6fd7ee..18edcf49c6 100644 >> --- a/target/arm/cpu.c >> +++ b/target/arm/cpu.c >> @@ -2710,6 +2710,29 @@ static const struct SysemuCPUOps arm_sysemu_ops = { >> #endif >> #ifdef CONFIG_TCG >> +#ifndef CONFIG_USER_ONLY >> +static vaddr aprofile_pointer_wrap(CPUState *cs, int mmu_idx, >> + vaddr result, vaddr base) >> +{ >> + /* >> + * The Stage2 and Phys indexes are only used for ptw on arm32, >> + * and all pte's are aligned, so we never produce a wrap for these. >> + * Double check that we're not truncating a 40-bit physical address. >> + */ >> + assert((unsigned)mmu_idx < (ARMMMUIdx_Stage2_S & ARM_MMU_IDX_COREIDX_MASK)); >> + >> + if (!is_a64(cpu_env(cs))) { >> + return (uint32_t)result; >> + } >> + >> + /* >> + * TODO: For FEAT_CPA2, decide how to we want to resolve >> + * Unpredictable_CPACHECK in AddressIncrement. >> + */ >> + return result; >> +} >> +#endif /* !CONFIG_USER_ONLY */ >> + >> static const TCGCPUOps arm_tcg_ops = { >> .mttcg_supported = true, >> /* ARM processors have a weak memory model */ >> @@ -2729,6 +2752,7 @@ static const TCGCPUOps arm_tcg_ops = { >> .untagged_addr = aarch64_untagged_addr, >> #else >> .tlb_fill_align = arm_cpu_tlb_fill_align, >> + .pointer_wrap = aprofile_pointer_wrap, > > IIUC this is also used by non A-profiles (R-profiles and > non Cortex cores). Yes, r-profile is mostly a-profile. Those non-cortex cores are also a-profile: armv[456]. The point is the separation between m-profile and not. In particular, the mmu indexes are different between A and M (see ARM_MMU_IDX_TYPE_MASK). The assert would not be valid for m-profile. We can avoid a check vs ARM_FEATURE_M by only using this function for not-m-profile. r~
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 45cb6fd7ee..18edcf49c6 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2710,6 +2710,29 @@ static const struct SysemuCPUOps arm_sysemu_ops = { #endif #ifdef CONFIG_TCG +#ifndef CONFIG_USER_ONLY +static vaddr aprofile_pointer_wrap(CPUState *cs, int mmu_idx, + vaddr result, vaddr base) +{ + /* + * The Stage2 and Phys indexes are only used for ptw on arm32, + * and all pte's are aligned, so we never produce a wrap for these. + * Double check that we're not truncating a 40-bit physical address. + */ + assert((unsigned)mmu_idx < (ARMMMUIdx_Stage2_S & ARM_MMU_IDX_COREIDX_MASK)); + + if (!is_a64(cpu_env(cs))) { + return (uint32_t)result; + } + + /* + * TODO: For FEAT_CPA2, decide how to we want to resolve + * Unpredictable_CPACHECK in AddressIncrement. + */ + return result; +} +#endif /* !CONFIG_USER_ONLY */ + static const TCGCPUOps arm_tcg_ops = { .mttcg_supported = true, /* ARM processors have a weak memory model */ @@ -2729,6 +2752,7 @@ static const TCGCPUOps arm_tcg_ops = { .untagged_addr = aarch64_untagged_addr, #else .tlb_fill_align = arm_cpu_tlb_fill_align, + .pointer_wrap = aprofile_pointer_wrap, .cpu_exec_interrupt = arm_cpu_exec_interrupt, .cpu_exec_halt = arm_cpu_exec_halt, .cpu_exec_reset = cpu_reset, diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c index 95b23d9b55..8e1a083b91 100644 --- a/target/arm/tcg/cpu-v7m.c +++ b/target/arm/tcg/cpu-v7m.c @@ -249,6 +249,7 @@ static const TCGCPUOps arm_v7m_tcg_ops = { .record_sigbus = arm_cpu_record_sigbus, #else .tlb_fill_align = arm_cpu_tlb_fill_align, + .pointer_wrap = cpu_pointer_wrap_uint32, .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt, .cpu_exec_halt = arm_cpu_exec_halt, .cpu_exec_reset = cpu_reset,
For a-profile, check A32 vs A64 state. For m-profile, use cpu_pointer_wrap_uint32. Cc: qemu-arm@nongnu.org Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/cpu.c | 24 ++++++++++++++++++++++++ target/arm/tcg/cpu-v7m.c | 1 + 2 files changed, 25 insertions(+)