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.muell...@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 --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 -- 2.43.0