Re: [PATCH v2 04/39] xen/riscv: introduce csr_read64()

Andrew Cooper <[email protected]>
Newsgroups gmane.comp.emulators.xen.devel
Message-ID <[email protected]>
On 27/08/2026 4:20 pm, Oleksii Kurochko wrote:
> diff --git a/xen/arch/riscv/include/asm/csr.h b/xen/arch/riscv/include/asm/csr.h
> index 888d6a2a86d6..a5cdd6f99c8e 100644
> --- a/xen/arch/riscv/include/asm/csr.h
> +++ b/xen/arch/riscv/include/asm/csr.h
> @@ -39,12 +39,36 @@
>      csr_write(csr, v_);             \
>      csr_write(csr ## H, v_ >> 32);  \
>  })
> +
> +/*
> + * The two halves are read by separate instructions, so a CSR which hardware
> + * increments can carry from the low half into the high one in between,
> + * yielding a value the CSR never held. Re-read the high half and retry the
> + * sequence if it changed.
> + */
> +#define csr_read64(csr)                         \
> +({                                              \
> +    uint32_t hi_, lo_;                          \
> +                                                \
> +    do {                                        \
> +        hi_ = csr_read(csr ## H);               \
> +        lo_ = csr_read(csr);                    \
> +    } while ( hi_ != csr_read(csr ## H) );      \
> +                                                \
> +    ((uint64_t)hi_ << 32) | lo_;                \
> +})

This double reads H in the looping case.  You want something more like:

hi = csr_read();
do {
    old = hi;
    lo = csr_read();
} while ( (hi = csr_read()) != old );


Still, this only matters for volatile CSRs, and is unnecessary in the
general case.  I'd suggest naming it csr_volatile_read64().  Most CSRs
can use a simple split access.

~Andrew
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.