On Thu, Feb 11, 2016 at 2:22 PM, Alex Bennée <alex.ben...@linaro.org> wrote: > > Alvise Rigo <a.r...@virtualopensystems.com> 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 <jani.kokko...@huawei.com> >> Suggested-by: Claudio Fontana <claudio.font...@huawei.com> >> Signed-off-by: Alvise Rigo <a.r...@virtualopensystems.com> >> --- >> 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 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. OK. Thank you, alvise > >> + >> 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