[PATCH v2 13/16] target/riscv: Fix PTE A/D atomic update endianness

Djordje Todorovic posted 16 patches 1 month, 2 weeks ago
There is a newer version of this series
[PATCH v2 13/16] target/riscv: Fix PTE A/D atomic update endianness
Posted by Djordje Todorovic 1 month, 2 weeks ago
From: djtodoro <djordje.todorovic@htecgroup.com>

Use tswap32/tswap64 instead of hardcoded cpu_to_le32/le64 for PTE
atomic compare-and-swap updates, so the encoding matches how PTEs
are read via address_space_ldl/ldq (target endian).
---
 target/riscv/cpu_helper.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index dd6c861a90..f6990b2dfa 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -37,6 +37,7 @@
 #include "debug.h"
 #include "pmp.h"
 #include "qemu/plugin.h"
+#include "exec/tswap.h"
 
 int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
 {
@@ -1567,11 +1568,11 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
             target_ulong *pte_pa = qemu_map_ram_ptr(mr->ram_block, addr1);
             target_ulong old_pte;
             if (riscv_cpu_sxl(env) == MXL_RV32) {
-                old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, cpu_to_le32(pte), cpu_to_le32(updated_pte));
-                old_pte = le32_to_cpu(old_pte);
+                old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, tswap32(pte), tswap32(updated_pte));
+                old_pte = tswap32(old_pte);
             } else {
-                old_pte = qatomic_cmpxchg(pte_pa, cpu_to_le64(pte), cpu_to_le64(updated_pte));
-                old_pte = le64_to_cpu(old_pte);
+                old_pte = qatomic_cmpxchg(pte_pa, tswap64(pte), tswap64(updated_pte));
+                old_pte = tswap64(old_pte);
             }
             if (old_pte != pte) {
                 goto restart;
-- 
2.34.1
Re: [PATCH v2 13/16] target/riscv: Fix PTE A/D atomic update endianness
Posted by Philippe Mathieu-Daudé 1 month, 1 week ago
On 25/2/26 11:20, Djordje Todorovic wrote:
> From: djtodoro <djordje.todorovic@htecgroup.com>
> 
> Use tswap32/tswap64 instead of hardcoded cpu_to_le32/le64 for PTE
> atomic compare-and-swap updates, so the encoding matches how PTEs
> are read via address_space_ldl/ldq (target endian).
> ---
>   target/riscv/cpu_helper.c | 9 +++++----
>   1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index dd6c861a90..f6990b2dfa 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -37,6 +37,7 @@
>   #include "debug.h"
>   #include "pmp.h"
>   #include "qemu/plugin.h"
> +#include "exec/tswap.h"
>   
>   int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
>   {
> @@ -1567,11 +1568,11 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
>               target_ulong *pte_pa = qemu_map_ram_ptr(mr->ram_block, addr1);

Should we use address_space_ld[l/q]_le() with the HART AS (via @env)
here instead of accessing the RAMBlock manually?

>               target_ulong old_pte;
>               if (riscv_cpu_sxl(env) == MXL_RV32) {
> -                old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, cpu_to_le32(pte), cpu_to_le32(updated_pte));
> -                old_pte = le32_to_cpu(old_pte);
> +                old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, tswap32(pte), tswap32(updated_pte));
> +                old_pte = tswap32(old_pte);
>               } else {
> -                old_pte = qatomic_cmpxchg(pte_pa, cpu_to_le64(pte), cpu_to_le64(updated_pte));
> -                old_pte = le64_to_cpu(old_pte);
> +                old_pte = qatomic_cmpxchg(pte_pa, tswap64(pte), tswap64(updated_pte));
> +                old_pte = tswap64(old_pte);
>               }
>               if (old_pte != pte) {
>                   goto restart;