From patchwork Wed Dec 28 14:07:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Llu=C3=ADs_Vilanova?= X-Patchwork-Id: 9490347 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1E622602A7 for ; Wed, 28 Dec 2016 14:08:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0C830201BC for ; Wed, 28 Dec 2016 14:08:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F355720009; Wed, 28 Dec 2016 14:08:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 3BFA020009 for ; Wed, 28 Dec 2016 14:08:41 +0000 (UTC) Received: from localhost ([::1]:59354 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cMEuG-0001jw-6A for patchwork-qemu-devel@patchwork.kernel.org; Wed, 28 Dec 2016 09:08:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50780) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cMEtg-0001hg-Su for qemu-devel@nongnu.org; Wed, 28 Dec 2016 09:08:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cMEtc-0003U3-HV for qemu-devel@nongnu.org; Wed, 28 Dec 2016 09:08:04 -0500 Received: from roura.ac.upc.es ([147.83.33.10]:35134) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cMEtc-0003Tw-4R for qemu-devel@nongnu.org; Wed, 28 Dec 2016 09:08:00 -0500 Received: from gw-3.ac.upc.es (gw-3.ac.upc.es [147.83.30.9]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id uBSE7wCo008620; Wed, 28 Dec 2016 15:07:58 +0100 Received: from localhost (unknown [84.88.51.85]) by gw-3.ac.upc.es (Postfix) with ESMTPSA id C2DAA1EB; Wed, 28 Dec 2016 15:07:58 +0100 (CET) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 28 Dec 2016 15:07:58 +0100 Message-Id: <148293407851.28901.12400926737554982114.stgit@fimbulvetr.bsc.es> X-Mailer: git-send-email 2.11.0 In-Reply-To: <148293406236.28901.9490775858242540392.stgit@fimbulvetr.bsc.es> References: <148293406236.28901.9490775858242540392.stgit@fimbulvetr.bsc.es> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id uBSE7wCo008620 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 3/7] trace: [tcg] Delay changes to dynamic state when translating 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: Eduardo Habkost , Peter Crosthwaite , Stefan Hajnoczi , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This keeps consistency across all decisions taken during translation when the dynamic state of a vCPU is changed in the middle of translating some guest code. Signed-off-by: LluĂ­s Vilanova --- cpu-exec.c | 26 ++++++++++++++++++++++++++ include/qom/cpu.h | 7 +++++++ qom/cpu.c | 4 ++++ trace/control-target.c | 11 +++++++++-- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 4188fed3c6..1b7366efb0 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -33,6 +33,7 @@ #include "hw/i386/apic.h" #endif #include "sysemu/replay.h" +#include "trace/control.h" /* -icount align implementation. */ @@ -451,9 +452,21 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret) #ifndef CONFIG_USER_ONLY } else if (replay_has_exception() && cpu->icount_decr.u16.low + cpu->icount_extra == 0) { + /* delay changes to this vCPU's dstate during translation */ + atomic_set(&cpu->trace_dstate_delayed_req, false); + atomic_set(&cpu->trace_dstate_must_delay, true); + /* try to cause an exception pending in the log */ cpu_exec_nocache(cpu, 1, tb_find(cpu, NULL, 0), true); *ret = -1; + + /* apply and disable delayed dstate changes */ + atomic_set(&cpu->trace_dstate_must_delay, false); + if (unlikely(atomic_read(&cpu->trace_dstate_delayed_req))) { + bitmap_copy(cpu->trace_dstate, cpu->trace_dstate_delayed, + trace_get_vcpu_event_count()); + } + return true; #endif } @@ -634,8 +647,21 @@ int cpu_exec(CPUState *cpu) for(;;) { cpu_handle_interrupt(cpu, &last_tb); + + /* delay changes to this vCPU's dstate during translation */ + atomic_set(&cpu->trace_dstate_delayed_req, false); + atomic_set(&cpu->trace_dstate_must_delay, true); + tb = tb_find(cpu, last_tb, tb_exit); cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit, &sc); + + /* apply and disable delayed dstate changes */ + atomic_set(&cpu->trace_dstate_must_delay, false); + if (unlikely(atomic_read(&cpu->trace_dstate_delayed_req))) { + bitmap_copy(cpu->trace_dstate, cpu->trace_dstate_delayed, + trace_get_vcpu_event_count()); + } + /* Try to align the host and virtual clocks if the guest is in advance */ align_clocks(&sc, cpu); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 3f79a8e955..58255d06fa 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -295,6 +295,10 @@ struct qemu_work_item; * @kvm_fd: vCPU file descriptor for KVM. * @work_mutex: Lock to prevent multiple access to queued_work_*. * @queued_work_first: First asynchronous work pending. + * @trace_dstate_must_delay: Whether a change to trace_dstate must be delayed. + * @trace_dstate_delayed_req: Whether a change to trace_dstate was delayed. + * @trace_dstate_delayed: Delayed changes to trace_dstate (includes all changes + * to @trace_dstate). * @trace_dstate: Dynamic tracing state of events for this vCPU (bitmask). * * State of one CPU core or thread. @@ -370,6 +374,9 @@ struct CPUState { * Dynamically allocated based on bitmap requried to hold up to * trace_get_vcpu_event_count() entries. */ + bool trace_dstate_must_delay; + bool trace_dstate_delayed_req; + unsigned long *trace_dstate_delayed; unsigned long *trace_dstate; /* TODO Move common fields from CPUArchState here. */ diff --git a/qom/cpu.c b/qom/cpu.c index 03d9190f8c..d56496d28d 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -367,6 +367,9 @@ static void cpu_common_initfn(Object *obj) QTAILQ_INIT(&cpu->breakpoints); QTAILQ_INIT(&cpu->watchpoints); + cpu->trace_dstate_must_delay = false; + cpu->trace_dstate_delayed_req = false; + cpu->trace_dstate_delayed = bitmap_new(trace_get_vcpu_event_count()); cpu->trace_dstate = bitmap_new(trace_get_vcpu_event_count()); cpu_exec_initfn(cpu); @@ -375,6 +378,7 @@ static void cpu_common_initfn(Object *obj) static void cpu_common_finalize(Object *obj) { CPUState *cpu = CPU(obj); + g_free(cpu->trace_dstate_delayed); g_free(cpu->trace_dstate); } diff --git a/trace/control-target.c b/trace/control-target.c index 7ebf6e0bcb..aba8db55de 100644 --- a/trace/control-target.c +++ b/trace/control-target.c @@ -69,13 +69,20 @@ void trace_event_set_vcpu_state_dynamic(CPUState *vcpu, if (state_pre != state) { if (state) { trace_events_enabled_count++; - set_bit(vcpu_id, vcpu->trace_dstate); + set_bit(vcpu_id, vcpu->trace_dstate_delayed); + if (!atomic_read(&vcpu->trace_dstate_must_delay)) { + set_bit(vcpu_id, vcpu->trace_dstate); + } (*ev->dstate)++; } else { trace_events_enabled_count--; - clear_bit(vcpu_id, vcpu->trace_dstate); + clear_bit(vcpu_id, vcpu->trace_dstate_delayed); + if (!atomic_read(&vcpu->trace_dstate_must_delay)) { + clear_bit(vcpu_id, vcpu->trace_dstate); + } (*ev->dstate)--; } + atomic_set(&vcpu->trace_dstate_delayed_req, true); } }