On Wed, Mar 19, 2025 at 7:36 AM Richard Henderson <richard.hender...@linaro.org> wrote: > > Perform aligned atomic reads in translator_ld, if possible. > According to > > https://lore.kernel.org/qemu-devel/20240607101403.1109-1-jim....@sifive.com/ > > this is required for RISC-V Ziccif.
Thanks Richard!! > > Signed-off-by: Richard Henderson <richard.hender...@linaro.org> Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > accel/tcg/translator.c | 42 ++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 38 insertions(+), 4 deletions(-) > > diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c > index ef1538b4fc..157be33bf6 100644 > --- a/accel/tcg/translator.c > +++ b/accel/tcg/translator.c > @@ -265,12 +265,14 @@ static bool translator_ld(CPUArchState *env, > DisasContextBase *db, > > if (likely(((base ^ last) & TARGET_PAGE_MASK) == 0)) { > /* Entire read is from the first page. */ > - memcpy(dest, host + (pc - base), len); > - return true; > + goto do_read; > } > > if (unlikely(((base ^ pc) & TARGET_PAGE_MASK) == 0)) { > - /* Read begins on the first page and extends to the second. */ > + /* > + * Read begins on the first page and extends to the second. > + * The unaligned read is never atomic. > + */ > size_t len0 = -(pc | TARGET_PAGE_MASK); > memcpy(dest, host + (pc - base), len0); > pc += len0; > @@ -329,7 +331,39 @@ static bool translator_ld(CPUArchState *env, > DisasContextBase *db, > host = db->host_addr[1]; > } > > - memcpy(dest, host + (pc - base), len); > + do_read: > + /* > + * Assume aligned reads should be atomic, if possible. > + * We're not in a position to jump out with EXCP_ATOMIC. > + */ > + host += pc - base; > + switch (len) { > + case 2: > + if (QEMU_IS_ALIGNED(pc, 2)) { > + uint16_t t = qatomic_read((uint16_t *)host); > + stw_he_p(dest, t); > + return true; > + } > + break; > + case 4: > + if (QEMU_IS_ALIGNED(pc, 4)) { > + uint32_t t = qatomic_read((uint32_t *)host); > + stl_he_p(dest, t); > + return true; > + } > + break; > +#ifdef CONFIG_ATOMIC64 > + case 8: > + if (QEMU_IS_ALIGNED(pc, 8)) { > + uint64_t t = qatomic_read__nocheck((uint64_t *)host); > + stq_he_p(dest, t); > + return true; > + } > + break; > +#endif > + } > + /* Unaligned or partial read from the second page is not atomic. */ > + memcpy(dest, host, len); > return true; > } > > -- > 2.43.0 > >