From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47203) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTrCU-0001GR-QD for qemu-devel@nongnu.org; Thu, 11 Feb 2016 08:22:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aTrCQ-0005t1-Iz for qemu-devel@nongnu.org; Thu, 11 Feb 2016 08:22:26 -0500 Received: from mail-wm0-x233.google.com ([2a00:1450:400c:c09::233]:36083) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTrCQ-0005sw-9K for qemu-devel@nongnu.org; Thu, 11 Feb 2016 08:22:22 -0500 Received: by mail-wm0-x233.google.com with SMTP id p63so72829092wmp.1 for ; Thu, 11 Feb 2016 05:22:22 -0800 (PST) References: <1454059965-23402-1-git-send-email-a.rigo@virtualopensystems.com> <1454059965-23402-7-git-send-email-a.rigo@virtualopensystems.com> From: Alex =?utf-8?Q?Benn=C3=A9e?= In-reply-to: <1454059965-23402-7-git-send-email-a.rigo@virtualopensystems.com> Date: Thu, 11 Feb 2016 13:22:19 +0000 Message-ID: <874mdfbcvo.fsf@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Subject: Re: [Qemu-devel] [RFC v7 06/16] qom: cpu: Add CPUClass hooks for exclusive range List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alvise Rigo Cc: mttcg@listserver.greensocs.com, claudio.fontana@huawei.com, qemu-devel@nongnu.org, pbonzini@redhat.com, jani.kokkonen@huawei.com, tech@virtualopensystems.com, rth@twiddle.net Alvise Rigo writes: > The excl_protected_range is a hwaddr range set by the VCPU at the > execution of a LoadLink instruction. If a normal access writes to this > range, the corresponding StoreCond will fail. > > Each architecture can set the exclusive range when issuing the LoadLink > operation through a CPUClass hook. This comes in handy to emulate, for > instance, the exclusive monitor implemented in some ARM architectures > (more precisely, the Exclusive Reservation Granule). > > In addition, add another CPUClass hook called to decide whether a > StoreCond has to fail or not. > > Suggested-by: Jani Kokkonen > Suggested-by: Claudio Fontana > Signed-off-by: Alvise Rigo > --- > include/qom/cpu.h | 15 +++++++++++++++ > qom/cpu.c | 20 ++++++++++++++++++++ > 2 files changed, 35 insertions(+) > > diff --git a/include/qom/cpu.h b/include/qom/cpu.h > index 2e5229d..682c81d 100644 > --- a/include/qom/cpu.h > +++ b/include/qom/cpu.h > @@ -29,6 +29,7 @@ > #include "qemu/queue.h" > #include "qemu/thread.h" > #include "qemu/typedefs.h" > +#include "qemu/range.h" > > typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size, > void *opaque); > @@ -183,6 +184,12 @@ typedef struct CPUClass { > void (*cpu_exec_exit)(CPUState *cpu); > bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request); > > + /* Atomic instruction handling */ > + void (*cpu_set_excl_protected_range)(CPUState *cpu, hwaddr addr, > + hwaddr size); > + int (*cpu_valid_excl_access)(CPUState *cpu, hwaddr addr, > + hwaddr size); > + > void (*disas_set_info)(CPUState *cpu, disassemble_info *info); > } CPUClass; > > @@ -219,6 +226,9 @@ struct kvm_run; > #define TB_JMP_CACHE_BITS 12 > #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) > > +/* Atomic insn translation TLB support. */ > +#define EXCLUSIVE_RESET_ADDR ULLONG_MAX > + > /** > * CPUState: > * @cpu_index: CPU index (informative). > @@ -341,6 +351,11 @@ struct CPUState { > */ > bool throttle_thread_scheduled; > > + /* vCPU's exclusive addresses range. > + * The address is set to EXCLUSIVE_RESET_ADDR if the vCPU is not > + * in the middle of a LL/SC. */ > + struct Range excl_protected_range; > + In which case we should probably initialise that on CPU creation as we don't start in the middle of a LL/SC. > /* Note that this is accessed at the start of every TB via a negative > offset from AREG0. Leave this field at the end so as to make the > (absolute value) offset as small as possible. This reduces code > diff --git a/qom/cpu.c b/qom/cpu.c > index 8f537a4..a5d360c 100644 > --- a/qom/cpu.c > +++ b/qom/cpu.c > @@ -203,6 +203,24 @@ static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req) > return false; > } > > +static void cpu_common_set_excl_range(CPUState *cpu, hwaddr addr, hwaddr size) > +{ > + cpu->excl_protected_range.begin = addr; > + cpu->excl_protected_range.end = addr + size; > +} > + > +static int cpu_common_valid_excl_access(CPUState *cpu, hwaddr addr, hwaddr size) > +{ > + /* Check if the excl range completely covers the access */ > + if (cpu->excl_protected_range.begin <= addr && > + cpu->excl_protected_range.end >= addr + size) { > + > + return 1; > + } > + > + return 0; > +} This can be a bool function. > + > void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, > int flags) > { > @@ -355,6 +373,8 @@ static void cpu_class_init(ObjectClass *klass, void *data) > k->cpu_exec_enter = cpu_common_noop; > k->cpu_exec_exit = cpu_common_noop; > k->cpu_exec_interrupt = cpu_common_exec_interrupt; > + k->cpu_set_excl_protected_range = cpu_common_set_excl_range; > + k->cpu_valid_excl_access = cpu_common_valid_excl_access; > dc->realize = cpu_common_realizefn; > /* > * Reason: CPUs still need special care by board code: wiring up -- Alex Bennée