From patchwork Tue Apr 19 13:39:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alvise rigo X-Patchwork-Id: 8880231 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A4A439F1C1 for ; Tue, 19 Apr 2016 13:44:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B2264202D1 for ; Tue, 19 Apr 2016 13:44:34 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9FBCF2027D for ; Tue, 19 Apr 2016 13:44:33 +0000 (UTC) Received: from localhost ([::1]:58169 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1asVxA-0004Mv-WF for patchwork-qemu-devel@patchwork.kernel.org; Tue, 19 Apr 2016 09:44:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57081) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1asVsb-0003In-3u for qemu-devel@nongnu.org; Tue, 19 Apr 2016 09:39:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1asVsZ-0000gk-Rz for qemu-devel@nongnu.org; Tue, 19 Apr 2016 09:39:49 -0400 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:33310) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1asVsZ-0000gU-Iw for qemu-devel@nongnu.org; Tue, 19 Apr 2016 09:39:47 -0400 Received: by mail-wm0-x242.google.com with SMTP id y144so5290906wmd.0 for ; Tue, 19 Apr 2016 06:39:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtualopensystems-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xkTNe8LbWK6xulXneOsAwHc6v+5GHBHdVu4Rh+eTn3U=; b=t8AxA8DppQhdWU5ouZgZXHlPFjhnweB0k9Lt8oolSgsd1EFYmx4T/0qsn2GMidO1sx WUGBfTwB8uzAa9NMMHHBIfNG8L6TVUdiOcon7uBtj8SedENlYqfGIPhNDMDPHQN4zxGZ l/+m+IUt89EBmRVWH+GtNKLv0Br6YK73GfHyHuYEahMtAXv2gp2YKrr2zBc/Ah9RMQ9g EcwgUR/+lUAhdEDnFWo/A9zZmu3F2h9ArPQZLJkdjzQ85ZUAjg8ypcz/SVkSmsOfF2+Y aqmp1+rS9QqIyIh/S9XHpApzEwWLh72CDfzLZby6srB4jspFYn8xUY8PoiehM6VSVPLE VHvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xkTNe8LbWK6xulXneOsAwHc6v+5GHBHdVu4Rh+eTn3U=; b=N67QzTAXqEDSvVyI7M+gVkFabaKHNkcalnzC+i0mtjiaBIyhHg1B69bCQXOBXS9t4v wAAWgEvPyDRIeySqvZjX6KlhPiEgtLSj12g+t50EZx5WZfi1vrAS4bxb2l35GliB/MwZ S4Yt4UetSIeAWfNrZqWBGfzA7e3n0xNvGLm6nNSzQyKURk2rqUWJt5d9URorFCXFIDVv 3bsBdVYZ0cxhPMPl7jM135SG4wjVgpLyDMRhC3bApxoX3BemAZtTsztPeF5/L12p9Zs3 /Eql6wqEoKS8mQtqHUuHj5wD7FkH8dNboL892rak/o8ghFs1piFDz0SCaHMAA5jwzP6Q fv2w== X-Gm-Message-State: AOPr4FXx5omm8H27ab75sLFIe/vXxYyGYhwWNkY05NqfcbyhcQ9d5eb6Bv88gbnG7iEnoQ== X-Received: by 10.194.140.17 with SMTP id rc17mr3738264wjb.175.1461073186800; Tue, 19 Apr 2016 06:39:46 -0700 (PDT) Received: from localhost.localdomain (LPuteaux-656-1-278-113.w80-15.abo.wanadoo.fr. [80.15.154.113]) by smtp.googlemail.com with ESMTPSA id c85sm2789756wmd.0.2016.04.19.06.39.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 19 Apr 2016 06:39:46 -0700 (PDT) From: Alvise Rigo To: qemu-devel@nongnu.org, mttcg@listserver.greensocs.com Date: Tue, 19 Apr 2016 15:39:23 +0200 Message-Id: <1461073171-22953-7-git-send-email-a.rigo@virtualopensystems.com> X-Mailer: git-send-email 2.8.0 In-Reply-To: <1461073171-22953-1-git-send-email-a.rigo@virtualopensystems.com> References: <1461073171-22953-1-git-send-email-a.rigo@virtualopensystems.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::242 Subject: [Qemu-devel] [RFC v8 06/14] qom: cpu: Add CPUClass hooks for exclusive range X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: claudio.fontana@huawei.com, Alvise Rigo , serge.fdrv@gmail.com, pbonzini@redhat.com, jani.kokkonen@huawei.com, tech@virtualopensystems.com, alex.bennee@linaro.org, =?UTF-8?q?Andreas=20F=C3=A4rber?= , rth@twiddle.net Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 | 20 ++++++++++++++++++++ qom/cpu.c | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 2e5229d..21f10eb 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); @@ -123,6 +124,10 @@ struct TranslationBlock; * @cpu_exec_enter: Callback for cpu_exec preparation. * @cpu_exec_exit: Callback for cpu_exec cleanup. * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec. + * @cpu_set_excl_protected_range: Callback used by LL operation for setting the + * exclusive range. + * @cpu_valid_excl_access: Callback for checking the validity of a SC operation. + * @cpu_reset_excl_context: Callback for resetting the exclusive context. * @disas_set_info: Setup architecture specific components of disassembly info * * Represents a CPU family or model. @@ -183,6 +188,13 @@ 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); + bool (*cpu_valid_excl_access)(CPUState *cpu, hwaddr addr, + hwaddr size); + void (*cpu_reset_excl_context)(CPUState *cpu); + void (*disas_set_info)(CPUState *cpu, disassemble_info *info); } CPUClass; @@ -219,6 +231,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 +356,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; + /* 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..309d487 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -203,6 +203,29 @@ 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 bool 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 true; + } + + return false; +} + +static void cpu_common_reset_excl_context(CPUState *cpu) +{ + cpu->excl_protected_range.begin = EXCLUSIVE_RESET_ADDR; +} + void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags) { @@ -252,6 +275,7 @@ static void cpu_common_reset(CPUState *cpu) cpu->can_do_io = 1; cpu->exception_index = -1; cpu->crash_occurred = false; + cpu_common_reset_excl_context(cpu); memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *)); } @@ -355,6 +379,9 @@ 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; + k->cpu_reset_excl_context = cpu_common_reset_excl_context; dc->realize = cpu_common_realizefn; /* * Reason: CPUs still need special care by board code: wiring up