As far as I understand, linux-user uses a mutex to make the atomic accesses exclusive with respect to other CPU's atomic accesses. So basically in the LDREX case it implements: lock() -> access() -> unlock() This patch series makes the atomic accesses exclusive with respect to every memory access, this is allowed by the softmmu. The access is now something like: lock() -> softmmu_access() -> unlock() where "softmmu_access()" is not just a memory access, but includes a manipulation of the EXCL bitmap and possible queries of TLB flushes. So there are similarities, but are pretty much confined to the locking/unlocking of a spinlock/mutex.
This made me think, how does linux-user can properly work with upstream TCG, for instance, in an absurd configuration like target-arm on ARM host? alvise On Wed, Jun 8, 2016 at 11:21 AM, Alex Bennée <alex.ben...@linaro.org> wrote: > > Alvise Rigo <a.r...@virtualopensystems.com> writes: > >> Add tcg_exclusive_{lock,unlock}() functions that will be used for making >> the emulation of LL and SC instructions thread safe. > > I wonder how much similarity there is to the mechanism linus-user ends > up using for it's exclusive-start/end? > >> >> Signed-off-by: Alvise Rigo <a.r...@virtualopensystems.com> >> --- >> cpus.c | 2 ++ >> exec.c | 18 ++++++++++++++++++ >> include/qom/cpu.h | 5 +++++ >> 3 files changed, 25 insertions(+) >> >> diff --git a/cpus.c b/cpus.c >> index 860e7ba..b9ec903 100644 >> --- a/cpus.c >> +++ b/cpus.c >> @@ -961,6 +961,8 @@ void qemu_init_cpu_loop(void) >> qemu_cond_init(&qemu_work_cond); >> qemu_mutex_init(&qemu_global_mutex); >> >> + qemu_spin_init(&cpu_exclusive_lock); >> + >> qemu_thread_get_self(&io_thread); >> >> safe_work = g_array_sized_new(TRUE, TRUE, sizeof(qemu_safe_work_item), >> 128); >> diff --git a/exec.c b/exec.c >> index a24b31c..1c72113 100644 >> --- a/exec.c >> +++ b/exec.c >> @@ -197,6 +197,24 @@ void cpu_exclusive_history_free(void) >> g_free(excl_history.c_array); >> } >> } >> + >> +__thread bool cpu_have_exclusive_lock; >> +QemuSpin cpu_exclusive_lock; >> +inline void tcg_exclusive_lock(void) >> +{ >> + if (!cpu_have_exclusive_lock) { >> + qemu_spin_lock(&cpu_exclusive_lock); >> + cpu_have_exclusive_lock = true; >> + } >> +} >> + >> +inline void tcg_exclusive_unlock(void) >> +{ >> + if (cpu_have_exclusive_lock) { >> + cpu_have_exclusive_lock = false; >> + qemu_spin_unlock(&cpu_exclusive_lock); >> + } >> +} >> #endif >> >> #if !defined(CONFIG_USER_ONLY) >> diff --git a/include/qom/cpu.h b/include/qom/cpu.h >> index 0f51870..019f06d 100644 >> --- a/include/qom/cpu.h >> +++ b/include/qom/cpu.h >> @@ -201,6 +201,11 @@ typedef struct CPUClass { >> void (*disas_set_info)(CPUState *cpu, disassemble_info *info); >> } CPUClass; >> >> +/* Protect cpu_exclusive_* variable .*/ >> +void tcg_exclusive_lock(void); >> +void tcg_exclusive_unlock(void); >> +extern QemuSpin cpu_exclusive_lock; >> + >> #ifdef HOST_WORDS_BIGENDIAN >> typedef struct icount_decr_u16 { >> uint16_t high; > > > -- > Alex Bennée