diff mbox series

[RFC,v2,4/4] linux-user/riscv: Implement dynamic memory consistency model support

Message ID 20240209064117.2746701-5-christoph.muellner@vrull.eu (mailing list archive)
State New, archived
Headers show
Series RISC-V: Add dynamic TSO support | expand

Commit Message

Christoph Müllner Feb. 9, 2024, 6:41 a.m. UTC
This patch implements the dynamic memory consistency model prctl calls
for RISC-V. The implementation introduces a single boolean variable to
keep the DTSO state.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 linux-user/riscv/target_prctl.h | 76 ++++++++++++++++++++++++++++++++-
 target/riscv/cpu.c              |  5 +++
 target/riscv/cpu.h              |  1 +
 3 files changed, 81 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/linux-user/riscv/target_prctl.h b/linux-user/riscv/target_prctl.h
index eb53b31ad5..e54321d872 100644
--- a/linux-user/riscv/target_prctl.h
+++ b/linux-user/riscv/target_prctl.h
@@ -1 +1,75 @@ 
-/* No special prctl support required. */
+/*
+ * RISC-V specific prctl functions for linux-user
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef RISCV_TARGET_PRCTL_H
+#define RISCV_TARGET_PRCTL_H
+
+static inline void riscv_dtso_set_enable(CPURISCVState *env, bool enable)
+{
+    env->dtso_ena = enable;
+}
+
+static inline bool riscv_dtso_is_enabled(CPURISCVState *env)
+{
+    return env->dtso_ena;
+}
+
+static abi_long do_prctl_set_memory_consistency_model(CPUArchState *cpu_env,
+                                                      abi_long arg2)
+{
+    RISCVCPU *cpu = env_archcpu(cpu_env);
+    bool dtso_ena_old = riscv_dtso_is_enabled(cpu_env);
+    bool dtso_ena_new;
+    bool has_dtso = cpu->cfg.ext_ssdtso;
+
+    switch (arg2) {
+        case PR_MEMORY_CONSISTENCY_MODEL_RISCV_WMO:
+            dtso_ena_new = false;
+            break;
+        case PR_MEMORY_CONSISTENCY_MODEL_RISCV_TSO:
+	    dtso_ena_new = true;
+            break;
+        default:
+            return -TARGET_EINVAL;
+    }
+
+    /* No change requested. */
+    if (dtso_ena_old == dtso_ena_new)
+	    return 0;
+
+    /* Enabling TSO only works if DTSO is available. */
+    if (dtso_ena_new && !has_dtso)
+	    return -TARGET_EINVAL;
+
+    /* Switchin TSO->WMO is not allowed. */
+    if (!dtso_ena_new)
+	    return -TARGET_EINVAL;
+
+    riscv_dtso_set_enable(cpu_env, dtso_ena_new);
+
+    /*
+     * No need to reschedule other threads, because the emulation
+     * of DTSO is fine (from a memory model view) if they are out
+     * of sync until they will eventually reschedule.
+     */
+
+    return 0;
+}
+
+#define do_prctl_set_memory_consistency_model \
+        do_prctl_set_memory_consistency_model
+
+static abi_long do_prctl_get_memory_consistency_model(CPUArchState *cpu_env)
+{
+    if (riscv_dtso_is_enabled(cpu_env))
+	    return PR_MEMORY_CONSISTENCY_MODEL_RISCV_TSO;
+
+    return PR_MEMORY_CONSISTENCY_MODEL_RISCV_WMO;
+}
+
+#define do_prctl_get_memory_consistency_model \
+        do_prctl_get_memory_consistency_model
+
+#endif /* RISCV_TARGET_PRCTL_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ee90c09600..2e2aac73dc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -922,6 +922,11 @@  static void riscv_cpu_reset_hold(Object *obj)
     if (mcc->parent_phases.hold) {
         mcc->parent_phases.hold(obj);
     }
+#ifdef CONFIG_USER_ONLY
+    /* Default is true if Ztso is enabled, false otherwise. */
+    env->dtso_ena = cpu->cfg.ext_ztso;
+#endif
+
 #ifndef CONFIG_USER_ONLY
     env->misa_mxl = mcc->misa_mxl_max;
     env->priv = PRV_M;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f52dce78ba..69420b2ae3 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -200,6 +200,7 @@  struct CPUArchState {
 
 #ifdef CONFIG_USER_ONLY
     uint32_t elf_flags;
+    bool dtso_ena; /* Dynamic TSO enable */
 #endif
 
 #ifndef CONFIG_USER_ONLY