From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49615) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aWP1u-0000Ff-0y for qemu-devel@nongnu.org; Thu, 18 Feb 2016 08:54:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aWP1q-0006Hw-M4 for qemu-devel@nongnu.org; Thu, 18 Feb 2016 08:54:01 -0500 Received: from mail-ig0-x22d.google.com ([2607:f8b0:4001:c05::22d]:37904) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aWP1q-0006Hj-Dl for qemu-devel@nongnu.org; Thu, 18 Feb 2016 08:53:58 -0500 Received: by mail-ig0-x22d.google.com with SMTP id y8so12875846igp.1 for ; Thu, 18 Feb 2016 05:53:57 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <874mdfbcvo.fsf@linaro.org> References: <1454059965-23402-1-git-send-email-a.rigo@virtualopensystems.com> <1454059965-23402-7-git-send-email-a.rigo@virtualopensystems.com> <874mdfbcvo.fsf@linaro.org> Date: Thu, 18 Feb 2016 14:53:57 +0100 Message-ID: From: alvise rigo Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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: =?UTF-8?B?QWxleCBCZW5uw6ll?= Cc: MTTCG Devel , Claudio Fontana , QEMU Developers , Paolo Bonzini , Jani Kokkonen , VirtualOpenSystems Technical Team , Richard Henderson On Thu, Feb 11, 2016 at 2:22 PM, Alex Benn=C3=A9e = wrote: > > 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. Agreed. > >> /* Note that this is accessed at the start of every TB via a negati= ve >> offset from AREG0. Leave this field at the end so as to make th= e >> (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, hwadd= r size) >> +{ >> + cpu->excl_protected_range.begin =3D addr; >> + cpu->excl_protected_range.end =3D addr + size; >> +} >> + >> +static int cpu_common_valid_excl_access(CPUState *cpu, hwaddr addr, hwa= ddr size) >> +{ >> + /* Check if the excl range completely covers the access */ >> + if (cpu->excl_protected_range.begin <=3D addr && >> + cpu->excl_protected_range.end >=3D addr + size) { >> + >> + return 1; >> + } >> + >> + return 0; >> +} > > This can be a bool function. OK. Thank you, alvise > >> + >> void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprint= f, >> int flags) >> { >> @@ -355,6 +373,8 @@ static void cpu_class_init(ObjectClass *klass, void = *data) >> k->cpu_exec_enter =3D cpu_common_noop; >> k->cpu_exec_exit =3D cpu_common_noop; >> k->cpu_exec_interrupt =3D cpu_common_exec_interrupt; >> + k->cpu_set_excl_protected_range =3D cpu_common_set_excl_range; >> + k->cpu_valid_excl_access =3D cpu_common_valid_excl_access; >> dc->realize =3D cpu_common_realizefn; >> /* >> * Reason: CPUs still need special care by board code: wiring up > > > -- > Alex Benn=C3=A9e