From patchwork Tue Oct 6 07:29:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377244 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=pSaEKjIY; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Qj6gnQz9sS8 for ; Tue, 6 Oct 2020 18:35:57 +1100 (AEDT) Received: from localhost ([::1]:51416 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhVq-0000kV-8w for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:35:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39494) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ2-0002Ka-OH for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:54 -0400 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:43091) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhPy-0001N1-4U for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:54 -0400 Received: by mail-wr1-x433.google.com with SMTP id g12so6785413wrp.10 for ; Tue, 06 Oct 2020 00:29:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ubSoOmxIKUCP7aK3dWLiNekiWkYZ9huH3OUhBzVnvSc=; b=pSaEKjIY7ibKj/xXUzmR+Ks3Z7mC3MpNvlS/V7wyorRcDLrJXeh52tff1V0yVUiG4e ENbVDU2mJQMghRxmrxa1G+uahPTr4lBZC8s0E+3dKwxX6wWpJnizpNjqFgdLBXU58qGt ctPGk0juGiZ7eqslooTFyYKP4ySFtN2EgOu9cBAnV+K0bKphuDuZjphF0bH5N7dY8sPF min4FZWVElC0BET7DnuEXCTFdton/g5RnM8kd9la1tR6YjXaz/IiMsyElsolbAYRtMvm +z1so++NEtZHimdHHlrjtdZKW8DHPx3ar8sGu5mjGV3fauOWXgNFdA8JiZDM0M/lPbd9 ASpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=ubSoOmxIKUCP7aK3dWLiNekiWkYZ9huH3OUhBzVnvSc=; b=XqepIFphQCsc3DeKI/VjvyvFeaizGH6svCTOqskIKUFquUCMgmcPCXYCD+Bnv9yYsJ LHMNBnXG/0YM/ucifQDw6+4WNbkaD/1orImtHEzmTQ3Urz+dr7Hy0fQ5DFBlNfFUDrG4 nJuoH/0Z/gjQEZdCH/EN1rX+gwtG4Do/iFpP6b5tRZWMqm8Px/5Pc6sapJCOz2mWE3vZ YaWRhDPlSYoIKSjmtnOWHgVYiBoLhj3PM+rYk29o6FIuqOUEbZ4td+TdBpcQoBFoCLEW 1DrtENpRpVLASMA5lAVNR/yaVOYFI6Je+8w8YkqW/dWXOF0n3BGMyYbL4rlbLxq2l5Wj DiSQ== X-Gm-Message-State: AOAM531pYJs6r9xdUAwSY3Gj2eV+BhFwdnLrp82NcoqSjCch9Y4HsIO6 LP4s3WiDsSdUMEkf0YLgKGhEjoa8JtU= X-Google-Smtp-Source: ABdhPJySF66SjM9JKMWNYCrhR0CUemBAlF9U4KX9fs+0fNhnzlPzaufogxiXKkJRS+W7tpOjrgSYlg== X-Received: by 2002:adf:ecc1:: with SMTP id s1mr3287471wro.120.1601969387014; Tue, 06 Oct 2020 00:29:47 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:46 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 01/37] cpu-timers, icount: new modules Date: Tue, 6 Oct 2020 09:29:11 +0200 Message-Id: <20201006072947.487729-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::433; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x433.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana refactoring of cpus.c continues with cpu timer state extraction. cpu-timers: responsible for the softmmu cpu timers state, including cpu clocks and ticks. icount: counts the TCG instructions executed. As such it is specific to the TCG accelerator. Therefore, it is built only under CONFIG_TCG. One complication is due to qtest, which uses an icount field to warp time as part of qtest (qtest_clock_warp). In order to solve this problem, provide a separate counter for qtest. This requires fixing assumptions scattered in the code that qtest_enabled() implies icount_enabled(), checking each specific case. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson [remove redundant initialization with qemu_spice_init] Reviewed-by: Alex Bennée [fix lingering calls to icount_get] Signed-off-by: Claudio Fontana Signed-off-by: Paolo Bonzini --- MAINTAINERS | 2 + accel/qtest.c | 6 +- accel/tcg/cpu-exec.c | 39 +- accel/tcg/tcg-all.c | 7 +- accel/tcg/translate-all.c | 3 +- dma-helpers.c | 4 +- exec.c | 4 - hw/core/ptimer.c | 8 +- hw/i386/x86.c | 1 + include/exec/cpu-all.h | 4 + include/exec/exec-all.h | 4 +- include/qemu/timer.h | 24 +- include/sysemu/cpu-timers.h | 87 ++++ include/sysemu/cpus.h | 12 +- include/sysemu/qtest.h | 2 + replay/replay.c | 4 +- softmmu/cpu-timers.c | 284 +++++++++++++ softmmu/cpus.c | 744 +---------------------------------- softmmu/icount.c | 492 +++++++++++++++++++++++ softmmu/meson.build | 10 +- softmmu/qtest.c | 34 +- softmmu/timers-state.h | 69 ++++ softmmu/vl.c | 6 +- stubs/clock-warp.c | 7 - stubs/cpu-get-clock.c | 3 +- stubs/cpu-get-icount.c | 16 - stubs/icount.c | 45 +++ stubs/meson.build | 4 +- stubs/qemu-timer-notify-cb.c | 2 +- stubs/qtest.c | 5 + target/alpha/translate.c | 3 +- target/arm/helper.c | 3 +- target/riscv/csr.c | 4 +- tests/ptimer-test-stubs.c | 5 +- tests/test-timed-average.c | 2 +- util/main-loop.c | 12 +- util/qemu-timer.c | 10 +- 37 files changed, 1128 insertions(+), 843 deletions(-) create mode 100644 include/sysemu/cpu-timers.h create mode 100644 softmmu/cpu-timers.c create mode 100644 softmmu/icount.c create mode 100644 softmmu/timers-state.h delete mode 100644 stubs/clock-warp.c delete mode 100644 stubs/cpu-get-icount.c create mode 100644 stubs/icount.c diff --git a/MAINTAINERS b/MAINTAINERS index b76fb31861..a59be84de6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2321,6 +2321,8 @@ F: softmmu/vl.c F: softmmu/main.c F: softmmu/cpus.c F: softmmu/cpu-throttle.c +F: softmmu/cpu-timers.c +F: softmmu/icount.c F: qapi/run-state.json Read, Copy, Update (RCU) diff --git a/accel/qtest.c b/accel/qtest.c index 5b88f55921..119d0f16a4 100644 --- a/accel/qtest.c +++ b/accel/qtest.c @@ -19,14 +19,10 @@ #include "sysemu/accel.h" #include "sysemu/qtest.h" #include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" static int qtest_init_accel(MachineState *ms) { - QemuOpts *opts = qemu_opts_create(qemu_find_opts("icount"), NULL, 0, - &error_abort); - qemu_opt_set(opts, "shift", "0", &error_abort); - configure_icount(opts, &error_abort); - qemu_opts_del(opts); return 0; } diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index e10b46283c..35bfe2ca92 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" +#include "qemu/qemu-print.h" #include "cpu.h" #include "trace.h" #include "disas/disas.h" @@ -36,6 +37,8 @@ #include "hw/i386/apic.h" #endif #include "sysemu/cpus.h" +#include "exec/cpu-all.h" +#include "sysemu/cpu-timers.h" #include "sysemu/replay.h" /* -icount align implementation. */ @@ -56,6 +59,9 @@ typedef struct SyncClocks { #define MAX_DELAY_PRINT_RATE 2000000000LL #define MAX_NB_PRINTS 100 +static int64_t max_delay; +static int64_t max_advance; + static void align_clocks(SyncClocks *sc, CPUState *cpu) { int64_t cpu_icount; @@ -98,9 +104,9 @@ static void print_delay(const SyncClocks *sc) (-sc->diff_clk / (float)1000000000LL < (threshold_delay - THRESHOLD_REDUCE))) { threshold_delay = (-sc->diff_clk / 1000000000LL) + 1; - printf("Warning: The guest is now late by %.1f to %.1f seconds\n", - threshold_delay - 1, - threshold_delay); + qemu_printf("Warning: The guest is now late by %.1f to %.1f seconds\n", + threshold_delay - 1, + threshold_delay); nb_prints++; last_realtime_clock = sc->realtime_clock; } @@ -615,7 +621,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, /* Finally, check if we need to exit to the main loop. */ if (unlikely(qatomic_read(&cpu->exit_request)) - || (use_icount + || (icount_enabled() && cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra == 0)) { qatomic_set(&cpu->exit_request, 0); if (cpu->exception_index == -1) { @@ -656,7 +662,7 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb, } /* Instruction counter expired. */ - assert(use_icount); + assert(icount_enabled()); #ifndef CONFIG_USER_ONLY /* Ensure global icount has gone forward */ cpu_update_icount(cpu); @@ -759,3 +765,26 @@ int cpu_exec(CPUState *cpu) return ret; } + +#ifndef CONFIG_USER_ONLY + +void dump_drift_info(void) +{ + if (!icount_enabled()) { + return; + } + + qemu_printf("Host - Guest clock %"PRIi64" ms\n", + (cpu_get_clock() - cpu_get_icount()) / SCALE_MS); + if (icount_align_option) { + qemu_printf("Max guest delay %"PRIi64" ms\n", + -max_delay / SCALE_MS); + qemu_printf("Max guest advance %"PRIi64" ms\n", + max_advance / SCALE_MS); + } else { + qemu_printf("Max guest delay NA\n"); + qemu_printf("Max guest advance NA\n"); + } +} + +#endif /* !CONFIG_USER_ONLY */ diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c index 1c664924d7..2d13df3f72 100644 --- a/accel/tcg/tcg-all.c +++ b/accel/tcg/tcg-all.c @@ -29,6 +29,7 @@ #include "qom/object.h" #include "cpu.h" #include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "qemu/main-loop.h" #include "tcg/tcg.h" #include "qapi/error.h" @@ -66,7 +67,7 @@ static void tcg_handle_interrupt(CPUState *cpu, int mask) qemu_cpu_kick(cpu); } else { qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1); - if (use_icount && + if (icount_enabled() && !cpu->can_do_io && (mask & ~old_mask) != 0) { cpu_abort(cpu, "Raised interrupt while not in I/O function"); @@ -105,7 +106,7 @@ static bool check_tcg_memory_orders_compatible(void) static bool default_mttcg_enabled(void) { - if (use_icount || TCG_OVERSIZED_GUEST) { + if (icount_enabled() || TCG_OVERSIZED_GUEST) { return false; } else { #ifdef TARGET_SUPPORTS_MTTCG @@ -147,7 +148,7 @@ static void tcg_set_thread(Object *obj, const char *value, Error **errp) if (strcmp(value, "multi") == 0) { if (TCG_OVERSIZED_GUEST) { error_setg(errp, "No MTTCG when guest word size > hosts"); - } else if (use_icount) { + } else if (icount_enabled()) { error_setg(errp, "No MTTCG when icount is enabled"); } else { #ifndef TARGET_SUPPORTS_MTTCG diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index e82fc35b32..d76097296d 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -57,6 +57,7 @@ #include "qemu/main-loop.h" #include "exec/log.h" #include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "sysemu/tcg.h" /* #define DEBUG_TB_INVALIDATE */ @@ -369,7 +370,7 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, found: if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) { - assert(use_icount); + assert(icount_enabled()); /* Reset the cycle counter to the start of the block and shift if to the number of actually executed instructions */ cpu_neg(cpu)->icount_decr.u16.low += num_insns - i; diff --git a/dma-helpers.c b/dma-helpers.c index 41ef24a63b..03c92e0cc6 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -13,7 +13,7 @@ #include "trace/trace-root.h" #include "qemu/thread.h" #include "qemu/main-loop.h" -#include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "qemu/range.h" /* #define DEBUG_IOMMU */ @@ -151,7 +151,7 @@ static void dma_blk_cb(void *opaque, int ret) * from several sectors. This code splits all SGs into several * groups. SGs in every group do not overlap. */ - if (mem && use_icount && dbs->dir == DMA_DIRECTION_FROM_DEVICE) { + if (mem && icount_enabled() && dbs->dir == DMA_DIRECTION_FROM_DEVICE) { int i; for (i = 0 ; i < dbs->iov.niov ; ++i) { if (ranges_overlap((intptr_t)dbs->iov.iov[i].iov_base, diff --git a/exec.c b/exec.c index c088559d94..2305f5553e 100644 --- a/exec.c +++ b/exec.c @@ -102,10 +102,6 @@ uintptr_t qemu_host_page_size; intptr_t qemu_host_page_mask; #if !defined(CONFIG_USER_ONLY) -/* 0 = Do not count executed instructions. - 1 = Precise instruction counting. - 2 = Adaptive rate instruction counting. */ -int use_icount; typedef struct PhysPageEntry PhysPageEntry; diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c index b5a54e2536..c6d2beb1da 100644 --- a/hw/core/ptimer.c +++ b/hw/core/ptimer.c @@ -7,11 +7,11 @@ */ #include "qemu/osdep.h" -#include "qemu/timer.h" #include "hw/ptimer.h" #include "migration/vmstate.h" #include "qemu/host-utils.h" #include "sysemu/replay.h" +#include "sysemu/cpu-timers.h" #include "sysemu/qtest.h" #include "block/aio.h" #include "sysemu/cpus.h" @@ -134,7 +134,8 @@ static void ptimer_reload(ptimer_state *s, int delta_adjust) * on the current generation of host machines. */ - if (s->enabled == 1 && (delta * period < 10000) && !use_icount) { + if (s->enabled == 1 && (delta * period < 10000) && + !icount_enabled() && !qtest_enabled()) { period = 10000 / delta; period_frac = 0; } @@ -217,7 +218,8 @@ uint64_t ptimer_get_count(ptimer_state *s) uint32_t period_frac = s->period_frac; uint64_t period = s->period; - if (!oneshot && (s->delta * period < 10000) && !use_icount) { + if (!oneshot && (s->delta * period < 10000) && + !icount_enabled() && !qtest_enabled()) { period = 10000 / s->delta; period_frac = 0; } diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 403c2b1dad..953083e063 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -34,6 +34,7 @@ #include "sysemu/numa.h" #include "sysemu/replay.h" #include "sysemu/sysemu.h" +#include "sysemu/cpu-timers.h" #include "trace.h" #include "hw/i386/x86.h" diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index f6439c4705..61e13b5038 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -407,8 +407,12 @@ static inline bool tlb_hit(target_ulong tlb_addr, target_ulong addr) return tlb_hit_page(tlb_addr, addr & TARGET_PAGE_MASK); } +#ifdef CONFIG_TCG +void dump_drift_info(void); void dump_exec_info(void); void dump_opcount_info(void); +#endif /* CONFIG_TCG */ + #endif /* !CONFIG_USER_ONLY */ /* Returns: 0 on success, -1 on error */ diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 1fe28d574f..66f9b4cca6 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -25,7 +25,7 @@ #ifdef CONFIG_TCG #include "exec/cpu_ldst.h" #endif -#include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" /* allow to see translation results - the slowdown should be negligible, so we leave it */ #define DEBUG_DISAS @@ -497,7 +497,7 @@ static inline uint32_t tb_cflags(const TranslationBlock *tb) static inline uint32_t curr_cflags(void) { return (parallel_cpus ? CF_PARALLEL : 0) - | (use_icount ? CF_USE_ICOUNT : 0); + | (icount_enabled() ? CF_USE_ICOUNT : 0); } /* TranslationBlock invalidate API */ diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 1dc880e94e..bdecc5b41f 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -166,8 +166,8 @@ bool qemu_clock_expired(QEMUClockType type); * * Determine whether a clock should be used for deadline * calculations. Some clocks, for instance vm_clock with - * use_icount set, do not count in nanoseconds. Such clocks - * are not used for deadline calculations, and are presumed + * icount_enabled() set, do not count in nanoseconds. + * Such clocks are not used for deadline calculations, and are presumed * to interrupt any poll using qemu_notify/aio_notify * etc. * @@ -224,13 +224,6 @@ void qemu_clock_notify(QEMUClockType type); */ void qemu_clock_enable(QEMUClockType type, bool enabled); -/** - * qemu_start_warp_timer: - * - * Starts a timer for virtual clock update - */ -void qemu_start_warp_timer(void); - /** * qemu_clock_run_timers: * @type: clock on which to operate @@ -791,12 +784,6 @@ static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2) */ void init_clocks(QEMUTimerListNotifyCB *notify_cb); -int64_t cpu_get_ticks(void); -/* Caller must hold BQL */ -void cpu_enable_ticks(void); -/* Caller must hold BQL */ -void cpu_disable_ticks(void); - static inline int64_t get_max_clock_jump(void) { /* This should be small enough to prevent excessive interrupts from being @@ -850,13 +837,6 @@ static inline int64_t get_clock(void) } #endif -/* icount */ -int64_t cpu_get_icount_raw(void); -int64_t cpu_get_icount(void); -int64_t cpu_get_clock(void); -int64_t cpu_icount_to_ns(int64_t icount); -void cpu_update_icount(CPUState *cpu); - /*******************************************/ /* host CPU ticks (if available) */ diff --git a/include/sysemu/cpu-timers.h b/include/sysemu/cpu-timers.h new file mode 100644 index 0000000000..4b621fea51 --- /dev/null +++ b/include/sysemu/cpu-timers.h @@ -0,0 +1,87 @@ +/* + * CPU timers state API + * + * Copyright 2020 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#ifndef SYSEMU_CPU_TIMERS_H +#define SYSEMU_CPU_TIMERS_H + +#include "qemu/timer.h" + +/* init the whole cpu timers API, including icount, ticks, and cpu_throttle */ +void cpu_timers_init(void); + +/* icount - Instruction Counter API */ + +/* + * icount enablement state: + * + * 0 = Disabled - Do not count executed instructions. + * 1 = Enabled - Fixed conversion of insn to ns via "shift" option + * 2 = Enabled - Runtime adaptive algorithm to compute shift + */ +#ifdef CONFIG_TCG +extern int use_icount; +#define icount_enabled() (use_icount) +#else +#define icount_enabled() 0 +#endif + +/* + * Update the icount with the executed instructions. Called by + * cpus-tcg vCPU thread so the main-loop can see time has moved forward. + */ +void cpu_update_icount(CPUState *cpu); + +/* get raw icount value */ +int64_t cpu_get_icount_raw(void); + +/* return the virtual CPU time in ns, based on the instruction counter. */ +int64_t cpu_get_icount(void); +/* + * convert an instruction counter value to ns, based on the icount shift. + * This shift is set as a fixed value with the icount "shift" option + * (precise mode), or it is constantly approximated and corrected at + * runtime in adaptive mode. + */ +int64_t cpu_icount_to_ns(int64_t icount); + +/* configure the icount options, including "shift" */ +void configure_icount(QemuOpts *opts, Error **errp); + +/* used by tcg vcpu thread to calc icount budget */ +int64_t qemu_icount_round(int64_t count); + +/* if the CPUs are idle, start accounting real time to virtual clock. */ +void qemu_start_warp_timer(void); +void qemu_account_warp_timer(void); + +/* + * CPU Ticks and Clock + */ + +/* Caller must hold BQL */ +void cpu_enable_ticks(void); +/* Caller must hold BQL */ +void cpu_disable_ticks(void); + +/* + * return the time elapsed in VM between vm_start and vm_stop. Unless + * icount is active, cpu_get_ticks() uses units of the host CPU cycle + * counter. + */ +int64_t cpu_get_ticks(void); + +/* + * Returns the monotonic time elapsed in VM, i.e., + * the time between vm_start and vm_stop + */ +int64_t cpu_get_clock(void); + +void qemu_timer_notify_cb(void *opaque, QEMUClockType type); + +#endif /* SYSEMU_CPU_TIMERS_H */ diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 3c1da6a018..149de000a0 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -4,33 +4,23 @@ #include "qemu/timer.h" /* cpus.c */ +bool all_cpu_threads_idle(void); bool qemu_in_vcpu_thread(void); void qemu_init_cpu_loop(void); void resume_all_vcpus(void); void pause_all_vcpus(void); void cpu_stop_current(void); -void cpu_ticks_init(void); -void configure_icount(QemuOpts *opts, Error **errp); -extern int use_icount; extern int icount_align_option; -/* drift information for info jit command */ -extern int64_t max_delay; -extern int64_t max_advance; -void dump_drift_info(void); - /* Unblock cpu */ void qemu_cpu_kick_self(void); -void qemu_timer_notify_cb(void *opaque, QEMUClockType type); void cpu_synchronize_all_states(void); void cpu_synchronize_all_post_reset(void); void cpu_synchronize_all_post_init(void); void cpu_synchronize_all_pre_loadvm(void); -void qtest_clock_warp(int64_t dest); - #ifndef CONFIG_USER_ONLY /* vl.c */ /* *-user doesn't have configurable SMP topology */ diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h index eedd3664f0..4c53537ef3 100644 --- a/include/sysemu/qtest.h +++ b/include/sysemu/qtest.h @@ -30,4 +30,6 @@ void qtest_server_set_send_handler(void (*send)(void *, const char *), void *opaque); void qtest_server_inproc_recv(void *opaque, const char *buf); +int64_t qtest_get_virtual_clock(void); + #endif diff --git a/replay/replay.c b/replay/replay.c index 83ed9e0e24..7e4a1ba78e 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -11,10 +11,10 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "sysemu/cpu-timers.h" #include "sysemu/replay.h" #include "sysemu/runstate.h" #include "replay-internal.h" -#include "qemu/timer.h" #include "qemu/main-loop.h" #include "qemu/option.h" #include "sysemu/cpus.h" @@ -345,7 +345,7 @@ void replay_start(void) error_reportf_err(replay_blockers->data, "Record/replay: "); exit(1); } - if (!use_icount) { + if (!icount_enabled()) { error_report("Please enable icount to use record/replay"); exit(1); } diff --git a/softmmu/cpu-timers.c b/softmmu/cpu-timers.c new file mode 100644 index 0000000000..6c6c56090f --- /dev/null +++ b/softmmu/cpu-timers.c @@ -0,0 +1,284 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/cutils.h" +#include "migration/vmstate.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "exec/exec-all.h" +#include "sysemu/cpus.h" +#include "sysemu/qtest.h" +#include "qemu/main-loop.h" +#include "qemu/option.h" +#include "qemu/seqlock.h" +#include "sysemu/replay.h" +#include "sysemu/runstate.h" +#include "hw/core/cpu.h" +#include "sysemu/cpu-timers.h" +#include "sysemu/cpu-throttle.h" +#include "timers-state.h" + +/* clock and ticks */ + +static int64_t cpu_get_ticks_locked(void) +{ + int64_t ticks = timers_state.cpu_ticks_offset; + if (timers_state.cpu_ticks_enabled) { + ticks += cpu_get_host_ticks(); + } + + if (timers_state.cpu_ticks_prev > ticks) { + /* Non increasing ticks may happen if the host uses software suspend. */ + timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks; + ticks = timers_state.cpu_ticks_prev; + } + + timers_state.cpu_ticks_prev = ticks; + return ticks; +} + +/* + * return the time elapsed in VM between vm_start and vm_stop. Unless + * icount is active, cpu_get_ticks() uses units of the host CPU cycle + * counter. + */ +int64_t cpu_get_ticks(void) +{ + int64_t ticks; + + if (icount_enabled()) { + return cpu_get_icount(); + } + + qemu_spin_lock(&timers_state.vm_clock_lock); + ticks = cpu_get_ticks_locked(); + qemu_spin_unlock(&timers_state.vm_clock_lock); + return ticks; +} + +int64_t cpu_get_clock_locked(void) +{ + int64_t time; + + time = timers_state.cpu_clock_offset; + if (timers_state.cpu_ticks_enabled) { + time += get_clock(); + } + + return time; +} + +/* + * Return the monotonic time elapsed in VM, i.e., + * the time between vm_start and vm_stop + */ +int64_t cpu_get_clock(void) +{ + int64_t ti; + unsigned start; + + do { + start = seqlock_read_begin(&timers_state.vm_clock_seqlock); + ti = cpu_get_clock_locked(); + } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); + + return ti; +} + +/* + * enable cpu_get_ticks() + * Caller must hold BQL which serves as mutex for vm_clock_seqlock. + */ +void cpu_enable_ticks(void) +{ + seqlock_write_lock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + if (!timers_state.cpu_ticks_enabled) { + timers_state.cpu_ticks_offset -= cpu_get_host_ticks(); + timers_state.cpu_clock_offset -= get_clock(); + timers_state.cpu_ticks_enabled = 1; + } + seqlock_write_unlock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); +} + +/* + * disable cpu_get_ticks() : the clock is stopped. You must not call + * cpu_get_ticks() after that. + * Caller must hold BQL which serves as mutex for vm_clock_seqlock. + */ +void cpu_disable_ticks(void) +{ + seqlock_write_lock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + if (timers_state.cpu_ticks_enabled) { + timers_state.cpu_ticks_offset += cpu_get_host_ticks(); + timers_state.cpu_clock_offset = cpu_get_clock_locked(); + timers_state.cpu_ticks_enabled = 0; + } + seqlock_write_unlock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); +} + +static bool icount_state_needed(void *opaque) +{ + return icount_enabled(); +} + +static bool warp_timer_state_needed(void *opaque) +{ + TimersState *s = opaque; + return s->icount_warp_timer != NULL; +} + +static bool adjust_timers_state_needed(void *opaque) +{ + TimersState *s = opaque; + return s->icount_rt_timer != NULL; +} + +static bool shift_state_needed(void *opaque) +{ + return icount_enabled() == 2; +} + +/* + * Subsection for warp timer migration is optional, because may not be created + */ +static const VMStateDescription icount_vmstate_warp_timer = { + .name = "timer/icount/warp_timer", + .version_id = 1, + .minimum_version_id = 1, + .needed = warp_timer_state_needed, + .fields = (VMStateField[]) { + VMSTATE_INT64(vm_clock_warp_start, TimersState), + VMSTATE_TIMER_PTR(icount_warp_timer, TimersState), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription icount_vmstate_adjust_timers = { + .name = "timer/icount/timers", + .version_id = 1, + .minimum_version_id = 1, + .needed = adjust_timers_state_needed, + .fields = (VMStateField[]) { + VMSTATE_TIMER_PTR(icount_rt_timer, TimersState), + VMSTATE_TIMER_PTR(icount_vm_timer, TimersState), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription icount_vmstate_shift = { + .name = "timer/icount/shift", + .version_id = 1, + .minimum_version_id = 1, + .needed = shift_state_needed, + .fields = (VMStateField[]) { + VMSTATE_INT16(icount_time_shift, TimersState), + VMSTATE_END_OF_LIST() + } +}; + +/* + * This is a subsection for icount migration. + */ +static const VMStateDescription icount_vmstate_timers = { + .name = "timer/icount", + .version_id = 1, + .minimum_version_id = 1, + .needed = icount_state_needed, + .fields = (VMStateField[]) { + VMSTATE_INT64(qemu_icount_bias, TimersState), + VMSTATE_INT64(qemu_icount, TimersState), + VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &icount_vmstate_warp_timer, + &icount_vmstate_adjust_timers, + &icount_vmstate_shift, + NULL + } +}; + +static const VMStateDescription vmstate_timers = { + .name = "timer", + .version_id = 2, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_INT64(cpu_ticks_offset, TimersState), + VMSTATE_UNUSED(8), + VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2), + VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &icount_vmstate_timers, + NULL + } +}; + +static void do_nothing(CPUState *cpu, run_on_cpu_data unused) +{ +} + +void qemu_timer_notify_cb(void *opaque, QEMUClockType type) +{ + if (!icount_enabled() || type != QEMU_CLOCK_VIRTUAL) { + qemu_notify_event(); + return; + } + + if (qemu_in_vcpu_thread()) { + /* + * A CPU is currently running; kick it back out to the + * tcg_cpu_exec() loop so it will recalculate its + * icount deadline immediately. + */ + qemu_cpu_kick(current_cpu); + } else if (first_cpu) { + /* + * qemu_cpu_kick is not enough to kick a halted CPU out of + * qemu_tcg_wait_io_event. async_run_on_cpu, instead, + * causes cpu_thread_is_idle to return false. This way, + * handle_icount_deadline can run. + * If we have no CPUs at all for some reason, we don't + * need to do anything. + */ + async_run_on_cpu(first_cpu, do_nothing, RUN_ON_CPU_NULL); + } +} + +TimersState timers_state; + +/* initialize timers state and the cpu throttle for convenience */ +void cpu_timers_init(void) +{ + seqlock_init(&timers_state.vm_clock_seqlock); + qemu_spin_init(&timers_state.vm_clock_lock); + vmstate_register(NULL, 0, &vmstate_timers, &timers_state); + + cpu_throttle_init(); +} diff --git a/softmmu/cpus.c b/softmmu/cpus.c index ac8940d52e..4f2777a738 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -58,11 +58,10 @@ #include "hw/nmi.h" #include "sysemu/replay.h" #include "sysemu/runstate.h" +#include "sysemu/cpu-timers.h" #include "hw/boards.h" #include "hw/hw.h" -#include "sysemu/cpu-throttle.h" - #ifdef CONFIG_LINUX #include @@ -83,9 +82,6 @@ static QemuMutex qemu_global_mutex; -int64_t max_delay; -int64_t max_advance; - bool cpu_is_stopped(CPUState *cpu) { return cpu->stopped || !runstate_is_running(); @@ -116,7 +112,7 @@ static bool cpu_thread_is_idle(CPUState *cpu) return true; } -static bool all_cpu_threads_idle(void) +bool all_cpu_threads_idle(void) { CPUState *cpu; @@ -128,688 +124,9 @@ static bool all_cpu_threads_idle(void) return true; } -/***********************************************************/ -/* guest cycle counter */ - -/* Protected by TimersState seqlock */ - -static bool icount_sleep = true; -/* Arbitrarily pick 1MIPS as the minimum allowable speed. */ -#define MAX_ICOUNT_SHIFT 10 - -typedef struct TimersState { - /* Protected by BQL. */ - int64_t cpu_ticks_prev; - int64_t cpu_ticks_offset; - - /* Protect fields that can be respectively read outside the - * BQL, and written from multiple threads. - */ - QemuSeqLock vm_clock_seqlock; - QemuSpin vm_clock_lock; - - int16_t cpu_ticks_enabled; - - /* Conversion factor from emulated instructions to virtual clock ticks. */ - int16_t icount_time_shift; - - /* Compensate for varying guest execution speed. */ - int64_t qemu_icount_bias; - - int64_t vm_clock_warp_start; - int64_t cpu_clock_offset; - - /* Only written by TCG thread */ - int64_t qemu_icount; - - /* for adjusting icount */ - QEMUTimer *icount_rt_timer; - QEMUTimer *icount_vm_timer; - QEMUTimer *icount_warp_timer; -} TimersState; - -static TimersState timers_state; bool mttcg_enabled; -/* The current number of executed instructions is based on what we - * originally budgeted minus the current state of the decrementing - * icount counters in extra/u16.low. - */ -static int64_t cpu_get_icount_executed(CPUState *cpu) -{ - return (cpu->icount_budget - - (cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra)); -} - -/* - * Update the global shared timer_state.qemu_icount to take into - * account executed instructions. This is done by the TCG vCPU - * thread so the main-loop can see time has moved forward. - */ -static void cpu_update_icount_locked(CPUState *cpu) -{ - int64_t executed = cpu_get_icount_executed(cpu); - cpu->icount_budget -= executed; - - qatomic_set_i64(&timers_state.qemu_icount, - timers_state.qemu_icount + executed); -} - -/* - * Update the global shared timer_state.qemu_icount to take into - * account executed instructions. This is done by the TCG vCPU - * thread so the main-loop can see time has moved forward. - */ -void cpu_update_icount(CPUState *cpu) -{ - seqlock_write_lock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - cpu_update_icount_locked(cpu); - seqlock_write_unlock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); -} - -static int64_t cpu_get_icount_raw_locked(void) -{ - CPUState *cpu = current_cpu; - - if (cpu && cpu->running) { - if (!cpu->can_do_io) { - error_report("Bad icount read"); - exit(1); - } - /* Take into account what has run */ - cpu_update_icount_locked(cpu); - } - /* The read is protected by the seqlock, but needs atomic64 to avoid UB */ - return qatomic_read_i64(&timers_state.qemu_icount); -} - -static int64_t cpu_get_icount_locked(void) -{ - int64_t icount = cpu_get_icount_raw_locked(); - return qatomic_read_i64(&timers_state.qemu_icount_bias) + - cpu_icount_to_ns(icount); -} - -int64_t cpu_get_icount_raw(void) -{ - int64_t icount; - unsigned start; - - do { - start = seqlock_read_begin(&timers_state.vm_clock_seqlock); - icount = cpu_get_icount_raw_locked(); - } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); - - return icount; -} - -/* Return the virtual CPU time, based on the instruction counter. */ -int64_t cpu_get_icount(void) -{ - int64_t icount; - unsigned start; - - do { - start = seqlock_read_begin(&timers_state.vm_clock_seqlock); - icount = cpu_get_icount_locked(); - } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); - - return icount; -} - -int64_t cpu_icount_to_ns(int64_t icount) -{ - return icount << qatomic_read(&timers_state.icount_time_shift); -} - -static int64_t cpu_get_ticks_locked(void) -{ - int64_t ticks = timers_state.cpu_ticks_offset; - if (timers_state.cpu_ticks_enabled) { - ticks += cpu_get_host_ticks(); - } - - if (timers_state.cpu_ticks_prev > ticks) { - /* Non increasing ticks may happen if the host uses software suspend. */ - timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks; - ticks = timers_state.cpu_ticks_prev; - } - - timers_state.cpu_ticks_prev = ticks; - return ticks; -} - -/* return the time elapsed in VM between vm_start and vm_stop. Unless - * icount is active, cpu_get_ticks() uses units of the host CPU cycle - * counter. - */ -int64_t cpu_get_ticks(void) -{ - int64_t ticks; - - if (use_icount) { - return cpu_get_icount(); - } - - qemu_spin_lock(&timers_state.vm_clock_lock); - ticks = cpu_get_ticks_locked(); - qemu_spin_unlock(&timers_state.vm_clock_lock); - return ticks; -} - -static int64_t cpu_get_clock_locked(void) -{ - int64_t time; - - time = timers_state.cpu_clock_offset; - if (timers_state.cpu_ticks_enabled) { - time += get_clock(); - } - - return time; -} - -/* Return the monotonic time elapsed in VM, i.e., - * the time between vm_start and vm_stop - */ -int64_t cpu_get_clock(void) -{ - int64_t ti; - unsigned start; - - do { - start = seqlock_read_begin(&timers_state.vm_clock_seqlock); - ti = cpu_get_clock_locked(); - } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); - - return ti; -} - -/* enable cpu_get_ticks() - * Caller must hold BQL which serves as mutex for vm_clock_seqlock. - */ -void cpu_enable_ticks(void) -{ - seqlock_write_lock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - if (!timers_state.cpu_ticks_enabled) { - timers_state.cpu_ticks_offset -= cpu_get_host_ticks(); - timers_state.cpu_clock_offset -= get_clock(); - timers_state.cpu_ticks_enabled = 1; - } - seqlock_write_unlock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); -} - -/* disable cpu_get_ticks() : the clock is stopped. You must not call - * cpu_get_ticks() after that. - * Caller must hold BQL which serves as mutex for vm_clock_seqlock. - */ -void cpu_disable_ticks(void) -{ - seqlock_write_lock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - if (timers_state.cpu_ticks_enabled) { - timers_state.cpu_ticks_offset += cpu_get_host_ticks(); - timers_state.cpu_clock_offset = cpu_get_clock_locked(); - timers_state.cpu_ticks_enabled = 0; - } - seqlock_write_unlock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); -} - -/* Correlation between real and virtual time is always going to be - fairly approximate, so ignore small variation. - When the guest is idle real and virtual time will be aligned in - the IO wait loop. */ -#define ICOUNT_WOBBLE (NANOSECONDS_PER_SECOND / 10) - -static void icount_adjust(void) -{ - int64_t cur_time; - int64_t cur_icount; - int64_t delta; - - /* Protected by TimersState mutex. */ - static int64_t last_delta; - - /* If the VM is not running, then do nothing. */ - if (!runstate_is_running()) { - return; - } - - seqlock_write_lock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - cur_time = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT, - cpu_get_clock_locked()); - cur_icount = cpu_get_icount_locked(); - - delta = cur_icount - cur_time; - /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ - if (delta > 0 - && last_delta + ICOUNT_WOBBLE < delta * 2 - && timers_state.icount_time_shift > 0) { - /* The guest is getting too far ahead. Slow time down. */ - qatomic_set(&timers_state.icount_time_shift, - timers_state.icount_time_shift - 1); - } - if (delta < 0 - && last_delta - ICOUNT_WOBBLE > delta * 2 - && timers_state.icount_time_shift < MAX_ICOUNT_SHIFT) { - /* The guest is getting too far behind. Speed time up. */ - qatomic_set(&timers_state.icount_time_shift, - timers_state.icount_time_shift + 1); - } - last_delta = delta; - qatomic_set_i64(&timers_state.qemu_icount_bias, - cur_icount - (timers_state.qemu_icount - << timers_state.icount_time_shift)); - seqlock_write_unlock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); -} - -static void icount_adjust_rt(void *opaque) -{ - timer_mod(timers_state.icount_rt_timer, - qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000); - icount_adjust(); -} - -static void icount_adjust_vm(void *opaque) -{ - timer_mod(timers_state.icount_vm_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - NANOSECONDS_PER_SECOND / 10); - icount_adjust(); -} - -static int64_t qemu_icount_round(int64_t count) -{ - int shift = qatomic_read(&timers_state.icount_time_shift); - return (count + (1 << shift) - 1) >> shift; -} - -static void icount_warp_rt(void) -{ - unsigned seq; - int64_t warp_start; - - /* The icount_warp_timer is rescheduled soon after vm_clock_warp_start - * changes from -1 to another value, so the race here is okay. - */ - do { - seq = seqlock_read_begin(&timers_state.vm_clock_seqlock); - warp_start = timers_state.vm_clock_warp_start; - } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq)); - - if (warp_start == -1) { - return; - } - - seqlock_write_lock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - if (runstate_is_running()) { - int64_t clock = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT, - cpu_get_clock_locked()); - int64_t warp_delta; - - warp_delta = clock - timers_state.vm_clock_warp_start; - if (use_icount == 2) { - /* - * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too - * far ahead of real time. - */ - int64_t cur_icount = cpu_get_icount_locked(); - int64_t delta = clock - cur_icount; - warp_delta = MIN(warp_delta, delta); - } - qatomic_set_i64(&timers_state.qemu_icount_bias, - timers_state.qemu_icount_bias + warp_delta); - } - timers_state.vm_clock_warp_start = -1; - seqlock_write_unlock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - - if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) { - qemu_clock_notify(QEMU_CLOCK_VIRTUAL); - } -} - -static void icount_timer_cb(void *opaque) -{ - /* No need for a checkpoint because the timer already synchronizes - * with CHECKPOINT_CLOCK_VIRTUAL_RT. - */ - icount_warp_rt(); -} - -void qtest_clock_warp(int64_t dest) -{ - int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - AioContext *aio_context; - assert(qtest_enabled()); - aio_context = qemu_get_aio_context(); - while (clock < dest) { - int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, - QEMU_TIMER_ATTR_ALL); - int64_t warp = qemu_soonest_timeout(dest - clock, deadline); - - seqlock_write_lock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - qatomic_set_i64(&timers_state.qemu_icount_bias, - timers_state.qemu_icount_bias + warp); - seqlock_write_unlock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - - qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL); - timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]); - clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - } - qemu_clock_notify(QEMU_CLOCK_VIRTUAL); -} - -void qemu_start_warp_timer(void) -{ - int64_t clock; - int64_t deadline; - - if (!use_icount) { - return; - } - - /* Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers - * do not fire, so computing the deadline does not make sense. - */ - if (!runstate_is_running()) { - return; - } - - if (replay_mode != REPLAY_MODE_PLAY) { - if (!all_cpu_threads_idle()) { - return; - } - - if (qtest_enabled()) { - /* When testing, qtest commands advance icount. */ - return; - } - - replay_checkpoint(CHECKPOINT_CLOCK_WARP_START); - } else { - /* warp clock deterministically in record/replay mode */ - if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_START)) { - /* vCPU is sleeping and warp can't be started. - It is probably a race condition: notification sent - to vCPU was processed in advance and vCPU went to sleep. - Therefore we have to wake it up for doing someting. */ - if (replay_has_checkpoint()) { - qemu_clock_notify(QEMU_CLOCK_VIRTUAL); - } - return; - } - } - - /* We want to use the earliest deadline from ALL vm_clocks */ - clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); - deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, - ~QEMU_TIMER_ATTR_EXTERNAL); - if (deadline < 0) { - static bool notified; - if (!icount_sleep && !notified) { - warn_report("icount sleep disabled and no active timers"); - notified = true; - } - return; - } - - if (deadline > 0) { - /* - * Ensure QEMU_CLOCK_VIRTUAL proceeds even when the virtual CPU goes to - * sleep. Otherwise, the CPU might be waiting for a future timer - * interrupt to wake it up, but the interrupt never comes because - * the vCPU isn't running any insns and thus doesn't advance the - * QEMU_CLOCK_VIRTUAL. - */ - if (!icount_sleep) { - /* - * We never let VCPUs sleep in no sleep icount mode. - * If there is a pending QEMU_CLOCK_VIRTUAL timer we just advance - * to the next QEMU_CLOCK_VIRTUAL event and notify it. - * It is useful when we want a deterministic execution time, - * isolated from host latencies. - */ - seqlock_write_lock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - qatomic_set_i64(&timers_state.qemu_icount_bias, - timers_state.qemu_icount_bias + deadline); - seqlock_write_unlock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - qemu_clock_notify(QEMU_CLOCK_VIRTUAL); - } else { - /* - * We do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL after some - * "real" time, (related to the time left until the next event) has - * passed. The QEMU_CLOCK_VIRTUAL_RT clock will do this. - * This avoids that the warps are visible externally; for example, - * you will not be sending network packets continuously instead of - * every 100ms. - */ - seqlock_write_lock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - if (timers_state.vm_clock_warp_start == -1 - || timers_state.vm_clock_warp_start > clock) { - timers_state.vm_clock_warp_start = clock; - } - seqlock_write_unlock(&timers_state.vm_clock_seqlock, - &timers_state.vm_clock_lock); - timer_mod_anticipate(timers_state.icount_warp_timer, - clock + deadline); - } - } else if (deadline == 0) { - qemu_clock_notify(QEMU_CLOCK_VIRTUAL); - } -} - -static void qemu_account_warp_timer(void) -{ - if (!use_icount || !icount_sleep) { - return; - } - - /* Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers - * do not fire, so computing the deadline does not make sense. - */ - if (!runstate_is_running()) { - return; - } - - /* warp clock deterministically in record/replay mode */ - if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_ACCOUNT)) { - return; - } - - timer_del(timers_state.icount_warp_timer); - icount_warp_rt(); -} - -static bool icount_state_needed(void *opaque) -{ - return use_icount; -} - -static bool warp_timer_state_needed(void *opaque) -{ - TimersState *s = opaque; - return s->icount_warp_timer != NULL; -} - -static bool adjust_timers_state_needed(void *opaque) -{ - TimersState *s = opaque; - return s->icount_rt_timer != NULL; -} - -static bool shift_state_needed(void *opaque) -{ - return use_icount == 2; -} - -/* - * Subsection for warp timer migration is optional, because may not be created - */ -static const VMStateDescription icount_vmstate_warp_timer = { - .name = "timer/icount/warp_timer", - .version_id = 1, - .minimum_version_id = 1, - .needed = warp_timer_state_needed, - .fields = (VMStateField[]) { - VMSTATE_INT64(vm_clock_warp_start, TimersState), - VMSTATE_TIMER_PTR(icount_warp_timer, TimersState), - VMSTATE_END_OF_LIST() - } -}; - -static const VMStateDescription icount_vmstate_adjust_timers = { - .name = "timer/icount/timers", - .version_id = 1, - .minimum_version_id = 1, - .needed = adjust_timers_state_needed, - .fields = (VMStateField[]) { - VMSTATE_TIMER_PTR(icount_rt_timer, TimersState), - VMSTATE_TIMER_PTR(icount_vm_timer, TimersState), - VMSTATE_END_OF_LIST() - } -}; - -static const VMStateDescription icount_vmstate_shift = { - .name = "timer/icount/shift", - .version_id = 1, - .minimum_version_id = 1, - .needed = shift_state_needed, - .fields = (VMStateField[]) { - VMSTATE_INT16(icount_time_shift, TimersState), - VMSTATE_END_OF_LIST() - } -}; - -/* - * This is a subsection for icount migration. - */ -static const VMStateDescription icount_vmstate_timers = { - .name = "timer/icount", - .version_id = 1, - .minimum_version_id = 1, - .needed = icount_state_needed, - .fields = (VMStateField[]) { - VMSTATE_INT64(qemu_icount_bias, TimersState), - VMSTATE_INT64(qemu_icount, TimersState), - VMSTATE_END_OF_LIST() - }, - .subsections = (const VMStateDescription*[]) { - &icount_vmstate_warp_timer, - &icount_vmstate_adjust_timers, - &icount_vmstate_shift, - NULL - } -}; - -static const VMStateDescription vmstate_timers = { - .name = "timer", - .version_id = 2, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_INT64(cpu_ticks_offset, TimersState), - VMSTATE_UNUSED(8), - VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2), - VMSTATE_END_OF_LIST() - }, - .subsections = (const VMStateDescription*[]) { - &icount_vmstate_timers, - NULL - } -}; - -void cpu_ticks_init(void) -{ - seqlock_init(&timers_state.vm_clock_seqlock); - qemu_spin_init(&timers_state.vm_clock_lock); - vmstate_register(NULL, 0, &vmstate_timers, &timers_state); - cpu_throttle_init(); -} - -void configure_icount(QemuOpts *opts, Error **errp) -{ - const char *option = qemu_opt_get(opts, "shift"); - bool sleep = qemu_opt_get_bool(opts, "sleep", true); - bool align = qemu_opt_get_bool(opts, "align", false); - long time_shift = -1; - - if (!option) { - if (qemu_opt_get(opts, "align") != NULL) { - error_setg(errp, "Please specify shift option when using align"); - } - return; - } - - if (align && !sleep) { - error_setg(errp, "align=on and sleep=off are incompatible"); - return; - } - - if (strcmp(option, "auto") != 0) { - if (qemu_strtol(option, NULL, 0, &time_shift) < 0 - || time_shift < 0 || time_shift > MAX_ICOUNT_SHIFT) { - error_setg(errp, "icount: Invalid shift value"); - return; - } - } else if (icount_align_option) { - error_setg(errp, "shift=auto and align=on are incompatible"); - return; - } else if (!icount_sleep) { - error_setg(errp, "shift=auto and sleep=off are incompatible"); - return; - } - - icount_sleep = sleep; - if (icount_sleep) { - timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, - icount_timer_cb, NULL); - } - - icount_align_option = align; - - if (time_shift >= 0) { - timers_state.icount_time_shift = time_shift; - use_icount = 1; - return; - } - - use_icount = 2; - - /* 125MIPS seems a reasonable initial guess at the guest speed. - It will be corrected fairly quickly anyway. */ - timers_state.icount_time_shift = 3; - - /* Have both realtime and virtual time triggers for speed adjustment. - The realtime trigger catches emulated time passing too slowly, - the virtual time trigger catches emulated time passing too fast. - Realtime triggers occur even when idle, so use them less frequently - than VM triggers. */ - timers_state.vm_clock_warp_start = -1; - timers_state.icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT, - icount_adjust_rt, NULL); - timer_mod(timers_state.icount_rt_timer, - qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000); - timers_state.icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - icount_adjust_vm, NULL); - timer_mod(timers_state.icount_vm_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - NANOSECONDS_PER_SECOND / 10); -} - /***********************************************************/ /* TCG vCPU kick timer * @@ -854,35 +171,6 @@ static void qemu_cpu_kick_rr_cpus(void) }; } -static void do_nothing(CPUState *cpu, run_on_cpu_data unused) -{ -} - -void qemu_timer_notify_cb(void *opaque, QEMUClockType type) -{ - if (!use_icount || type != QEMU_CLOCK_VIRTUAL) { - qemu_notify_event(); - return; - } - - if (qemu_in_vcpu_thread()) { - /* A CPU is currently running; kick it back out to the - * tcg_cpu_exec() loop so it will recalculate its - * icount deadline immediately. - */ - qemu_cpu_kick(current_cpu); - } else if (first_cpu) { - /* qemu_cpu_kick is not enough to kick a halted CPU out of - * qemu_tcg_wait_io_event. async_run_on_cpu, instead, - * causes cpu_thread_is_idle to return false. This way, - * handle_icount_deadline can run. - * If we have no CPUs at all for some reason, we don't - * need to do anything. - */ - async_run_on_cpu(first_cpu, do_nothing, RUN_ON_CPU_NULL); - } -} - static void kick_tcg_thread(void *opaque) { timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick()); @@ -1288,7 +576,7 @@ static void notify_aio_contexts(void) static void handle_icount_deadline(void) { assert(qemu_in_vcpu_thread()); - if (use_icount) { + if (icount_enabled()) { int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, QEMU_TIMER_ATTR_ALL); @@ -1300,7 +588,7 @@ static void handle_icount_deadline(void) static void prepare_icount_for_run(CPUState *cpu) { - if (use_icount) { + if (icount_enabled()) { int insns_left; /* These should always be cleared by process_icount_data after @@ -1325,7 +613,7 @@ static void prepare_icount_for_run(CPUState *cpu) static void process_icount_data(CPUState *cpu) { - if (use_icount) { + if (icount_enabled()) { /* Account for executed instructions */ cpu_update_icount(cpu); @@ -1486,7 +774,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qatomic_mb_set(&cpu->exit_request, 0); } - if (use_icount && all_cpu_threads_idle()) { + if (icount_enabled() && all_cpu_threads_idle()) { /* * When all cpus are sleeping (e.g in WFI), to avoid a deadlock * in the main_loop, wake it up in order to start the warp timer. @@ -1639,7 +927,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) CPUState *cpu = arg; assert(tcg_enabled()); - g_assert(!use_icount); + g_assert(!icount_enabled()); rcu_register_thread(); tcg_register_thread(); @@ -2227,21 +1515,3 @@ void qmp_inject_nmi(Error **errp) nmi_monitor_handle(monitor_get_cpu_index(), errp); } -void dump_drift_info(void) -{ - if (!use_icount) { - return; - } - - qemu_printf("Host - Guest clock %"PRIi64" ms\n", - (cpu_get_clock() - cpu_get_icount())/SCALE_MS); - if (icount_align_option) { - qemu_printf("Max guest delay %"PRIi64" ms\n", - -max_delay / SCALE_MS); - qemu_printf("Max guest advance %"PRIi64" ms\n", - max_advance / SCALE_MS); - } else { - qemu_printf("Max guest delay NA\n"); - qemu_printf("Max guest advance NA\n"); - } -} diff --git a/softmmu/icount.c b/softmmu/icount.c new file mode 100644 index 0000000000..0b815fe88f --- /dev/null +++ b/softmmu/icount.c @@ -0,0 +1,492 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/cutils.h" +#include "migration/vmstate.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "exec/exec-all.h" +#include "sysemu/cpus.h" +#include "sysemu/qtest.h" +#include "qemu/main-loop.h" +#include "qemu/option.h" +#include "qemu/seqlock.h" +#include "sysemu/replay.h" +#include "sysemu/runstate.h" +#include "hw/core/cpu.h" +#include "sysemu/cpu-timers.h" +#include "sysemu/cpu-throttle.h" +#include "timers-state.h" + +/* + * ICOUNT: Instruction Counter + * + * this module is split off from cpu-timers because the icount part + * is TCG-specific, and does not need to be built for other accels. + */ +static bool icount_sleep = true; +/* Arbitrarily pick 1MIPS as the minimum allowable speed. */ +#define MAX_ICOUNT_SHIFT 10 + +/* + * 0 = Do not count executed instructions. + * 1 = Fixed conversion of insn to ns via "shift" option + * 2 = Runtime adaptive algorithm to compute shift + */ +int use_icount; + +static void icount_enable_precise(void) +{ + use_icount = 1; +} + +static void icount_enable_adaptive(void) +{ + use_icount = 2; +} + +/* + * The current number of executed instructions is based on what we + * originally budgeted minus the current state of the decrementing + * icount counters in extra/u16.low. + */ +static int64_t cpu_get_icount_executed(CPUState *cpu) +{ + return (cpu->icount_budget - + (cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra)); +} + +/* + * Update the global shared timer_state.qemu_icount to take into + * account executed instructions. This is done by the TCG vCPU + * thread so the main-loop can see time has moved forward. + */ +static void cpu_update_icount_locked(CPUState *cpu) +{ + int64_t executed = cpu_get_icount_executed(cpu); + cpu->icount_budget -= executed; + + qatomic_set_i64(&timers_state.qemu_icount, + timers_state.qemu_icount + executed); +} + +/* + * Update the global shared timer_state.qemu_icount to take into + * account executed instructions. This is done by the TCG vCPU + * thread so the main-loop can see time has moved forward. + */ +void cpu_update_icount(CPUState *cpu) +{ + seqlock_write_lock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + cpu_update_icount_locked(cpu); + seqlock_write_unlock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); +} + +static int64_t cpu_get_icount_raw_locked(void) +{ + CPUState *cpu = current_cpu; + + if (cpu && cpu->running) { + if (!cpu->can_do_io) { + error_report("Bad icount read"); + exit(1); + } + /* Take into account what has run */ + cpu_update_icount_locked(cpu); + } + /* The read is protected by the seqlock, but needs atomic64 to avoid UB */ + return qatomic_read_i64(&timers_state.qemu_icount); +} + +static int64_t cpu_get_icount_locked(void) +{ + int64_t icount = cpu_get_icount_raw_locked(); + return qatomic_read_i64(&timers_state.qemu_icount_bias) + + cpu_icount_to_ns(icount); +} + +int64_t cpu_get_icount_raw(void) +{ + int64_t icount; + unsigned start; + + do { + start = seqlock_read_begin(&timers_state.vm_clock_seqlock); + icount = cpu_get_icount_raw_locked(); + } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); + + return icount; +} + +/* Return the virtual CPU time, based on the instruction counter. */ +int64_t cpu_get_icount(void) +{ + int64_t icount; + unsigned start; + + do { + start = seqlock_read_begin(&timers_state.vm_clock_seqlock); + icount = cpu_get_icount_locked(); + } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); + + return icount; +} + +int64_t cpu_icount_to_ns(int64_t icount) +{ + return icount << qatomic_read(&timers_state.icount_time_shift); +} + +/* + * Correlation between real and virtual time is always going to be + * fairly approximate, so ignore small variation. + * When the guest is idle real and virtual time will be aligned in + * the IO wait loop. + */ +#define ICOUNT_WOBBLE (NANOSECONDS_PER_SECOND / 10) + +static void icount_adjust(void) +{ + int64_t cur_time; + int64_t cur_icount; + int64_t delta; + + /* Protected by TimersState mutex. */ + static int64_t last_delta; + + /* If the VM is not running, then do nothing. */ + if (!runstate_is_running()) { + return; + } + + seqlock_write_lock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + cur_time = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT, + cpu_get_clock_locked()); + cur_icount = cpu_get_icount_locked(); + + delta = cur_icount - cur_time; + /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ + if (delta > 0 + && last_delta + ICOUNT_WOBBLE < delta * 2 + && timers_state.icount_time_shift > 0) { + /* The guest is getting too far ahead. Slow time down. */ + qatomic_set(&timers_state.icount_time_shift, + timers_state.icount_time_shift - 1); + } + if (delta < 0 + && last_delta - ICOUNT_WOBBLE > delta * 2 + && timers_state.icount_time_shift < MAX_ICOUNT_SHIFT) { + /* The guest is getting too far behind. Speed time up. */ + qatomic_set(&timers_state.icount_time_shift, + timers_state.icount_time_shift + 1); + } + last_delta = delta; + qatomic_set_i64(&timers_state.qemu_icount_bias, + cur_icount - (timers_state.qemu_icount + << timers_state.icount_time_shift)); + seqlock_write_unlock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); +} + +static void icount_adjust_rt(void *opaque) +{ + timer_mod(timers_state.icount_rt_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000); + icount_adjust(); +} + +static void icount_adjust_vm(void *opaque) +{ + timer_mod(timers_state.icount_vm_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + NANOSECONDS_PER_SECOND / 10); + icount_adjust(); +} + +int64_t qemu_icount_round(int64_t count) +{ + int shift = qatomic_read(&timers_state.icount_time_shift); + return (count + (1 << shift) - 1) >> shift; +} + +static void icount_warp_rt(void) +{ + unsigned seq; + int64_t warp_start; + + /* + * The icount_warp_timer is rescheduled soon after vm_clock_warp_start + * changes from -1 to another value, so the race here is okay. + */ + do { + seq = seqlock_read_begin(&timers_state.vm_clock_seqlock); + warp_start = timers_state.vm_clock_warp_start; + } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq)); + + if (warp_start == -1) { + return; + } + + seqlock_write_lock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + if (runstate_is_running()) { + int64_t clock = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT, + cpu_get_clock_locked()); + int64_t warp_delta; + + warp_delta = clock - timers_state.vm_clock_warp_start; + if (icount_enabled() == 2) { + /* + * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too + * far ahead of real time. + */ + int64_t cur_icount = cpu_get_icount_locked(); + int64_t delta = clock - cur_icount; + warp_delta = MIN(warp_delta, delta); + } + qatomic_set_i64(&timers_state.qemu_icount_bias, + timers_state.qemu_icount_bias + warp_delta); + } + timers_state.vm_clock_warp_start = -1; + seqlock_write_unlock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + + if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) { + qemu_clock_notify(QEMU_CLOCK_VIRTUAL); + } +} + +static void icount_timer_cb(void *opaque) +{ + /* + * No need for a checkpoint because the timer already synchronizes + * with CHECKPOINT_CLOCK_VIRTUAL_RT. + */ + icount_warp_rt(); +} + +void qemu_start_warp_timer(void) +{ + int64_t clock; + int64_t deadline; + + assert(icount_enabled()); + + /* + * Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers + * do not fire, so computing the deadline does not make sense. + */ + if (!runstate_is_running()) { + return; + } + + if (replay_mode != REPLAY_MODE_PLAY) { + if (!all_cpu_threads_idle()) { + return; + } + + if (qtest_enabled()) { + /* When testing, qtest commands advance icount. */ + return; + } + + replay_checkpoint(CHECKPOINT_CLOCK_WARP_START); + } else { + /* warp clock deterministically in record/replay mode */ + if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_START)) { + /* + * vCPU is sleeping and warp can't be started. + * It is probably a race condition: notification sent + * to vCPU was processed in advance and vCPU went to sleep. + * Therefore we have to wake it up for doing someting. + */ + if (replay_has_checkpoint()) { + qemu_clock_notify(QEMU_CLOCK_VIRTUAL); + } + return; + } + } + + /* We want to use the earliest deadline from ALL vm_clocks */ + clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); + deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, + ~QEMU_TIMER_ATTR_EXTERNAL); + if (deadline < 0) { + static bool notified; + if (!icount_sleep && !notified) { + warn_report("icount sleep disabled and no active timers"); + notified = true; + } + return; + } + + if (deadline > 0) { + /* + * Ensure QEMU_CLOCK_VIRTUAL proceeds even when the virtual CPU goes to + * sleep. Otherwise, the CPU might be waiting for a future timer + * interrupt to wake it up, but the interrupt never comes because + * the vCPU isn't running any insns and thus doesn't advance the + * QEMU_CLOCK_VIRTUAL. + */ + if (!icount_sleep) { + /* + * We never let VCPUs sleep in no sleep icount mode. + * If there is a pending QEMU_CLOCK_VIRTUAL timer we just advance + * to the next QEMU_CLOCK_VIRTUAL event and notify it. + * It is useful when we want a deterministic execution time, + * isolated from host latencies. + */ + seqlock_write_lock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + qatomic_set_i64(&timers_state.qemu_icount_bias, + timers_state.qemu_icount_bias + deadline); + seqlock_write_unlock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + qemu_clock_notify(QEMU_CLOCK_VIRTUAL); + } else { + /* + * We do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL after some + * "real" time, (related to the time left until the next event) has + * passed. The QEMU_CLOCK_VIRTUAL_RT clock will do this. + * This avoids that the warps are visible externally; for example, + * you will not be sending network packets continuously instead of + * every 100ms. + */ + seqlock_write_lock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + if (timers_state.vm_clock_warp_start == -1 + || timers_state.vm_clock_warp_start > clock) { + timers_state.vm_clock_warp_start = clock; + } + seqlock_write_unlock(&timers_state.vm_clock_seqlock, + &timers_state.vm_clock_lock); + timer_mod_anticipate(timers_state.icount_warp_timer, + clock + deadline); + } + } else if (deadline == 0) { + qemu_clock_notify(QEMU_CLOCK_VIRTUAL); + } +} + +void qemu_account_warp_timer(void) +{ + if (!icount_enabled() || !icount_sleep) { + return; + } + + /* + * Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers + * do not fire, so computing the deadline does not make sense. + */ + if (!runstate_is_running()) { + return; + } + + /* warp clock deterministically in record/replay mode */ + if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_ACCOUNT)) { + return; + } + + timer_del(timers_state.icount_warp_timer); + icount_warp_rt(); +} + +void configure_icount(QemuOpts *opts, Error **errp) +{ + const char *option = qemu_opt_get(opts, "shift"); + bool sleep = qemu_opt_get_bool(opts, "sleep", true); + bool align = qemu_opt_get_bool(opts, "align", false); + long time_shift = -1; + + if (!option) { + if (qemu_opt_get(opts, "align") != NULL) { + error_setg(errp, "Please specify shift option when using align"); + } + return; + } + + if (align && !sleep) { + error_setg(errp, "align=on and sleep=off are incompatible"); + return; + } + + if (strcmp(option, "auto") != 0) { + if (qemu_strtol(option, NULL, 0, &time_shift) < 0 + || time_shift < 0 || time_shift > MAX_ICOUNT_SHIFT) { + error_setg(errp, "icount: Invalid shift value"); + return; + } + } else if (icount_align_option) { + error_setg(errp, "shift=auto and align=on are incompatible"); + return; + } else if (!icount_sleep) { + error_setg(errp, "shift=auto and sleep=off are incompatible"); + return; + } + + icount_sleep = sleep; + if (icount_sleep) { + timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, + icount_timer_cb, NULL); + } + + icount_align_option = align; + + if (time_shift >= 0) { + timers_state.icount_time_shift = time_shift; + icount_enable_precise(); + return; + } + + icount_enable_adaptive(); + + /* + * 125MIPS seems a reasonable initial guess at the guest speed. + * It will be corrected fairly quickly anyway. + */ + timers_state.icount_time_shift = 3; + + /* + * Have both realtime and virtual time triggers for speed adjustment. + * The realtime trigger catches emulated time passing too slowly, + * the virtual time trigger catches emulated time passing too fast. + * Realtime triggers occur even when idle, so use them less frequently + * than VM triggers. + */ + timers_state.vm_clock_warp_start = -1; + timers_state.icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT, + icount_adjust_rt, NULL); + timer_mod(timers_state.icount_rt_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000); + timers_state.icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + icount_adjust_vm, NULL); + timer_mod(timers_state.icount_vm_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + NANOSECONDS_PER_SECOND / 10); +} diff --git a/softmmu/meson.build b/softmmu/meson.build index 95d38df259..36c96e7b15 100644 --- a/softmmu/meson.build +++ b/softmmu/meson.build @@ -1,4 +1,4 @@ -specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( +specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files( 'arch_init.c', 'balloon.c', 'cpus.c', @@ -7,4 +7,10 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( 'memory.c', 'memory_mapping.c', 'qtest.c', - 'vl.c')) + 'vl.c', + 'cpu-timers.c', +)]) + +specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: [files( + 'icount.c' +)]) diff --git a/softmmu/qtest.c b/softmmu/qtest.c index 4e439caec7..0d43cf8883 100644 --- a/softmmu/qtest.c +++ b/softmmu/qtest.c @@ -21,7 +21,7 @@ #include "exec/memory.h" #include "hw/irq.h" #include "sysemu/accel.h" -#include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "qemu/config-file.h" #include "qemu/option.h" #include "qemu/error-report.h" @@ -273,6 +273,38 @@ static void qtest_irq_handler(void *opaque, int n, int level) } } +static int64_t qtest_clock_counter; + +int64_t qtest_get_virtual_clock(void) +{ + return qatomic_read_i64(&qtest_clock_counter); +} + +static void qtest_set_virtual_clock(int64_t count) +{ + qatomic_set_i64(&qtest_clock_counter, count); +} + +static void qtest_clock_warp(int64_t dest) +{ + int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + AioContext *aio_context; + assert(qtest_enabled()); + aio_context = qemu_get_aio_context(); + while (clock < dest) { + int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, + QEMU_TIMER_ATTR_ALL); + int64_t warp = qemu_soonest_timeout(dest - clock, deadline); + + qtest_set_virtual_clock(qtest_get_virtual_clock() + warp); + + qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL); + timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]); + clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + } + qemu_clock_notify(QEMU_CLOCK_VIRTUAL); +} + static void qtest_process_command(CharBackend *chr, gchar **words) { const gchar *command; diff --git a/softmmu/timers-state.h b/softmmu/timers-state.h new file mode 100644 index 0000000000..db4e60f18f --- /dev/null +++ b/softmmu/timers-state.h @@ -0,0 +1,69 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef TIMERS_STATE_H +#define TIMERS_STATE_H + +/* timers state, for sharing between icount and cpu-timers */ + +typedef struct TimersState { + /* Protected by BQL. */ + int64_t cpu_ticks_prev; + int64_t cpu_ticks_offset; + + /* + * Protect fields that can be respectively read outside the + * BQL, and written from multiple threads. + */ + QemuSeqLock vm_clock_seqlock; + QemuSpin vm_clock_lock; + + int16_t cpu_ticks_enabled; + + /* Conversion factor from emulated instructions to virtual clock ticks. */ + int16_t icount_time_shift; + + /* Compensate for varying guest execution speed. */ + int64_t qemu_icount_bias; + + int64_t vm_clock_warp_start; + int64_t cpu_clock_offset; + + /* Only written by TCG thread */ + int64_t qemu_icount; + + /* for adjusting icount */ + QEMUTimer *icount_rt_timer; + QEMUTimer *icount_vm_timer; + QEMUTimer *icount_warp_timer; +} TimersState; + +extern TimersState timers_state; + +/* + * icount needs this internal from cpu-timers when adjusting the icount shift. + */ +int64_t cpu_get_clock_locked(void); + +#endif /* TIMERS_STATE_H */ diff --git a/softmmu/vl.c b/softmmu/vl.c index 22bc570df4..6a1ee531db 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -74,6 +74,7 @@ #include "hw/audio/soundhw.h" #include "audio/audio.h" #include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "migration/colo.h" #include "migration/postcopy-ram.h" #include "sysemu/kvm.h" @@ -2804,7 +2805,7 @@ static void configure_accelerators(const char *progname) error_report("falling back to %s", ac->name); } - if (use_icount && !(tcg_enabled() || qtest_enabled())) { + if (icount_enabled() && !tcg_enabled()) { error_report("-icount is not allowed with hardware virtualization"); exit(1); } @@ -4254,7 +4255,8 @@ void qemu_init(int argc, char **argv, char **envp) semihosting_arg_fallback(kernel_filename, kernel_cmdline); } - cpu_ticks_init(); + /* initialize cpu timers and VCPU throttle modules */ + cpu_timers_init(); if (default_net) { QemuOptsList *net = qemu_find_opts("net"); diff --git a/stubs/clock-warp.c b/stubs/clock-warp.c deleted file mode 100644 index b53e5dd94c..0000000000 --- a/stubs/clock-warp.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "qemu/osdep.h" -#include "qemu/timer.h" - -void qemu_start_warp_timer(void) -{ -} - diff --git a/stubs/cpu-get-clock.c b/stubs/cpu-get-clock.c index 5a92810e87..9e92404816 100644 --- a/stubs/cpu-get-clock.c +++ b/stubs/cpu-get-clock.c @@ -1,5 +1,6 @@ #include "qemu/osdep.h" -#include "qemu/timer.h" +#include "sysemu/cpu-timers.h" +#include "qemu/main-loop.h" int64_t cpu_get_clock(void) { diff --git a/stubs/cpu-get-icount.c b/stubs/cpu-get-icount.c deleted file mode 100644 index 4001613240..0000000000 --- a/stubs/cpu-get-icount.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "qemu/osdep.h" -#include "qemu/timer.h" -#include "sysemu/cpus.h" -#include "qemu/main-loop.h" - -int use_icount; - -int64_t cpu_get_icount(void) -{ - abort(); -} - -int64_t cpu_get_icount_raw(void) -{ - abort(); -} diff --git a/stubs/icount.c b/stubs/icount.c new file mode 100644 index 0000000000..61e28cbaf9 --- /dev/null +++ b/stubs/icount.c @@ -0,0 +1,45 @@ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "sysemu/cpu-timers.h" + +/* icount - Instruction Counter API */ + +int use_icount; + +void cpu_update_icount(CPUState *cpu) +{ + abort(); +} +void configure_icount(QemuOpts *opts, Error **errp) +{ + /* signal error */ + error_setg(errp, "cannot configure icount, TCG support not available"); +} +int64_t cpu_get_icount_raw(void) +{ + abort(); + return 0; +} +int64_t cpu_get_icount(void) +{ + abort(); + return 0; +} +int64_t cpu_icount_to_ns(int64_t icount) +{ + abort(); + return 0; +} +int64_t qemu_icount_round(int64_t count) +{ + abort(); + return 0; +} +void qemu_start_warp_timer(void) +{ + abort(); +} +void qemu_account_warp_timer(void) +{ + abort(); +} diff --git a/stubs/meson.build b/stubs/meson.build index 5730f1d967..cbd955a7cd 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -3,10 +3,10 @@ stub_ss.add(files('bdrv-next-monitor-owned.c')) stub_ss.add(files('blk-commit-all.c')) stub_ss.add(files('blockdev-close-all-bdrv-states.c')) stub_ss.add(files('change-state-handler.c')) -stub_ss.add(files('clock-warp.c')) stub_ss.add(files('cmos.c')) stub_ss.add(files('cpu-get-clock.c')) -stub_ss.add(files('cpu-get-icount.c')) +stub_ss.add(files('qemu-timer-notify-cb.c')) +stub_ss.add(files('icount.c')) stub_ss.add(files('dump.c')) stub_ss.add(files('error-printf.c')) stub_ss.add(files('fdset.c')) diff --git a/stubs/qemu-timer-notify-cb.c b/stubs/qemu-timer-notify-cb.c index 054b408b1c..845e46f8e0 100644 --- a/stubs/qemu-timer-notify-cb.c +++ b/stubs/qemu-timer-notify-cb.c @@ -1,5 +1,5 @@ #include "qemu/osdep.h" -#include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "qemu/main-loop.h" void qemu_timer_notify_cb(void *opaque, QEMUClockType type) diff --git a/stubs/qtest.c b/stubs/qtest.c index 891eb954fb..4666a49d7d 100644 --- a/stubs/qtest.c +++ b/stubs/qtest.c @@ -18,3 +18,8 @@ bool qtest_driver(void) { return false; } + +int64_t qtest_get_virtual_clock(void) +{ + return 0; +} diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 8870284f57..36be602179 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "disas/disas.h" #include "qemu/host-utils.h" #include "exec/exec-all.h" @@ -1329,7 +1330,7 @@ static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno) case 249: /* VMTIME */ helper = gen_helper_get_vmtime; do_helper: - if (use_icount) { + if (icount_enabled()) { gen_io_start(); helper(va); return DISAS_PC_STALE; diff --git a/target/arm/helper.c b/target/arm/helper.c index b394db394a..b0bc4aa534 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -24,6 +24,7 @@ #include "hw/irq.h" #include "hw/semihosting/semihost.h" #include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "sysemu/kvm.h" #include "sysemu/tcg.h" #include "qemu/range.h" @@ -1206,7 +1207,7 @@ static int64_t cycles_ns_per(uint64_t cycles) static bool instructions_supported(CPUARMState *env) { - return use_icount == 1 /* Precise instruction counting */; + return icount_enabled() == 1; /* Precise instruction counting */ } static uint64_t instructions_get_count(CPUARMState *env) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 26ae347b4a..e51ed7b9ca 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -299,7 +299,7 @@ static int write_vstart(CPURISCVState *env, int csrno, target_ulong val) static int read_instret(CPURISCVState *env, int csrno, target_ulong *val) { #if !defined(CONFIG_USER_ONLY) - if (use_icount) { + if (icount_enabled()) { *val = cpu_get_icount(); } else { *val = cpu_get_host_ticks(); @@ -314,7 +314,7 @@ static int read_instret(CPURISCVState *env, int csrno, target_ulong *val) static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val) { #if !defined(CONFIG_USER_ONLY) - if (use_icount) { + if (icount_enabled()) { *val = cpu_get_icount() >> 32; } else { *val = cpu_get_host_ticks() >> 32; diff --git a/tests/ptimer-test-stubs.c b/tests/ptimer-test-stubs.c index ed393d9082..e935a1395e 100644 --- a/tests/ptimer-test-stubs.c +++ b/tests/ptimer-test-stubs.c @@ -12,6 +12,7 @@ #include "qemu/main-loop.h" #include "sysemu/replay.h" #include "migration/vmstate.h" +#include "sysemu/cpu-timers.h" #include "ptimer-test.h" @@ -30,8 +31,8 @@ QEMUTimerListGroup main_loop_tlg; int64_t ptimer_test_time_ns; -/* Do not artificially limit period - see hw/core/ptimer.c. */ -int use_icount = 1; +/* under qtest_enabled(), will not artificially limit period - see hw/core/ptimer.c. */ +int use_icount; bool qtest_allowed; void timer_init_full(QEMUTimer *ts, diff --git a/tests/test-timed-average.c b/tests/test-timed-average.c index e2bcf5fe13..82c92500df 100644 --- a/tests/test-timed-average.c +++ b/tests/test-timed-average.c @@ -11,7 +11,7 @@ */ #include "qemu/osdep.h" - +#include "sysemu/cpu-timers.h" #include "qemu/timed-average.h" /* This is the clock for QEMU_CLOCK_VIRTUAL */ diff --git a/util/main-loop.c b/util/main-loop.c index 217c8d6056..0c5fe0107e 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -27,7 +27,7 @@ #include "qemu/cutils.h" #include "qemu/timer.h" #include "sysemu/qtest.h" -#include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" #include "sysemu/replay.h" #include "qemu/main-loop.h" #include "block/aio.h" @@ -521,9 +521,13 @@ void main_loop_wait(int nonblocking) mlpoll.state = ret < 0 ? MAIN_LOOP_POLL_ERR : MAIN_LOOP_POLL_OK; notifier_list_notify(&main_loop_poll_notifiers, &mlpoll); - /* CPU thread can infinitely wait for event after - missing the warp */ - qemu_start_warp_timer(); + if (icount_enabled()) { + /* + * CPU thread can infinitely wait for event after + * missing the warp + */ + qemu_start_warp_timer(); + } qemu_clock_run_all_timers(); } diff --git a/util/qemu-timer.c b/util/qemu-timer.c index ca677836cb..0674046b09 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -26,8 +26,10 @@ #include "qemu/main-loop.h" #include "qemu/timer.h" #include "qemu/lockable.h" +#include "sysemu/cpu-timers.h" #include "sysemu/replay.h" #include "sysemu/cpus.h" +#include "sysemu/qtest.h" #ifdef CONFIG_POSIX #include @@ -134,7 +136,7 @@ static void qemu_clock_init(QEMUClockType type, QEMUTimerListNotifyCB *notify_cb bool qemu_clock_use_for_deadline(QEMUClockType type) { - return !(use_icount && (type == QEMU_CLOCK_VIRTUAL)); + return !(icount_enabled() && (type == QEMU_CLOCK_VIRTUAL)); } void qemu_clock_notify(QEMUClockType type) @@ -416,7 +418,7 @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list, static void timerlist_rearm(QEMUTimerList *timer_list) { /* Interrupt execution to force deadline recalculation. */ - if (timer_list->clock->type == QEMU_CLOCK_VIRTUAL) { + if (icount_enabled() && timer_list->clock->type == QEMU_CLOCK_VIRTUAL) { qemu_start_warp_timer(); } timerlist_notify(timer_list); @@ -633,8 +635,10 @@ int64_t qemu_clock_get_ns(QEMUClockType type) return get_clock(); default: case QEMU_CLOCK_VIRTUAL: - if (use_icount) { + if (icount_enabled()) { return cpu_get_icount(); + } else if (qtest_enabled()) { /* for qtest_clock_warp */ + return qtest_get_virtual_clock(); } else { return cpu_get_clock(); } From patchwork Tue Oct 6 07:29:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377239 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=KTPkd86p; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Mt0MK9z9sS8 for ; Tue, 6 Oct 2020 18:33:30 +1100 (AEDT) Received: from localhost ([::1]:43190 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhTT-0005qZ-Vo for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:33:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39442) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ0-0002HY-AF for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:52 -0400 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]:36875) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhPy-0001My-3U for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:52 -0400 Received: by mail-wr1-x434.google.com with SMTP id h7so8606507wre.4 for ; Tue, 06 Oct 2020 00:29:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=idFqZXx36LnOimhunbyC+weOV1rVwXuc0b22FJ7H8UY=; b=KTPkd86pruptfR1CUIdVJWEp20YqJNAJOLwaMC3EsUHO4QTFGLjtO6jyvG9paHy3A8 GXeFnmvSvgdt6mOhN4cR3PjqX+iW0in3y3J+cy//NUaRN4LzcwxX7p50SFFeh5a0LCoG LAWS5ixlLKWJiiCEQG1vt7zbJsdTdDicZ3SbuRYlSYLUSQRowpt/YAYEZEbjtZdPLTHb hcR950CU8qmATaD/BCUcti1DVh11Lk34IeDTP3FDA8k+9f0+xZmqf688HPb22tpprgdv r0X7l4IKcLQmhKbRkc0cBP9AY0VNFj9+9azZkdW8GkYZfHF52cjrkr5I8O10qrtuHjPz VT8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=idFqZXx36LnOimhunbyC+weOV1rVwXuc0b22FJ7H8UY=; b=kdmCDgAVmYmAoxYt9iUxQOjEIq/U4K03REhChHU5TLBPGv+tXMVlx00g43fFC/O+U4 bmwDK9mfAgAjZyGdusktT3Rfnhn8L1YAsBblBt48znYux0jTJPPo9bjW0dNMiOiP8Cz3 t2ROUsdT1LkvymvDvp4++9vtuZc95sinxo8TdJXWnYV2RILEolu0KRGfQL3QmOXMz1Jy bZJXbSkrBb/GNGkJsUc77I3yPvA3KTB7rvi8WJVQExqMXeW6FpO7UY6MHUZALcnStOxy 9YoC3GCFX6LRAjfD243j3Qvq6mpoUqo+XVc/Pizk5w2v6jItO5o3vSWgT97fYi/O3xli kKOw== X-Gm-Message-State: AOAM533JdLqaddGx5MAvV/eyqNaGD/MujiJ3OlJpEcVgIS1cXSVB9CEr LVOWg9QD3yNiIZsYKY1vzHeGrQ7MKiM= X-Google-Smtp-Source: ABdhPJwLXVQzHZ2gsMcmPfkvDTeQxwap2DpwsWLXvmbz59XpZXamShQLyRAHOjxMgxBkJMj6cchQ7w== X-Received: by 2002:a5d:4c88:: with SMTP id z8mr3275346wrs.218.1601969387867; Tue, 06 Oct 2020 00:29:47 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:47 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 02/37] icount: rename functions to be consistent with the module name Date: Tue, 6 Oct 2020 09:29:12 +0200 Message-Id: <20201006072947.487729-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::434; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x434.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Reviewed-by: Alex Bennée Signed-off-by: Paolo Bonzini --- accel/tcg/cpu-exec.c | 6 +++--- docs/replay.txt | 6 +++--- include/sysemu/cpu-timers.h | 16 +++++++------- include/sysemu/replay.h | 4 ++-- replay/replay.c | 2 +- softmmu/cpu-timers.c | 6 +++--- softmmu/cpus.c | 6 +++--- softmmu/icount.c | 42 ++++++++++++++++++------------------- softmmu/vl.c | 2 +- stubs/icount.c | 16 +++++++------- target/arm/helper.c | 4 ++-- target/riscv/csr.c | 4 ++-- util/main-loop.c | 2 +- util/qemu-timer.c | 4 ++-- 14 files changed, 60 insertions(+), 60 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 35bfe2ca92..0dbe67acf5 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -71,7 +71,7 @@ static void align_clocks(SyncClocks *sc, CPUState *cpu) } cpu_icount = cpu->icount_extra + cpu_neg(cpu)->icount_decr.u16.low; - sc->diff_clk += cpu_icount_to_ns(sc->last_cpu_icount - cpu_icount); + sc->diff_clk += icount_to_ns(sc->last_cpu_icount - cpu_icount); sc->last_cpu_icount = cpu_icount; if (sc->diff_clk > VM_CLOCK_ADVANCE) { @@ -665,7 +665,7 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb, assert(icount_enabled()); #ifndef CONFIG_USER_ONLY /* Ensure global icount has gone forward */ - cpu_update_icount(cpu); + icount_update(cpu); /* Refill decrementer and continue execution. */ insns_left = MIN(0xffff, cpu->icount_budget); cpu_neg(cpu)->icount_decr.u16.low = insns_left; @@ -775,7 +775,7 @@ void dump_drift_info(void) } qemu_printf("Host - Guest clock %"PRIi64" ms\n", - (cpu_get_clock() - cpu_get_icount()) / SCALE_MS); + (cpu_get_clock() - icount_get()) / SCALE_MS); if (icount_align_option) { qemu_printf("Max guest delay %"PRIi64" ms\n", -max_delay / SCALE_MS); diff --git a/docs/replay.txt b/docs/replay.txt index 70c27edb36..8952e6d852 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -184,11 +184,11 @@ is then incremented (which is called "warping" the virtual clock) as soon as the timer fires or the CPUs need to go out of the idle state. Two functions are used for this purpose; because these actions change virtual machine state and must be deterministic, each of them creates a -checkpoint. qemu_start_warp_timer checks if the CPUs are idle and if so -starts accounting real time to virtual clock. qemu_account_warp_timer +checkpoint. icount_start_warp_timer checks if the CPUs are idle and if so +starts accounting real time to virtual clock. icount_account_warp_timer is called when the CPUs get an interrupt or when the warp timer fires, and it warps the virtual clock by the amount of real time that has passed -since qemu_start_warp_timer. +since icount_start_warp_timer. Bottom halves ------------- diff --git a/include/sysemu/cpu-timers.h b/include/sysemu/cpu-timers.h index 4b621fea51..7726e005cd 100644 --- a/include/sysemu/cpu-timers.h +++ b/include/sysemu/cpu-timers.h @@ -35,30 +35,30 @@ extern int use_icount; * Update the icount with the executed instructions. Called by * cpus-tcg vCPU thread so the main-loop can see time has moved forward. */ -void cpu_update_icount(CPUState *cpu); +void icount_update(CPUState *cpu); /* get raw icount value */ -int64_t cpu_get_icount_raw(void); +int64_t icount_get_raw(void); /* return the virtual CPU time in ns, based on the instruction counter. */ -int64_t cpu_get_icount(void); +int64_t icount_get(void); /* * convert an instruction counter value to ns, based on the icount shift. * This shift is set as a fixed value with the icount "shift" option * (precise mode), or it is constantly approximated and corrected at * runtime in adaptive mode. */ -int64_t cpu_icount_to_ns(int64_t icount); +int64_t icount_to_ns(int64_t icount); /* configure the icount options, including "shift" */ -void configure_icount(QemuOpts *opts, Error **errp); +void icount_configure(QemuOpts *opts, Error **errp); /* used by tcg vcpu thread to calc icount budget */ -int64_t qemu_icount_round(int64_t count); +int64_t icount_round(int64_t count); /* if the CPUs are idle, start accounting real time to virtual clock. */ -void qemu_start_warp_timer(void); -void qemu_account_warp_timer(void); +void icount_start_warp_timer(void); +void icount_account_warp_timer(void); /* * CPU Ticks and Clock diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 5471bb514d..a140d69a73 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -109,12 +109,12 @@ int64_t replay_read_clock(ReplayClockKind kind); #define REPLAY_CLOCK(clock, value) \ (replay_mode == REPLAY_MODE_PLAY ? replay_read_clock((clock)) \ : replay_mode == REPLAY_MODE_RECORD \ - ? replay_save_clock((clock), (value), cpu_get_icount_raw()) \ + ? replay_save_clock((clock), (value), icount_get_raw()) \ : (value)) #define REPLAY_CLOCK_LOCKED(clock, value) \ (replay_mode == REPLAY_MODE_PLAY ? replay_read_clock((clock)) \ : replay_mode == REPLAY_MODE_RECORD \ - ? replay_save_clock((clock), (value), cpu_get_icount_raw_locked()) \ + ? replay_save_clock((clock), (value), icount_get_raw_locked()) \ : (value)) /* Processing data from random generators */ diff --git a/replay/replay.c b/replay/replay.c index 7e4a1ba78e..4c1457b07e 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -64,7 +64,7 @@ bool replay_next_event_is(int event) uint64_t replay_get_current_icount(void) { - return cpu_get_icount_raw(); + return icount_get_raw(); } int replay_get_instructions(void) diff --git a/softmmu/cpu-timers.c b/softmmu/cpu-timers.c index 6c6c56090f..7efec17fea 100644 --- a/softmmu/cpu-timers.c +++ b/softmmu/cpu-timers.c @@ -70,7 +70,7 @@ int64_t cpu_get_ticks(void) int64_t ticks; if (icount_enabled()) { - return cpu_get_icount(); + return icount_get(); } qemu_spin_lock(&timers_state.vm_clock_lock); @@ -160,7 +160,7 @@ static bool adjust_timers_state_needed(void *opaque) return s->icount_rt_timer != NULL; } -static bool shift_state_needed(void *opaque) +static bool icount_shift_state_needed(void *opaque) { return icount_enabled() == 2; } @@ -196,7 +196,7 @@ static const VMStateDescription icount_vmstate_shift = { .name = "timer/icount/shift", .version_id = 1, .minimum_version_id = 1, - .needed = shift_state_needed, + .needed = icount_shift_state_needed, .fields = (VMStateField[]) { VMSTATE_INT16(icount_time_shift, TimersState), VMSTATE_END_OF_LIST() diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 4f2777a738..eeea495763 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -560,7 +560,7 @@ static int64_t tcg_get_icount_limit(void) deadline = INT32_MAX; } - return qemu_icount_round(deadline); + return icount_round(deadline); } else { return replay_get_instructions(); } @@ -615,7 +615,7 @@ static void process_icount_data(CPUState *cpu) { if (icount_enabled()) { /* Account for executed instructions */ - cpu_update_icount(cpu); + icount_update(cpu); /* Reset the counters */ cpu_neg(cpu)->icount_decr.u16.low = 0; @@ -716,7 +716,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) replay_mutex_lock(); qemu_mutex_lock_iothread(); /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ - qemu_account_warp_timer(); + icount_account_warp_timer(); /* Run the timers here. This is much more efficient than * waking up the I/O thread and waiting for completion. diff --git a/softmmu/icount.c b/softmmu/icount.c index 0b815fe88f..020a201a01 100644 --- a/softmmu/icount.c +++ b/softmmu/icount.c @@ -73,7 +73,7 @@ static void icount_enable_adaptive(void) * originally budgeted minus the current state of the decrementing * icount counters in extra/u16.low. */ -static int64_t cpu_get_icount_executed(CPUState *cpu) +static int64_t icount_get_executed(CPUState *cpu) { return (cpu->icount_budget - (cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra)); @@ -84,9 +84,9 @@ static int64_t cpu_get_icount_executed(CPUState *cpu) * account executed instructions. This is done by the TCG vCPU * thread so the main-loop can see time has moved forward. */ -static void cpu_update_icount_locked(CPUState *cpu) +static void icount_update_locked(CPUState *cpu) { - int64_t executed = cpu_get_icount_executed(cpu); + int64_t executed = icount_get_executed(cpu); cpu->icount_budget -= executed; qatomic_set_i64(&timers_state.qemu_icount, @@ -98,16 +98,16 @@ static void cpu_update_icount_locked(CPUState *cpu) * account executed instructions. This is done by the TCG vCPU * thread so the main-loop can see time has moved forward. */ -void cpu_update_icount(CPUState *cpu) +void icount_update(CPUState *cpu) { seqlock_write_lock(&timers_state.vm_clock_seqlock, &timers_state.vm_clock_lock); - cpu_update_icount_locked(cpu); + icount_update_locked(cpu); seqlock_write_unlock(&timers_state.vm_clock_seqlock, &timers_state.vm_clock_lock); } -static int64_t cpu_get_icount_raw_locked(void) +static int64_t icount_get_raw_locked(void) { CPUState *cpu = current_cpu; @@ -117,47 +117,47 @@ static int64_t cpu_get_icount_raw_locked(void) exit(1); } /* Take into account what has run */ - cpu_update_icount_locked(cpu); + icount_update_locked(cpu); } /* The read is protected by the seqlock, but needs atomic64 to avoid UB */ return qatomic_read_i64(&timers_state.qemu_icount); } -static int64_t cpu_get_icount_locked(void) +static int64_t icount_get_locked(void) { - int64_t icount = cpu_get_icount_raw_locked(); + int64_t icount = icount_get_raw_locked(); return qatomic_read_i64(&timers_state.qemu_icount_bias) + - cpu_icount_to_ns(icount); + icount_to_ns(icount); } -int64_t cpu_get_icount_raw(void) +int64_t icount_get_raw(void) { int64_t icount; unsigned start; do { start = seqlock_read_begin(&timers_state.vm_clock_seqlock); - icount = cpu_get_icount_raw_locked(); + icount = icount_get_raw_locked(); } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); return icount; } /* Return the virtual CPU time, based on the instruction counter. */ -int64_t cpu_get_icount(void) +int64_t icount_get(void) { int64_t icount; unsigned start; do { start = seqlock_read_begin(&timers_state.vm_clock_seqlock); - icount = cpu_get_icount_locked(); + icount = icount_get_locked(); } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); return icount; } -int64_t cpu_icount_to_ns(int64_t icount) +int64_t icount_to_ns(int64_t icount) { return icount << qatomic_read(&timers_state.icount_time_shift); } @@ -188,7 +188,7 @@ static void icount_adjust(void) &timers_state.vm_clock_lock); cur_time = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT, cpu_get_clock_locked()); - cur_icount = cpu_get_icount_locked(); + cur_icount = icount_get_locked(); delta = cur_icount - cur_time; /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ @@ -229,7 +229,7 @@ static void icount_adjust_vm(void *opaque) icount_adjust(); } -int64_t qemu_icount_round(int64_t count) +int64_t icount_round(int64_t count) { int shift = qatomic_read(&timers_state.icount_time_shift); return (count + (1 << shift) - 1) >> shift; @@ -266,7 +266,7 @@ static void icount_warp_rt(void) * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too * far ahead of real time. */ - int64_t cur_icount = cpu_get_icount_locked(); + int64_t cur_icount = icount_get_locked(); int64_t delta = clock - cur_icount; warp_delta = MIN(warp_delta, delta); } @@ -291,7 +291,7 @@ static void icount_timer_cb(void *opaque) icount_warp_rt(); } -void qemu_start_warp_timer(void) +void icount_start_warp_timer(void) { int64_t clock; int64_t deadline; @@ -394,7 +394,7 @@ void qemu_start_warp_timer(void) } } -void qemu_account_warp_timer(void) +void icount_account_warp_timer(void) { if (!icount_enabled() || !icount_sleep) { return; @@ -417,7 +417,7 @@ void qemu_account_warp_timer(void) icount_warp_rt(); } -void configure_icount(QemuOpts *opts, Error **errp) +void icount_configure(QemuOpts *opts, Error **errp) { const char *option = qemu_opt_get(opts, "shift"); bool sleep = qemu_opt_get_bool(opts, "sleep", true); diff --git a/softmmu/vl.c b/softmmu/vl.c index 6a1ee531db..5a11a62f78 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -2695,7 +2695,7 @@ static void user_register_global_props(void) static int do_configure_icount(void *opaque, QemuOpts *opts, Error **errp) { - configure_icount(opts, errp); + icount_configure(opts, errp); return 0; } diff --git a/stubs/icount.c b/stubs/icount.c index 61e28cbaf9..f13c43568b 100644 --- a/stubs/icount.c +++ b/stubs/icount.c @@ -6,40 +6,40 @@ int use_icount; -void cpu_update_icount(CPUState *cpu) +void icount_update(CPUState *cpu) { abort(); } -void configure_icount(QemuOpts *opts, Error **errp) +void icount_configure(QemuOpts *opts, Error **errp) { /* signal error */ error_setg(errp, "cannot configure icount, TCG support not available"); } -int64_t cpu_get_icount_raw(void) +int64_t icount_get_raw(void) { abort(); return 0; } -int64_t cpu_get_icount(void) +int64_t icount_get(void) { abort(); return 0; } -int64_t cpu_icount_to_ns(int64_t icount) +int64_t icount_to_ns(int64_t icount) { abort(); return 0; } -int64_t qemu_icount_round(int64_t count) +int64_t icount_round(int64_t count) { abort(); return 0; } -void qemu_start_warp_timer(void) +void icount_start_warp_timer(void) { abort(); } -void qemu_account_warp_timer(void) +void icount_account_warp_timer(void) { abort(); } diff --git a/target/arm/helper.c b/target/arm/helper.c index b0bc4aa534..cd0779ff5f 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1212,12 +1212,12 @@ static bool instructions_supported(CPUARMState *env) static uint64_t instructions_get_count(CPUARMState *env) { - return (uint64_t)cpu_get_icount_raw(); + return (uint64_t)icount_get_raw(); } static int64_t instructions_ns_per(uint64_t icount) { - return cpu_icount_to_ns((int64_t)icount); + return icount_to_ns((int64_t)icount); } #endif diff --git a/target/riscv/csr.c b/target/riscv/csr.c index e51ed7b9ca..aaef6c6f20 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -300,7 +300,7 @@ static int read_instret(CPURISCVState *env, int csrno, target_ulong *val) { #if !defined(CONFIG_USER_ONLY) if (icount_enabled()) { - *val = cpu_get_icount(); + *val = icount_get(); } else { *val = cpu_get_host_ticks(); } @@ -315,7 +315,7 @@ static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val) { #if !defined(CONFIG_USER_ONLY) if (icount_enabled()) { - *val = cpu_get_icount() >> 32; + *val = icount_get() >> 32; } else { *val = cpu_get_host_ticks() >> 32; } diff --git a/util/main-loop.c b/util/main-loop.c index 0c5fe0107e..6470f8eae3 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -526,7 +526,7 @@ void main_loop_wait(int nonblocking) * CPU thread can infinitely wait for event after * missing the warp */ - qemu_start_warp_timer(); + icount_start_warp_timer(); } qemu_clock_run_all_timers(); } diff --git a/util/qemu-timer.c b/util/qemu-timer.c index 0674046b09..b69c6bb27b 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -419,7 +419,7 @@ static void timerlist_rearm(QEMUTimerList *timer_list) { /* Interrupt execution to force deadline recalculation. */ if (icount_enabled() && timer_list->clock->type == QEMU_CLOCK_VIRTUAL) { - qemu_start_warp_timer(); + icount_start_warp_timer(); } timerlist_notify(timer_list); } @@ -636,7 +636,7 @@ int64_t qemu_clock_get_ns(QEMUClockType type) default: case QEMU_CLOCK_VIRTUAL: if (icount_enabled()) { - return cpu_get_icount(); + return icount_get(); } else if (qtest_enabled()) { /* for qtest_clock_warp */ return qtest_get_virtual_clock(); } else { From patchwork Tue Oct 6 07:29:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377235 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=PVJ1GSim; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58JN2X9Qz9sS8 for ; Tue, 6 Oct 2020 18:30:28 +1100 (AEDT) Received: from localhost ([::1]:35416 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhQY-0002KU-8S for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:30:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39462) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ1-0002Iu-Dz for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:53 -0400 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]:41037) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhPy-0001N4-Gd for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:53 -0400 Received: by mail-wr1-x432.google.com with SMTP id w5so12224439wrp.8 for ; Tue, 06 Oct 2020 00:29:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ihHp+CQmQtCbB/09x1F/Jt79dOEbFF1HYizOEDP3qi0=; b=PVJ1GSimjTdv260auuK4tUIeaIRKlr75ciyt+CskCR+3PVlZgZyf1QVYX7QozgNdrr mLwMN3W1ZGFNIGjE7rQ+WLSYORWgNwYh1H7mO0CHxbpYbbfBrIjvEjXIi6/9p2r6ZtZd gnAyvHC9VuOyb9kHSbFo5nLz5DawxR/xsXJb+7IZkjOETVfVEb/9GS6UQX/qkr1Jfmhn 7YnGgNyAj0ecB++B3CeSMduzv+IjqAPPKIPPsW7KRjfDm/RisRsbjKI9sQcdzjWhQ3tv 2Aej0IO93Z5B9XuFzl4vsnzSFzkVhYg0AQHXC6FsdLHo9bWpk6SpkOhJ8begwTtI7E/6 RKuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=ihHp+CQmQtCbB/09x1F/Jt79dOEbFF1HYizOEDP3qi0=; b=GxJSp4zHX+lgctLUyJ+REgA005bmvZk7Yk5xLJqUEjViWvBclObSHlrJiqsbbFlz/P UCzT1CiM46VHJ8rLbm51N4Lv7FEo+IyWiO4JmDAzy9fJxXlFxlUSz0LlhgoOlBYO59RC yblvjuvmzxgiLWiDB0P+Knqib3uUihOUpmI4BM/59MdYWYfB3S9yABiw5/1iz+/fhp49 7/szwol3olmMYlahgJralYJmfP/NzYZpyZ0MdVymTzFjABc6FtNYIiLTpCo0l68Q3DAc r2eqxgn2ZdygIUA3374PcJLoeQqGKCESdd1fYj0PP4Lf4BwgZmcM8fw6BgQdNTs46vIn zAxQ== X-Gm-Message-State: AOAM532Iddmwg+hX3Be9/mhUNIksjdDSVNqJxdupWQjW5T7svpBaF+Dx 9nyC0CQmz9ZO65qU8KYbBx6JqsjOfVY= X-Google-Smtp-Source: ABdhPJwAMF+n0uW7djjs4W4QfB1lLn96kpkOaxj4YKnnXz8DNHl8e2RKf+vVlBSfc3tQ4T7FkTuOvQ== X-Received: by 2002:adf:90a2:: with SMTP id i31mr3605115wri.276.1601969388635; Tue, 06 Oct 2020 00:29:48 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:48 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 03/37] cpus: prepare new CpusAccel cpu accelerator interface Date: Tue, 6 Oct 2020 09:29:13 +0200 Message-Id: <20201006072947.487729-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x432.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana The new interface starts unused, will start being used by the next patches. It provides methods for each accelerator to start a vcpu, kick a vcpu, synchronize state, get cpu virtual clock and elapsed ticks. In qemu_wait_io_event, make it clear that APC is used only for HAX on Windows. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- hw/core/cpu.c | 1 + hw/i386/x86.c | 2 +- include/sysemu/cpu-timers.h | 9 +- include/sysemu/cpus.h | 36 ++++++ include/sysemu/hw_accel.h | 69 +----------- softmmu/cpu-timers.c | 9 +- softmmu/cpus.c | 195 ++++++++++++++++++++++++++------- stubs/cpu-synchronize-state.c | 9 ++ stubs/cpus-get-virtual-clock.c | 8 ++ stubs/meson.build | 2 + util/qemu-timer.c | 8 +- 11 files changed, 225 insertions(+), 123 deletions(-) create mode 100644 stubs/cpu-synchronize-state.c create mode 100644 stubs/cpus-get-virtual-clock.c diff --git a/hw/core/cpu.c b/hw/core/cpu.c index c55c09f734..d596182621 100644 --- a/hw/core/cpu.c +++ b/hw/core/cpu.c @@ -33,6 +33,7 @@ #include "hw/qdev-properties.h" #include "trace/trace-root.h" #include "qemu/plugin.h" +#include "sysemu/hw_accel.h" CPUInterruptHandler cpu_interrupt_handler; diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 953083e063..3137a20085 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -522,7 +522,7 @@ static long get_file_size(FILE *f) /* TSC handling */ uint64_t cpu_get_tsc(CPUX86State *env) { - return cpu_get_ticks(); + return cpus_get_elapsed_ticks(); } /* IRQ handling */ diff --git a/include/sysemu/cpu-timers.h b/include/sysemu/cpu-timers.h index 7726e005cd..ed6ee5c46c 100644 --- a/include/sysemu/cpu-timers.h +++ b/include/sysemu/cpu-timers.h @@ -70,9 +70,8 @@ void cpu_enable_ticks(void); void cpu_disable_ticks(void); /* - * return the time elapsed in VM between vm_start and vm_stop. Unless - * icount is active, cpu_get_ticks() uses units of the host CPU cycle - * counter. + * return the time elapsed in VM between vm_start and vm_stop. + * cpu_get_ticks() uses units of the host CPU cycle counter. */ int64_t cpu_get_ticks(void); @@ -84,4 +83,8 @@ int64_t cpu_get_clock(void); void qemu_timer_notify_cb(void *opaque, QEMUClockType type); +/* get the VIRTUAL clock and VM elapsed ticks via the cpus accel interface */ +int64_t cpus_get_virtual_clock(void); +int64_t cpus_get_elapsed_ticks(void); + #endif /* SYSEMU_CPU_TIMERS_H */ diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 149de000a0..26171697f5 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -4,7 +4,43 @@ #include "qemu/timer.h" /* cpus.c */ + +/* CPU execution threads */ + +typedef struct CpusAccel { + void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY */ + void (*kick_vcpu_thread)(CPUState *cpu); + + void (*synchronize_post_reset)(CPUState *cpu); + void (*synchronize_post_init)(CPUState *cpu); + void (*synchronize_state)(CPUState *cpu); + void (*synchronize_pre_loadvm)(CPUState *cpu); + + int64_t (*get_virtual_clock)(void); + int64_t (*get_elapsed_ticks)(void); +} CpusAccel; + +/* register accel-specific cpus interface implementation */ +void cpus_register_accel(const CpusAccel *i); + +/* interface available for cpus accelerator threads */ + +/* For temporary buffers for forming a name */ +#define VCPU_THREAD_NAME_SIZE 16 + +void cpus_kick_thread(CPUState *cpu); +bool cpu_work_list_empty(CPUState *cpu); +bool cpu_thread_is_idle(CPUState *cpu); bool all_cpu_threads_idle(void); +bool cpu_can_run(CPUState *cpu); +void qemu_wait_io_event_common(CPUState *cpu); +void qemu_wait_io_event(CPUState *cpu); +void cpu_thread_signal_created(CPUState *cpu); +void cpu_thread_signal_destroyed(CPUState *cpu); +void cpu_handle_guest_debug(CPUState *cpu); + +/* end interface for cpus accelerator threads */ + bool qemu_in_vcpu_thread(void); void qemu_init_cpu_loop(void); void resume_all_vcpus(void); diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h index e128f8b06b..ffed6192a3 100644 --- a/include/sysemu/hw_accel.h +++ b/include/sysemu/hw_accel.h @@ -1,5 +1,5 @@ /* - * QEMU Hardware accelertors support + * QEMU Hardware accelerators support * * Copyright 2016 Google, Inc. * @@ -17,68 +17,9 @@ #include "sysemu/hvf.h" #include "sysemu/whpx.h" -static inline void cpu_synchronize_state(CPUState *cpu) -{ - if (kvm_enabled()) { - kvm_cpu_synchronize_state(cpu); - } - if (hax_enabled()) { - hax_cpu_synchronize_state(cpu); - } - if (hvf_enabled()) { - hvf_cpu_synchronize_state(cpu); - } - if (whpx_enabled()) { - whpx_cpu_synchronize_state(cpu); - } -} - -static inline void cpu_synchronize_post_reset(CPUState *cpu) -{ - if (kvm_enabled()) { - kvm_cpu_synchronize_post_reset(cpu); - } - if (hax_enabled()) { - hax_cpu_synchronize_post_reset(cpu); - } - if (hvf_enabled()) { - hvf_cpu_synchronize_post_reset(cpu); - } - if (whpx_enabled()) { - whpx_cpu_synchronize_post_reset(cpu); - } -} - -static inline void cpu_synchronize_post_init(CPUState *cpu) -{ - if (kvm_enabled()) { - kvm_cpu_synchronize_post_init(cpu); - } - if (hax_enabled()) { - hax_cpu_synchronize_post_init(cpu); - } - if (hvf_enabled()) { - hvf_cpu_synchronize_post_init(cpu); - } - if (whpx_enabled()) { - whpx_cpu_synchronize_post_init(cpu); - } -} - -static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) -{ - if (kvm_enabled()) { - kvm_cpu_synchronize_pre_loadvm(cpu); - } - if (hax_enabled()) { - hax_cpu_synchronize_pre_loadvm(cpu); - } - if (hvf_enabled()) { - hvf_cpu_synchronize_pre_loadvm(cpu); - } - if (whpx_enabled()) { - whpx_cpu_synchronize_pre_loadvm(cpu); - } -} +void cpu_synchronize_state(CPUState *cpu); +void cpu_synchronize_post_reset(CPUState *cpu); +void cpu_synchronize_post_init(CPUState *cpu); +void cpu_synchronize_pre_loadvm(CPUState *cpu); #endif /* QEMU_HW_ACCEL_H */ diff --git a/softmmu/cpu-timers.c b/softmmu/cpu-timers.c index 7efec17fea..1eb7c675c1 100644 --- a/softmmu/cpu-timers.c +++ b/softmmu/cpu-timers.c @@ -61,18 +61,13 @@ static int64_t cpu_get_ticks_locked(void) } /* - * return the time elapsed in VM between vm_start and vm_stop. Unless - * icount is active, cpu_get_ticks() uses units of the host CPU cycle - * counter. + * return the time elapsed in VM between vm_start and vm_stop. + * cpu_get_ticks() uses units of the host CPU cycle counter. */ int64_t cpu_get_ticks(void) { int64_t ticks; - if (icount_enabled()) { - return icount_get(); - } - qemu_spin_lock(&timers_state.vm_clock_lock); ticks = cpu_get_ticks_locked(); qemu_spin_unlock(&timers_state.vm_clock_lock); diff --git a/softmmu/cpus.c b/softmmu/cpus.c index eeea495763..f932fc1f74 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -87,7 +87,7 @@ bool cpu_is_stopped(CPUState *cpu) return cpu->stopped || !runstate_is_running(); } -static inline bool cpu_work_list_empty(CPUState *cpu) +bool cpu_work_list_empty(CPUState *cpu) { bool ret; @@ -97,7 +97,7 @@ static inline bool cpu_work_list_empty(CPUState *cpu) return ret; } -static bool cpu_thread_is_idle(CPUState *cpu) +bool cpu_thread_is_idle(CPUState *cpu) { if (cpu->stop || !cpu_work_list_empty(cpu)) { return false; @@ -215,6 +215,11 @@ void hw_error(const char *fmt, ...) abort(); } +/* + * The chosen accelerator is supposed to register this. + */ +static const CpusAccel *cpus_accel; + void cpu_synchronize_all_states(void) { CPUState *cpu; @@ -251,6 +256,102 @@ void cpu_synchronize_all_pre_loadvm(void) } } +void cpu_synchronize_state(CPUState *cpu) +{ + if (cpus_accel && cpus_accel->synchronize_state) { + cpus_accel->synchronize_state(cpu); + } + if (kvm_enabled()) { + kvm_cpu_synchronize_state(cpu); + } + if (hax_enabled()) { + hax_cpu_synchronize_state(cpu); + } + if (whpx_enabled()) { + whpx_cpu_synchronize_state(cpu); + } +} + +void cpu_synchronize_post_reset(CPUState *cpu) +{ + if (cpus_accel && cpus_accel->synchronize_post_reset) { + cpus_accel->synchronize_post_reset(cpu); + } + if (kvm_enabled()) { + kvm_cpu_synchronize_post_reset(cpu); + } + if (hax_enabled()) { + hax_cpu_synchronize_post_reset(cpu); + } + if (whpx_enabled()) { + whpx_cpu_synchronize_post_reset(cpu); + } +} + +void cpu_synchronize_post_init(CPUState *cpu) +{ + if (cpus_accel && cpus_accel->synchronize_post_init) { + cpus_accel->synchronize_post_init(cpu); + } + if (kvm_enabled()) { + kvm_cpu_synchronize_post_init(cpu); + } + if (hax_enabled()) { + hax_cpu_synchronize_post_init(cpu); + } + if (whpx_enabled()) { + whpx_cpu_synchronize_post_init(cpu); + } +} + +void cpu_synchronize_pre_loadvm(CPUState *cpu) +{ + if (cpus_accel && cpus_accel->synchronize_pre_loadvm) { + cpus_accel->synchronize_pre_loadvm(cpu); + } + if (kvm_enabled()) { + kvm_cpu_synchronize_pre_loadvm(cpu); + } + if (hax_enabled()) { + hax_cpu_synchronize_pre_loadvm(cpu); + } + if (hvf_enabled()) { + hvf_cpu_synchronize_pre_loadvm(cpu); + } + if (whpx_enabled()) { + whpx_cpu_synchronize_pre_loadvm(cpu); + } +} + +int64_t cpus_get_virtual_clock(void) +{ + if (cpus_accel && cpus_accel->get_virtual_clock) { + return cpus_accel->get_virtual_clock(); + } + if (icount_enabled()) { + return icount_get(); + } else if (qtest_enabled()) { /* for qtest_clock_warp */ + return qtest_get_virtual_clock(); + } + return cpu_get_clock(); +} + +/* + * return the time elapsed in VM between vm_start and vm_stop. Unless + * icount is active, cpus_get_elapsed_ticks() uses units of the host CPU cycle + * counter. + */ +int64_t cpus_get_elapsed_ticks(void) +{ + if (cpus_accel && cpus_accel->get_elapsed_ticks) { + return cpus_accel->get_elapsed_ticks(); + } + if (icount_enabled()) { + return icount_get(); + } + return cpu_get_ticks(); +} + static int do_vm_stop(RunState state, bool send_stop) { int ret = 0; @@ -279,7 +380,7 @@ int vm_shutdown(void) return do_vm_stop(RUN_STATE_SHUTDOWN, false); } -static bool cpu_can_run(CPUState *cpu) +bool cpu_can_run(CPUState *cpu) { if (cpu->stop) { return false; @@ -290,7 +391,7 @@ static bool cpu_can_run(CPUState *cpu) return true; } -static void cpu_handle_guest_debug(CPUState *cpu) +void cpu_handle_guest_debug(CPUState *cpu) { gdb_set_stop_cpu(cpu); qemu_system_debug_request(); @@ -396,7 +497,7 @@ static void qemu_cpu_stop(CPUState *cpu, bool exit) qemu_cond_broadcast(&qemu_pause_cond); } -static void qemu_wait_io_event_common(CPUState *cpu) +void qemu_wait_io_event_common(CPUState *cpu) { qatomic_mb_set(&cpu->thread_kicked, false); if (cpu->stop) { @@ -421,7 +522,7 @@ static void qemu_tcg_rr_wait_io_event(void) } } -static void qemu_wait_io_event(CPUState *cpu) +void qemu_wait_io_event(CPUState *cpu) { bool slept = false; @@ -437,8 +538,8 @@ static void qemu_wait_io_event(CPUState *cpu) } #ifdef _WIN32 - /* Eat dummy APC queued by qemu_cpu_kick_thread. */ - if (!tcg_enabled()) { + /* Eat dummy APC queued by cpus_kick_thread. */ + if (hax_enabled()) { SleepEx(0, TRUE); } #endif @@ -467,8 +568,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) kvm_init_cpu_signals(cpu); /* signal CPU creation */ - cpu->created = true; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_created(cpu); qemu_guest_random_seed_thread_part2(cpu->random_seed); do { @@ -482,8 +582,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) } while (!cpu->unplug || cpu_can_run(cpu)); qemu_kvm_destroy_vcpu(cpu); - cpu->created = false; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_destroyed(cpu); qemu_mutex_unlock_iothread(); rcu_unregister_thread(); return NULL; @@ -511,8 +610,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) sigaddset(&waitset, SIG_IPI); /* signal CPU creation */ - cpu->created = true; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_created(cpu); qemu_guest_random_seed_thread_part2(cpu->random_seed); do { @@ -660,8 +758,7 @@ static void deal_with_unplugged_cpus(void) CPU_FOREACH(cpu) { if (cpu->unplug && !cpu_can_run(cpu)) { qemu_tcg_destroy_vcpu(cpu); - cpu->created = false; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_destroyed(cpu); break; } } @@ -688,9 +785,8 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) qemu_thread_get_self(cpu->thread); cpu->thread_id = qemu_get_thread_id(); - cpu->created = true; cpu->can_do_io = 1; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_created(cpu); qemu_guest_random_seed_thread_part2(cpu->random_seed); /* wait for initial kick-off after machine start */ @@ -800,11 +896,9 @@ static void *qemu_hax_cpu_thread_fn(void *arg) qemu_thread_get_self(cpu->thread); cpu->thread_id = qemu_get_thread_id(); - cpu->created = true; current_cpu = cpu; - hax_init_vcpu(cpu); - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_created(cpu); qemu_guest_random_seed_thread_part2(cpu->random_seed); do { @@ -843,8 +937,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg) hvf_init_vcpu(cpu); /* signal CPU creation */ - cpu->created = true; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_created(cpu); qemu_guest_random_seed_thread_part2(cpu->random_seed); do { @@ -858,8 +951,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg) } while (!cpu->unplug || cpu_can_run(cpu)); hvf_vcpu_destroy(cpu); - cpu->created = false; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_destroyed(cpu); qemu_mutex_unlock_iothread(); rcu_unregister_thread(); return NULL; @@ -884,8 +976,7 @@ static void *qemu_whpx_cpu_thread_fn(void *arg) } /* signal CPU creation */ - cpu->created = true; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_created(cpu); qemu_guest_random_seed_thread_part2(cpu->random_seed); do { @@ -902,8 +993,7 @@ static void *qemu_whpx_cpu_thread_fn(void *arg) } while (!cpu->unplug || cpu_can_run(cpu)); whpx_destroy_vcpu(cpu); - cpu->created = false; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_destroyed(cpu); qemu_mutex_unlock_iothread(); rcu_unregister_thread(); return NULL; @@ -936,10 +1026,9 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) qemu_thread_get_self(cpu->thread); cpu->thread_id = qemu_get_thread_id(); - cpu->created = true; cpu->can_do_io = 1; current_cpu = cpu; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_created(cpu); qemu_guest_random_seed_thread_part2(cpu->random_seed); /* process any pending work */ @@ -980,14 +1069,13 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) } while (!cpu->unplug || cpu_can_run(cpu)); qemu_tcg_destroy_vcpu(cpu); - cpu->created = false; - qemu_cond_signal(&qemu_cpu_cond); + cpu_thread_signal_destroyed(cpu); qemu_mutex_unlock_iothread(); rcu_unregister_thread(); return NULL; } -static void qemu_cpu_kick_thread(CPUState *cpu) +void cpus_kick_thread(CPUState *cpu) { #ifndef _WIN32 int err; @@ -1017,7 +1105,10 @@ static void qemu_cpu_kick_thread(CPUState *cpu) void qemu_cpu_kick(CPUState *cpu) { qemu_cond_broadcast(cpu->halt_cond); - if (tcg_enabled()) { + + if (cpus_accel && cpus_accel->kick_vcpu_thread) { + cpus_accel->kick_vcpu_thread(cpu); + } else if (tcg_enabled()) { if (qemu_tcg_mttcg_enabled()) { cpu_exit(cpu); } else { @@ -1031,14 +1122,14 @@ void qemu_cpu_kick(CPUState *cpu) */ cpu->exit_request = 1; } - qemu_cpu_kick_thread(cpu); + cpus_kick_thread(cpu); } } void qemu_cpu_kick_self(void) { assert(current_cpu); - qemu_cpu_kick_thread(current_cpu); + cpus_kick_thread(current_cpu); } bool qemu_cpu_is_self(CPUState *cpu) @@ -1088,6 +1179,21 @@ void qemu_cond_timedwait_iothread(QemuCond *cond, int ms) qemu_cond_timedwait(cond, &qemu_global_mutex, ms); } +/* signal CPU creation */ +void cpu_thread_signal_created(CPUState *cpu) +{ + cpu->created = true; + qemu_cond_signal(&qemu_cpu_cond); +} + +/* signal CPU destruction */ +void cpu_thread_signal_destroyed(CPUState *cpu) +{ + cpu->created = false; + qemu_cond_signal(&qemu_cpu_cond); +} + + static bool all_vcpus_paused(void) { CPUState *cpu; @@ -1163,9 +1269,6 @@ void cpu_remove_sync(CPUState *cpu) qemu_mutex_lock_iothread(); } -/* For temporary buffers for forming a name */ -#define VCPU_THREAD_NAME_SIZE 16 - static void qemu_tcg_init_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -1295,6 +1398,13 @@ static void qemu_whpx_start_vcpu(CPUState *cpu) #endif } +void cpus_register_accel(const CpusAccel *ca) +{ + assert(ca != NULL); + assert(ca->create_vcpu_thread != NULL); /* mandatory */ + cpus_accel = ca; +} + static void qemu_dummy_start_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -1325,7 +1435,10 @@ void qemu_init_vcpu(CPUState *cpu) cpu_address_space_init(cpu, 0, "cpu-memory", cpu->memory); } - if (kvm_enabled()) { + if (cpus_accel) { + /* accelerator already implements the CpusAccel interface */ + cpus_accel->create_vcpu_thread(cpu); + } else if (kvm_enabled()) { qemu_kvm_start_vcpu(cpu); } else if (hax_enabled()) { qemu_hax_start_vcpu(cpu); diff --git a/stubs/cpu-synchronize-state.c b/stubs/cpu-synchronize-state.c new file mode 100644 index 0000000000..d9211da66c --- /dev/null +++ b/stubs/cpu-synchronize-state.c @@ -0,0 +1,9 @@ +#include "qemu/osdep.h" +#include "sysemu/hw_accel.h" + +void cpu_synchronize_state(CPUState *cpu) +{ +} +void cpu_synchronize_post_init(CPUState *cpu) +{ +} diff --git a/stubs/cpus-get-virtual-clock.c b/stubs/cpus-get-virtual-clock.c new file mode 100644 index 0000000000..fd447d53f3 --- /dev/null +++ b/stubs/cpus-get-virtual-clock.c @@ -0,0 +1,8 @@ +#include "qemu/osdep.h" +#include "sysemu/cpu-timers.h" +#include "qemu/main-loop.h" + +int64_t cpus_get_virtual_clock(void) +{ + return cpu_get_clock(); +} diff --git a/stubs/meson.build b/stubs/meson.build index cbd955a7cd..67f2a8c069 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -5,6 +5,7 @@ stub_ss.add(files('blockdev-close-all-bdrv-states.c')) stub_ss.add(files('change-state-handler.c')) stub_ss.add(files('cmos.c')) stub_ss.add(files('cpu-get-clock.c')) +stub_ss.add(files('cpus-get-virtual-clock.c')) stub_ss.add(files('qemu-timer-notify-cb.c')) stub_ss.add(files('icount.c')) stub_ss.add(files('dump.c')) @@ -44,6 +45,7 @@ stub_ss.add(files('vmgenid.c')) stub_ss.add(files('vmstate.c')) stub_ss.add(files('vm-stop.c')) stub_ss.add(files('win32-kbd-hook.c')) +stub_ss.add(files('cpu-synchronize-state.c')) if have_system stub_ss.add(files('semihost.c')) stub_ss.add(files('xen-hw-stub.c')) diff --git a/util/qemu-timer.c b/util/qemu-timer.c index b69c6bb27b..81c28af517 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -635,13 +635,7 @@ int64_t qemu_clock_get_ns(QEMUClockType type) return get_clock(); default: case QEMU_CLOCK_VIRTUAL: - if (icount_enabled()) { - return icount_get(); - } else if (qtest_enabled()) { /* for qtest_clock_warp */ - return qtest_get_virtual_clock(); - } else { - return cpu_get_clock(); - } + return cpus_get_virtual_clock(); case QEMU_CLOCK_HOST: return REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime()); case QEMU_CLOCK_VIRTUAL_RT: From patchwork Tue Oct 6 07:29:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377241 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=I6gqgpnW; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58N21775z9sSs for ; Tue, 6 Oct 2020 18:33:38 +1100 (AEDT) Received: from localhost ([::1]:43864 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhTc-00067H-23 for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:33:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39506) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ3-0002Le-AK for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:55 -0400 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]:41041) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhPz-0001NP-Sn for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:54 -0400 Received: by mail-wr1-x436.google.com with SMTP id w5so12224510wrp.8 for ; Tue, 06 Oct 2020 00:29:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uNVNjKk+cr6nxn497WGeV8Kg2WRlDxRv0yC5TjSfOf4=; b=I6gqgpnWlBfmtUlgtfdOg4WB13P3sStB8ReGMbUIdl3VD3AiUYSj4eFBqQ5LDQGeN6 z5aOt/6XzH6tj5wuc4VNqByoY+MXXPyfe033MRxrduNDZf33Im+4BruWs+zHjS8Q3z0O YV4GPHQ4vI2xk9wKWwCjqCwLr7j7CP9yJbEuNST5LABqVzp5rm2UdFYwGnT3sEphlXyV 81i3WvQJEcWwbnBLTF1LMpBpqyGQNzCamWYAGUx6KINXUx/I1oBbJzFbULEgiAYMv5lW T2O9VrlgLer+repgsooLZCa5br3RhI40H2zqoZRtyZh/Rp62aKPZ147V1OYTGrvg1dmO okug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=uNVNjKk+cr6nxn497WGeV8Kg2WRlDxRv0yC5TjSfOf4=; b=FF7EzHFYDuinO3tNRZC3g6tJEQP3Qs1anCtrDuL+uOoc2uLN9C00xTnxlfDtaQMjb2 N43A+oLC/drg8stUygwTLRzXr+wTkwF8t3gcAqim0vK/0CNXcDQyIU6J1Fjctir5q9S+ W0EYmbLvGtzC+DDcniSaHtdWyAvVlNFLa6X3CgE/auvDRjPJLm/ub6C8Wx6n+GZRP/LV R3473aSAxtvjzSGiSj/4FD+B631LsRA8MTDszL8t4k8Y/WR8Vtpulw1lu1xcGLnX2Ks1 W6yY5GRGdGQiWhZ5MUtWn8XOB1c6dAjKsiwcJhatGHPA5rzdW48I9z6/TS7wrlsf5Gqc b4ig== X-Gm-Message-State: AOAM530C4/bVxpbkbM9UHNItVGW1gQqcWGFe8zA5haUydJS8x/krkCza WyYO07UiDeSpVagbVK3swHCxrPgwoYw= X-Google-Smtp-Source: ABdhPJznM4nhFBRZ+2KQOQYjNs8ldsj8UrpMHEk5w+t4BS/TdZCBD9dLqyb/HMNQpju6qsucuoPI0Q== X-Received: by 2002:a5d:6547:: with SMTP id z7mr3294297wrv.322.1601969389752; Tue, 06 Oct 2020 00:29:49 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:49 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 04/37] cpus: extract out TCG-specific code to accel/tcg Date: Tue, 6 Oct 2020 09:29:14 +0200 Message-Id: <20201006072947.487729-5-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::436; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x436.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , =?utf-8?q?Philippe_Mathie?= =?utf-8?q?u-Daud=C3=A9?= , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana TCG is the first accelerator to register a "CpusAccel" interface on initialization, providing functions for starting a vcpu, kicking a vcpu, sychronizing state and getting virtual clock and ticks. Signed-off-by: Claudio Fontana Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé [added const] Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Reviewed-by: Alex Bennée Signed-off-by: Paolo Bonzini --- accel/tcg/meson.build | 2 +- accel/tcg/tcg-all.c | 11 +- accel/tcg/tcg-cpus.c | 551 ++++++++++++++++++++++++++++++++++++++++++ accel/tcg/tcg-cpus.h | 17 ++ softmmu/cpus.c | 505 +------------------------------------- 5 files changed, 576 insertions(+), 510 deletions(-) create mode 100644 accel/tcg/tcg-cpus.c create mode 100644 accel/tcg/tcg-cpus.h diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build index 96a76ed23d..19b9343d5b 100644 --- a/accel/tcg/meson.build +++ b/accel/tcg/meson.build @@ -12,4 +12,4 @@ tcg_ss.add(when: 'CONFIG_SOFTMMU', if_false: files('user-exec-stub.c')) tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: [files('plugin-gen.c'), libdl]) specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss) -specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files('tcg-all.c', 'cputlb.c')) +specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files('tcg-all.c', 'cputlb.c', 'tcg-cpus.c')) diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c index 2d13df3f72..000fe4dbd9 100644 --- a/accel/tcg/tcg-all.c +++ b/accel/tcg/tcg-all.c @@ -24,18 +24,15 @@ */ #include "qemu/osdep.h" -#include "sysemu/accel.h" +#include "qemu-common.h" #include "sysemu/tcg.h" -#include "qom/object.h" -#include "cpu.h" -#include "sysemu/cpus.h" #include "sysemu/cpu-timers.h" -#include "qemu/main-loop.h" #include "tcg/tcg.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "hw/boards.h" #include "qapi/qapi-builtin-visit.h" +#include "tcg-cpus.h" struct TCGState { AccelState parent_obj; @@ -124,6 +121,8 @@ static void tcg_accel_instance_init(Object *obj) s->mttcg_enabled = default_mttcg_enabled(); } +bool mttcg_enabled; + static int tcg_init(MachineState *ms) { TCGState *s = TCG_STATE(current_accel()); @@ -131,6 +130,8 @@ static int tcg_init(MachineState *ms) tcg_exec_init(s->tb_size * 1024 * 1024); cpu_interrupt_handler = tcg_handle_interrupt; mttcg_enabled = s->mttcg_enabled; + cpus_register_accel(&tcg_cpus); + return 0; } diff --git a/accel/tcg/tcg-cpus.c b/accel/tcg/tcg-cpus.c new file mode 100644 index 0000000000..4f15c7f0de --- /dev/null +++ b/accel/tcg/tcg-cpus.c @@ -0,0 +1,551 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (c) 2014 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "sysemu/tcg.h" +#include "sysemu/replay.h" +#include "qemu/main-loop.h" +#include "qemu/guest-random.h" +#include "exec/exec-all.h" +#include "hw/boards.h" + +#include "tcg-cpus.h" + +/* Kick all RR vCPUs */ +static void qemu_cpu_kick_rr_cpus(void) +{ + CPUState *cpu; + + CPU_FOREACH(cpu) { + cpu_exit(cpu); + }; +} + +static void tcg_kick_vcpu_thread(CPUState *cpu) +{ + if (qemu_tcg_mttcg_enabled()) { + cpu_exit(cpu); + } else { + qemu_cpu_kick_rr_cpus(); + } +} + +/* + * TCG vCPU kick timer + * + * The kick timer is responsible for moving single threaded vCPU + * emulation on to the next vCPU. If more than one vCPU is running a + * timer event with force a cpu->exit so the next vCPU can get + * scheduled. + * + * The timer is removed if all vCPUs are idle and restarted again once + * idleness is complete. + */ + +static QEMUTimer *tcg_kick_vcpu_timer; +static CPUState *tcg_current_rr_cpu; + +#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10) + +static inline int64_t qemu_tcg_next_kick(void) +{ + return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD; +} + +/* Kick the currently round-robin scheduled vCPU to next */ +static void qemu_cpu_kick_rr_next_cpu(void) +{ + CPUState *cpu; + do { + cpu = qatomic_mb_read(&tcg_current_rr_cpu); + if (cpu) { + cpu_exit(cpu); + } + } while (cpu != qatomic_mb_read(&tcg_current_rr_cpu)); +} + +static void kick_tcg_thread(void *opaque) +{ + timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick()); + qemu_cpu_kick_rr_next_cpu(); +} + +static void start_tcg_kick_timer(void) +{ + assert(!mttcg_enabled); + if (!tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) { + tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + kick_tcg_thread, NULL); + } + if (tcg_kick_vcpu_timer && !timer_pending(tcg_kick_vcpu_timer)) { + timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick()); + } +} + +static void stop_tcg_kick_timer(void) +{ + assert(!mttcg_enabled); + if (tcg_kick_vcpu_timer && timer_pending(tcg_kick_vcpu_timer)) { + timer_del(tcg_kick_vcpu_timer); + } +} + +static void qemu_tcg_destroy_vcpu(CPUState *cpu) +{ +} + +static void qemu_tcg_rr_wait_io_event(void) +{ + CPUState *cpu; + + while (all_cpu_threads_idle()) { + stop_tcg_kick_timer(); + qemu_cond_wait_iothread(first_cpu->halt_cond); + } + + start_tcg_kick_timer(); + + CPU_FOREACH(cpu) { + qemu_wait_io_event_common(cpu); + } +} + +static int64_t tcg_get_icount_limit(void) +{ + int64_t deadline; + + if (replay_mode != REPLAY_MODE_PLAY) { + /* + * Include all the timers, because they may need an attention. + * Too long CPU execution may create unnecessary delay in UI. + */ + deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, + QEMU_TIMER_ATTR_ALL); + /* Check realtime timers, because they help with input processing */ + deadline = qemu_soonest_timeout(deadline, + qemu_clock_deadline_ns_all(QEMU_CLOCK_REALTIME, + QEMU_TIMER_ATTR_ALL)); + + /* + * Maintain prior (possibly buggy) behaviour where if no deadline + * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than + * INT32_MAX nanoseconds ahead, we still use INT32_MAX + * nanoseconds. + */ + if ((deadline < 0) || (deadline > INT32_MAX)) { + deadline = INT32_MAX; + } + + return icount_round(deadline); + } else { + return replay_get_instructions(); + } +} + +static void notify_aio_contexts(void) +{ + /* Wake up other AioContexts. */ + qemu_clock_notify(QEMU_CLOCK_VIRTUAL); + qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL); +} + +static void handle_icount_deadline(void) +{ + assert(qemu_in_vcpu_thread()); + if (icount_enabled()) { + int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, + QEMU_TIMER_ATTR_ALL); + + if (deadline == 0) { + notify_aio_contexts(); + } + } +} + +static void prepare_icount_for_run(CPUState *cpu) +{ + if (icount_enabled()) { + int insns_left; + + /* + * These should always be cleared by process_icount_data after + * each vCPU execution. However u16.high can be raised + * asynchronously by cpu_exit/cpu_interrupt/tcg_handle_interrupt + */ + g_assert(cpu_neg(cpu)->icount_decr.u16.low == 0); + g_assert(cpu->icount_extra == 0); + + cpu->icount_budget = tcg_get_icount_limit(); + insns_left = MIN(0xffff, cpu->icount_budget); + cpu_neg(cpu)->icount_decr.u16.low = insns_left; + cpu->icount_extra = cpu->icount_budget - insns_left; + + replay_mutex_lock(); + + if (cpu->icount_budget == 0 && replay_has_checkpoint()) { + notify_aio_contexts(); + } + } +} + +static void process_icount_data(CPUState *cpu) +{ + if (icount_enabled()) { + /* Account for executed instructions */ + icount_update(cpu); + + /* Reset the counters */ + cpu_neg(cpu)->icount_decr.u16.low = 0; + cpu->icount_extra = 0; + cpu->icount_budget = 0; + + replay_account_executed_instructions(); + + replay_mutex_unlock(); + } +} + +static int tcg_cpu_exec(CPUState *cpu) +{ + int ret; +#ifdef CONFIG_PROFILER + int64_t ti; +#endif + + assert(tcg_enabled()); +#ifdef CONFIG_PROFILER + ti = profile_getclock(); +#endif + cpu_exec_start(cpu); + ret = cpu_exec(cpu); + cpu_exec_end(cpu); +#ifdef CONFIG_PROFILER + qatomic_set(&tcg_ctx->prof.cpu_exec_time, + tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti); +#endif + return ret; +} + +/* + * Destroy any remaining vCPUs which have been unplugged and have + * finished running + */ +static void deal_with_unplugged_cpus(void) +{ + CPUState *cpu; + + CPU_FOREACH(cpu) { + if (cpu->unplug && !cpu_can_run(cpu)) { + qemu_tcg_destroy_vcpu(cpu); + cpu_thread_signal_destroyed(cpu); + break; + } + } +} + +/* + * Single-threaded TCG + * + * In the single-threaded case each vCPU is simulated in turn. If + * there is more than a single vCPU we create a simple timer to kick + * the vCPU and ensure we don't get stuck in a tight loop in one vCPU. + * This is done explicitly rather than relying on side-effects + * elsewhere. + */ + +static void *tcg_rr_cpu_thread_fn(void *arg) +{ + CPUState *cpu = arg; + + assert(tcg_enabled()); + rcu_register_thread(); + tcg_register_thread(); + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + + cpu->thread_id = qemu_get_thread_id(); + cpu->can_do_io = 1; + cpu_thread_signal_created(cpu); + qemu_guest_random_seed_thread_part2(cpu->random_seed); + + /* wait for initial kick-off after machine start */ + while (first_cpu->stopped) { + qemu_cond_wait_iothread(first_cpu->halt_cond); + + /* process any pending work */ + CPU_FOREACH(cpu) { + current_cpu = cpu; + qemu_wait_io_event_common(cpu); + } + } + + start_tcg_kick_timer(); + + cpu = first_cpu; + + /* process any pending work */ + cpu->exit_request = 1; + + while (1) { + qemu_mutex_unlock_iothread(); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); + /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ + icount_account_warp_timer(); + + /* + * Run the timers here. This is much more efficient than + * waking up the I/O thread and waiting for completion. + */ + handle_icount_deadline(); + + replay_mutex_unlock(); + + if (!cpu) { + cpu = first_cpu; + } + + while (cpu && cpu_work_list_empty(cpu) && !cpu->exit_request) { + + qatomic_mb_set(&tcg_current_rr_cpu, cpu); + current_cpu = cpu; + + qemu_clock_enable(QEMU_CLOCK_VIRTUAL, + (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0); + + if (cpu_can_run(cpu)) { + int r; + + qemu_mutex_unlock_iothread(); + prepare_icount_for_run(cpu); + + r = tcg_cpu_exec(cpu); + + process_icount_data(cpu); + qemu_mutex_lock_iothread(); + + if (r == EXCP_DEBUG) { + cpu_handle_guest_debug(cpu); + break; + } else if (r == EXCP_ATOMIC) { + qemu_mutex_unlock_iothread(); + cpu_exec_step_atomic(cpu); + qemu_mutex_lock_iothread(); + break; + } + } else if (cpu->stop) { + if (cpu->unplug) { + cpu = CPU_NEXT(cpu); + } + break; + } + + cpu = CPU_NEXT(cpu); + } /* while (cpu && !cpu->exit_request).. */ + + /* Does not need qatomic_mb_set because a spurious wakeup is okay. */ + qatomic_set(&tcg_current_rr_cpu, NULL); + + if (cpu && cpu->exit_request) { + qatomic_mb_set(&cpu->exit_request, 0); + } + + if (icount_enabled() && all_cpu_threads_idle()) { + /* + * When all cpus are sleeping (e.g in WFI), to avoid a deadlock + * in the main_loop, wake it up in order to start the warp timer. + */ + qemu_notify_event(); + } + + qemu_tcg_rr_wait_io_event(); + deal_with_unplugged_cpus(); + } + + rcu_unregister_thread(); + return NULL; +} + +/* + * Multi-threaded TCG + * + * In the multi-threaded case each vCPU has its own thread. The TLS + * variable current_cpu can be used deep in the code to find the + * current CPUState for a given thread. + */ + +static void *tcg_cpu_thread_fn(void *arg) +{ + CPUState *cpu = arg; + + assert(tcg_enabled()); + g_assert(!icount_enabled()); + + rcu_register_thread(); + tcg_register_thread(); + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + + cpu->thread_id = qemu_get_thread_id(); + cpu->can_do_io = 1; + current_cpu = cpu; + cpu_thread_signal_created(cpu); + qemu_guest_random_seed_thread_part2(cpu->random_seed); + + /* process any pending work */ + cpu->exit_request = 1; + + do { + if (cpu_can_run(cpu)) { + int r; + qemu_mutex_unlock_iothread(); + r = tcg_cpu_exec(cpu); + qemu_mutex_lock_iothread(); + switch (r) { + case EXCP_DEBUG: + cpu_handle_guest_debug(cpu); + break; + case EXCP_HALTED: + /* + * during start-up the vCPU is reset and the thread is + * kicked several times. If we don't ensure we go back + * to sleep in the halted state we won't cleanly + * start-up when the vCPU is enabled. + * + * cpu->halted should ensure we sleep in wait_io_event + */ + g_assert(cpu->halted); + break; + case EXCP_ATOMIC: + qemu_mutex_unlock_iothread(); + cpu_exec_step_atomic(cpu); + qemu_mutex_lock_iothread(); + default: + /* Ignore everything else? */ + break; + } + } + + qatomic_mb_set(&cpu->exit_request, 0); + qemu_wait_io_event(cpu); + } while (!cpu->unplug || cpu_can_run(cpu)); + + qemu_tcg_destroy_vcpu(cpu); + cpu_thread_signal_destroyed(cpu); + qemu_mutex_unlock_iothread(); + rcu_unregister_thread(); + return NULL; +} + +static void tcg_start_vcpu_thread(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + static QemuCond *single_tcg_halt_cond; + static QemuThread *single_tcg_cpu_thread; + static int tcg_region_inited; + + assert(tcg_enabled()); + /* + * Initialize TCG regions--once. Now is a good time, because: + * (1) TCG's init context, prologue and target globals have been set up. + * (2) qemu_tcg_mttcg_enabled() works now (TCG init code runs before the + * -accel flag is processed, so the check doesn't work then). + */ + if (!tcg_region_inited) { + tcg_region_inited = 1; + tcg_region_init(); + /* + * If MTTCG, and we will create multiple cpus, + * then we will have cpus running in parallel. + */ + if (qemu_tcg_mttcg_enabled()) { + MachineState *ms = MACHINE(qdev_get_machine()); + if (ms->smp.max_cpus > 1) { + parallel_cpus = true; + } + } + } + + if (qemu_tcg_mttcg_enabled() || !single_tcg_cpu_thread) { + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + + if (qemu_tcg_mttcg_enabled()) { + /* create a thread per vCPU with TCG (MTTCG) */ + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", + cpu->cpu_index); + + qemu_thread_create(cpu->thread, thread_name, tcg_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); + + } else { + /* share a single thread for all cpus with TCG */ + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG"); + qemu_thread_create(cpu->thread, thread_name, + tcg_rr_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); + + single_tcg_halt_cond = cpu->halt_cond; + single_tcg_cpu_thread = cpu->thread; + } +#ifdef _WIN32 + cpu->hThread = qemu_thread_get_handle(cpu->thread); +#endif + } else { + /* For non-MTTCG cases we share the thread */ + cpu->thread = single_tcg_cpu_thread; + cpu->halt_cond = single_tcg_halt_cond; + cpu->thread_id = first_cpu->thread_id; + cpu->can_do_io = 1; + cpu->created = true; + } +} + +static int64_t tcg_get_virtual_clock(void) +{ + if (icount_enabled()) { + return icount_get(); + } + return cpu_get_clock(); +} + +static int64_t tcg_get_elapsed_ticks(void) +{ + if (icount_enabled()) { + return icount_get(); + } + return cpu_get_ticks(); +} + +const CpusAccel tcg_cpus = { + .create_vcpu_thread = tcg_start_vcpu_thread, + .kick_vcpu_thread = tcg_kick_vcpu_thread, + .get_virtual_clock = tcg_get_virtual_clock, + .get_elapsed_ticks = tcg_get_elapsed_ticks, +}; diff --git a/accel/tcg/tcg-cpus.h b/accel/tcg/tcg-cpus.h new file mode 100644 index 0000000000..8b1d9d2abc --- /dev/null +++ b/accel/tcg/tcg-cpus.h @@ -0,0 +1,17 @@ +/* + * Accelerator CPUS Interface + * + * Copyright 2020 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef TCG_CPUS_H +#define TCG_CPUS_H + +#include "sysemu/cpus.h" + +extern const CpusAccel tcg_cpus; + +#endif /* TCG_CPUS_H */ diff --git a/softmmu/cpus.c b/softmmu/cpus.c index f932fc1f74..25f12e3ee9 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -24,27 +24,19 @@ #include "qemu/osdep.h" #include "qemu-common.h" -#include "qemu/config-file.h" -#include "qemu/cutils.h" -#include "migration/vmstate.h" #include "monitor/monitor.h" #include "qapi/error.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-events-run-state.h" #include "qapi/qmp/qerror.h" -#include "qemu/error-report.h" -#include "qemu/qemu-print.h" #include "sysemu/tcg.h" -#include "sysemu/block-backend.h" #include "exec/gdbstub.h" -#include "sysemu/dma.h" #include "sysemu/hw_accel.h" #include "sysemu/kvm.h" #include "sysemu/hax.h" #include "sysemu/hvf.h" #include "sysemu/whpx.h" #include "exec/exec-all.h" - #include "qemu/thread.h" #include "qemu/plugin.h" #include "sysemu/cpus.h" @@ -124,79 +116,6 @@ bool all_cpu_threads_idle(void) return true; } -bool mttcg_enabled; - - -/***********************************************************/ -/* TCG vCPU kick timer - * - * The kick timer is responsible for moving single threaded vCPU - * emulation on to the next vCPU. If more than one vCPU is running a - * timer event with force a cpu->exit so the next vCPU can get - * scheduled. - * - * The timer is removed if all vCPUs are idle and restarted again once - * idleness is complete. - */ - -static QEMUTimer *tcg_kick_vcpu_timer; -static CPUState *tcg_current_rr_cpu; - -#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10) - -static inline int64_t qemu_tcg_next_kick(void) -{ - return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD; -} - -/* Kick the currently round-robin scheduled vCPU to next */ -static void qemu_cpu_kick_rr_next_cpu(void) -{ - CPUState *cpu; - do { - cpu = qatomic_mb_read(&tcg_current_rr_cpu); - if (cpu) { - cpu_exit(cpu); - } - } while (cpu != qatomic_mb_read(&tcg_current_rr_cpu)); -} - -/* Kick all RR vCPUs */ -static void qemu_cpu_kick_rr_cpus(void) -{ - CPUState *cpu; - - CPU_FOREACH(cpu) { - cpu_exit(cpu); - }; -} - -static void kick_tcg_thread(void *opaque) -{ - timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick()); - qemu_cpu_kick_rr_next_cpu(); -} - -static void start_tcg_kick_timer(void) -{ - assert(!mttcg_enabled); - if (!tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) { - tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - kick_tcg_thread, NULL); - } - if (tcg_kick_vcpu_timer && !timer_pending(tcg_kick_vcpu_timer)) { - timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick()); - } -} - -static void stop_tcg_kick_timer(void) -{ - assert(!mttcg_enabled); - if (tcg_kick_vcpu_timer && timer_pending(tcg_kick_vcpu_timer)) { - timer_del(tcg_kick_vcpu_timer); - } -} - /***********************************************************/ void hw_error(const char *fmt, ...) { @@ -328,9 +247,7 @@ int64_t cpus_get_virtual_clock(void) if (cpus_accel && cpus_accel->get_virtual_clock) { return cpus_accel->get_virtual_clock(); } - if (icount_enabled()) { - return icount_get(); - } else if (qtest_enabled()) { /* for qtest_clock_warp */ + if (qtest_enabled()) { /* for qtest_clock_warp */ return qtest_get_virtual_clock(); } return cpu_get_clock(); @@ -346,9 +263,6 @@ int64_t cpus_get_elapsed_ticks(void) if (cpus_accel && cpus_accel->get_elapsed_ticks) { return cpus_accel->get_elapsed_ticks(); } - if (icount_enabled()) { - return icount_get(); - } return cpu_get_ticks(); } @@ -482,10 +396,6 @@ static void qemu_kvm_destroy_vcpu(CPUState *cpu) } } -static void qemu_tcg_destroy_vcpu(CPUState *cpu) -{ -} - static void qemu_cpu_stop(CPUState *cpu, bool exit) { g_assert(qemu_cpu_is_self(cpu)); @@ -506,22 +416,6 @@ void qemu_wait_io_event_common(CPUState *cpu) process_queued_cpu_work(cpu); } -static void qemu_tcg_rr_wait_io_event(void) -{ - CPUState *cpu; - - while (all_cpu_threads_idle()) { - stop_tcg_kick_timer(); - qemu_cond_wait(first_cpu->halt_cond, &qemu_global_mutex); - } - - start_tcg_kick_timer(); - - CPU_FOREACH(cpu) { - qemu_wait_io_event_common(cpu); - } -} - void qemu_wait_io_event(CPUState *cpu) { bool slept = false; @@ -633,259 +527,6 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) #endif } -static int64_t tcg_get_icount_limit(void) -{ - int64_t deadline; - - if (replay_mode != REPLAY_MODE_PLAY) { - /* - * Include all the timers, because they may need an attention. - * Too long CPU execution may create unnecessary delay in UI. - */ - deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, - QEMU_TIMER_ATTR_ALL); - /* Check realtime timers, because they help with input processing */ - deadline = qemu_soonest_timeout(deadline, - qemu_clock_deadline_ns_all(QEMU_CLOCK_REALTIME, - QEMU_TIMER_ATTR_ALL)); - - /* Maintain prior (possibly buggy) behaviour where if no deadline - * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than - * INT32_MAX nanoseconds ahead, we still use INT32_MAX - * nanoseconds. - */ - if ((deadline < 0) || (deadline > INT32_MAX)) { - deadline = INT32_MAX; - } - - return icount_round(deadline); - } else { - return replay_get_instructions(); - } -} - -static void notify_aio_contexts(void) -{ - /* Wake up other AioContexts. */ - qemu_clock_notify(QEMU_CLOCK_VIRTUAL); - qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL); -} - -static void handle_icount_deadline(void) -{ - assert(qemu_in_vcpu_thread()); - if (icount_enabled()) { - int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, - QEMU_TIMER_ATTR_ALL); - - if (deadline == 0) { - notify_aio_contexts(); - } - } -} - -static void prepare_icount_for_run(CPUState *cpu) -{ - if (icount_enabled()) { - int insns_left; - - /* These should always be cleared by process_icount_data after - * each vCPU execution. However u16.high can be raised - * asynchronously by cpu_exit/cpu_interrupt/tcg_handle_interrupt - */ - g_assert(cpu_neg(cpu)->icount_decr.u16.low == 0); - g_assert(cpu->icount_extra == 0); - - cpu->icount_budget = tcg_get_icount_limit(); - insns_left = MIN(0xffff, cpu->icount_budget); - cpu_neg(cpu)->icount_decr.u16.low = insns_left; - cpu->icount_extra = cpu->icount_budget - insns_left; - - replay_mutex_lock(); - - if (cpu->icount_budget == 0 && replay_has_checkpoint()) { - notify_aio_contexts(); - } - } -} - -static void process_icount_data(CPUState *cpu) -{ - if (icount_enabled()) { - /* Account for executed instructions */ - icount_update(cpu); - - /* Reset the counters */ - cpu_neg(cpu)->icount_decr.u16.low = 0; - cpu->icount_extra = 0; - cpu->icount_budget = 0; - - replay_account_executed_instructions(); - - replay_mutex_unlock(); - } -} - - -static int tcg_cpu_exec(CPUState *cpu) -{ - int ret; -#ifdef CONFIG_PROFILER - int64_t ti; -#endif - - assert(tcg_enabled()); -#ifdef CONFIG_PROFILER - ti = profile_getclock(); -#endif - cpu_exec_start(cpu); - ret = cpu_exec(cpu); - cpu_exec_end(cpu); -#ifdef CONFIG_PROFILER - qatomic_set(&tcg_ctx->prof.cpu_exec_time, - tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti); -#endif - return ret; -} - -/* Destroy any remaining vCPUs which have been unplugged and have - * finished running - */ -static void deal_with_unplugged_cpus(void) -{ - CPUState *cpu; - - CPU_FOREACH(cpu) { - if (cpu->unplug && !cpu_can_run(cpu)) { - qemu_tcg_destroy_vcpu(cpu); - cpu_thread_signal_destroyed(cpu); - break; - } - } -} - -/* Single-threaded TCG - * - * In the single-threaded case each vCPU is simulated in turn. If - * there is more than a single vCPU we create a simple timer to kick - * the vCPU and ensure we don't get stuck in a tight loop in one vCPU. - * This is done explicitly rather than relying on side-effects - * elsewhere. - */ - -static void *qemu_tcg_rr_cpu_thread_fn(void *arg) -{ - CPUState *cpu = arg; - - assert(tcg_enabled()); - rcu_register_thread(); - tcg_register_thread(); - - qemu_mutex_lock_iothread(); - qemu_thread_get_self(cpu->thread); - - cpu->thread_id = qemu_get_thread_id(); - cpu->can_do_io = 1; - cpu_thread_signal_created(cpu); - qemu_guest_random_seed_thread_part2(cpu->random_seed); - - /* wait for initial kick-off after machine start */ - while (first_cpu->stopped) { - qemu_cond_wait(first_cpu->halt_cond, &qemu_global_mutex); - - /* process any pending work */ - CPU_FOREACH(cpu) { - current_cpu = cpu; - qemu_wait_io_event_common(cpu); - } - } - - start_tcg_kick_timer(); - - cpu = first_cpu; - - /* process any pending work */ - cpu->exit_request = 1; - - while (1) { - qemu_mutex_unlock_iothread(); - replay_mutex_lock(); - qemu_mutex_lock_iothread(); - /* Account partial waits to QEMU_CLOCK_VIRTUAL. */ - icount_account_warp_timer(); - - /* Run the timers here. This is much more efficient than - * waking up the I/O thread and waiting for completion. - */ - handle_icount_deadline(); - - replay_mutex_unlock(); - - if (!cpu) { - cpu = first_cpu; - } - - while (cpu && cpu_work_list_empty(cpu) && !cpu->exit_request) { - - qatomic_mb_set(&tcg_current_rr_cpu, cpu); - current_cpu = cpu; - - qemu_clock_enable(QEMU_CLOCK_VIRTUAL, - (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0); - - if (cpu_can_run(cpu)) { - int r; - - qemu_mutex_unlock_iothread(); - prepare_icount_for_run(cpu); - - r = tcg_cpu_exec(cpu); - - process_icount_data(cpu); - qemu_mutex_lock_iothread(); - - if (r == EXCP_DEBUG) { - cpu_handle_guest_debug(cpu); - break; - } else if (r == EXCP_ATOMIC) { - qemu_mutex_unlock_iothread(); - cpu_exec_step_atomic(cpu); - qemu_mutex_lock_iothread(); - break; - } - } else if (cpu->stop) { - if (cpu->unplug) { - cpu = CPU_NEXT(cpu); - } - break; - } - - cpu = CPU_NEXT(cpu); - } /* while (cpu && !cpu->exit_request).. */ - - /* Does not need qatomic_mb_set because a spurious wakeup is okay. */ - qatomic_set(&tcg_current_rr_cpu, NULL); - - if (cpu && cpu->exit_request) { - qatomic_mb_set(&cpu->exit_request, 0); - } - - if (icount_enabled() && all_cpu_threads_idle()) { - /* - * When all cpus are sleeping (e.g in WFI), to avoid a deadlock - * in the main_loop, wake it up in order to start the warp timer. - */ - qemu_notify_event(); - } - - qemu_tcg_rr_wait_io_event(); - deal_with_unplugged_cpus(); - } - - rcu_unregister_thread(); - return NULL; -} - static void *qemu_hax_cpu_thread_fn(void *arg) { CPUState *cpu = arg; @@ -1005,76 +646,6 @@ static void CALLBACK dummy_apc_func(ULONG_PTR unused) } #endif -/* Multi-threaded TCG - * - * In the multi-threaded case each vCPU has its own thread. The TLS - * variable current_cpu can be used deep in the code to find the - * current CPUState for a given thread. - */ - -static void *qemu_tcg_cpu_thread_fn(void *arg) -{ - CPUState *cpu = arg; - - assert(tcg_enabled()); - g_assert(!icount_enabled()); - - rcu_register_thread(); - tcg_register_thread(); - - qemu_mutex_lock_iothread(); - qemu_thread_get_self(cpu->thread); - - cpu->thread_id = qemu_get_thread_id(); - cpu->can_do_io = 1; - current_cpu = cpu; - cpu_thread_signal_created(cpu); - qemu_guest_random_seed_thread_part2(cpu->random_seed); - - /* process any pending work */ - cpu->exit_request = 1; - - do { - if (cpu_can_run(cpu)) { - int r; - qemu_mutex_unlock_iothread(); - r = tcg_cpu_exec(cpu); - qemu_mutex_lock_iothread(); - switch (r) { - case EXCP_DEBUG: - cpu_handle_guest_debug(cpu); - break; - case EXCP_HALTED: - /* during start-up the vCPU is reset and the thread is - * kicked several times. If we don't ensure we go back - * to sleep in the halted state we won't cleanly - * start-up when the vCPU is enabled. - * - * cpu->halted should ensure we sleep in wait_io_event - */ - g_assert(cpu->halted); - break; - case EXCP_ATOMIC: - qemu_mutex_unlock_iothread(); - cpu_exec_step_atomic(cpu); - qemu_mutex_lock_iothread(); - default: - /* Ignore everything else? */ - break; - } - } - - qatomic_mb_set(&cpu->exit_request, 0); - qemu_wait_io_event(cpu); - } while (!cpu->unplug || cpu_can_run(cpu)); - - qemu_tcg_destroy_vcpu(cpu); - cpu_thread_signal_destroyed(cpu); - qemu_mutex_unlock_iothread(); - rcu_unregister_thread(); - return NULL; -} - void cpus_kick_thread(CPUState *cpu) { #ifndef _WIN32 @@ -1105,15 +676,8 @@ void cpus_kick_thread(CPUState *cpu) void qemu_cpu_kick(CPUState *cpu) { qemu_cond_broadcast(cpu->halt_cond); - if (cpus_accel && cpus_accel->kick_vcpu_thread) { cpus_accel->kick_vcpu_thread(cpu); - } else if (tcg_enabled()) { - if (qemu_tcg_mttcg_enabled()) { - cpu_exit(cpu); - } else { - qemu_cpu_kick_rr_cpus(); - } } else { if (hax_enabled()) { /* @@ -1269,71 +833,6 @@ void cpu_remove_sync(CPUState *cpu) qemu_mutex_lock_iothread(); } -static void qemu_tcg_init_vcpu(CPUState *cpu) -{ - char thread_name[VCPU_THREAD_NAME_SIZE]; - static QemuCond *single_tcg_halt_cond; - static QemuThread *single_tcg_cpu_thread; - static int tcg_region_inited; - - assert(tcg_enabled()); - /* - * Initialize TCG regions--once. Now is a good time, because: - * (1) TCG's init context, prologue and target globals have been set up. - * (2) qemu_tcg_mttcg_enabled() works now (TCG init code runs before the - * -accel flag is processed, so the check doesn't work then). - */ - if (!tcg_region_inited) { - tcg_region_inited = 1; - tcg_region_init(); - /* - * If MTTCG, and we will create multiple cpus, - * then we will have cpus running in parallel. - */ - if (qemu_tcg_mttcg_enabled()) { - MachineState *ms = MACHINE(qdev_get_machine()); - if (ms->smp.max_cpus > 1) { - parallel_cpus = true; - } - } - } - - if (qemu_tcg_mttcg_enabled() || !single_tcg_cpu_thread) { - cpu->thread = g_malloc0(sizeof(QemuThread)); - cpu->halt_cond = g_malloc0(sizeof(QemuCond)); - qemu_cond_init(cpu->halt_cond); - - if (qemu_tcg_mttcg_enabled()) { - /* create a thread per vCPU with TCG (MTTCG) */ - snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", - cpu->cpu_index); - - qemu_thread_create(cpu->thread, thread_name, qemu_tcg_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); - - } else { - /* share a single thread for all cpus with TCG */ - snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG"); - qemu_thread_create(cpu->thread, thread_name, - qemu_tcg_rr_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); - - single_tcg_halt_cond = cpu->halt_cond; - single_tcg_cpu_thread = cpu->thread; - } -#ifdef _WIN32 - cpu->hThread = qemu_thread_get_handle(cpu->thread); -#endif - } else { - /* For non-MTTCG cases we share the thread */ - cpu->thread = single_tcg_cpu_thread; - cpu->halt_cond = single_tcg_halt_cond; - cpu->thread_id = first_cpu->thread_id; - cpu->can_do_io = 1; - cpu->created = true; - } -} - static void qemu_hax_start_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -1444,8 +943,6 @@ void qemu_init_vcpu(CPUState *cpu) qemu_hax_start_vcpu(cpu); } else if (hvf_enabled()) { qemu_hvf_start_vcpu(cpu); - } else if (tcg_enabled()) { - qemu_tcg_init_vcpu(cpu); } else if (whpx_enabled()) { qemu_whpx_start_vcpu(cpu); } else { From patchwork Tue Oct 6 07:29:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377236 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=kv3iKfQb; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58JP47cnz9sSs for ; Tue, 6 Oct 2020 18:30:29 +1100 (AEDT) Received: from localhost ([::1]:35482 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhQY-0002Mq-P5 for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:30:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39478) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ2-0002K1-6O for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:54 -0400 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]:44674) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ0-0001NT-9J for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:53 -0400 Received: by mail-wr1-x432.google.com with SMTP id t9so3589513wrq.11 for ; Tue, 06 Oct 2020 00:29:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=81nWIRLht3o1MJNlTnzMkrF2Tl977yTreL4rR+87628=; b=kv3iKfQbiLh1h7z2k/deAoQvq9EvZiFxHy0yfOiZoE0t/8PZbB0vFAe342oxDR1Sn+ xr3y3glLuLqjjESOLlLJNViLHjI2R5z6n561cdT3jjB9RrHDzYXmat00i+TDL8+q6qFr 6jZlrU9M9iPFxuEm8So5XBnECZXqS5Ti1oycfm5WfVmjFolx0F2n/XHTfQLF6FlFrQk7 aHcROyH/qJL/DhfM2uGqeHLT8LAKMyC3OenGcrshkDWCj40BqMP+F14R6IfGk+OWzwdd ccP9ylw5GjRIGtSU0rx8CLHsfPwDyMmgw2Rz1RsPv81D4uWEn8ynxQ7eERuYgr6ZQPL9 D1AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=81nWIRLht3o1MJNlTnzMkrF2Tl977yTreL4rR+87628=; b=s0/6eHTIOcTZ9u+dUqy7/cf1beq3CfBwGpvZpLmGESTHEmMLiRtzL6pc7kPhPGhvnv +9wyWJZi+3ET4OEj1ixYbK33EUCgLIXzYUPrRvaFMm60oltGBM4m7BwSGwV2NUQJtPF/ 9sL7m9/03iqYIK08r0iIbfRSN/L97zBSQMCoCa5BqPbptLElHNwCJmjiepReN4bmwGUH pLCk461R6RToAArUf8I9K69iamj1WV2YyhPKZBEw3H87wwWiWRRqCbOwQMAECnVxOW5b 7XV0D23R36C4rgFOED11Eio+Ce6mMtnMBeDRtfJa3Dh1KAv4qSeXDfBLn0/J6UqY6Jb3 uDEg== X-Gm-Message-State: AOAM5332gWUn0fYLuo31r/od/FJEm1k9wWaxVIvyBHSz87b/8QwyO5Iw msYs6coh72VcN5Itnwql50dEVtxQpvg= X-Google-Smtp-Source: ABdhPJw3S2LjdDggMXzon2SPof4RZHpDO9+/G/LZeEq374kWepGhAexwl8t3klmA6af+iuOdWe7loQ== X-Received: by 2002:adf:cf0c:: with SMTP id o12mr3161965wrj.287.1601969390678; Tue, 06 Oct 2020 00:29:50 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:50 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 05/37] cpus: extract out qtest-specific code to accel/qtest Date: Tue, 6 Oct 2020 09:29:15 +0200 Message-Id: <20201006072947.487729-6-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x432.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana register a "CpusAccel" interface for qtest as well. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- MAINTAINERS | 2 +- accel/meson.build | 2 +- accel/qtest/meson.build | 7 +++ accel/qtest/qtest-cpus.c | 91 +++++++++++++++++++++++++++++++++++++++ accel/qtest/qtest-cpus.h | 17 ++++++++ accel/{ => qtest}/qtest.c | 7 +++ softmmu/cpus.c | 64 +-------------------------- 7 files changed, 125 insertions(+), 65 deletions(-) create mode 100644 accel/qtest/meson.build create mode 100644 accel/qtest/qtest-cpus.c create mode 100644 accel/qtest/qtest-cpus.h rename accel/{ => qtest}/qtest.c (86%) diff --git a/MAINTAINERS b/MAINTAINERS index a59be84de6..ecc45dfac4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2492,7 +2492,7 @@ M: Laurent Vivier R: Paolo Bonzini S: Maintained F: softmmu/qtest.c -F: accel/qtest.c +F: accel/qtest/ F: tests/qtest/ X: tests/qtest/bios-tables-test-allowed-diff.h diff --git a/accel/meson.build b/accel/meson.build index 26c503e480..bb00d0fd13 100644 --- a/accel/meson.build +++ b/accel/meson.build @@ -1,6 +1,6 @@ softmmu_ss.add(files('accel.c')) -specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], if_true: files('qtest.c')) +subdir('qtest') subdir('kvm') subdir('tcg') subdir('xen') diff --git a/accel/qtest/meson.build b/accel/qtest/meson.build new file mode 100644 index 0000000000..e477cb2ae2 --- /dev/null +++ b/accel/qtest/meson.build @@ -0,0 +1,7 @@ +qtest_ss = ss.source_set() +qtest_ss.add(files( + 'qtest.c', + 'qtest-cpus.c', +)) + +specific_ss.add_all(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], if_true: qtest_ss) diff --git a/accel/qtest/qtest-cpus.c b/accel/qtest/qtest-cpus.c new file mode 100644 index 0000000000..7c5399ed9d --- /dev/null +++ b/accel/qtest/qtest-cpus.c @@ -0,0 +1,91 @@ +/* + * QTest accelerator code + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu/rcu.h" +#include "qapi/error.h" +#include "qemu/module.h" +#include "qemu/option.h" +#include "qemu/config-file.h" +#include "sysemu/accel.h" +#include "sysemu/qtest.h" +#include "sysemu/cpus.h" +#include "sysemu/cpu-timers.h" +#include "qemu/guest-random.h" +#include "qemu/main-loop.h" +#include "hw/core/cpu.h" + +#include "qtest-cpus.h" + +static void *qtest_cpu_thread_fn(void *arg) +{ +#ifdef _WIN32 + error_report("qtest is not supported under Windows"); + exit(1); +#else + CPUState *cpu = arg; + sigset_t waitset; + int r; + + rcu_register_thread(); + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id = qemu_get_thread_id(); + cpu->can_do_io = 1; + current_cpu = cpu; + + sigemptyset(&waitset); + sigaddset(&waitset, SIG_IPI); + + /* signal CPU creation */ + cpu_thread_signal_created(cpu); + qemu_guest_random_seed_thread_part2(cpu->random_seed); + + do { + qemu_mutex_unlock_iothread(); + do { + int sig; + r = sigwait(&waitset, &sig); + } while (r == -1 && (errno == EAGAIN || errno == EINTR)); + if (r == -1) { + perror("sigwait"); + exit(1); + } + qemu_mutex_lock_iothread(); + qemu_wait_io_event(cpu); + } while (!cpu->unplug); + + qemu_mutex_unlock_iothread(); + rcu_unregister_thread(); + return NULL; +#endif +} + +static void qtest_start_vcpu_thread(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qtest_cpu_thread_fn, cpu, + QEMU_THREAD_JOINABLE); +} + +const CpusAccel qtest_cpus = { + .create_vcpu_thread = qtest_start_vcpu_thread, + .get_virtual_clock = qtest_get_virtual_clock, +}; diff --git a/accel/qtest/qtest-cpus.h b/accel/qtest/qtest-cpus.h new file mode 100644 index 0000000000..739519a472 --- /dev/null +++ b/accel/qtest/qtest-cpus.h @@ -0,0 +1,17 @@ +/* + * Accelerator CPUS Interface + * + * Copyright 2020 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef QTEST_CPUS_H +#define QTEST_CPUS_H + +#include "sysemu/cpus.h" + +extern const CpusAccel qtest_cpus; + +#endif /* QTEST_CPUS_H */ diff --git a/accel/qtest.c b/accel/qtest/qtest.c similarity index 86% rename from accel/qtest.c rename to accel/qtest/qtest.c index 119d0f16a4..537e8b449c 100644 --- a/accel/qtest.c +++ b/accel/qtest/qtest.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qemu/rcu.h" #include "qapi/error.h" #include "qemu/module.h" #include "qemu/option.h" @@ -20,9 +21,15 @@ #include "sysemu/qtest.h" #include "sysemu/cpus.h" #include "sysemu/cpu-timers.h" +#include "qemu/guest-random.h" +#include "qemu/main-loop.h" +#include "hw/core/cpu.h" + +#include "qtest-cpus.h" static int qtest_init_accel(MachineState *ms) { + cpus_register_accel(&qtest_cpus); return 0; } diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 25f12e3ee9..b14b22161f 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -40,7 +40,6 @@ #include "qemu/thread.h" #include "qemu/plugin.h" #include "sysemu/cpus.h" -#include "sysemu/qtest.h" #include "qemu/main-loop.h" #include "qemu/option.h" #include "qemu/bitmap.h" @@ -247,9 +246,6 @@ int64_t cpus_get_virtual_clock(void) if (cpus_accel && cpus_accel->get_virtual_clock) { return cpus_accel->get_virtual_clock(); } - if (qtest_enabled()) { /* for qtest_clock_warp */ - return qtest_get_virtual_clock(); - } return cpu_get_clock(); } @@ -482,51 +478,6 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) return NULL; } -static void *qemu_dummy_cpu_thread_fn(void *arg) -{ -#ifdef _WIN32 - error_report("qtest is not supported under Windows"); - exit(1); -#else - CPUState *cpu = arg; - sigset_t waitset; - int r; - - rcu_register_thread(); - - qemu_mutex_lock_iothread(); - qemu_thread_get_self(cpu->thread); - cpu->thread_id = qemu_get_thread_id(); - cpu->can_do_io = 1; - current_cpu = cpu; - - sigemptyset(&waitset); - sigaddset(&waitset, SIG_IPI); - - /* signal CPU creation */ - cpu_thread_signal_created(cpu); - qemu_guest_random_seed_thread_part2(cpu->random_seed); - - do { - qemu_mutex_unlock_iothread(); - do { - int sig; - r = sigwait(&waitset, &sig); - } while (r == -1 && (errno == EAGAIN || errno == EINTR)); - if (r == -1) { - perror("sigwait"); - exit(1); - } - qemu_mutex_lock_iothread(); - qemu_wait_io_event(cpu); - } while (!cpu->unplug); - - qemu_mutex_unlock_iothread(); - rcu_unregister_thread(); - return NULL; -#endif -} - static void *qemu_hax_cpu_thread_fn(void *arg) { CPUState *cpu = arg; @@ -904,19 +855,6 @@ void cpus_register_accel(const CpusAccel *ca) cpus_accel = ca; } -static void qemu_dummy_start_vcpu(CPUState *cpu) -{ - char thread_name[VCPU_THREAD_NAME_SIZE]; - - cpu->thread = g_malloc0(sizeof(QemuThread)); - cpu->halt_cond = g_malloc0(sizeof(QemuCond)); - qemu_cond_init(cpu->halt_cond); - snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY", - cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_dummy_cpu_thread_fn, cpu, - QEMU_THREAD_JOINABLE); -} - void qemu_init_vcpu(CPUState *cpu) { MachineState *ms = MACHINE(qdev_get_machine()); @@ -946,7 +884,7 @@ void qemu_init_vcpu(CPUState *cpu) } else if (whpx_enabled()) { qemu_whpx_start_vcpu(cpu); } else { - qemu_dummy_start_vcpu(cpu); + g_assert_not_reached(); } while (!cpu->created) { From patchwork Tue Oct 6 07:29:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377252 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=KAwtw5e8; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Tp3tQTz9sS8 for ; Tue, 6 Oct 2020 18:38:38 +1100 (AEDT) Received: from localhost ([::1]:60862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhYS-0004fX-Bh for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:38:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39502) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ3-0002LV-7B for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:55 -0400 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:38413) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ1-0001Nk-9V for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:54 -0400 Received: by mail-wr1-x42e.google.com with SMTP id n18so4414724wrs.5 for ; Tue, 06 Oct 2020 00:29:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XKuqPTs8be++xZGyvL7rQyJ9PUjeBH7cxBsMq1MMFoo=; b=KAwtw5e8iOJ5mamSKH4eEwV418VOO21t7V8aM5zrfZ9rnx3dV8L6nvjJdbcOOv+w6E 58j/+UceMV5zvnmz89fYomJquCZwh2mLEepumiIUFQOrLAt1EAdxsQONMw6xM2MjNwiK owQia7Eq42mgSiIxX5rVp+fh7DRQrW/uD4rXpexy7WUlAS8quahL+aCNtFaSqxrvqhC2 8Dda1aM9VaoUPUuRx3KI3Nkt1HOrMsyuIGSKZvZLUuoF6ncbYT+pwKtVWQwzrWuN60MX xoFEH44UWyr7Yfro4S/E6+rcGjyA5boA1QBzPkO9Ii08DCAmq6sH/CJYcJrSanGERi+z vsKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=XKuqPTs8be++xZGyvL7rQyJ9PUjeBH7cxBsMq1MMFoo=; b=mGjyR8D8VNesrDnsb00AT6XY4jPyUg4mbn4P1Bv3N+vPxHXCFgF4SSGfldQ3q8CUVM Nt9wx19II+WNpHOqumLHCYFr5Z5H3QtV1wkpaPNPscKiPUhe7D33BOZlDtNbx10Eimub MeBb23RcN7IEGep/7+GHNKTWjzmmmMDh9kH/IVRAroiiauLh4WgG/mLu4naHexOa9ep5 R2LpfEqfau5530/sDRieNb02NKSjhvqcOnTSfvxnqWfm0SeB2Vy3P65XwVHv1zNNg6d3 czxDFhr93dD/OSk4J+vv5pMNIme52Wyo0C0TwaQhw8tFCKV/eowe4LU/V19aYF0p6G5f Ihpw== X-Gm-Message-State: AOAM5330yY1FR4dKw4KLXYTHBG4zzF/RvfQkNV7+3nkTDie575175sMw mLb3N71kT6jxsOv585zxA8mvJ278TWg= X-Google-Smtp-Source: ABdhPJwidL0VhdJBOl6aHNG5w1I79tqZ1w/Q0t4nSPklQWpJaIFyzMYp5zZEODxc7TNFKsW3myktzw== X-Received: by 2002:adf:dd89:: with SMTP id x9mr3555444wrl.25.1601969391559; Tue, 06 Oct 2020 00:29:51 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:51 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 06/37] cpus: extract out kvm-specific code to accel/kvm Date: Tue, 6 Oct 2020 09:29:16 +0200 Message-Id: <20201006072947.487729-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42e; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42e.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , =?utf-8?q?Philippe_Mat?= =?utf-8?q?hieu-Daud=C3=A9?= , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana register a "CpusAccel" interface for KVM as well. Signed-off-by: Claudio Fontana Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé [added const] Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- accel/kvm/kvm-all.c | 14 ++++++- accel/kvm/kvm-cpus.c | 88 ++++++++++++++++++++++++++++++++++++++++++ accel/kvm/kvm-cpus.h | 17 ++++++++ accel/kvm/meson.build | 5 ++- accel/stubs/kvm-stub.c | 3 +- include/sysemu/kvm.h | 2 +- softmmu/cpus.c | 77 ------------------------------------ 7 files changed, 124 insertions(+), 82 deletions(-) create mode 100644 accel/kvm/kvm-cpus.c create mode 100644 accel/kvm/kvm-cpus.h diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index e4bbf78366..784e9dad55 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -44,6 +44,9 @@ #include "qapi/qapi-types-common.h" #include "qapi/qapi-visit-common.h" #include "sysemu/reset.h" +#include "qemu/guest-random.h" +#include "sysemu/hw_accel.h" +#include "kvm-cpus.h" #include "hw/boards.h" @@ -378,7 +381,7 @@ err: return ret; } -int kvm_destroy_vcpu(CPUState *cpu) +static int do_kvm_destroy_vcpu(CPUState *cpu) { KVMState *s = kvm_state; long mmap_size; @@ -412,6 +415,14 @@ err: return ret; } +void kvm_destroy_vcpu(CPUState *cpu) +{ + if (do_kvm_destroy_vcpu(cpu) < 0) { + error_report("kvm_destroy_vcpu failed"); + exit(EXIT_FAILURE); + } +} + static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id) { struct KVMParkedVcpu *cpu; @@ -2232,6 +2243,7 @@ static int kvm_init(MachineState *ms) assert(!ret); } + cpus_register_accel(&kvm_cpus); return 0; err: diff --git a/accel/kvm/kvm-cpus.c b/accel/kvm/kvm-cpus.c new file mode 100644 index 0000000000..a120601564 --- /dev/null +++ b/accel/kvm/kvm-cpus.c @@ -0,0 +1,88 @@ +/* + * QEMU KVM support + * + * Copyright IBM, Corp. 2008 + * Red Hat, Inc. 2008 + * + * Authors: + * Anthony Liguori + * Glauber Costa + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/main-loop.h" +#include "sysemu/kvm_int.h" +#include "sysemu/runstate.h" +#include "sysemu/cpus.h" +#include "qemu/guest-random.h" + +#include "kvm-cpus.h" + +static void *kvm_vcpu_thread_fn(void *arg) +{ + CPUState *cpu = arg; + int r; + + rcu_register_thread(); + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id = qemu_get_thread_id(); + cpu->can_do_io = 1; + current_cpu = cpu; + + r = kvm_init_vcpu(cpu); + if (r < 0) { + error_report("kvm_init_vcpu failed: %s", strerror(-r)); + exit(1); + } + + kvm_init_cpu_signals(cpu); + + /* signal CPU creation */ + cpu_thread_signal_created(cpu); + qemu_guest_random_seed_thread_part2(cpu->random_seed); + + do { + if (cpu_can_run(cpu)) { + r = kvm_cpu_exec(cpu); + if (r == EXCP_DEBUG) { + cpu_handle_guest_debug(cpu); + } + } + qemu_wait_io_event(cpu); + } while (!cpu->unplug || cpu_can_run(cpu)); + + kvm_destroy_vcpu(cpu); + cpu_thread_signal_destroyed(cpu); + qemu_mutex_unlock_iothread(); + rcu_unregister_thread(); + return NULL; +} + +static void kvm_start_vcpu_thread(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, kvm_vcpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +} + +const CpusAccel kvm_cpus = { + .create_vcpu_thread = kvm_start_vcpu_thread, + + .synchronize_post_reset = kvm_cpu_synchronize_post_reset, + .synchronize_post_init = kvm_cpu_synchronize_post_init, + .synchronize_state = kvm_cpu_synchronize_state, + .synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm, +}; diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h new file mode 100644 index 0000000000..547fbee111 --- /dev/null +++ b/accel/kvm/kvm-cpus.h @@ -0,0 +1,17 @@ +/* + * Accelerator CPUS Interface + * + * Copyright 2020 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef KVM_CPUS_H +#define KVM_CPUS_H + +#include "sysemu/cpus.h" + +extern const CpusAccel kvm_cpus; + +#endif /* KVM_CPUS_H */ diff --git a/accel/kvm/meson.build b/accel/kvm/meson.build index 4db2388e2f..7e9dafe24c 100644 --- a/accel/kvm/meson.build +++ b/accel/kvm/meson.build @@ -1,5 +1,8 @@ kvm_ss = ss.source_set() -kvm_ss.add(files('kvm-all.c')) +kvm_ss.add(files( + 'kvm-all.c', + 'kvm-cpus.c', +)) kvm_ss.add(when: 'CONFIG_SEV', if_false: files('sev-stub.c')) specific_ss.add_all(when: 'CONFIG_KVM', if_true: kvm_ss) diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index 82f118d2df..69f8a842da 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -32,9 +32,8 @@ bool kvm_readonly_mem_allowed; bool kvm_ioeventfd_any_length_allowed; bool kvm_msi_use_devid; -int kvm_destroy_vcpu(CPUState *cpu) +void kvm_destroy_vcpu(CPUState *cpu) { - return -ENOSYS; } int kvm_init_vcpu(CPUState *cpu) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 5bbea53883..07937454d2 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -225,7 +225,7 @@ int kvm_has_intx_set_mask(void); int kvm_init_vcpu(CPUState *cpu); int kvm_cpu_exec(CPUState *cpu); -int kvm_destroy_vcpu(CPUState *cpu); +void kvm_destroy_vcpu(CPUState *cpu); /** * kvm_arm_supports_user_irq diff --git a/softmmu/cpus.c b/softmmu/cpus.c index b14b22161f..9fa73735a2 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -179,9 +179,6 @@ void cpu_synchronize_state(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_state) { cpus_accel->synchronize_state(cpu); } - if (kvm_enabled()) { - kvm_cpu_synchronize_state(cpu); - } if (hax_enabled()) { hax_cpu_synchronize_state(cpu); } @@ -195,9 +192,6 @@ void cpu_synchronize_post_reset(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_post_reset) { cpus_accel->synchronize_post_reset(cpu); } - if (kvm_enabled()) { - kvm_cpu_synchronize_post_reset(cpu); - } if (hax_enabled()) { hax_cpu_synchronize_post_reset(cpu); } @@ -211,9 +205,6 @@ void cpu_synchronize_post_init(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_post_init) { cpus_accel->synchronize_post_init(cpu); } - if (kvm_enabled()) { - kvm_cpu_synchronize_post_init(cpu); - } if (hax_enabled()) { hax_cpu_synchronize_post_init(cpu); } @@ -227,9 +218,6 @@ void cpu_synchronize_pre_loadvm(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_pre_loadvm) { cpus_accel->synchronize_pre_loadvm(cpu); } - if (kvm_enabled()) { - kvm_cpu_synchronize_pre_loadvm(cpu); - } if (hax_enabled()) { hax_cpu_synchronize_pre_loadvm(cpu); } @@ -384,14 +372,6 @@ void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data) do_run_on_cpu(cpu, func, data, &qemu_global_mutex); } -static void qemu_kvm_destroy_vcpu(CPUState *cpu) -{ - if (kvm_destroy_vcpu(cpu) < 0) { - error_report("kvm_destroy_vcpu failed"); - exit(EXIT_FAILURE); - } -} - static void qemu_cpu_stop(CPUState *cpu, bool exit) { g_assert(qemu_cpu_is_self(cpu)); @@ -436,48 +416,6 @@ void qemu_wait_io_event(CPUState *cpu) qemu_wait_io_event_common(cpu); } -static void *qemu_kvm_cpu_thread_fn(void *arg) -{ - CPUState *cpu = arg; - int r; - - rcu_register_thread(); - - qemu_mutex_lock_iothread(); - qemu_thread_get_self(cpu->thread); - cpu->thread_id = qemu_get_thread_id(); - cpu->can_do_io = 1; - current_cpu = cpu; - - r = kvm_init_vcpu(cpu); - if (r < 0) { - error_report("kvm_init_vcpu failed: %s", strerror(-r)); - exit(1); - } - - kvm_init_cpu_signals(cpu); - - /* signal CPU creation */ - cpu_thread_signal_created(cpu); - qemu_guest_random_seed_thread_part2(cpu->random_seed); - - do { - if (cpu_can_run(cpu)) { - r = kvm_cpu_exec(cpu); - if (r == EXCP_DEBUG) { - cpu_handle_guest_debug(cpu); - } - } - qemu_wait_io_event(cpu); - } while (!cpu->unplug || cpu_can_run(cpu)); - - qemu_kvm_destroy_vcpu(cpu); - cpu_thread_signal_destroyed(cpu); - qemu_mutex_unlock_iothread(); - rcu_unregister_thread(); - return NULL; -} - static void *qemu_hax_cpu_thread_fn(void *arg) { CPUState *cpu = arg; @@ -801,19 +739,6 @@ static void qemu_hax_start_vcpu(CPUState *cpu) #endif } -static void qemu_kvm_start_vcpu(CPUState *cpu) -{ - char thread_name[VCPU_THREAD_NAME_SIZE]; - - cpu->thread = g_malloc0(sizeof(QemuThread)); - cpu->halt_cond = g_malloc0(sizeof(QemuCond)); - qemu_cond_init(cpu->halt_cond); - snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM", - cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); -} - static void qemu_hvf_start_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -875,8 +800,6 @@ void qemu_init_vcpu(CPUState *cpu) if (cpus_accel) { /* accelerator already implements the CpusAccel interface */ cpus_accel->create_vcpu_thread(cpu); - } else if (kvm_enabled()) { - qemu_kvm_start_vcpu(cpu); } else if (hax_enabled()) { qemu_hax_start_vcpu(cpu); } else if (hvf_enabled()) { From patchwork Tue Oct 6 07:29:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377246 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=sM8kEhid; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Qz3lg2z9sS8 for ; Tue, 6 Oct 2020 18:36:11 +1100 (AEDT) Received: from localhost ([::1]:52428 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhW5-0001AU-2D for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:36:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39526) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ4-0002OH-Dz for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:56 -0400 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]:38416) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ2-0001Nr-5v for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:56 -0400 Received: by mail-wr1-x431.google.com with SMTP id n18so4414774wrs.5 for ; Tue, 06 Oct 2020 00:29:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2EgtVjM3/ycQDYmpVws4Od1mOvuE8ipTuPkscDkDf3k=; b=sM8kEhidy2G4DCu+2AIEBVjGPDyZyzkHjxGp9+hRmS2cJU6VbT2lN78L5iHThyvsDz Xq1dLHDwnsWFa1V6zwtT76mU6WjVk90H4CArOGm5hY3bHUB6B0r+xBRoF5ZNMCgGBX9h KC8AQwnrmPbR0YMMUvfX1GKVDIFd/k5fPdwJB5S00tX5RZFHNaeXgk32/8WgfqyZGzL/ qb007njjYzf7+9/fpDSWFdLnk++2KiTOy7kWTl/cW02Mw9v0gdWlv9k77BWrvz6XrfUh yHtzKmdKzld8xIBTGDM1itn2NyuTKlmBfyriT5bxkmxYguyeGCXYonX/+kOaMFkfDFNc 5J8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=2EgtVjM3/ycQDYmpVws4Od1mOvuE8ipTuPkscDkDf3k=; b=cE/lf84mcrmRfQjRHIyuPecxDSbHHKHUaJO02YZFLKwQx8zFsSR7imcMw8ej3ic2Pw gRgXkG9LshlacjzePPuEPKhMnZVtFD5spnTWPY9bECovJNYJKZiJyiAcd9Ytc9FXNh8B ukJMWnfZm5jCGaGceq4AzDvS3SBtZLs0ITMSZuCFX3lWYVqQQw995kEhaq2Vn/UcVzXL 2MP04wR+Q/9yPizyTwIhr+T+3zH9GnKpQeZi/7VWgfi5bT6OnBrW3HBtA6L7SucUmjsP OiuXrplnCWU8QexLWE0a4EibeMgO6TJxGO2mYsHEDKI1b7GcZZv5qd4BNFjrA1dvGjO9 jO0g== X-Gm-Message-State: AOAM531OMyoynaML07OYuG8lHUktMvmPOa9pgI5wzuN+Fg42I5fy+IO9 VgfFCSzjjP3obFUKHaKsbvXQxUIo0cY= X-Google-Smtp-Source: ABdhPJwMRbMDbCzfTmogEulMjDoZZqJH0M7h2AjoV3GHwDeUjZIjlD3iiLWf3p+up/XsWK+wydOuuw== X-Received: by 2002:a5d:688b:: with SMTP id h11mr3213897wru.319.1601969392418; Tue, 06 Oct 2020 00:29:52 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:51 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 07/37] cpus: extract out hax-specific code to target/i386/ Date: Tue, 6 Oct 2020 09:29:17 +0200 Message-Id: <20201006072947.487729-8-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x431.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana register a "CpusAccel" interface for HAX as well. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- softmmu/cpus.c | 80 +----------------------------------- target/i386/hax-all.c | 6 ++- target/i386/hax-cpus.c | 85 +++++++++++++++++++++++++++++++++++++++ target/i386/hax-cpus.h | 17 ++++++++ target/i386/hax-i386.h | 2 + target/i386/hax-posix.c | 12 ++++++ target/i386/hax-windows.c | 20 +++++++++ target/i386/meson.build | 9 ++++- 8 files changed, 149 insertions(+), 82 deletions(-) create mode 100644 target/i386/hax-cpus.c create mode 100644 target/i386/hax-cpus.h diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 9fa73735a2..900fff827a 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -33,7 +33,6 @@ #include "exec/gdbstub.h" #include "sysemu/hw_accel.h" #include "sysemu/kvm.h" -#include "sysemu/hax.h" #include "sysemu/hvf.h" #include "sysemu/whpx.h" #include "exec/exec-all.h" @@ -179,9 +178,6 @@ void cpu_synchronize_state(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_state) { cpus_accel->synchronize_state(cpu); } - if (hax_enabled()) { - hax_cpu_synchronize_state(cpu); - } if (whpx_enabled()) { whpx_cpu_synchronize_state(cpu); } @@ -192,9 +188,6 @@ void cpu_synchronize_post_reset(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_post_reset) { cpus_accel->synchronize_post_reset(cpu); } - if (hax_enabled()) { - hax_cpu_synchronize_post_reset(cpu); - } if (whpx_enabled()) { whpx_cpu_synchronize_post_reset(cpu); } @@ -205,9 +198,6 @@ void cpu_synchronize_post_init(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_post_init) { cpus_accel->synchronize_post_init(cpu); } - if (hax_enabled()) { - hax_cpu_synchronize_post_init(cpu); - } if (whpx_enabled()) { whpx_cpu_synchronize_post_init(cpu); } @@ -218,9 +208,6 @@ void cpu_synchronize_pre_loadvm(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_pre_loadvm) { cpus_accel->synchronize_pre_loadvm(cpu); } - if (hax_enabled()) { - hax_cpu_synchronize_pre_loadvm(cpu); - } if (hvf_enabled()) { hvf_cpu_synchronize_pre_loadvm(cpu); } @@ -416,35 +403,6 @@ void qemu_wait_io_event(CPUState *cpu) qemu_wait_io_event_common(cpu); } -static void *qemu_hax_cpu_thread_fn(void *arg) -{ - CPUState *cpu = arg; - int r; - - rcu_register_thread(); - qemu_mutex_lock_iothread(); - qemu_thread_get_self(cpu->thread); - - cpu->thread_id = qemu_get_thread_id(); - current_cpu = cpu; - hax_init_vcpu(cpu); - cpu_thread_signal_created(cpu); - qemu_guest_random_seed_thread_part2(cpu->random_seed); - - do { - if (cpu_can_run(cpu)) { - r = hax_smp_cpu_exec(cpu); - if (r == EXCP_DEBUG) { - cpu_handle_guest_debug(cpu); - } - } - - qemu_wait_io_event(cpu); - } while (!cpu->unplug || cpu_can_run(cpu)); - rcu_unregister_thread(); - return NULL; -} - /* The HVF-specific vCPU thread function. This one should only run when the host * CPU supports the VMX "unrestricted guest" feature. */ static void *qemu_hvf_cpu_thread_fn(void *arg) @@ -529,12 +487,6 @@ static void *qemu_whpx_cpu_thread_fn(void *arg) return NULL; } -#ifdef _WIN32 -static void CALLBACK dummy_apc_func(ULONG_PTR unused) -{ -} -#endif - void cpus_kick_thread(CPUState *cpu) { #ifndef _WIN32 @@ -553,10 +505,6 @@ void cpus_kick_thread(CPUState *cpu) if (!qemu_cpu_is_self(cpu)) { if (whpx_enabled()) { whpx_vcpu_kick(cpu); - } else if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) { - fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n", - __func__, GetLastError()); - exit(1); } } #endif @@ -567,14 +515,7 @@ void qemu_cpu_kick(CPUState *cpu) qemu_cond_broadcast(cpu->halt_cond); if (cpus_accel && cpus_accel->kick_vcpu_thread) { cpus_accel->kick_vcpu_thread(cpu); - } else { - if (hax_enabled()) { - /* - * FIXME: race condition with the exit_request check in - * hax_vcpu_hax_exec - */ - cpu->exit_request = 1; - } + } else { /* default */ cpus_kick_thread(cpu); } } @@ -722,23 +663,6 @@ void cpu_remove_sync(CPUState *cpu) qemu_mutex_lock_iothread(); } -static void qemu_hax_start_vcpu(CPUState *cpu) -{ - char thread_name[VCPU_THREAD_NAME_SIZE]; - - cpu->thread = g_malloc0(sizeof(QemuThread)); - cpu->halt_cond = g_malloc0(sizeof(QemuCond)); - qemu_cond_init(cpu->halt_cond); - - snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HAX", - cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_hax_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); -#ifdef _WIN32 - cpu->hThread = qemu_thread_get_handle(cpu->thread); -#endif -} - static void qemu_hvf_start_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -800,8 +724,6 @@ void qemu_init_vcpu(CPUState *cpu) if (cpus_accel) { /* accelerator already implements the CpusAccel interface */ cpus_accel->create_vcpu_thread(cpu); - } else if (hax_enabled()) { - qemu_hax_start_vcpu(cpu); } else if (hvf_enabled()) { qemu_hvf_start_vcpu(cpu); } else if (whpx_enabled()) { diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c index c93bb23a44..b66ddeb8bf 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -32,9 +32,10 @@ #include "sysemu/accel.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" -#include "qemu/main-loop.h" #include "hw/boards.h" +#include "hax-cpus.h" + #define DEBUG_HAX 0 #define DPRINTF(fmt, ...) \ @@ -374,6 +375,9 @@ static int hax_accel_init(MachineState *ms) !ret ? "working" : "not working", !ret ? "fast virt" : "emulation"); } + if (ret == 0) { + cpus_register_accel(&hax_cpus); + } return ret; } diff --git a/target/i386/hax-cpus.c b/target/i386/hax-cpus.c new file mode 100644 index 0000000000..9aad98bc7a --- /dev/null +++ b/target/i386/hax-cpus.c @@ -0,0 +1,85 @@ +/* + * QEMU HAX support + * + * Copyright IBM, Corp. 2008 + * Red Hat, Inc. 2008 + * + * Authors: + * Anthony Liguori + * Glauber Costa + * + * Copyright (c) 2011 Intel Corporation + * Written by: + * Jiang Yunhong + * Xin Xiaohui + * Zhang Xiantao + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/main-loop.h" +#include "hax-i386.h" +#include "sysemu/runstate.h" +#include "sysemu/cpus.h" +#include "qemu/guest-random.h" + +#include "hax-cpus.h" + +static void *hax_cpu_thread_fn(void *arg) +{ + CPUState *cpu = arg; + int r; + + rcu_register_thread(); + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + + cpu->thread_id = qemu_get_thread_id(); + hax_init_vcpu(cpu); + cpu_thread_signal_created(cpu); + qemu_guest_random_seed_thread_part2(cpu->random_seed); + + do { + if (cpu_can_run(cpu)) { + r = hax_smp_cpu_exec(cpu); + if (r == EXCP_DEBUG) { + cpu_handle_guest_debug(cpu); + } + } + + qemu_wait_io_event(cpu); + } while (!cpu->unplug || cpu_can_run(cpu)); + rcu_unregister_thread(); + return NULL; +} + +static void hax_start_vcpu_thread(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HAX", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, hax_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +#ifdef _WIN32 + cpu->hThread = qemu_thread_get_handle(cpu->thread); +#endif +} + +const CpusAccel hax_cpus = { + .create_vcpu_thread = hax_start_vcpu_thread, + .kick_vcpu_thread = hax_kick_vcpu_thread, + + .synchronize_post_reset = hax_cpu_synchronize_post_reset, + .synchronize_post_init = hax_cpu_synchronize_post_init, + .synchronize_state = hax_cpu_synchronize_state, + .synchronize_pre_loadvm = hax_cpu_synchronize_pre_loadvm, +}; diff --git a/target/i386/hax-cpus.h b/target/i386/hax-cpus.h new file mode 100644 index 0000000000..a64417fe2d --- /dev/null +++ b/target/i386/hax-cpus.h @@ -0,0 +1,17 @@ +/* + * Accelerator CPUS Interface + * + * Copyright 2020 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HAX_CPUS_H +#define HAX_CPUS_H + +#include "sysemu/cpus.h" + +extern const CpusAccel hax_cpus; + +#endif /* HAX_CPUS_H */ diff --git a/target/i386/hax-i386.h b/target/i386/hax-i386.h index ec28708185..48c4abe14e 100644 --- a/target/i386/hax-i386.h +++ b/target/i386/hax-i386.h @@ -60,6 +60,8 @@ int hax_inject_interrupt(CPUArchState *env, int vector); struct hax_vm *hax_vm_create(struct hax_state *hax, int max_cpus); int hax_vcpu_run(struct hax_vcpu_state *vcpu); int hax_vcpu_create(int id); +void hax_kick_vcpu_thread(CPUState *cpu); + int hax_sync_vcpu_state(CPUArchState *env, struct vcpu_state_t *state, int set); int hax_sync_msr(CPUArchState *env, struct hax_msr_data *msrs, int set); diff --git a/target/i386/hax-posix.c b/target/i386/hax-posix.c index 5f9d1b803d..6fb7867d11 100644 --- a/target/i386/hax-posix.c +++ b/target/i386/hax-posix.c @@ -16,6 +16,8 @@ #include "target/i386/hax-i386.h" +#include "sysemu/cpus.h" + hax_fd hax_mod_open(void) { int fd = open("/dev/HAX", O_RDWR); @@ -292,3 +294,13 @@ int hax_inject_interrupt(CPUArchState *env, int vector) return ioctl(fd, HAX_VCPU_IOCTL_INTERRUPT, &vector); } + +void hax_kick_vcpu_thread(CPUState *cpu) +{ + /* + * FIXME: race condition with the exit_request check in + * hax_vcpu_hax_exec + */ + cpu->exit_request = 1; + cpus_kick_thread(cpu); +} diff --git a/target/i386/hax-windows.c b/target/i386/hax-windows.c index 863c2bcc19..469b48e608 100644 --- a/target/i386/hax-windows.c +++ b/target/i386/hax-windows.c @@ -463,3 +463,23 @@ int hax_inject_interrupt(CPUArchState *env, int vector) return 0; } } + +static void CALLBACK dummy_apc_func(ULONG_PTR unused) +{ +} + +void hax_kick_vcpu_thread(CPUState *cpu) +{ + /* + * FIXME: race condition with the exit_request check in + * hax_vcpu_hax_exec + */ + cpu->exit_request = 1; + if (!qemu_cpu_is_self(cpu)) { + if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) { + fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n", + __func__, GetLastError()); + exit(1); + } + } +} diff --git a/target/i386/meson.build b/target/i386/meson.build index e0b71ade56..1db619841c 100644 --- a/target/i386/meson.build +++ b/target/i386/meson.build @@ -31,8 +31,13 @@ i386_softmmu_ss.add(files( i386_softmmu_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c')) i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) i386_softmmu_ss.add(when: 'CONFIG_WHPX', if_true: files('whpx-all.c')) -i386_softmmu_ss.add(when: ['CONFIG_POSIX', 'CONFIG_HAX'], if_true: files('hax-all.c', 'hax-mem.c', 'hax-posix.c')) -i386_softmmu_ss.add(when: ['CONFIG_WIN32', 'CONFIG_HAX'], if_true: files('hax-all.c', 'hax-mem.c', 'hax-windows.c')) +i386_softmmu_ss.add(when: 'CONFIG_HAX', if_true: files( + 'hax-all.c', + 'hax-mem.c', + 'hax-cpus.c', +)) +i386_softmmu_ss.add(when: ['CONFIG_HAX', 'CONFIG_POSIX'], if_true: files('hax-posix.c')) +i386_softmmu_ss.add(when: ['CONFIG_HAX', 'CONFIG_WIN32'], if_true: files('hax-windows.c')) subdir('hvf') From patchwork Tue Oct 6 07:29:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377237 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=HgdtKo4U; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58JT25mTz9sSs for ; Tue, 6 Oct 2020 18:30:33 +1100 (AEDT) Received: from localhost ([::1]:35698 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhQd-0002SW-7i for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:30:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39534) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ5-0002Pw-3i for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:57 -0400 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:45339) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ3-0001O7-72 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:56 -0400 Received: by mail-wr1-x42e.google.com with SMTP id e17so3522156wru.12 for ; Tue, 06 Oct 2020 00:29:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4l0KodklduhKlx54LMAJs5VWrUciVPXI+FEJ8wv1X/w=; b=HgdtKo4USm8oUhwzHZJvdI9aTrD3E6hFXaG85E5Tr5OMgKOPByABLaEzFgRlESpH8y Vd26jhEouqHhLVMtz6656371WhX+731tx3INHdWyZOHPYn/CZNWhOBH5qS+k7ICvX/nD gjeaRMlielsxneyBJ7eL/mtceQvcfSUOXhqJcwZSVNNgk05amCaNx37wv41tm5vtKZ2/ kh4Ol95G74reuh2aJ3j0og/EZufBdfPYAmLrMcFt6iOG9BZPAFV5GMe2PQ8XYTKH1mNC rJ/osQdNV0kNhUqnroyRYm2Wtv7OMfMZ1f+Ke9mK011Mzh0J4efgbLSOYHApzQaMD7xf QS4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=4l0KodklduhKlx54LMAJs5VWrUciVPXI+FEJ8wv1X/w=; b=LifQy8L9uM01wKwfM+5YcVuzSPyN7czs270eojtZesbVLwEf7WxMkybpfK5LsEfjp/ nImvH7v3BPIp1uvBbq1GBbXiWH9v6M6lHAKyTpUFnHaRw2SSBoqETXdalVohkhAV+v0y KridPZLzbAyjXK0lhhnQC//iNgG8jizExM78Bc0hRZXR/76DhliPmvwudRGqY47RNNfD Qo0VrVdDi59nKkzh5Cd3xT+BwcVuEZFALfGVHThKdDdNDy6nqC8BDWZTxU8XYrzl97sI a4atcYHLdZ467SvHfgioZXkX7k2s9B7P0TcTaY7LZ6wyGEnDoR84z8YICYiBbtcOo1IQ hEjw== X-Gm-Message-State: AOAM532u06DYwLWucRvSL15pUaaZVAVgtiXOLd2GbsO8RE6uKZdFuvnx gyI/+QdMXODz1Gt3zHZph4WSrIjhy8E= X-Google-Smtp-Source: ABdhPJz7r1aj5ZoBtUeY0bvy2CTL+UscQ6VbubwJIILahQdIqpaFmaTg8gPZQhjQfseY5ORQW+3QfA== X-Received: by 2002:adf:ce05:: with SMTP id p5mr3270193wrn.110.1601969393482; Tue, 06 Oct 2020 00:29:53 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:52 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 08/37] cpus: extract out whpx-specific code to target/i386/ Date: Tue, 6 Oct 2020 09:29:18 +0200 Message-Id: <20201006072947.487729-9-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42e; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42e.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana register a "CpusAccel" interface for WHPX as well. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- MAINTAINERS | 1 + softmmu/cpus.c | 79 --------------------------------- target/i386/meson.build | 5 ++- target/i386/whpx-all.c | 3 ++ target/i386/whpx-cpus.c | 96 +++++++++++++++++++++++++++++++++++++++++ target/i386/whpx-cpus.h | 17 ++++++++ 6 files changed, 121 insertions(+), 80 deletions(-) create mode 100644 target/i386/whpx-cpus.c create mode 100644 target/i386/whpx-cpus.h diff --git a/MAINTAINERS b/MAINTAINERS index ecc45dfac4..231f854437 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -451,6 +451,7 @@ WHPX CPUs M: Sunil Muthuswamy S: Supported F: target/i386/whpx-all.c +F: target/i386/whpx-cpus.c F: target/i386/whp-dispatch.h F: accel/stubs/whpx-stub.c F: include/sysemu/whpx.h diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 900fff827a..067dae12eb 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -34,7 +34,6 @@ #include "sysemu/hw_accel.h" #include "sysemu/kvm.h" #include "sysemu/hvf.h" -#include "sysemu/whpx.h" #include "exec/exec-all.h" #include "qemu/thread.h" #include "qemu/plugin.h" @@ -178,9 +177,6 @@ void cpu_synchronize_state(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_state) { cpus_accel->synchronize_state(cpu); } - if (whpx_enabled()) { - whpx_cpu_synchronize_state(cpu); - } } void cpu_synchronize_post_reset(CPUState *cpu) @@ -188,9 +184,6 @@ void cpu_synchronize_post_reset(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_post_reset) { cpus_accel->synchronize_post_reset(cpu); } - if (whpx_enabled()) { - whpx_cpu_synchronize_post_reset(cpu); - } } void cpu_synchronize_post_init(CPUState *cpu) @@ -198,9 +191,6 @@ void cpu_synchronize_post_init(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_post_init) { cpus_accel->synchronize_post_init(cpu); } - if (whpx_enabled()) { - whpx_cpu_synchronize_post_init(cpu); - } } void cpu_synchronize_pre_loadvm(CPUState *cpu) @@ -211,9 +201,6 @@ void cpu_synchronize_pre_loadvm(CPUState *cpu) if (hvf_enabled()) { hvf_cpu_synchronize_pre_loadvm(cpu); } - if (whpx_enabled()) { - whpx_cpu_synchronize_pre_loadvm(cpu); - } } int64_t cpus_get_virtual_clock(void) @@ -445,48 +432,6 @@ static void *qemu_hvf_cpu_thread_fn(void *arg) return NULL; } -static void *qemu_whpx_cpu_thread_fn(void *arg) -{ - CPUState *cpu = arg; - int r; - - rcu_register_thread(); - - qemu_mutex_lock_iothread(); - qemu_thread_get_self(cpu->thread); - cpu->thread_id = qemu_get_thread_id(); - current_cpu = cpu; - - r = whpx_init_vcpu(cpu); - if (r < 0) { - fprintf(stderr, "whpx_init_vcpu failed: %s\n", strerror(-r)); - exit(1); - } - - /* signal CPU creation */ - cpu_thread_signal_created(cpu); - qemu_guest_random_seed_thread_part2(cpu->random_seed); - - do { - if (cpu_can_run(cpu)) { - r = whpx_vcpu_exec(cpu); - if (r == EXCP_DEBUG) { - cpu_handle_guest_debug(cpu); - } - } - while (cpu_thread_is_idle(cpu)) { - qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); - } - qemu_wait_io_event_common(cpu); - } while (!cpu->unplug || cpu_can_run(cpu)); - - whpx_destroy_vcpu(cpu); - cpu_thread_signal_destroyed(cpu); - qemu_mutex_unlock_iothread(); - rcu_unregister_thread(); - return NULL; -} - void cpus_kick_thread(CPUState *cpu) { #ifndef _WIN32 @@ -501,12 +446,6 @@ void cpus_kick_thread(CPUState *cpu) fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); exit(1); } -#else /* _WIN32 */ - if (!qemu_cpu_is_self(cpu)) { - if (whpx_enabled()) { - whpx_vcpu_kick(cpu); - } - } #endif } @@ -681,22 +620,6 @@ static void qemu_hvf_start_vcpu(CPUState *cpu) cpu, QEMU_THREAD_JOINABLE); } -static void qemu_whpx_start_vcpu(CPUState *cpu) -{ - char thread_name[VCPU_THREAD_NAME_SIZE]; - - cpu->thread = g_malloc0(sizeof(QemuThread)); - cpu->halt_cond = g_malloc0(sizeof(QemuCond)); - qemu_cond_init(cpu->halt_cond); - snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/WHPX", - cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_whpx_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); -#ifdef _WIN32 - cpu->hThread = qemu_thread_get_handle(cpu->thread); -#endif -} - void cpus_register_accel(const CpusAccel *ca) { assert(ca != NULL); @@ -726,8 +649,6 @@ void qemu_init_vcpu(CPUState *cpu) cpus_accel->create_vcpu_thread(cpu); } else if (hvf_enabled()) { qemu_hvf_start_vcpu(cpu); - } else if (whpx_enabled()) { - qemu_whpx_start_vcpu(cpu); } else { g_assert_not_reached(); } diff --git a/target/i386/meson.build b/target/i386/meson.build index 1db619841c..a1a02f3e99 100644 --- a/target/i386/meson.build +++ b/target/i386/meson.build @@ -30,7 +30,10 @@ i386_softmmu_ss.add(files( )) i386_softmmu_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c')) i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) -i386_softmmu_ss.add(when: 'CONFIG_WHPX', if_true: files('whpx-all.c')) +i386_softmmu_ss.add(when: 'CONFIG_WHPX', if_true: files( + 'whpx-all.c', + 'whpx-cpus.c', +)) i386_softmmu_ss.add(when: 'CONFIG_HAX', if_true: files( 'hax-all.c', 'hax-mem.c', diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 2a8fcb68fd..91ee2e59f9 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -24,6 +24,8 @@ #include "migration/blocker.h" #include "whp-dispatch.h" +#include "whpx-cpus.h" + #include #include @@ -1650,6 +1652,7 @@ static int whpx_accel_init(MachineState *ms) whpx_memory_init(); cpu_interrupt_handler = whpx_handle_interrupt; + cpus_register_accel(&whpx_cpus); printf("Windows Hypervisor Platform accelerator is operational\n"); return 0; diff --git a/target/i386/whpx-cpus.c b/target/i386/whpx-cpus.c new file mode 100644 index 0000000000..d9bd5a2d36 --- /dev/null +++ b/target/i386/whpx-cpus.c @@ -0,0 +1,96 @@ +/* + * QEMU Windows Hypervisor Platform accelerator (WHPX) + * + * Copyright Microsoft Corp. 2017 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "sysemu/kvm_int.h" +#include "qemu/main-loop.h" +#include "sysemu/cpus.h" +#include "qemu/guest-random.h" + +#include "sysemu/whpx.h" +#include "whpx-cpus.h" + +#include +#include + +static void *whpx_cpu_thread_fn(void *arg) +{ + CPUState *cpu = arg; + int r; + + rcu_register_thread(); + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id = qemu_get_thread_id(); + current_cpu = cpu; + + r = whpx_init_vcpu(cpu); + if (r < 0) { + fprintf(stderr, "whpx_init_vcpu failed: %s\n", strerror(-r)); + exit(1); + } + + /* signal CPU creation */ + cpu_thread_signal_created(cpu); + qemu_guest_random_seed_thread_part2(cpu->random_seed); + + do { + if (cpu_can_run(cpu)) { + r = whpx_vcpu_exec(cpu); + if (r == EXCP_DEBUG) { + cpu_handle_guest_debug(cpu); + } + } + while (cpu_thread_is_idle(cpu)) { + qemu_cond_wait_iothread(cpu->halt_cond); + } + qemu_wait_io_event_common(cpu); + } while (!cpu->unplug || cpu_can_run(cpu)); + + whpx_destroy_vcpu(cpu); + cpu_thread_signal_destroyed(cpu); + qemu_mutex_unlock_iothread(); + rcu_unregister_thread(); + return NULL; +} + +static void whpx_start_vcpu_thread(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/WHPX", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, whpx_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +#ifdef _WIN32 + cpu->hThread = qemu_thread_get_handle(cpu->thread); +#endif +} + +static void whpx_kick_vcpu_thread(CPUState *cpu) +{ + if (!qemu_cpu_is_self(cpu)) { + whpx_vcpu_kick(cpu); + } +} + +const CpusAccel whpx_cpus = { + .create_vcpu_thread = whpx_start_vcpu_thread, + .kick_vcpu_thread = whpx_kick_vcpu_thread, + + .synchronize_post_reset = whpx_cpu_synchronize_post_reset, + .synchronize_post_init = whpx_cpu_synchronize_post_init, + .synchronize_state = whpx_cpu_synchronize_state, + .synchronize_pre_loadvm = whpx_cpu_synchronize_pre_loadvm, +}; diff --git a/target/i386/whpx-cpus.h b/target/i386/whpx-cpus.h new file mode 100644 index 0000000000..2393944954 --- /dev/null +++ b/target/i386/whpx-cpus.h @@ -0,0 +1,17 @@ +/* + * Accelerator CPUS Interface + * + * Copyright 2020 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef WHPX_CPUS_H +#define WHPX_CPUS_H + +#include "sysemu/cpus.h" + +extern const CpusAccel whpx_cpus; + +#endif /* WHPX_CPUS_H */ From patchwork Tue Oct 6 07:29:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377240 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=mJqWGbwg; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Mz2p7vz9sSs for ; Tue, 6 Oct 2020 18:33:35 +1100 (AEDT) Received: from localhost ([::1]:43778 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhTZ-000652-B1 for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:33:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39562) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ6-0002SR-FE for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:58 -0400 Received: from mail-wm1-x329.google.com ([2a00:1450:4864:20::329]:53625) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ4-0001OS-7B for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:58 -0400 Received: by mail-wm1-x329.google.com with SMTP id f21so1823164wml.3 for ; Tue, 06 Oct 2020 00:29:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yRG/T0HeJHZkMdsvaa0+J6i3DpCw+CAupvrmBr3TGJc=; b=mJqWGbwgcPiJs5iP9Ha8E6jHs60cGEftLKaEZ9L6hnAH38RZzU4gZ6PRE6suwfr07F Y7RShs3Rd9FxRFmRKDaV2o6SR/Slws4Beqsj72CadWlaGC36EdjOZE/Iorx4+S7GZ8TI +LlbGisO2pL/nfl+FV+aMLxlaGrdiD39/NFxkxn9EesUaXXIb9/0d/sIB3cgy9R9jEoH NRrOw5V9qJINwBiM1+WzWkfiaZRbTIpUVlHbGAieiUQjDbUS0DzVVFbqOq+PFy6oggcS 0K7mPNbsSpNPMVRZkR3zi0foH5t7mQJPydzsvwOJeG6apaxDq1FEdphUMJcm6BG7q/3+ AWHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=yRG/T0HeJHZkMdsvaa0+J6i3DpCw+CAupvrmBr3TGJc=; b=GHehzmVhYfff4ECZat9rQgJM9XA5pjtIFxDJ0t0jmJxPAi7vIbc2/z8gHXQyS2Bmg2 4HIxmRYY3ZMBLFMUu0viqJmqsSml+VOtJ0y62fZMkXNoplHvqqIJVXD9ZoKOXl6ok1FA WJcHNttXUqKK9YH21Vo4EILOgA0VxpJxKA7rV5s+fJ6MkX5xfKNhLQyw/7RxTikXO0UU rx3OJl8zRijFihlvEbi9/d+0aNQXYU2MoOsfJ6sQWK4tFMD2HsJk60+5BmkFbZXQVPZC sQd0kCmuIP70MHMrkXrXEWvGP2XFwmLTw8mtWtpXeWwb2lxxYKaiAOUEiO9Pm3oja16/ F/3Q== X-Gm-Message-State: AOAM531cVMPcp60Ih11oWAXf+6dht3mubUlGZFEAR95lNorSpDIEfdQD IrlW6N/FlLIxJc95kCHXyKY7u6YqG88= X-Google-Smtp-Source: ABdhPJwM0xZ+8QciUlLR5A1z8olDImdt3sFxNmLL/O6zMgElWc2M950/rrYQXkA4hvUkSPOl8pLwHA== X-Received: by 2002:a1c:2394:: with SMTP id j142mr3117086wmj.3.1601969394437; Tue, 06 Oct 2020 00:29:54 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:53 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 09/37] cpus: extract out hvf-specific code to target/i386/hvf/ Date: Tue, 6 Oct 2020 09:29:19 +0200 Message-Id: <20201006072947.487729-10-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::329; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x329.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Roman Bolshakov , Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana register a "CpusAccel" interface for HVF as well. Signed-off-by: Claudio Fontana Reviewed-by: Roman Bolshakov [added const] Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- softmmu/cpus.c | 66 ------------------ target/i386/hvf/hvf-cpus.c | 131 ++++++++++++++++++++++++++++++++++++ target/i386/hvf/hvf-cpus.h | 17 +++++ target/i386/hvf/hvf.c | 3 + target/i386/hvf/meson.build | 1 + 5 files changed, 152 insertions(+), 66 deletions(-) create mode 100644 target/i386/hvf/hvf-cpus.c create mode 100644 target/i386/hvf/hvf-cpus.h diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 067dae12eb..adc20eb3de 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -33,7 +33,6 @@ #include "exec/gdbstub.h" #include "sysemu/hw_accel.h" #include "sysemu/kvm.h" -#include "sysemu/hvf.h" #include "exec/exec-all.h" #include "qemu/thread.h" #include "qemu/plugin.h" @@ -198,9 +197,6 @@ void cpu_synchronize_pre_loadvm(CPUState *cpu) if (cpus_accel && cpus_accel->synchronize_pre_loadvm) { cpus_accel->synchronize_pre_loadvm(cpu); } - if (hvf_enabled()) { - hvf_cpu_synchronize_pre_loadvm(cpu); - } } int64_t cpus_get_virtual_clock(void) @@ -390,48 +386,6 @@ void qemu_wait_io_event(CPUState *cpu) qemu_wait_io_event_common(cpu); } -/* The HVF-specific vCPU thread function. This one should only run when the host - * CPU supports the VMX "unrestricted guest" feature. */ -static void *qemu_hvf_cpu_thread_fn(void *arg) -{ - CPUState *cpu = arg; - - int r; - - assert(hvf_enabled()); - - rcu_register_thread(); - - qemu_mutex_lock_iothread(); - qemu_thread_get_self(cpu->thread); - - cpu->thread_id = qemu_get_thread_id(); - cpu->can_do_io = 1; - current_cpu = cpu; - - hvf_init_vcpu(cpu); - - /* signal CPU creation */ - cpu_thread_signal_created(cpu); - qemu_guest_random_seed_thread_part2(cpu->random_seed); - - do { - if (cpu_can_run(cpu)) { - r = hvf_vcpu_exec(cpu); - if (r == EXCP_DEBUG) { - cpu_handle_guest_debug(cpu); - } - } - qemu_wait_io_event(cpu); - } while (!cpu->unplug || cpu_can_run(cpu)); - - hvf_vcpu_destroy(cpu); - cpu_thread_signal_destroyed(cpu); - qemu_mutex_unlock_iothread(); - rcu_unregister_thread(); - return NULL; -} - void cpus_kick_thread(CPUState *cpu) { #ifndef _WIN32 @@ -602,24 +556,6 @@ void cpu_remove_sync(CPUState *cpu) qemu_mutex_lock_iothread(); } -static void qemu_hvf_start_vcpu(CPUState *cpu) -{ - char thread_name[VCPU_THREAD_NAME_SIZE]; - - /* HVF currently does not support TCG, and only runs in - * unrestricted-guest mode. */ - assert(hvf_enabled()); - - cpu->thread = g_malloc0(sizeof(QemuThread)); - cpu->halt_cond = g_malloc0(sizeof(QemuCond)); - qemu_cond_init(cpu->halt_cond); - - snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF", - cpu->cpu_index); - qemu_thread_create(cpu->thread, thread_name, qemu_hvf_cpu_thread_fn, - cpu, QEMU_THREAD_JOINABLE); -} - void cpus_register_accel(const CpusAccel *ca) { assert(ca != NULL); @@ -647,8 +583,6 @@ void qemu_init_vcpu(CPUState *cpu) if (cpus_accel) { /* accelerator already implements the CpusAccel interface */ cpus_accel->create_vcpu_thread(cpu); - } else if (hvf_enabled()) { - qemu_hvf_start_vcpu(cpu); } else { g_assert_not_reached(); } diff --git a/target/i386/hvf/hvf-cpus.c b/target/i386/hvf/hvf-cpus.c new file mode 100644 index 0000000000..817b3d7452 --- /dev/null +++ b/target/i386/hvf/hvf-cpus.c @@ -0,0 +1,131 @@ +/* + * Copyright 2008 IBM Corporation + * 2008 Red Hat, Inc. + * Copyright 2011 Intel Corporation + * Copyright 2016 Veertu, Inc. + * Copyright 2017 The Android Open Source Project + * + * QEMU Hypervisor.framework support + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * This file contain code under public domain from the hvdos project: + * https://github.com/mist64/hvdos + * + * Parts Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/main-loop.h" +#include "sysemu/hvf.h" +#include "sysemu/runstate.h" +#include "target/i386/cpu.h" +#include "qemu/guest-random.h" + +#include "hvf-cpus.h" + +/* + * The HVF-specific vCPU thread function. This one should only run when the host + * CPU supports the VMX "unrestricted guest" feature. + */ +static void *hvf_cpu_thread_fn(void *arg) +{ + CPUState *cpu = arg; + + int r; + + assert(hvf_enabled()); + + rcu_register_thread(); + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + + cpu->thread_id = qemu_get_thread_id(); + cpu->can_do_io = 1; + current_cpu = cpu; + + hvf_init_vcpu(cpu); + + /* signal CPU creation */ + cpu_thread_signal_created(cpu); + qemu_guest_random_seed_thread_part2(cpu->random_seed); + + do { + if (cpu_can_run(cpu)) { + r = hvf_vcpu_exec(cpu); + if (r == EXCP_DEBUG) { + cpu_handle_guest_debug(cpu); + } + } + qemu_wait_io_event(cpu); + } while (!cpu->unplug || cpu_can_run(cpu)); + + hvf_vcpu_destroy(cpu); + cpu_thread_signal_destroyed(cpu); + qemu_mutex_unlock_iothread(); + rcu_unregister_thread(); + return NULL; +} + +static void hvf_start_vcpu_thread(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + /* + * HVF currently does not support TCG, and only runs in + * unrestricted-guest mode. + */ + assert(hvf_enabled()); + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, hvf_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +} + +const CpusAccel hvf_cpus = { + .create_vcpu_thread = hvf_start_vcpu_thread, + + .synchronize_post_reset = hvf_cpu_synchronize_post_reset, + .synchronize_post_init = hvf_cpu_synchronize_post_init, + .synchronize_state = hvf_cpu_synchronize_state, + .synchronize_pre_loadvm = hvf_cpu_synchronize_pre_loadvm, +}; diff --git a/target/i386/hvf/hvf-cpus.h b/target/i386/hvf/hvf-cpus.h new file mode 100644 index 0000000000..262e449fd6 --- /dev/null +++ b/target/i386/hvf/hvf-cpus.h @@ -0,0 +1,17 @@ +/* + * Accelerator CPUS Interface + * + * Copyright 2020 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HVF_CPUS_H +#define HVF_CPUS_H + +#include "sysemu/cpus.h" + +extern const CpusAccel hvf_cpus; + +#endif /* HVF_CPUS_H */ diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index d81f569aed..7ac6987c1b 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -72,6 +72,8 @@ #include "sysemu/accel.h" #include "target/i386/cpu.h" +#include "hvf-cpus.h" + HVFState *hvf_state; static void assert_hvf_ok(hv_return_t ret) @@ -894,6 +896,7 @@ static int hvf_accel_init(MachineState *ms) hvf_state = s; cpu_interrupt_handler = hvf_handle_interrupt; memory_listener_register(&hvf_memory_listener, &address_space_memory); + cpus_register_accel(&hvf_cpus); return 0; } diff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build index c8a43717ee..409c9a3f14 100644 --- a/target/i386/hvf/meson.build +++ b/target/i386/hvf/meson.build @@ -1,5 +1,6 @@ i386_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files( 'hvf.c', + 'hvf-cpus.c', 'x86.c', 'x86_cpuid.c', 'x86_decode.c', From patchwork Tue Oct 6 07:29:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377256 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Ob51tosD; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Wq5tGrz9sS8 for ; Tue, 6 Oct 2020 18:40:23 +1100 (AEDT) Received: from localhost ([::1]:41084 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPha9-00088q-N9 for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:40:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39558) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ6-0002S9-AJ for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:58 -0400 Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]:36541) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ4-0001Od-RT for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:58 -0400 Received: by mail-wr1-x42c.google.com with SMTP id z1so12223703wrt.3 for ; Tue, 06 Oct 2020 00:29:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XxU4JUy0D8PVTLSMbq2V+3PgAaQreqZ5rvwSi2NUvwk=; b=Ob51tosDyW2KApUJTZUWjhiBmWvKH4VpcNnK9j6A+zQrWhTnE/lqCn7Ai/Tlw3M+ZW 0KALosaH8ZxMro6bv4Rguwc+WyUai6h2ebtzAdpSj2bDqAzHLiBJp1p3ciTF85FgwmtN 4iKa8pjkuPopMM7jtz9NPFL7uiqrQTipbwKtMdB/Ru6XVwHYH1PlB70WmE0oTsllDEIQ coIAzU7CFjt4H2k1OXZLwjoohPxCr2RDfqTas0owc+zDgJ1NGHXC8eJ7F/iVegmHI6ni PUZWLyk8ZChQ2Urp0WB1i0VgWG48tvTcxNPxgEB3bI+lpK/+l2XLaPkxwTJv72iLuwXQ O6tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=XxU4JUy0D8PVTLSMbq2V+3PgAaQreqZ5rvwSi2NUvwk=; b=JLy3LdL9CWeXyYu6EVZSIoyT0SlWWzXCB8qvClS4XQd6SCpRB6PMf/EqZhSzhWUyiB LquO7NRY3GzTFfcB+n3K8i7lDkgxi/AlfCxVFgw63dEalsMpIaQ7PLoOS0+TkIYx6Iib F7JtSjIHKczMm5OW18X5qsYjLq9L3FTEi1dKsJi3s5/7D8Qb/NMeQdH4tUyL0giITTdh oprbBADlPFA3dytxSaylxS/aXFhzbbfIi7UK3Wwz8RYYlzgxD/d26r2DPz9Lo4rQDZ+q yeaTItO/qVqYh/6ZR491aZfpeJa7Q8S7ZycHWXlldk/i+poA0cWOXBAsWE6kjFcOePZ6 o5YQ== X-Gm-Message-State: AOAM531F8UqnW0KqHXsF5LVIue6de9EWVTvWbn7GrlTOuN+AG20ZOpfz gvjCFqiBVyfJ4yYYNpkNtW18rTyqfQ8= X-Google-Smtp-Source: ABdhPJzaxJ9eQ6RMMm1H6MLLJwHvmI1z9xvwMN7+Xo1+uQDn1Xa2ZvZiC+qQF2Am+tO2BtPX2kVcLg== X-Received: by 2002:adf:f552:: with SMTP id j18mr3536256wrp.128.1601969395331; Tue, 06 Oct 2020 00:29:55 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:54 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 10/37] cpus: cleanup now unneeded includes Date: Tue, 6 Oct 2020 09:29:20 +0200 Message-Id: <20201006072947.487729-11-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42c; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42c.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Reviewed-by: Alex Bennée Signed-off-by: Paolo Bonzini --- softmmu/cpus.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/softmmu/cpus.c b/softmmu/cpus.c index adc20eb3de..1180103ede 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -29,20 +29,13 @@ #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-events-run-state.h" #include "qapi/qmp/qerror.h" -#include "sysemu/tcg.h" #include "exec/gdbstub.h" #include "sysemu/hw_accel.h" -#include "sysemu/kvm.h" #include "exec/exec-all.h" #include "qemu/thread.h" #include "qemu/plugin.h" #include "sysemu/cpus.h" -#include "qemu/main-loop.h" -#include "qemu/option.h" -#include "qemu/bitmap.h" -#include "qemu/seqlock.h" #include "qemu/guest-random.h" -#include "tcg/tcg.h" #include "hw/nmi.h" #include "sysemu/replay.h" #include "sysemu/runstate.h" From patchwork Tue Oct 6 07:29:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377251 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=I5RxjlOy; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Tb6tpdz9sS8 for ; Tue, 6 Oct 2020 18:38:27 +1100 (AEDT) Received: from localhost ([::1]:60612 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhYH-0004Ya-So for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:38:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39590) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ7-0002Vm-M5 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:59 -0400 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]:34653) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ5-0001Ow-Vv for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:29:59 -0400 Received: by mail-wm1-x336.google.com with SMTP id l15so1591244wmh.1 for ; Tue, 06 Oct 2020 00:29:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uRdMRxER7cb8oQTA+SlFFqVRv1uiq/QJ/9qurTpeFuY=; b=I5RxjlOyRFyDCOx7B2cHVipakBL84ekWCpjwOvzgBsEmNxB62h9R+u9yxpvDaFcykg dBzb4k9fzdlGBNYybAa09bN/8qIBzhR86PqinruMgjYuQCkw7tHrTYlhYtSJWMAEIdAg 8RJmEaTDYvHWkc8LdoMCva5cOlIli3SPLExfnsflP6e1Rcl4qVoP4BFMROQ1oaf/6oL0 ljKLf94Jv+GupLHuG3UKWH0zJfKCWcHFr+kxUOxXHC9Mf4sblx9iYkUNZRv0uWKPb0MX BFrn/qGvC+gkvSpMzFkR59qmO2VMdmHi7EIIduy9Oxhl+EqRp5pZmDdR7qQPUM45MNzY X6gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=uRdMRxER7cb8oQTA+SlFFqVRv1uiq/QJ/9qurTpeFuY=; b=YDK5s6VMASCD+734IRRhbZaQoCLC9+R2AKj9YrnciDVVWtwaGwZjd2wdexyhfmeGqf PR0ph4cC4f0kLuHWemTAkxxf7QQSPsWyKOoY3+/CASdg+OuwfFQ7b11IDJJTGzCz7wPR tCvgZgAiYh4TGT/wyBmb7ZfdMdiIOeo6z3NQP/4zaI/C+UJiSHDA4pH+tPQSQPNK69ju tfiqQwdhHhyuxAS934vvcngc6eHw982DZqW77lWriHNUK5UocJYa/waDsiHBs6m/Rf9H /ccKYrjXBHJbwn+tNy9pmGl1kSLJhHCd2tY6ZsnQdJ21b8NnXZ+lGUwo8apuHJO34opn mW7Q== X-Gm-Message-State: AOAM531EmuzSgozXoBsxNwmFABUwRsJYklqhpl+5lZwQq8zzj0prCwI0 0EK7spvcx0Ue90W06qQnM5qIJju8HdY= X-Google-Smtp-Source: ABdhPJx0qPeCsMpmH7psxhr6lfDulKqVL9lep2Umi6rMuFnwdJXvTAwgahb/0mQMebOPcvGjIpdX+Q== X-Received: by 2002:a1c:2cc4:: with SMTP id s187mr3289979wms.30.1601969396276; Tue, 06 Oct 2020 00:29:56 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:55 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 11/37] cpus: remove checks for non-NULL cpus_accel Date: Tue, 6 Oct 2020 09:29:21 +0200 Message-Id: <20201006072947.487729-12-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::336; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x336.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana now that all accelerators support the CpusAccel interface, we can remove most checks for non-NULL cpus_accel, we just add a sanity check/assert at vcpu creation. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- softmmu/cpus.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 1180103ede..99f418437b 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -166,34 +166,46 @@ void cpu_synchronize_all_pre_loadvm(void) void cpu_synchronize_state(CPUState *cpu) { - if (cpus_accel && cpus_accel->synchronize_state) { + if (cpus_accel->synchronize_state) { cpus_accel->synchronize_state(cpu); } } void cpu_synchronize_post_reset(CPUState *cpu) { - if (cpus_accel && cpus_accel->synchronize_post_reset) { + if (cpus_accel->synchronize_post_reset) { cpus_accel->synchronize_post_reset(cpu); } } void cpu_synchronize_post_init(CPUState *cpu) { - if (cpus_accel && cpus_accel->synchronize_post_init) { + if (cpus_accel->synchronize_post_init) { cpus_accel->synchronize_post_init(cpu); } } void cpu_synchronize_pre_loadvm(CPUState *cpu) { - if (cpus_accel && cpus_accel->synchronize_pre_loadvm) { + if (cpus_accel->synchronize_pre_loadvm) { cpus_accel->synchronize_pre_loadvm(cpu); } } int64_t cpus_get_virtual_clock(void) { + /* + * XXX + * + * need to check that cpus_accel is not NULL, because qcow2 calls + * qemu_get_clock_ns(CLOCK_VIRTUAL) without any accel initialized and + * with ticks disabled in some io-tests: + * 030 040 041 060 099 120 127 140 156 161 172 181 191 192 195 203 229 249 256 267 + * + * is this expected? + * + * XXX + */ if (cpus_accel && cpus_accel->get_virtual_clock) { return cpus_accel->get_virtual_clock(); } @@ -207,7 +219,7 @@ int64_t cpus_get_virtual_clock(void) */ int64_t cpus_get_elapsed_ticks(void) { - if (cpus_accel && cpus_accel->get_elapsed_ticks) { + if (cpus_accel->get_elapsed_ticks) { return cpus_accel->get_elapsed_ticks(); } return cpu_get_ticks(); @@ -399,7 +411,7 @@ void cpus_kick_thread(CPUState *cpu) void qemu_cpu_kick(CPUState *cpu) { qemu_cond_broadcast(cpu->halt_cond); - if (cpus_accel && cpus_accel->kick_vcpu_thread) { + if (cpus_accel->kick_vcpu_thread) { cpus_accel->kick_vcpu_thread(cpu); } else { /* default */ cpus_kick_thread(cpu); @@ -573,12 +585,9 @@ void qemu_init_vcpu(CPUState *cpu) cpu_address_space_init(cpu, 0, "cpu-memory", cpu->memory); } - if (cpus_accel) { - /* accelerator already implements the CpusAccel interface */ - cpus_accel->create_vcpu_thread(cpu); - } else { - g_assert_not_reached(); - } + /* accelerators all implement the CpusAccel interface */ + g_assert(cpus_accel != NULL && cpus_accel->create_vcpu_thread != NULL); + cpus_accel->create_vcpu_thread(cpu); while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); From patchwork Tue Oct 6 07:29:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377260 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=L1FAcjUM; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58ZT0xb1z9sS8 for ; Tue, 6 Oct 2020 18:42:41 +1100 (AEDT) Received: from localhost ([::1]:49194 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhcN-0003Ap-4P for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:42:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39612) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ8-0002YL-Lg for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:00 -0400 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]:35322) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ6-0001P2-O2 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:00 -0400 Received: by mail-wr1-x42d.google.com with SMTP id n15so6471692wrq.2 for ; Tue, 06 Oct 2020 00:29:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tRws1uvIR8Dz3INqgE4H34M7MpVxrffO/G7ZokVze8I=; b=L1FAcjUMlpcIFb/Kk2sdWXvlPST3jkAV7iM8DAil5+XLFcC/Z0ppi+HhLtWFDZ0S6b up8zp1f58+z9+nB7Vazg9UtSPKAPU6eWDEegX1d2hphj31cRo/WYy4k7ENVMrU31eg9l Ou46+lAcKxdCMIUr+OA0YT13uLNYLygZosQib4EpMP1j6b6jqnfgjnn3LSXQQd7+jCDa kwrlbDgxUZ81rpqt5sgIGxu/ImS8rDOhNStLvcN24tVoa1/VNXsyTwVRWeG8BnkaQ2fE ryVU57LfYvZDvgk/fOGeyWYKLtSEAiSAfSj/+sPbti63EFeNb2ItcoZXxyfnj+Lf6QV8 JGeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=tRws1uvIR8Dz3INqgE4H34M7MpVxrffO/G7ZokVze8I=; b=nk7mFhCvDOfMLyYowQCF9fgRjXAEJgmny9LlXpsGKPh7k50fl3z+7Src5Wt8MoQG44 lgpocXekAroutDOoq4yIElR9Kwot9d94vv586L+jGbr2tzlWFO8sto+m+eHUJbNBSXJm DmNth/1JhQKpA0BNzrRmujJrLhbirD3fTyCdyeA7ZqZulXBHkNtOW1hakNJaHq9j1XMn p7cQNmwhOwyWIdICTPCXZQWbX9kXXyqLGmZ0cUppYKQaBIISquB2ZNptZrCs4DI9UcUZ eMX8GVSywvKVjL/AHYQEZCglKcVy+RkACv08rmAKvB1Ke1Kgb49tiyJqo5d7JK7CX/Wf EIwg== X-Gm-Message-State: AOAM530Dwl87kK48Vc+IJtWY+zuu/3L0R4zsV0/jSTVbs4UjCkJjyGfZ r4dJU1JRUSCVyJuxth7y7DG9hm9N7/w= X-Google-Smtp-Source: ABdhPJy27qF6i1D8bTgsJwrG/kcbU7+RUjK4jy3UdjFEKK8GriZ1YTNizl5gfT7CTgxvhSaksNUonw== X-Received: by 2002:adf:f3d2:: with SMTP id g18mr3199826wrp.367.1601969397024; Tue, 06 Oct 2020 00:29:57 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:56 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 12/37] cpus: add handle_interrupt to the CpusAccel interface Date: Tue, 6 Oct 2020 09:29:22 +0200 Message-Id: <20201006072947.487729-13-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42d; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42d.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana kvm: uses the generic handler qtest: uses the generic handler whpx: changed to use the generic handler (identical implementation) hax: changed to use the generic handler (identical implementation) hvf: changed to use the generic handler (identical implementation) tcg: adapt tcg-cpus to point to the tcg-specific handler Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- accel/tcg/tcg-all.c | 26 -------------------------- accel/tcg/tcg-cpus.c | 28 ++++++++++++++++++++++++++++ hw/core/cpu.c | 13 ------------- include/hw/core/cpu.h | 14 -------------- include/sysemu/cpus.h | 2 ++ softmmu/cpus.c | 18 ++++++++++++++++++ target/i386/hax-all.c | 10 ---------- target/i386/hvf/hvf.c | 9 --------- target/i386/whpx-all.c | 10 ---------- 9 files changed, 48 insertions(+), 82 deletions(-) diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c index 000fe4dbd9..fa1208158f 100644 --- a/accel/tcg/tcg-all.c +++ b/accel/tcg/tcg-all.c @@ -47,31 +47,6 @@ typedef struct TCGState TCGState; DECLARE_INSTANCE_CHECKER(TCGState, TCG_STATE, TYPE_TCG_ACCEL) -/* mask must never be zero, except for A20 change call */ -static void tcg_handle_interrupt(CPUState *cpu, int mask) -{ - int old_mask; - g_assert(qemu_mutex_iothread_locked()); - - old_mask = cpu->interrupt_request; - cpu->interrupt_request |= mask; - - /* - * If called from iothread context, wake the target cpu in - * case its halted. - */ - if (!qemu_cpu_is_self(cpu)) { - qemu_cpu_kick(cpu); - } else { - qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1); - if (icount_enabled() && - !cpu->can_do_io - && (mask & ~old_mask) != 0) { - cpu_abort(cpu, "Raised interrupt while not in I/O function"); - } - } -} - /* * We default to false if we know other options have been enabled * which are currently incompatible with MTTCG. Otherwise when each @@ -128,7 +103,6 @@ static int tcg_init(MachineState *ms) TCGState *s = TCG_STATE(current_accel()); tcg_exec_init(s->tb_size * 1024 * 1024); - cpu_interrupt_handler = tcg_handle_interrupt; mttcg_enabled = s->mttcg_enabled; cpus_register_accel(&tcg_cpus); diff --git a/accel/tcg/tcg-cpus.c b/accel/tcg/tcg-cpus.c index 4f15c7f0de..cedd1e6c4f 100644 --- a/accel/tcg/tcg-cpus.c +++ b/accel/tcg/tcg-cpus.c @@ -543,9 +543,37 @@ static int64_t tcg_get_elapsed_ticks(void) return cpu_get_ticks(); } +/* mask must never be zero, except for A20 change call */ +static void tcg_handle_interrupt(CPUState *cpu, int mask) +{ + int old_mask; + g_assert(qemu_mutex_iothread_locked()); + + old_mask = cpu->interrupt_request; + cpu->interrupt_request |= mask; + + /* + * If called from iothread context, wake the target cpu in + * case its halted. + */ + if (!qemu_cpu_is_self(cpu)) { + qemu_cpu_kick(cpu); + } else { + qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1); + if (icount_enabled() && + !cpu->can_do_io + && (mask & ~old_mask) != 0) { + cpu_abort(cpu, "Raised interrupt while not in I/O function"); + } + } +} + const CpusAccel tcg_cpus = { .create_vcpu_thread = tcg_start_vcpu_thread, .kick_vcpu_thread = tcg_kick_vcpu_thread, + + .handle_interrupt = tcg_handle_interrupt, + .get_virtual_clock = tcg_get_virtual_clock, .get_elapsed_ticks = tcg_get_elapsed_ticks, }; diff --git a/hw/core/cpu.c b/hw/core/cpu.c index d596182621..8654550d39 100644 --- a/hw/core/cpu.c +++ b/hw/core/cpu.c @@ -35,8 +35,6 @@ #include "qemu/plugin.h" #include "sysemu/hw_accel.h" -CPUInterruptHandler cpu_interrupt_handler; - CPUState *cpu_by_arch_id(int64_t id) { CPUState *cpu; @@ -394,17 +392,6 @@ static vaddr cpu_adjust_watchpoint_address(CPUState *cpu, vaddr addr, int len) return addr; } -static void generic_handle_interrupt(CPUState *cpu, int mask) -{ - cpu->interrupt_request |= mask; - - if (!qemu_cpu_is_self(cpu)) { - qemu_cpu_kick(cpu); - } -} - -CPUInterruptHandler cpu_interrupt_handler = generic_handle_interrupt; - static void cpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 6c34798c8b..4879f25026 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -844,12 +844,6 @@ bool cpu_exists(int64_t id); */ CPUState *cpu_by_arch_id(int64_t id); -#ifndef CONFIG_USER_ONLY - -typedef void (*CPUInterruptHandler)(CPUState *, int); - -extern CPUInterruptHandler cpu_interrupt_handler; - /** * cpu_interrupt: * @cpu: The CPU to set an interrupt on. @@ -857,17 +851,9 @@ extern CPUInterruptHandler cpu_interrupt_handler; * * Invokes the interrupt handler. */ -static inline void cpu_interrupt(CPUState *cpu, int mask) -{ - cpu_interrupt_handler(cpu, mask); -} - -#else /* USER_ONLY */ void cpu_interrupt(CPUState *cpu, int mask); -#endif /* USER_ONLY */ - #ifdef NEED_CPU_H #ifdef CONFIG_SOFTMMU diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 26171697f5..231685955d 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -16,6 +16,8 @@ typedef struct CpusAccel { void (*synchronize_state)(CPUState *cpu); void (*synchronize_pre_loadvm)(CPUState *cpu); + void (*handle_interrupt)(CPUState *cpu, int mask); + int64_t (*get_virtual_clock)(void); int64_t (*get_elapsed_ticks)(void); } CpusAccel; diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 99f418437b..f3d0c59f78 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -225,6 +225,24 @@ int64_t cpus_get_elapsed_ticks(void) return cpu_get_ticks(); } +static void generic_handle_interrupt(CPUState *cpu, int mask) +{ + cpu->interrupt_request |= mask; + + if (!qemu_cpu_is_self(cpu)) { + qemu_cpu_kick(cpu); + } +} + +void cpu_interrupt(CPUState *cpu, int mask) +{ + if (cpus_accel->handle_interrupt) { + cpus_accel->handle_interrupt(cpu, mask); + } else { + generic_handle_interrupt(cpu, mask); + } +} + static int do_vm_stop(RunState state, bool send_stop) { int ret = 0; diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c index b66ddeb8bf..fd1ab673d7 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -297,15 +297,6 @@ int hax_vm_destroy(struct hax_vm *vm) return 0; } -static void hax_handle_interrupt(CPUState *cpu, int mask) -{ - cpu->interrupt_request |= mask; - - if (!qemu_cpu_is_self(cpu)) { - qemu_cpu_kick(cpu); - } -} - static int hax_init(ram_addr_t ram_size, int max_cpus) { struct hax_state *hax = NULL; @@ -350,7 +341,6 @@ static int hax_init(ram_addr_t ram_size, int max_cpus) qversion.cur_version = hax_cur_version; qversion.min_version = hax_min_version; hax_notify_qemu_version(hax->vm->fd, &qversion); - cpu_interrupt_handler = hax_handle_interrupt; return ret; error: diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 7ac6987c1b..ed9356565c 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -262,14 +262,6 @@ static void update_apic_tpr(CPUState *cpu) #define VECTORING_INFO_VECTOR_MASK 0xff -static void hvf_handle_interrupt(CPUState * cpu, int mask) -{ - cpu->interrupt_request |= mask; - if (!qemu_cpu_is_self(cpu)) { - qemu_cpu_kick(cpu); - } -} - void hvf_handle_io(CPUArchState *env, uint16_t port, void *buffer, int direction, int size, int count) { @@ -894,7 +886,6 @@ static int hvf_accel_init(MachineState *ms) } hvf_state = s; - cpu_interrupt_handler = hvf_handle_interrupt; memory_listener_register(&hvf_memory_listener, &address_space_memory); cpus_register_accel(&hvf_cpus); return 0; diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index 91ee2e59f9..f4f3e33eac 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -1488,15 +1488,6 @@ static void whpx_memory_init(void) memory_listener_register(&whpx_memory_listener, &address_space_memory); } -static void whpx_handle_interrupt(CPUState *cpu, int mask) -{ - cpu->interrupt_request |= mask; - - if (!qemu_cpu_is_self(cpu)) { - qemu_cpu_kick(cpu); - } -} - /* * Load the functions from the given library, using the given handle. If a * handle is provided, it is used, otherwise the library is opened. The @@ -1651,7 +1642,6 @@ static int whpx_accel_init(MachineState *ms) whpx_memory_init(); - cpu_interrupt_handler = whpx_handle_interrupt; cpus_register_accel(&whpx_cpus); printf("Windows Hypervisor Platform accelerator is operational\n"); From patchwork Tue Oct 6 07:29:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377263 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=erWuw/tT; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58dg0kSFz9sS8 for ; Tue, 6 Oct 2020 18:45:27 +1100 (AEDT) Received: from localhost ([::1]:57398 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhf1-0006bF-Rt for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:45:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39618) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQ9-0002a5-A7 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:01 -0400 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:34803) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ7-0001PF-Ix for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:00 -0400 Received: by mail-wr1-x42e.google.com with SMTP id t10so12238520wrv.1 for ; Tue, 06 Oct 2020 00:29:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9PshzEAxmiySI9dhZtBtR355rxrVnXQvCn9xhLCKJkQ=; b=erWuw/tTrQOciYA3Lcrl2WoB16Tdz86cx/DocAcFkleWpI+PCVV8L0BdrCjfWmyb4V oeVB1ez7OrxeZ86SoojM75st1Z3FllW7RKSH7VEiz6AzkB/2j2w3Wqh8ROGukkfsxFiR bvO5k1vcvKsIizySpuysRnaDn7n3aGRB/wuDrOIrUUFGPyMRNOSOiaNK2yrnv2AQQIP/ QKfHN8TFituJvDGZqJHooivdKGH2fSlV5MI2Opbuklz44pT90bCDgxaT0AVXPijfAbVj b8YpBm0me4am0WmszDxf4Nx30e7UE30Hc4JvhwuF+5tje1OJKm/jaXwKBCe6bwQINiWY 7Y3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=9PshzEAxmiySI9dhZtBtR355rxrVnXQvCn9xhLCKJkQ=; b=qiV39+n6AvNvyYqBPR4UMvge3IX4q+jQij4/wwQE3fWqBUUJehQ3uF3VlW/b1BQ/IR L0jE5yVvm4JR6VgrTat8HUuyp5SLn/wERivIh/7JNqD3HyWFdKaRVeRGW28+BLelkQ/+ Y7ODxbdUIkiTdGrXiok+vIPJyjOC9PS7R/OzD5J3k7M2lHSXq99G5VkZoNkKZ0RTqM1N VjXaJJxNKo9gBCnw3kyK4W8zD2NOhN1DJUdl6DjPnQOvmPPafIxcptwaoX+BacRiN8Pm IBXQpt/B4HwrWFTHs0ih8dbrXZa6lvEukm7yySv+2EyKJYyRVkpoTmIGrsh0m7kW3eCV JpRA== X-Gm-Message-State: AOAM531/AhH3RgRLUKFyAnBA/LX3NPW2bYH4NdLjCIlbnTvzmdh6CR6V WBweSzk+aM2Y6qtdoDLHdklxUgrgIvc= X-Google-Smtp-Source: ABdhPJwgTEK6MiFUpJIMB6EYM26uvEshkTm8TD9FUxDEIPCwWitk55xdKMrd6c/u4itL4GgGglaZgg== X-Received: by 2002:adf:dd51:: with SMTP id u17mr3241648wrm.355.1601969398048; Tue, 06 Oct 2020 00:29:58 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:57 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 13/37] hvf: remove hvf specific functions from global includes Date: Tue, 6 Oct 2020 09:29:23 +0200 Message-Id: <20201006072947.487729-14-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42e; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42e.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Roman Bolshakov , Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Reviewed-by: Roman Bolshakov Signed-off-by: Paolo Bonzini --- accel/stubs/hvf-stub.c | 30 ------------------------------ accel/stubs/meson.build | 1 - include/sysemu/hvf.h | 8 -------- target/i386/hvf/hvf-cpus.h | 8 ++++++++ target/i386/hvf/x86hvf.c | 2 ++ target/i386/hvf/x86hvf.h | 1 - 6 files changed, 10 insertions(+), 40 deletions(-) delete mode 100644 accel/stubs/hvf-stub.c diff --git a/accel/stubs/hvf-stub.c b/accel/stubs/hvf-stub.c deleted file mode 100644 index e81dfe888c..0000000000 --- a/accel/stubs/hvf-stub.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * QEMU HVF support - * - * Copyright 2017 Red Hat, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2 or later, as published by the Free Software Foundation, - * and may be copied, distributed, and modified under those terms. - * - * See the COPYING file in the top-level directory. - * - */ - -#include "qemu/osdep.h" -#include "cpu.h" -#include "sysemu/hvf.h" - -int hvf_init_vcpu(CPUState *cpu) -{ - return -ENOSYS; -} - -int hvf_vcpu_exec(CPUState *cpu) -{ - return -ENOSYS; -} - -void hvf_vcpu_destroy(CPUState *cpu) -{ -} diff --git a/accel/stubs/meson.build b/accel/stubs/meson.build index 314e3cfff4..3fbe34e5bb 100644 --- a/accel/stubs/meson.build +++ b/accel/stubs/meson.build @@ -1,6 +1,5 @@ specific_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c')) specific_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c')) -specific_ss.add(when: 'CONFIG_HVF', if_false: files('hvf-stub.c')) specific_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) specific_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c')) specific_ss.add(when: 'CONFIG_WHPX', if_false: files('whpx-stub.c')) diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h index 1398679458..f893768df9 100644 --- a/include/sysemu/hvf.h +++ b/include/sysemu/hvf.h @@ -26,14 +26,6 @@ extern bool hvf_allowed; #define hvf_get_supported_cpuid(func, idx, reg) 0 #endif /* !CONFIG_HVF */ -int hvf_init_vcpu(CPUState *); -int hvf_vcpu_exec(CPUState *); -void hvf_cpu_synchronize_state(CPUState *); -void hvf_cpu_synchronize_post_reset(CPUState *); -void hvf_cpu_synchronize_post_init(CPUState *); -void hvf_cpu_synchronize_pre_loadvm(CPUState *); -void hvf_vcpu_destroy(CPUState *); - #define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf") typedef struct HVFState HVFState; diff --git a/target/i386/hvf/hvf-cpus.h b/target/i386/hvf/hvf-cpus.h index 262e449fd6..ced31b82c0 100644 --- a/target/i386/hvf/hvf-cpus.h +++ b/target/i386/hvf/hvf-cpus.h @@ -14,4 +14,12 @@ extern const CpusAccel hvf_cpus; +int hvf_init_vcpu(CPUState *); +int hvf_vcpu_exec(CPUState *); +void hvf_cpu_synchronize_state(CPUState *); +void hvf_cpu_synchronize_post_reset(CPUState *); +void hvf_cpu_synchronize_post_init(CPUState *); +void hvf_cpu_synchronize_pre_loadvm(CPUState *); +void hvf_vcpu_destroy(CPUState *); + #endif /* HVF_CPUS_H */ diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c index 5cbcb32ab6..b986213c0f 100644 --- a/target/i386/hvf/x86hvf.c +++ b/target/i386/hvf/x86hvf.c @@ -32,6 +32,8 @@ #include #include +#include "hvf-cpus.h" + void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg, SegmentCache *qseg, bool is_tr) { diff --git a/target/i386/hvf/x86hvf.h b/target/i386/hvf/x86hvf.h index 79539f7282..4fabc6d582 100644 --- a/target/i386/hvf/x86hvf.h +++ b/target/i386/hvf/x86hvf.h @@ -35,5 +35,4 @@ void hvf_get_msrs(CPUState *cpu_state); void vmx_clear_int_window_exiting(CPUState *cpu); void hvf_get_segments(CPUState *cpu_state); void vmx_update_tpr(CPUState *cpu); -void hvf_cpu_synchronize_state(CPUState *cpu_state); #endif From patchwork Tue Oct 6 07:29:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377266 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=N7hXGuA9; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58hQ705lz9sSs for ; Tue, 6 Oct 2020 18:47:50 +1100 (AEDT) Received: from localhost ([::1]:35990 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhhL-000164-Rz for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:47:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39626) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQA-0002d2-Ek for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:02 -0400 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]:56152) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ8-0001PN-H0 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:02 -0400 Received: by mail-wm1-x32b.google.com with SMTP id d4so1807682wmd.5 for ; Tue, 06 Oct 2020 00:30:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YbI7t/qKpjjw8V58GUWV3d2iHhPFnbKHoCO06ALduuQ=; b=N7hXGuA940xm54rW47mYdGEhKzX6eHcyRTIokni4TOO0zin/A/2RinvTq3Gh+kS+ny Wticr+qJJ/6sset8Xd1ZL3Z4ZDuv8FRXT9X/Mhz9LU4GpDDEbTA8TglL9eN0Wln9KJlL /RiIS4G6GhSUcWGPBM+3dU7Bw+jCWoDX66vg63YAPCjD+QxxstGFAWWitVTdHG6IxmS/ 0k0VWqV0cV8RHq0ME6PH2Yf3dSbk92C3eMfTet1ES5MwqacasReqU/xK9HgV5jsH8pd4 68U/tBEokCoJGGN9/t3wWarNU8Tjc+LdFvZEkZxHgbYPwzH7aWmfrwIMMkNihowlRZnL +gug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=YbI7t/qKpjjw8V58GUWV3d2iHhPFnbKHoCO06ALduuQ=; b=AdPowQfxi2a6aHpdjEHpS8oCKFunYDLAIm6auR2cmBzZq/qKGme3zoBTBp+uN3BV5n o5BXdZfBqm509JdGZbODz4w4DYTiziFXFxcp5HP4Sc7cFi1UOYT8C5VNSmpLdeTawUT6 pU2xBQQQKyF2cWYz7531SaSvfRM3vzL6bJFOtY8zeWIXcSapD7FXFA7R2QziBZsXCu5J esCwvgksd/dv5vyrP059wVSRy4m4sgxKAEeNb8Npv1OAVNfi805D8RikzEopKrwrCzBN a+gVLiTdeTCk7xdzVRhKYGVUGcjJDiLsSAKm/XthZHGAnme8J9neIhGUcsFMkLr4GHN3 nkXQ== X-Gm-Message-State: AOAM530FVMVftwLVzm6dwk5W2/WjmAsPhcoCE0/AmkBGsWh6FhsPZUpr v0J/cYw6E587Z5vE0oRP0RZuz7kt6GY= X-Google-Smtp-Source: ABdhPJzX0v3pzdRVJN0K1DR7Curs+00XAplo8N4ixFqPGiJwGs/piohMtwmt+nKOyeFnwKDLTjPi6w== X-Received: by 2002:a1c:6788:: with SMTP id b130mr3440758wmc.91.1601969398910; Tue, 06 Oct 2020 00:29:58 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:58 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 14/37] whpx: remove whpx specific functions from global includes Date: Tue, 6 Oct 2020 09:29:24 +0200 Message-Id: <20201006072947.487729-15-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32b; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32b.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- accel/stubs/meson.build | 1 - accel/stubs/whpx-stub.c | 47 ----------------------------------------- include/sysemu/whpx.h | 19 ----------------- target/i386/whpx-cpus.h | 17 +++++++++++++++ 4 files changed, 17 insertions(+), 67 deletions(-) delete mode 100644 accel/stubs/whpx-stub.c diff --git a/accel/stubs/meson.build b/accel/stubs/meson.build index 3fbe34e5bb..12dd1539af 100644 --- a/accel/stubs/meson.build +++ b/accel/stubs/meson.build @@ -2,4 +2,3 @@ specific_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c')) specific_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c')) specific_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) specific_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c')) -specific_ss.add(when: 'CONFIG_WHPX', if_false: files('whpx-stub.c')) diff --git a/accel/stubs/whpx-stub.c b/accel/stubs/whpx-stub.c deleted file mode 100644 index 1efb89f25e..0000000000 --- a/accel/stubs/whpx-stub.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * QEMU Windows Hypervisor Platform accelerator (WHPX) stub - * - * Copyright Microsoft Corp. 2017 - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ - -#include "qemu/osdep.h" -#include "cpu.h" -#include "sysemu/whpx.h" - -int whpx_init_vcpu(CPUState *cpu) -{ - return -1; -} - -int whpx_vcpu_exec(CPUState *cpu) -{ - return -1; -} - -void whpx_destroy_vcpu(CPUState *cpu) -{ -} - -void whpx_vcpu_kick(CPUState *cpu) -{ -} - -void whpx_cpu_synchronize_state(CPUState *cpu) -{ -} - -void whpx_cpu_synchronize_post_reset(CPUState *cpu) -{ -} - -void whpx_cpu_synchronize_post_init(CPUState *cpu) -{ -} - -void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu) -{ -} diff --git a/include/sysemu/whpx.h b/include/sysemu/whpx.h index a84b49e749..59edf13742 100644 --- a/include/sysemu/whpx.h +++ b/include/sysemu/whpx.h @@ -13,18 +13,6 @@ #ifndef QEMU_WHPX_H #define QEMU_WHPX_H - -int whpx_init_vcpu(CPUState *cpu); -int whpx_vcpu_exec(CPUState *cpu); -void whpx_destroy_vcpu(CPUState *cpu); -void whpx_vcpu_kick(CPUState *cpu); - - -void whpx_cpu_synchronize_state(CPUState *cpu); -void whpx_cpu_synchronize_post_reset(CPUState *cpu); -void whpx_cpu_synchronize_post_init(CPUState *cpu); -void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu); - #ifdef CONFIG_WHPX int whpx_enabled(void); @@ -35,11 +23,4 @@ int whpx_enabled(void); #endif /* CONFIG_WHPX */ -/* state subset only touched by the VCPU itself during runtime */ -#define WHPX_SET_RUNTIME_STATE 1 -/* state subset modified during VCPU reset */ -#define WHPX_SET_RESET_STATE 2 -/* full state set, modified during initialization or on vmload */ -#define WHPX_SET_FULL_STATE 3 - #endif /* QEMU_WHPX_H */ diff --git a/target/i386/whpx-cpus.h b/target/i386/whpx-cpus.h index 2393944954..bdb367d1d0 100644 --- a/target/i386/whpx-cpus.h +++ b/target/i386/whpx-cpus.h @@ -14,4 +14,21 @@ extern const CpusAccel whpx_cpus; +int whpx_init_vcpu(CPUState *cpu); +int whpx_vcpu_exec(CPUState *cpu); +void whpx_destroy_vcpu(CPUState *cpu); +void whpx_vcpu_kick(CPUState *cpu); + +void whpx_cpu_synchronize_state(CPUState *cpu); +void whpx_cpu_synchronize_post_reset(CPUState *cpu); +void whpx_cpu_synchronize_post_init(CPUState *cpu); +void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu); + +/* state subset only touched by the VCPU itself during runtime */ +#define WHPX_SET_RUNTIME_STATE 1 +/* state subset modified during VCPU reset */ +#define WHPX_SET_RESET_STATE 2 +/* full state set, modified during initialization or on vmload */ +#define WHPX_SET_FULL_STATE 3 + #endif /* WHPX_CPUS_H */ From patchwork Tue Oct 6 07:29:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377245 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=CiG+Ndfb; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Ql4XZJz9sT6 for ; Tue, 6 Oct 2020 18:35:59 +1100 (AEDT) Received: from localhost ([::1]:51884 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhVt-0000w1-Hi for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:35:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39648) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQB-0002gX-TN for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:03 -0400 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]:46270) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQ9-0001PU-Av for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:03 -0400 Received: by mail-wr1-x431.google.com with SMTP id o5so12221901wrn.13 for ; Tue, 06 Oct 2020 00:30:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1wBDqPu0Mh/k8EUaxsOa5LE93l3x7HmJK/nuzfwKfPY=; b=CiG+Ndfb7Yi+VakfHFYwq2ofJZZMpJX9NyRJhEuz00uucRfDIZ72jMnGwSHzzz3I+D mDXoLXNey7xtU1bBFO/lP/M7wJOkTbSdIJCRutlbNdO53zBbU0BDPbbj+LkDul20e86o MfuHwXqQCu79GsnPGTy9DiV1NA2Xq800pLBXYW30mFo8/SjnDTTKPmzRqr2xI13Ewapp MRTyjPPIWDWpAcq/Qlsqn6psdhroYKZukjs+KaXybmivhEVTDza3tsoBkNJzhe8p0Sge 7OtsSiflsaXi2fHIMVhoC1Rf9eaQVINjrG4xuBqrejfWRKxlUnZDakGpWkTZsBml+F+E Y5KQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=1wBDqPu0Mh/k8EUaxsOa5LE93l3x7HmJK/nuzfwKfPY=; b=MJH3TX4mC2zkG8RNuGJaUZ1OOKQgjF107TurOiS5Mmo8GC+sxaoGW+6QMQQcXR/9LC UW5n3ZRcDILlzTfg0GdlVf0Vy3vV6CXUZ/lNLy+woiMWygRce49W+ZowvNAhaGxEcs2a LQraoX8gk0yjrBLugxH8zDylVOwOgw+KwRZd2TU1TiLrLtwIYyKGRKUhjj0qVdB0yfGs 5ZF7MqleRPNXlcQakiDRYB9TTYExCe4U9iwEyUu03/Qrcgpnm9yxaEMG+owLGJFCAljW uFp6dYftqhk51AZEg1jpE7k3lmnoVbgwIA8qLcb87lGV8+BNzPMmJdHXC3WXZxa1mBvG c5Ww== X-Gm-Message-State: AOAM532rLaAfYuXJsSzKFyazyBiLOYWa6cDDkb4myTwACIRCiNX8DCGC 3cDKPWncFb4FW6UqJJsJZh1FDKMnPJU= X-Google-Smtp-Source: ABdhPJy7KQfpbD1gvvSG0FyhBXW9pm3+j0ZoKdNJSlwXm/f4uoRi8qTvpCQ697TUyGdDtfs+23ysZw== X-Received: by 2002:adf:f504:: with SMTP id q4mr3217147wro.353.1601969399730; Tue, 06 Oct 2020 00:29:59 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:29:59 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 15/37] hax: remove hax specific functions from global includes Date: Tue, 6 Oct 2020 09:29:25 +0200 Message-Id: <20201006072947.487729-16-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x431.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- accel/stubs/hax-stub.c | 10 ---------- include/sysemu/hax.h | 17 ----------------- target/i386/hax-all.c | 1 - target/i386/hax-cpus.c | 1 - target/i386/hax-cpus.h | 16 ++++++++++++++++ target/i386/hax-mem.c | 2 +- target/i386/hax-posix.c | 3 +-- target/i386/hax-windows.c | 2 +- target/i386/hax-windows.h | 2 ++ 9 files changed, 21 insertions(+), 33 deletions(-) diff --git a/accel/stubs/hax-stub.c b/accel/stubs/hax-stub.c index 7ad190cae2..1a9da83185 100644 --- a/accel/stubs/hax-stub.c +++ b/accel/stubs/hax-stub.c @@ -21,13 +21,3 @@ int hax_sync_vcpus(void) { return 0; } - -int hax_init_vcpu(CPUState *cpu) -{ - return -ENOSYS; -} - -int hax_smp_cpu_exec(CPUState *cpu) -{ - return -ENOSYS; -} diff --git a/include/sysemu/hax.h b/include/sysemu/hax.h index 9b27e65cc7..12fb54f990 100644 --- a/include/sysemu/hax.h +++ b/include/sysemu/hax.h @@ -22,29 +22,12 @@ #ifndef QEMU_HAX_H #define QEMU_HAX_H - int hax_sync_vcpus(void); -int hax_init_vcpu(CPUState *cpu); -int hax_smp_cpu_exec(CPUState *cpu); -int hax_populate_ram(uint64_t va, uint64_t size); - -void hax_cpu_synchronize_state(CPUState *cpu); -void hax_cpu_synchronize_post_reset(CPUState *cpu); -void hax_cpu_synchronize_post_init(CPUState *cpu); -void hax_cpu_synchronize_pre_loadvm(CPUState *cpu); #ifdef CONFIG_HAX int hax_enabled(void); -#include "qemu/bitops.h" -#include "exec/memory.h" -int hax_vcpu_destroy(CPUState *cpu); -void hax_raise_event(CPUState *cpu); -void hax_reset_vcpu_state(void *opaque); -#include "target/i386/hax-interface.h" -#include "target/i386/hax-i386.h" - #else /* CONFIG_HAX */ #define hax_enabled() (0) diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c index fd1ab673d7..fecfe8cd6e 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -28,7 +28,6 @@ #include "exec/address-spaces.h" #include "qemu-common.h" -#include "hax-i386.h" #include "sysemu/accel.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" diff --git a/target/i386/hax-cpus.c b/target/i386/hax-cpus.c index 9aad98bc7a..99770e590c 100644 --- a/target/i386/hax-cpus.c +++ b/target/i386/hax-cpus.c @@ -22,7 +22,6 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" -#include "hax-i386.h" #include "sysemu/runstate.h" #include "sysemu/cpus.h" #include "qemu/guest-random.h" diff --git a/target/i386/hax-cpus.h b/target/i386/hax-cpus.h index a64417fe2d..ee8ab7a631 100644 --- a/target/i386/hax-cpus.h +++ b/target/i386/hax-cpus.h @@ -14,4 +14,20 @@ extern const CpusAccel hax_cpus; +#include "hax-interface.h" +#include "hax-i386.h" + +int hax_init_vcpu(CPUState *cpu); +int hax_smp_cpu_exec(CPUState *cpu); +int hax_populate_ram(uint64_t va, uint64_t size); + +void hax_cpu_synchronize_state(CPUState *cpu); +void hax_cpu_synchronize_post_reset(CPUState *cpu); +void hax_cpu_synchronize_post_init(CPUState *cpu); +void hax_cpu_synchronize_pre_loadvm(CPUState *cpu); + +int hax_vcpu_destroy(CPUState *cpu); +void hax_raise_event(CPUState *cpu); +void hax_reset_vcpu_state(void *opaque); + #endif /* HAX_CPUS_H */ diff --git a/target/i386/hax-mem.c b/target/i386/hax-mem.c index 6bb5a24917..71e637cf16 100644 --- a/target/i386/hax-mem.c +++ b/target/i386/hax-mem.c @@ -13,7 +13,7 @@ #include "exec/address-spaces.h" #include "qemu/error-report.h" -#include "target/i386/hax-i386.h" +#include "hax-cpus.h" #include "qemu/queue.h" #define DEBUG_HAX_MEM 0 diff --git a/target/i386/hax-posix.c b/target/i386/hax-posix.c index 6fb7867d11..735a749d4b 100644 --- a/target/i386/hax-posix.c +++ b/target/i386/hax-posix.c @@ -14,9 +14,8 @@ #include "qemu/osdep.h" #include -#include "target/i386/hax-i386.h" - #include "sysemu/cpus.h" +#include "hax-cpus.h" hax_fd hax_mod_open(void) { diff --git a/target/i386/hax-windows.c b/target/i386/hax-windows.c index 469b48e608..6c82dfb54f 100644 --- a/target/i386/hax-windows.c +++ b/target/i386/hax-windows.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "hax-i386.h" +#include "hax-cpus.h" /* * return 0 when success, -1 when driver not loaded, diff --git a/target/i386/hax-windows.h b/target/i386/hax-windows.h index 12cbd813dc..a5ce12d663 100644 --- a/target/i386/hax-windows.h +++ b/target/i386/hax-windows.h @@ -23,6 +23,8 @@ #include #include +#include "hax-cpus.h" + #define HAX_INVALID_FD INVALID_HANDLE_VALUE static inline void hax_mod_close(struct hax_state *hax) From patchwork Tue Oct 6 07:29:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377267 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=fFDt0Koj; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58l01w3Bz9sTr for ; Tue, 6 Oct 2020 18:50:02 +1100 (AEDT) Received: from localhost ([::1]:42300 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhjQ-0003gp-A9 for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:49:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39656) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQC-0002hB-6g for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:04 -0400 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]:51955) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQA-0001Ph-9i for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:03 -0400 Received: by mail-wm1-x32d.google.com with SMTP id d81so1835639wmc.1 for ; Tue, 06 Oct 2020 00:30:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=McojN4hgI2v8lMIA/0vIa8DUoBcoEwCymxJZE7NE5hM=; b=fFDt0KojN8zQR9IVBJ+icCKNvvLKDjnRP4iBHVkL8keuPLAw8/klDMzIx3r+dWzj+N bvE3VCB11ai9FGokMmLgzdZ8i2pGO6wW37dfo47S1qMoIUSOtgsTe4WuI8Lygenc2JKt mZ+sH+wXEBEa063R75XVH72V7wISSjfFyfUcYURurTvjXB14Nb6YfZMYTqpsaU7i3uzL MSXx1kIB0FzWWPd01MJ9b0KBwdzoa+o+nkD+Hnf/FRGprftFRm2b3Ib8s5+qrNsrQMrI Qq1tyUMRaLRJtxa072r9ig2prMSKTIfXY0Fe9SgMSYS3GdEbko9wetZaYpaVXI14UddX bBhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=McojN4hgI2v8lMIA/0vIa8DUoBcoEwCymxJZE7NE5hM=; b=e6/7yTrmL3EHZLudmBhvAxNlbn0ZwU3dbzJgL2IbNzhRE8A6yzsvOPJd4ULpcq+ySQ /Lh9vVHaEWKzEnGFZZVfk4F3uP1ORKDoWcBk7XfzZVq+XGKDCR9dP4vM9UiOAH3XM7BH wtjr4aqylpRegbJlFC9WuFKJt3RKGvb3k1K4lYia890bE0yGhUC/K9dk4MzqIdeOa7Mj i/pifdWjBW5awpN62WGLmJOqA3EZxZn5w0SlsK0AhU6yO4UaYcIZ3tTz1m/fUS9/83h4 akhhxS1YJvd359SstNrA2Hbkud5ShdCvnd3wt0TlGPTLUmlDlwf366rT74+K9KgPCsdg uLTg== X-Gm-Message-State: AOAM533k2SQ7RUXRSRO1srsJxl5KjPw+TkTNHKM4HXSVFTC9wUgWniS4 e+i4Am3rSRW3aeAE3CgcWTH6UNF/FE8= X-Google-Smtp-Source: ABdhPJzFERkBba6rm09u5DrrABvfxBt8C8M0KaEImWlih2J/7WsC5VGEuxVnJhSZi5tosbLEFLHyqQ== X-Received: by 2002:a7b:c92c:: with SMTP id h12mr3204449wml.121.1601969400582; Tue, 06 Oct 2020 00:30:00 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.29.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:00 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 16/37] kvm: remove kvm specific functions from global includes Date: Tue, 6 Oct 2020 09:29:26 +0200 Message-Id: <20201006072947.487729-17-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32d; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32d.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- accel/kvm/kvm-cpus.h | 7 +++++++ accel/stubs/kvm-stub.c | 22 ---------------------- include/sysemu/kvm.h | 7 ------- 3 files changed, 7 insertions(+), 29 deletions(-) diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h index 547fbee111..60c5a554c2 100644 --- a/accel/kvm/kvm-cpus.h +++ b/accel/kvm/kvm-cpus.h @@ -14,4 +14,11 @@ extern const CpusAccel kvm_cpus; +int kvm_init_vcpu(CPUState *cpu); +int kvm_cpu_exec(CPUState *cpu); +void kvm_destroy_vcpu(CPUState *cpu); +void kvm_cpu_synchronize_post_reset(CPUState *cpu); +void kvm_cpu_synchronize_post_init(CPUState *cpu); +void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu); + #endif /* KVM_CPUS_H */ diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index 69f8a842da..680e099463 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -32,15 +32,6 @@ bool kvm_readonly_mem_allowed; bool kvm_ioeventfd_any_length_allowed; bool kvm_msi_use_devid; -void kvm_destroy_vcpu(CPUState *cpu) -{ -} - -int kvm_init_vcpu(CPUState *cpu) -{ - return -ENOSYS; -} - void kvm_flush_coalesced_mmio_buffer(void) { } @@ -49,19 +40,6 @@ void kvm_cpu_synchronize_state(CPUState *cpu) { } -void kvm_cpu_synchronize_post_reset(CPUState *cpu) -{ -} - -void kvm_cpu_synchronize_post_init(CPUState *cpu) -{ -} - -int kvm_cpu_exec(CPUState *cpu) -{ - abort(); -} - bool kvm_has_sync_mmu(void) { return false; diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 07937454d2..fe7dab1466 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -223,10 +223,6 @@ int kvm_has_many_ioeventfds(void); int kvm_has_gsi_routing(void); int kvm_has_intx_set_mask(void); -int kvm_init_vcpu(CPUState *cpu); -int kvm_cpu_exec(CPUState *cpu); -void kvm_destroy_vcpu(CPUState *cpu); - /** * kvm_arm_supports_user_irq * @@ -486,9 +482,6 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr, #endif /* NEED_CPU_H */ void kvm_cpu_synchronize_state(CPUState *cpu); -void kvm_cpu_synchronize_post_reset(CPUState *cpu); -void kvm_cpu_synchronize_post_init(CPUState *cpu); -void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu); void kvm_init_cpu_signals(CPUState *cpu); From patchwork Tue Oct 6 07:29:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377268 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=ryNCOtUp; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58p335xxz9sSs for ; Tue, 6 Oct 2020 18:52:43 +1100 (AEDT) Received: from localhost ([::1]:48040 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhm5-00068E-By for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:52:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39680) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQD-0002jc-5P for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:05 -0400 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]:36389) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQB-0001QK-5I for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:04 -0400 Received: by mail-wm1-x32a.google.com with SMTP id e2so1944227wme.1 for ; Tue, 06 Oct 2020 00:30:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SqRzPnflqZF33Smi8JSLtfga764GNYRU7t9sRkWeWhU=; b=ryNCOtUphSwWhHCff/cnoK1OBK8aVbxExbcSADQbdTSCoLyizvzweileTDhuZUnMlK 4mrneczo0Q7QGoOkZA1fcTCdWbTjmNu1hYcmdgFW0rc3Y59kP3yz5eSK9U0DKs465SJu EDIiQvFy4EMVt2m0pXeniP3srCX7DhcCMTedkTlB1Hs1AgPWCOU/cL0m9V3npx5DLT/G RRqv3aSg/C4KzOCLFlMqZTEQzUYpKU7C39DVH69ca8MKFCsGq9rZF4DjhQhaxQQiph5l j+oplpcWoM7lRvIHSKGh9SWfP6xMUeM43yAqp/Hq8xt8vNdvURbH72k60lq5S9p5Y+KS ecUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=SqRzPnflqZF33Smi8JSLtfga764GNYRU7t9sRkWeWhU=; b=Q3dJYrIfZYs1KKSmA0pe06AMvdyA1UmI3WqWSjW5rTHJ4Gh2BwkR7mv9B4N7/9YLb9 C2bbI8PgfhP7ppzvr+VVDXOS6OBIj76EirHCuUroTbdblZzIKvoKyFrLm7Co1wMRY1W3 yZ8ExlzyOvhavt39PmlHLyHuOwGpQjCmZO+I2HpJJMJW307wFVEGoMWl5Xv7QYvmI0BD 8y6Whnbcty95RfE0Nv4rVb5NgaRdfktQfOALHofZetO0KrBbcpOxptCv6lyXqdaUuCSR o5HHpiPtHmPV+cFaTdfhnRLUntOMhW5rwNCI6Ds12Tj7mLBZ25uRgfZpw6RwyCu8qSAo d7cw== X-Gm-Message-State: AOAM533n/cnHRpHwLrTav37BMngxKaonY1lSS8waE+XOEb7J5h7s6dJg 96jLu4NBlzctuXs0IcvSxw/H6Th7A3s= X-Google-Smtp-Source: ABdhPJyFBj5D8AmeSEoEK/YuSDeKH2QjvfiTiRuoJi1nQXwfNT2ZwqFUQa21/ehNK+MiQYhNjqmL0Q== X-Received: by 2002:a1c:23c2:: with SMTP id j185mr3106501wmj.136.1601969401506; Tue, 06 Oct 2020 00:30:01 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:00 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 17/37] kvm: kvm_init_vcpu take Error pointer Date: Tue, 6 Oct 2020 09:29:27 +0200 Message-Id: <20201006072947.487729-18-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32a; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32a.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: "Dr. David Alan Gilbert" Clean up the error handling in kvm_init_vcpu so we can see what went wrong more easily. Make it take an Error ** and fill it out with what failed, including the cpu id, so you can tell if it only fails at a given ID. Replace the remaining DPRINTF by a trace. This turns a: kvm_init_vcpu failed: Invalid argument into: kvm_init_vcpu: kvm_get_vcpu failed (256): Invalid argument and with the trace you then get to see: 19049@1595520414.310107:kvm_init_vcpu index: 169 id: 212 19050@1595520414.310635:kvm_init_vcpu index: 170 id: 256 qemu-system-x86_64: kvm_init_vcpu: kvm_get_vcpu failed (256): Invalid argument which makes stuff a lot more obvious. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20200723160915.129069-1-dgilbert@redhat.com> Signed-off-by: Paolo Bonzini --- accel/kvm/kvm-all.c | 19 ++++++++++++++----- accel/kvm/kvm-cpus.c | 8 ++------ accel/kvm/kvm-cpus.h | 2 +- accel/kvm/trace-events | 1 + 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 784e9dad55..9ef5daf4c5 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -441,17 +441,18 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id) return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id); } -int kvm_init_vcpu(CPUState *cpu) +int kvm_init_vcpu(CPUState *cpu, Error **errp) { KVMState *s = kvm_state; long mmap_size; int ret; - DPRINTF("kvm_init_vcpu\n"); + trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu)); ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu)); if (ret < 0) { - DPRINTF("kvm_create_vcpu failed\n"); + error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed (%lu)", + kvm_arch_vcpu_id(cpu)); goto err; } @@ -462,7 +463,8 @@ int kvm_init_vcpu(CPUState *cpu) mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0); if (mmap_size < 0) { ret = mmap_size; - DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n"); + error_setg_errno(errp, -mmap_size, + "kvm_init_vcpu: KVM_GET_VCPU_MMAP_SIZE failed"); goto err; } @@ -470,7 +472,9 @@ int kvm_init_vcpu(CPUState *cpu) cpu->kvm_fd, 0); if (cpu->kvm_run == MAP_FAILED) { ret = -errno; - DPRINTF("mmap'ing vcpu state failed\n"); + error_setg_errno(errp, ret, + "kvm_init_vcpu: mmap'ing vcpu state failed (%lu)", + kvm_arch_vcpu_id(cpu)); goto err; } @@ -480,6 +484,11 @@ int kvm_init_vcpu(CPUState *cpu) } ret = kvm_arch_init_vcpu(cpu); + if (ret < 0) { + error_setg_errno(errp, -ret, + "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)", + kvm_arch_vcpu_id(cpu)); + } err: return ret; } diff --git a/accel/kvm/kvm-cpus.c b/accel/kvm/kvm-cpus.c index a120601564..d809b1e74c 100644 --- a/accel/kvm/kvm-cpus.c +++ b/accel/kvm/kvm-cpus.c @@ -20,6 +20,7 @@ #include "sysemu/runstate.h" #include "sysemu/cpus.h" #include "qemu/guest-random.h" +#include "qapi/error.h" #include "kvm-cpus.h" @@ -36,12 +37,7 @@ static void *kvm_vcpu_thread_fn(void *arg) cpu->can_do_io = 1; current_cpu = cpu; - r = kvm_init_vcpu(cpu); - if (r < 0) { - error_report("kvm_init_vcpu failed: %s", strerror(-r)); - exit(1); - } - + r = kvm_init_vcpu(cpu, &error_fatal); kvm_init_cpu_signals(cpu); /* signal CPU creation */ diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h index 60c5a554c2..3df732b816 100644 --- a/accel/kvm/kvm-cpus.h +++ b/accel/kvm/kvm-cpus.h @@ -14,7 +14,7 @@ extern const CpusAccel kvm_cpus; -int kvm_init_vcpu(CPUState *cpu); +int kvm_init_vcpu(CPUState *cpu, Error **errp); int kvm_cpu_exec(CPUState *cpu); void kvm_destroy_vcpu(CPUState *cpu); void kvm_cpu_synchronize_post_reset(CPUState *cpu); diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events index a68eb66534..e15ae8980d 100644 --- a/accel/kvm/trace-events +++ b/accel/kvm/trace-events @@ -8,6 +8,7 @@ kvm_run_exit(int cpu_index, uint32_t reason) "cpu_index %d, reason %d" kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 0x%x, arg %p" kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s" kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s" +kvm_init_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu" kvm_irqchip_commit_routes(void) "" kvm_irqchip_add_msi_route(char *name, int vector, int virq) "dev %s vector %d virq %d" kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d" From patchwork Tue Oct 6 07:29:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377250 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=UxEZhLFN; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58TR75VJz9sS8 for ; Tue, 6 Oct 2020 18:38:19 +1100 (AEDT) Received: from localhost ([::1]:59942 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhY9-0004IB-UV for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:38:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39682) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQD-0002kh-Ku for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:05 -0400 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]:36878) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQB-0001R2-UQ for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:05 -0400 Received: by mail-wr1-x435.google.com with SMTP id h7so8607216wre.4 for ; Tue, 06 Oct 2020 00:30:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UkhUWSEpBOxaKVYckqggA+lLHZxUS/KpnMFT6sdHjJM=; b=UxEZhLFNuUmrddxiuKs+XcUO4W8jnpIq0RABzM757Iet3kp82ueINWu/UxQReNhf/1 xzu9thUOHlLI8l51OrYSB3dWgpPoYMusgNuElgF4vg5hVZG8fxg9EwmQ5wOjhfuC6TSi D2/62W5LZx+4I4lYDEfkLMCRH0QEHfRq2GdSO9IpKKDGegfggnURMCvqxgBcdLPuTrGD nOWd1aF9NxkMta5OoNad6A9vxTr1EJ1HxTvwWGO/ePmEBUclgeEYZO4BYRCnIQ0pZgSR itZwNZTFxZhrMuEYLJVT1LtDCFNw5qfLj6ET6UuqXwNTxDt+1h4rRCqr6i4xIUo9N3Bj 5RLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=UkhUWSEpBOxaKVYckqggA+lLHZxUS/KpnMFT6sdHjJM=; b=Wn2i/UDI25pkhanGVqts85sc1py2xvYMyqB/JMjZb6YVWxHio8HKmQcpXcSNBxTC1Z ZA4FNa1Y5Bq3Uw+xjvPgVvHwWr/CJLVemVz5qn0JkBx5sW5EFf/G8P7uoCifDXXnMhQM xmUMQpAGltOzXxvVr4SugdzYW9DGgXZaRss0Wa7hXKsTEMbN/Ig32+10n8lvPnML0cZH FOFQts6rgs+kl9G7XHS6NdaN9Mujz6r0LXolrrNWmKiAXXw+ANcUVXBYmwGe/0fZSV6k qEbwFCfVYaA8G/zS1F264h+Sz237V/hfJFWIyH49eZZBN5ySK3YeYANbhZomtbruBWDX aiEQ== X-Gm-Message-State: AOAM532fiyyz884FuS7wSm23MU0AzToNkXkgkYyBAheN6vnbnd6drohK YgS+nZgsOBZi+73kVTjdt487/G4VWB8= X-Google-Smtp-Source: ABdhPJwwr1ADq9JiNuIbwJlLv31JlmKqdEXzfIg0HYRsXSEsCbMiyyoJCGkvx8HjDlYl8TMlhM3V4Q== X-Received: by 2002:adf:cf0c:: with SMTP id o12mr3162809wrj.287.1601969402295; Tue, 06 Oct 2020 00:30:02 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:01 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 18/37] accel/tcg: use current_machine as it is always set for softmmu Date: Tue, 6 Oct 2020 09:29:28 +0200 Message-Id: <20201006072947.487729-19-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::435; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x435.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio Fontana Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Claudio Fontana current_machine is always set before accelerators are initialized, so use that instead of MACHINE(qdev_get_machine()). Signed-off-by: Claudio Fontana Signed-off-by: Paolo Bonzini --- accel/tcg/tcg-cpus.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/accel/tcg/tcg-cpus.c b/accel/tcg/tcg-cpus.c index cedd1e6c4f..da1c63d8f6 100644 --- a/accel/tcg/tcg-cpus.c +++ b/accel/tcg/tcg-cpus.c @@ -479,16 +479,7 @@ static void tcg_start_vcpu_thread(CPUState *cpu) if (!tcg_region_inited) { tcg_region_inited = 1; tcg_region_init(); - /* - * If MTTCG, and we will create multiple cpus, - * then we will have cpus running in parallel. - */ - if (qemu_tcg_mttcg_enabled()) { - MachineState *ms = MACHINE(qdev_get_machine()); - if (ms->smp.max_cpus > 1) { - parallel_cpus = true; - } - } + parallel_cpus = qemu_tcg_mttcg_enabled() && current_machine->smp.max_cpus > 1; } if (qemu_tcg_mttcg_enabled() || !single_tcg_cpu_thread) { From patchwork Tue Oct 6 07:29:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377272 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Tihx61qX; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58rP1SXkz9sS8 for ; Tue, 6 Oct 2020 18:54:45 +1100 (AEDT) Received: from localhost ([::1]:55546 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPho3-0000if-6H for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:54:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39694) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQF-0002oN-64 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:07 -0400 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]:50450) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQC-0001SE-ST for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:06 -0400 Received: by mail-wm1-x32b.google.com with SMTP id 13so1845356wmf.0 for ; Tue, 06 Oct 2020 00:30:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rkEQInELIm4l3kHrX4stDT4Egsv9I700XbmiV5BB840=; b=Tihx61qXjFgqK13p4Zknhe22kShtn+Xuts2sgqE07qqoHBrQVBJRiNeQmt/9MEbi32 8ibfKCCoa9wtiaRugWShKsVZ32s9CMTjEyZIO9i+iKBaP3qd5gkWTP8KHy6B/3ZlbZXm /gcIwGOz4pVOZUgAKU8fHkDe54tT3gU2sp16iPgWHOfsK3YPoP+qaGKVNYOc4VVldEQY UjA5Vhwrjd0IPKw3nc4N1JFK4Tns+fHdLQLvTuPTCqWY988P8A47yyDkh0uLtpxglViQ FIDXYhYNYDVP9Gcju2MsydS4tAlJ4A2xDvK5k2HQGCqgqxIci6vpuQ2p/8yq09rH4ZUR D3zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=rkEQInELIm4l3kHrX4stDT4Egsv9I700XbmiV5BB840=; b=ZBfPKPe2+0rGjJm3GHDCGvaf/+V3jiOCV8kp4MMDqPrh5vCxVsLzMeg0kjgKlaItNK HG4eQDtbVZmEutldHcZUCznfWNiCKulSnYOK4Ac5Lvnmvkh0aI69aX+iobBusH+0BPm1 x+XUa9SLJr5z7ZZins9zBXBfMwAOPDNGd61CapDrkWk4BCHIG1fWn0uCkSVSkWEtk+Sl yYeoduVlSrCzwxbgKr2DwXkjQNUW6Aq4ZNeMQd6xRNiE/fAymOdKwWZkb12wExnHAtFO z/hIi62kAlgpnpfm80woOv3nGanSfqm0MuRw0aWUtimkRmhtvbuARr1R4sHLiDGA4cru dLCQ== X-Gm-Message-State: AOAM533B0fiUgfQWcfOtxODl0InJdJpGcIlIL8/ZxY53h24SjaiVmFdy 8TadEGM69V9F89YkNJk1Awq80WInLS4= X-Google-Smtp-Source: ABdhPJzF12Po0vOAg0ZzewV5PQYyJtCzbKMAqXjds8S38jbEaTvNMWhczEdH3TWO/VPiGiey3l5kSQ== X-Received: by 2002:a1c:4856:: with SMTP id v83mr3395732wma.118.1601969403057; Tue, 06 Oct 2020 00:30:03 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:02 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 19/37] slirp: Convert Makefile bits to meson bits Date: Tue, 6 Oct 2020 09:29:29 +0200 Message-Id: <20201006072947.487729-20-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32b; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32b.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" SLIRP uses Meson so it could become a subproject in the future, but our choice of configure options is not yet supported in Meson (https://github.com/mesonbuild/meson/pull/7740). For now, build the library via the main meson.build just like for capstone. This improves the current state of affairs in that we will re-link the qemu executables against a changed libslirp.a, which we wouldn't do before-hand. Tested-by: Richard Henderson Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- Makefile | 7 +--- configure | 68 ++++--------------------------- meson.build | 90 +++++++++++++++++++++++++++++++++++++---- meson_options.txt | 3 ++ net/meson.build | 2 +- tests/qtest/meson.build | 6 +-- 6 files changed, 99 insertions(+), 77 deletions(-) diff --git a/Makefile b/Makefile index f27bd4b2eb..9d6b7fc8c0 100644 --- a/Makefile +++ b/Makefile @@ -163,12 +163,7 @@ dtc/%: .git-submodule-status capstone/all: .PHONY: slirp/all -slirp/all: .git-submodule-status - $(call quiet-command,$(MAKE) -C $(SRC_PATH)/slirp \ - BUILD_DIR="$(BUILD_DIR)/slirp" \ - PKG_CONFIG="$(PKG_CONFIG)" \ - CC="$(CC)" AR="$(AR)" LD="$(LD)" RANLIB="$(RANLIB)" \ - CFLAGS="$(QEMU_CFLAGS) $(CFLAGS)" LDFLAGS="$(QEMU_LDFLAGS)") +slirp/all: ROM_DIRS = $(addprefix pc-bios/, $(ROMS)) ROM_DIRS_RULES=$(foreach t, all clean, $(addsuffix /$(t), $(ROM_DIRS))) diff --git a/configure b/configure index 66641099fc..51f4e978be 100755 --- a/configure +++ b/configure @@ -349,7 +349,7 @@ modules="no" module_upgrades="no" prefix="/usr/local" qemu_suffix="qemu" -slirp="" +slirp="auto" oss_lib="" bsd="no" linux="no" @@ -1058,9 +1058,9 @@ for opt do ;; --enable-vnc-png) vnc_png="enabled" ;; - --disable-slirp) slirp="no" + --disable-slirp) slirp="disabled" ;; - --enable-slirp=git) slirp="git" + --enable-slirp=git) slirp="internal" ;; --enable-slirp=system) slirp="system" ;; @@ -5806,56 +5806,12 @@ fi ########################################## # check for slirp -# slirp is only required when building softmmu targets -if test -z "$slirp" -a "$softmmu" != "yes" ; then - slirp="no" -fi - case "$slirp" in - "" | yes) - if $pkg_config slirp; then - slirp=system - elif test -e "${source_path}/.git" && test $git_update = 'yes' ; then - slirp=git - elif test -e "${source_path}/slirp/Makefile" ; then - slirp=internal - elif test -z "$slirp" ; then - slirp=no - else - feature_not_found "slirp" "Install slirp devel or git submodule" - fi - ;; - - system) - if ! $pkg_config slirp; then - feature_not_found "slirp" "Install slirp devel" - fi - ;; -esac - -case "$slirp" in - git | internal) - if test "$slirp" = git; then + auto | enabled | internal) + # Simpler to always update submodule, even if not needed. + if test -e "${source_path}/.git" && test $git_update = 'yes' ; then git_submodules="${git_submodules} slirp" fi - mkdir -p slirp - slirp_cflags="-I${source_path}/slirp/src -Islirp/src" - slirp_libs="-Lslirp -lslirp" - if test "$mingw32" = "yes" ; then - slirp_libs="$slirp_libs -lws2_32 -liphlpapi" - fi - ;; - - system) - slirp_version=$($pkg_config --modversion slirp 2>/dev/null) - slirp_cflags=$($pkg_config --cflags slirp 2>/dev/null) - slirp_libs=$($pkg_config --libs slirp 2>/dev/null) - ;; - - no) - ;; - *) - error_exit "Unknown state for slirp: $slirp" ;; esac @@ -6256,16 +6212,8 @@ fi if test "$guest_agent" = "yes" ; then echo "CONFIG_GUEST_AGENT=y" >> $config_host_mak fi -if test "$slirp" != "no"; then - echo "CONFIG_SLIRP=y" >> $config_host_mak - echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak - echo "SLIRP_CFLAGS=$slirp_cflags" >> $config_host_mak - echo "SLIRP_LIBS=$slirp_libs" >> $config_host_mak -fi +echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak subdirs= -if [ "$slirp" = "git" -o "$slirp" = "internal" ]; then - subdirs="$subdirs slirp" -fi if test "$vde" = "yes" ; then echo "CONFIG_VDE=y" >> $config_host_mak echo "VDE_LIBS=$vde_libs" >> $config_host_mak @@ -7321,7 +7269,7 @@ NINJA=${ninja:-$PWD/ninjatool} $meson setup \ -Dcocoa=$cocoa -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \ -Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \ -Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f \ - -Dcapstone=$capstone \ + -Dcapstone=$capstone -Dslirp=$slirp \ $cross_arg \ "$PWD" "$source_path" diff --git a/meson.build b/meson.build index a02c743794..165716ddad 100644 --- a/meson.build +++ b/meson.build @@ -300,11 +300,6 @@ else xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'), method: 'pkg-config', static: enable_static) endif -slirp = not_found -if config_host.has_key('CONFIG_SLIRP') - slirp = declare_dependency(compile_args: config_host['SLIRP_CFLAGS'].split(), - link_args: config_host['SLIRP_LIBS'].split()) -endif vde = not_found if config_host.has_key('CONFIG_VDE') vde = declare_dependency(link_args: config_host['VDE_LIBS'].split()) @@ -978,7 +973,88 @@ if capstone_opt == 'internal' capstone = declare_dependency(link_with: libcapstone, include_directories: 'capstone/include/capstone') endif + +slirp = not_found +slirp_opt = 'disabled' +if have_system + slirp_opt = get_option('slirp') + if slirp_opt in ['enabled', 'auto', 'system'] + have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build') + slirp = dependency('slirp', static: enable_static, + method: 'pkg-config', + required: slirp_opt == 'system' or + slirp_opt == 'enabled' and not have_internal) + if slirp.found() + slirp_opt = 'system' + elif have_internal + slirp_opt = 'internal' + else + slirp_opt = 'disabled' + endif + endif + if slirp_opt == 'internal' + slirp_deps = [] + if targetos == 'windows' + slirp_deps = cc.find_library('iphlpapi') + endif + slirp_conf = configuration_data() + slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0]) + slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1]) + slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2]) + slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version()) + slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"'] + slirp_files = [ + 'slirp/src/arp_table.c', + 'slirp/src/bootp.c', + 'slirp/src/cksum.c', + 'slirp/src/dhcpv6.c', + 'slirp/src/dnssearch.c', + 'slirp/src/if.c', + 'slirp/src/ip6_icmp.c', + 'slirp/src/ip6_input.c', + 'slirp/src/ip6_output.c', + 'slirp/src/ip_icmp.c', + 'slirp/src/ip_input.c', + 'slirp/src/ip_output.c', + 'slirp/src/mbuf.c', + 'slirp/src/misc.c', + 'slirp/src/ncsi.c', + 'slirp/src/ndp_table.c', + 'slirp/src/sbuf.c', + 'slirp/src/slirp.c', + 'slirp/src/socket.c', + 'slirp/src/state.c', + 'slirp/src/stream.c', + 'slirp/src/tcp_input.c', + 'slirp/src/tcp_output.c', + 'slirp/src/tcp_subr.c', + 'slirp/src/tcp_timer.c', + 'slirp/src/tftp.c', + 'slirp/src/udp.c', + 'slirp/src/udp6.c', + 'slirp/src/util.c', + 'slirp/src/version.c', + 'slirp/src/vmstate.c', + ] + + configure_file( + input : 'slirp/src/libslirp-version.h.in', + output : 'libslirp-version.h', + configuration: slirp_conf) + + slirp_inc = include_directories('slirp', 'slirp/src') + libslirp = static_library('slirp', + sources: slirp_files, + c_args: slirp_cargs, + include_directories: slirp_inc) + slirp = declare_dependency(link_with: libslirp, + dependencies: slirp_deps, + include_directories: slirp_inc) + endif +endif + config_host_data.set('CONFIG_CAPSTONE', capstone.found()) +config_host_data.set('CONFIG_SLIRP', slirp.found()) genh += configure_file(output: 'config-host.h', configuration: config_host_data) @@ -1656,8 +1732,8 @@ summary_info += {'python': '@0@ (version: @1@)'.format(python.full_pa summary_info += {'sphinx-build': config_host['SPHINX_BUILD']} summary_info += {'genisoimage': config_host['GENISOIMAGE']} # TODO: add back version -summary_info += {'slirp support': config_host.has_key('CONFIG_SLIRP')} -if config_host.has_key('CONFIG_SLIRP') +summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt} +if slirp_opt != 'disabled' summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']} endif summary_info += {'module support': config_host.has_key('CONFIG_MODULES')} diff --git a/meson_options.txt b/meson_options.txt index a0455d8a95..8a362fb08d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -52,3 +52,6 @@ option('xkbcommon', type : 'feature', value : 'auto', option('capstone', type: 'combo', value: 'auto', choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], description: 'Whether and how to find the capstone library') +option('slirp', type: 'combo', value: 'auto', + choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], + description: 'Whether and how to find the slirp library') diff --git a/net/meson.build b/net/meson.build index 6c2ec47dd5..1c7e3a3cb9 100644 --- a/net/meson.build +++ b/net/meson.build @@ -18,7 +18,7 @@ softmmu_ss.add(files( )) softmmu_ss.add(when: 'CONFIG_L2TPV3', if_true: files('l2tpv3.c')) -softmmu_ss.add(when: ['CONFIG_SLIRP', slirp], if_true: files('slirp.c')) +softmmu_ss.add(when: slirp, if_true: files('slirp.c')) softmmu_ss.add(when: ['CONFIG_VDE', vde], if_true: files('vde.c')) softmmu_ss.add(when: 'CONFIG_NETMAP', if_true: files('netmap.c')) vhost_user_ss = ss.source_set() diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 4f7757ee93..ad33ac311d 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -23,7 +23,7 @@ qtests_pci = \ (config_all_devices.has_key('CONFIG_IVSHMEM_DEVICE') ? ['ivshmem-test'] : []) qtests_i386 = \ - (config_host.has_key('CONFIG_SLIRP') ? ['pxe-test', 'test-netfilter'] : []) + \ + (slirp.found() ? ['pxe-test', 'test-netfilter'] : []) + \ (config_host.has_key('CONFIG_POSIX') ? ['test-filter-mirror'] : []) + \ (have_tools ? ['ahci-test'] : []) + \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ @@ -117,7 +117,7 @@ qtests_ppc64 = \ (config_all_devices.has_key('CONFIG_PSERIES') ? ['device-plug-test'] : []) + \ (config_all_devices.has_key('CONFIG_POWERNV') ? ['pnv-xscom-test'] : []) + \ (config_all_devices.has_key('CONFIG_PSERIES') ? ['rtas-test'] : []) + \ - (config_host.has_key('CONFIG_SLIRP') ? ['pxe-test', 'test-netfilter'] : []) + \ + (slirp.found() ? ['pxe-test', 'test-netfilter'] : []) + \ (config_all_devices.has_key('CONFIG_USB_UHCI') ? ['usb-hcd-uhci-test'] : []) + \ (config_all_devices.has_key('CONFIG_USB_XHCI_NEC') ? ['usb-hcd-xhci-test'] : []) + \ (config_host.has_key('CONFIG_POSIX') ? ['test-filter-mirror'] : []) + \ @@ -151,7 +151,7 @@ qtests_aarch64 = \ 'migration-test'] qtests_s390x = \ - (config_host.has_key('CONFIG_SLIRP') ? ['pxe-test', 'test-netfilter'] : []) + \ + (slirp.found() ? ['pxe-test', 'test-netfilter'] : []) + \ (config_host.has_key('CONFIG_POSIX') ? ['test-filter-mirror'] : []) + \ (config_host.has_key('CONFIG_POSIX') ? ['test-filter-redirector'] : []) + \ ['boot-serial-test', From patchwork Tue Oct 6 07:29:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377254 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=T4P+HDC1; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Wb4h4lz9sS8 for ; Tue, 6 Oct 2020 18:40:11 +1100 (AEDT) Received: from localhost ([::1]:39942 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhZx-0007e4-If for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:40:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39718) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQG-0002sH-My for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:08 -0400 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]:41031) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQE-0001SV-3q for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:08 -0400 Received: by mail-wr1-x429.google.com with SMTP id w5so12225291wrp.8 for ; Tue, 06 Oct 2020 00:30:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=b33bn38NadSwKtQL54nStprGVkEdcrAKRDNn88+9DKo=; b=T4P+HDC1FF9PqLsamNFTnvW5fuOTb1ECsOpXmB+rXYtTDnekgpcjq5W9s1683sO0Tm 2a10mRQAcrErTzOnX0PaPiykvQA9PSsQ9w40n0cXqWRl9qENu2lhP3q7fS1hxLBuEuh6 ESHaEtSx7ugLglotZHSqq+b2T/6aFEbY4o4+zuLDDlSx+G9fJFPMEKVlehZ0Wg5he0+c /BxtO6nho5xJoLym49zaFBYwwD5uQr9zKr1RxhA4uyqbgdoiZzPAjUbYSsQc03ZAqcRx 0OqZPQURDkJA9ErhTND+QYFXHXkbtM2jRePK0TwQde27Oe0d8xfcSNXVe98atJ+XNynm AneA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=b33bn38NadSwKtQL54nStprGVkEdcrAKRDNn88+9DKo=; b=Vlw6yth5eWlSocFPJieMdabzcF8p/bbpw/WcaLv78JMsQlxtNy5iZTflD+3CAHhKqs 3Szfc//2+D2AQuTZClaqZxlep/HBCWVlas0xy4nwvxRpOPdPDU48MSg8gFm0sOhUf1w9 WPdigNKcyeM4QjNOB2o7z6Q9UUJQt/zgFxj15FM0RaA90H6RFuntEtKb/IMmKXcvadyg Om9po+E8HOKT88mAThqdVbvekRs9nq/PPGDdtaHKlDPPDgeujoj8ztRdgdK8PB9u5qRZ dCu0h2fBWHPViRtUgAsxZ+4LAp/8PSGA1MlDgwfe7OzeZjyQO64psY7vFtiOQehO2bEK XkcA== X-Gm-Message-State: AOAM531UleBctVQJCiB/1RKZDN2IP5M5ta7poXSZW3XXlGa+ZcGzQdP/ vNBQ0DCokp1js1+Fhu5GcKO1NSETjyc= X-Google-Smtp-Source: ABdhPJwn7OsHm5/GwHrel/q5DfAi2Sl1VQEB0upkFkaqI/+GjXWFc248A9dC/NyC2epUhmQwh2e9hQ== X-Received: by 2002:a5d:6992:: with SMTP id g18mr3234444wru.193.1601969404156; Tue, 06 Oct 2020 00:30:04 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:03 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 20/37] dtc: Convert Makefile bits to meson bits Date: Tue, 6 Oct 2020 09:29:30 +0200 Message-Id: <20201006072947.487729-21-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::429; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x429.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Build the library via the main meson.build just like for capstone. This improves the current state of affairs in that we will re-link the qemu executables against a changed libfdt.a, which we wouldn't do before-hand, and lets us remove the whole recursive make machinery. Tested-by: Richard Henderson Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- Makefile | 23 +---- configure | 93 ++++--------------- default-configs/targets/aarch64-softmmu.mak | 1 + default-configs/targets/arm-softmmu.mak | 1 + .../targets/microblaze-softmmu.mak | 1 + .../targets/microblazeel-softmmu.mak | 1 + default-configs/targets/mips64el-softmmu.mak | 1 + default-configs/targets/ppc-softmmu.mak | 1 + default-configs/targets/ppc64-softmmu.mak | 1 + default-configs/targets/riscv32-softmmu.mak | 1 + default-configs/targets/riscv64-softmmu.mak | 1 + default-configs/targets/rx-softmmu.mak | 1 + meson.build | 61 ++++++++++-- meson_options.txt | 3 + 14 files changed, 84 insertions(+), 106 deletions(-) diff --git a/Makefile b/Makefile index 9d6b7fc8c0..c37e513431 100644 --- a/Makefile +++ b/Makefile @@ -142,28 +142,7 @@ SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet) include $(SRC_PATH)/tests/Makefile.include all: recurse-all -Makefile: $(addsuffix /all, $(SUBDIRS)) - -# LIBFDT_lib="": avoid breaking existing trees with objects requiring -fPIC -DTC_MAKE_ARGS=-I$(SRC_PATH)/dtc VPATH=$(SRC_PATH)/dtc -C dtc V="$(V)" LIBFDT_lib="" -DTC_CFLAGS=$(CFLAGS) $(QEMU_CFLAGS) -DTC_CPPFLAGS=-I$(SRC_PATH)/dtc/libfdt - -.PHONY: dtc/all -dtc/all: .git-submodule-status dtc/libfdt - $(call quiet-command,$(MAKE) $(DTC_MAKE_ARGS) CPPFLAGS="$(DTC_CPPFLAGS)" CFLAGS="$(DTC_CFLAGS)" LDFLAGS="$(QEMU_LDFLAGS)" ARFLAGS="$(ARFLAGS)" CC="$(CC)" AR="$(AR)" LD="$(LD)" $(SUBDIR_MAKEFLAGS) libfdt,) - -dtc/%: .git-submodule-status - @mkdir -p $@ - -# Retain for a while so that incremental build across this patch -# does not raise an error for missing target "capstone/all", which -# comes from the saved SUBDIRS value. -.PHONY: capstone/all -capstone/all: - -.PHONY: slirp/all -slirp/all: +Makefile: ROM_DIRS = $(addprefix pc-bios/, $(ROMS)) ROM_DIRS_RULES=$(foreach t, all clean, $(addsuffix /$(t), $(ROM_DIRS))) diff --git a/configure b/configure index 51f4e978be..2fdb4339e8 100755 --- a/configure +++ b/configure @@ -296,7 +296,7 @@ brlapi="" curl="" curses="" docs="" -fdt="" +fdt="auto" netmap="no" sdl="auto" sdl_image="auto" @@ -1181,9 +1181,13 @@ for opt do ;; --enable-curl) curl="yes" ;; - --disable-fdt) fdt="no" + --disable-fdt) fdt="disabled" ;; - --enable-fdt) fdt="yes" + --enable-fdt) fdt="enabled" + ;; + --enable-fdt=git) fdt="internal" + ;; + --enable-fdt=system) fdt="system" ;; --disable-linux-aio) linux_aio="no" ;; @@ -3941,67 +3945,15 @@ fi ########################################## # fdt probe -# fdt support is mandatory for at least some target architectures, -# so insist on it if we're building those system emulators. -fdt_required=no -for target in $target_list; do - case $target in - aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu|riscv*-softmmu|rx-softmmu) - fdt_required=yes - ;; - esac -done - -if test "$fdt_required" = "yes"; then - if test "$fdt" = "no"; then - error_exit "fdt disabled but some requested targets require it." \ - "You can turn off fdt only if you also disable all the system emulation" \ - "targets which need it (by specifying a cut down --target-list)." - fi - fdt=yes -elif test "$fdt" != "yes" ; then - fdt=no -fi - -# fdt is only required when building softmmu targets -if test -z "$fdt" -a "$softmmu" != "yes" ; then - fdt="no" -fi -if test "$fdt" != "no" ; then - fdt_libs="-lfdt" - # explicitly check for libfdt_env.h as it is missing in some stable installs - # and test for required functions to make sure we are on a version >= 1.4.2 - cat > $TMPC << EOF -#include -#include -int main(void) { fdt_check_full(NULL, 0); return 0; } -EOF - if compile_prog "" "$fdt_libs" ; then - # system DTC is good - use it - fdt=system - else - # have GIT checkout, so activate dtc submodule - if test -e "${source_path}/.git" ; then - git_submodules="${git_submodules} dtc" - fi - if test -d "${source_path}/dtc/libfdt" || test -e "${source_path}/.git" ; then - fdt=git - mkdir -p dtc - fdt_cflags="-I${source_path}/dtc/libfdt" - fdt_ldflags="-Ldtc/libfdt" - fdt_libs="$fdt_libs" - elif test "$fdt" = "yes" ; then - # Not a git build & no libfdt found, prompt for system install - error_exit "DTC (libfdt) version >= 1.4.2 not present." \ - "Please install the DTC (libfdt) devel package" - else - # don't have and don't want - fdt_libs= - fdt=no - fi - fi -fi +case "$fdt" in + auto | enabled | internal) + # Simpler to always update submodule, even if not needed. + if test -e "${source_path}/.git" && test $git_update = 'yes' ; then + git_submodules="${git_submodules} dtc" + fi + ;; +esac ########################################## # opengl probe (for sdl2, gtk, milkymist-tmu2) @@ -6107,9 +6059,6 @@ fi if test $git_update = 'yes' ; then (cd "${source_path}" && GIT="$git" "./scripts/git-submodule.sh" update "$git_submodules") fi -if test "$fdt" = "git" ; then - symlink "$source_path/dtc/Makefile" "dtc/Makefile" -fi config_host_mak="config-host.mak" @@ -6213,7 +6162,6 @@ if test "$guest_agent" = "yes" ; then echo "CONFIG_GUEST_AGENT=y" >> $config_host_mak fi echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak -subdirs= if test "$vde" = "yes" ; then echo "CONFIG_VDE=y" >> $config_host_mak echo "VDE_LIBS=$vde_libs" >> $config_host_mak @@ -6539,11 +6487,6 @@ fi if test "$preadv" = "yes" ; then echo "CONFIG_PREADV=y" >> $config_host_mak fi -if test "$fdt" != "no" ; then - echo "CONFIG_FDT=y" >> $config_host_mak - echo "FDT_CFLAGS=$fdt_cflags" >> $config_host_mak - echo "FDT_LIBS=$fdt_ldflags $fdt_libs" >> $config_host_mak -fi if test "$membarrier" = "yes" ; then echo "CONFIG_MEMBARRIER=y" >> $config_host_mak fi @@ -7083,14 +7026,10 @@ for target in $target_list; do esac done -if [ "$fdt" = "git" ]; then - subdirs="$subdirs dtc" -fi echo "CONFIG_QEMU_INTERP_PREFIX=$interp_prefix" | sed 's/%M/@0@/' >> $config_host_mak if test "$default_targets" = "yes"; then echo "CONFIG_DEFAULT_TARGETS=y" >> $config_host_mak fi -echo "SUBDIRS=$subdirs" >> $config_host_mak if test "$numa" = "yes"; then echo "CONFIG_NUMA=y" >> $config_host_mak @@ -7269,7 +7208,7 @@ NINJA=${ninja:-$PWD/ninjatool} $meson setup \ -Dcocoa=$cocoa -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \ -Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \ -Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f \ - -Dcapstone=$capstone -Dslirp=$slirp \ + -Dcapstone=$capstone -Dslirp=$slirp -Dfdt=$fdt \ $cross_arg \ "$PWD" "$source_path" diff --git a/default-configs/targets/aarch64-softmmu.mak b/default-configs/targets/aarch64-softmmu.mak index a8c0174fc3..7703127674 100644 --- a/default-configs/targets/aarch64-softmmu.mak +++ b/default-configs/targets/aarch64-softmmu.mak @@ -2,3 +2,4 @@ TARGET_ARCH=aarch64 TARGET_BASE_ARCH=arm TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml +TARGET_NEED_FDT=y diff --git a/default-configs/targets/arm-softmmu.mak b/default-configs/targets/arm-softmmu.mak index 9b1a7f37c6..84a98f4818 100644 --- a/default-configs/targets/arm-softmmu.mak +++ b/default-configs/targets/arm-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=arm TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml +TARGET_NEED_FDT=y diff --git a/default-configs/targets/microblaze-softmmu.mak b/default-configs/targets/microblaze-softmmu.mak index 0b5c78ef00..33f2a00402 100644 --- a/default-configs/targets/microblaze-softmmu.mak +++ b/default-configs/targets/microblaze-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=microblaze TARGET_WORDS_BIGENDIAN=y TARGET_SUPPORTS_MTTCG=y +TARGET_NEED_FDT=y diff --git a/default-configs/targets/microblazeel-softmmu.mak b/default-configs/targets/microblazeel-softmmu.mak index dc822219d8..af40391f2f 100644 --- a/default-configs/targets/microblazeel-softmmu.mak +++ b/default-configs/targets/microblazeel-softmmu.mak @@ -1,2 +1,3 @@ TARGET_ARCH=microblaze TARGET_SUPPORTS_MTTCG=y +TARGET_NEED_FDT=y diff --git a/default-configs/targets/mips64el-softmmu.mak b/default-configs/targets/mips64el-softmmu.mak index b751ae1bcf..5a52aa4b64 100644 --- a/default-configs/targets/mips64el-softmmu.mak +++ b/default-configs/targets/mips64el-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=mips64 TARGET_BASE_ARCH=mips TARGET_ALIGNED_ONLY=y +TARGET_NEED_FDT=y diff --git a/default-configs/targets/ppc-softmmu.mak b/default-configs/targets/ppc-softmmu.mak index ef69037a2c..f4eef1819a 100644 --- a/default-configs/targets/ppc-softmmu.mak +++ b/default-configs/targets/ppc-softmmu.mak @@ -1,3 +1,4 @@ TARGET_ARCH=ppc TARGET_WORDS_BIGENDIAN=y TARGET_XML_FILES= gdb-xml/power-core.xml gdb-xml/power-fpu.xml gdb-xml/power-altivec.xml gdb-xml/power-spe.xml +TARGET_NEED_FDT=y diff --git a/default-configs/targets/ppc64-softmmu.mak b/default-configs/targets/ppc64-softmmu.mak index 0fde2d02b9..84fbf46be9 100644 --- a/default-configs/targets/ppc64-softmmu.mak +++ b/default-configs/targets/ppc64-softmmu.mak @@ -3,3 +3,4 @@ TARGET_BASE_ARCH=ppc TARGET_WORDS_BIGENDIAN=y TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/power64-core.xml gdb-xml/power-fpu.xml gdb-xml/power-altivec.xml gdb-xml/power-spe.xml gdb-xml/power-vsx.xml +TARGET_NEED_FDT=y diff --git a/default-configs/targets/riscv32-softmmu.mak b/default-configs/targets/riscv32-softmmu.mak index 4544e1ae9a..9446d96d13 100644 --- a/default-configs/targets/riscv32-softmmu.mak +++ b/default-configs/targets/riscv32-softmmu.mak @@ -2,3 +2,4 @@ TARGET_ARCH=riscv32 TARGET_BASE_ARCH=riscv TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/riscv-32bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-32bit-csr.xml gdb-xml/riscv-32bit-virtual.xml +TARGET_NEED_FDT=y diff --git a/default-configs/targets/riscv64-softmmu.mak b/default-configs/targets/riscv64-softmmu.mak index 6ce0b283cf..d809bd666a 100644 --- a/default-configs/targets/riscv64-softmmu.mak +++ b/default-configs/targets/riscv64-softmmu.mak @@ -2,3 +2,4 @@ TARGET_ARCH=riscv64 TARGET_BASE_ARCH=riscv TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/riscv-64bit-cpu.xml gdb-xml/riscv-32bit-fpu.xml gdb-xml/riscv-64bit-fpu.xml gdb-xml/riscv-64bit-csr.xml gdb-xml/riscv-64bit-virtual.xml +TARGET_NEED_FDT=y diff --git a/default-configs/targets/rx-softmmu.mak b/default-configs/targets/rx-softmmu.mak index 2d410e0b0c..0c458b2d07 100644 --- a/default-configs/targets/rx-softmmu.mak +++ b/default-configs/targets/rx-softmmu.mak @@ -1,2 +1,3 @@ TARGET_ARCH=rx TARGET_XML_FILES= gdb-xml/rx-core.xml +TARGET_NEED_FDT=y diff --git a/meson.build b/meson.build index 165716ddad..0b8ec210f0 100644 --- a/meson.build +++ b/meson.build @@ -531,11 +531,6 @@ if get_option('vnc').enabled() compile_args: '-DSTRUCT_IOVEC_DEFINED') endif endif -fdt = not_found -if 'CONFIG_FDT' in config_host - fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(), - link_args: config_host['FDT_LIBS'].split()) -endif snappy = not_found if 'CONFIG_SNAPPY' in config_host snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split()) @@ -723,6 +718,7 @@ ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host actual_target_dirs = [] +fdt_required = [] foreach target : target_dirs config_target = { 'TARGET_NAME': target.split('-')[0] } if target.endswith('linux-user') @@ -774,6 +770,10 @@ foreach target : target_dirs config_target += keyval.load('default-configs/targets' / target + '.mak') config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } + if 'TARGET_NEED_FDT' in config_target + fdt_required += target + endif + # Add default keys if 'TARGET_BASE_ARCH' not in config_target config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} @@ -1053,7 +1053,54 @@ if have_system endif endif +fdt = not_found +fdt_opt = get_option('fdt') +if have_system + if fdt_opt in ['enabled', 'auto', 'system'] + have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt') + fdt = cc.find_library('fdt', static: enable_static, + required: fdt_opt == 'system' or + fdt_opt == 'enabled' and not have_internal) + if fdt.found() and cc.links(''' + #include + #include + int main(void) { fdt_check_full(NULL, 0); return 0; }''', + dependencies: fdt) + fdt_opt = 'system' + elif have_internal + fdt_opt = 'internal' + else + fdt_opt = 'disabled' + endif + endif + if fdt_opt == 'internal' + fdt_files = files( + 'dtc/libfdt/fdt.c', + 'dtc/libfdt/fdt_ro.c', + 'dtc/libfdt/fdt_wip.c', + 'dtc/libfdt/fdt_sw.c', + 'dtc/libfdt/fdt_rw.c', + 'dtc/libfdt/fdt_strerror.c', + 'dtc/libfdt/fdt_empty_tree.c', + 'dtc/libfdt/fdt_addresses.c', + 'dtc/libfdt/fdt_overlay.c', + 'dtc/libfdt/fdt_check.c', + ) + + fdt_inc = include_directories('dtc/libfdt') + libfdt = static_library('fdt', + sources: fdt_files, + include_directories: fdt_inc) + fdt = declare_dependency(link_with: libfdt, + include_directories: fdt_inc) + endif +endif +if not fdt.found() and fdt_required.length() > 0 + error('fdt not available but required by targets ' + ', '.join(fdt_required)) +endif + config_host_data.set('CONFIG_CAPSTONE', capstone.found()) +config_host_data.set('CONFIG_FDT', fdt.found()) config_host_data.set('CONFIG_SLIRP', slirp.found()) genh += configure_file(output: 'config-host.h', configuration: config_host_data) @@ -1323,7 +1370,7 @@ softmmu_ss.add(files( softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c')) softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp]) -softmmu_ss.add(when: ['CONFIG_FDT', fdt], if_true: [files('device_tree.c')]) +softmmu_ss.add(when: fdt, if_true: files('device_tree.c')) common_ss.add(files('cpus-common.c')) @@ -1817,7 +1864,7 @@ endif summary_info += {'malloc trim support': has_malloc_trim} summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')} summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')} -summary_info += {'fdt support': config_host.has_key('CONFIG_FDT')} +summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')} summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')} summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')} diff --git a/meson_options.txt b/meson_options.txt index 8a362fb08d..1d3c94840a 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -55,3 +55,6 @@ option('capstone', type: 'combo', value: 'auto', option('slirp', type: 'combo', value: 'auto', choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], description: 'Whether and how to find the slirp library') +option('fdt', type: 'combo', value: 'auto', + choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], + description: 'Whether and how to find the libfdt library') From patchwork Tue Oct 6 07:29:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377279 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=pBEYnbw1; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58tt1CNyz9sS8 for ; Tue, 6 Oct 2020 18:56:54 +1100 (AEDT) Received: from localhost ([::1]:60046 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhq7-0002ew-0S for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:56:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39728) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQH-0002t5-2O for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:09 -0400 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]:42744) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQF-0001Si-2c for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:08 -0400 Received: by mail-wr1-x435.google.com with SMTP id e18so6321845wrw.9 for ; Tue, 06 Oct 2020 00:30:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=y+UrAyYkzrV9dWLGTb0lTUMTAA7wKFKG4L00OYHnaU4=; b=pBEYnbw1eMU+BqtSc34a/n08PLkcX5nb9fdBeql3fzC0bxwh59C9U8P2hZoUeqzfXe waywB9eXR06mjP4aW2gg5d4jeGQzD972el9EUYw58d0Xir1wJRkmqmMmMCclJroMQ/Ed gcUlV3WmNzl2JhW3murFb8Lsk3SewsX8czODJJqgoow4slWv+PFc3i63KUZSkqZl6V2H s0IUy/nGUmxjCiHwhe5BbNiDrOS+WPmEnpsheQHkJJKazC1QPeuCaxbNfKMyp/3WJ9IQ QKVVZtq/8NAHucFD/wEPq3FEHSh459BPzwG9wd+MgQkCKjjIXvgI7vCIpF3Fuu4/kkxg wlww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=y+UrAyYkzrV9dWLGTb0lTUMTAA7wKFKG4L00OYHnaU4=; b=rj8BT6OgUywsacIVLUGyddro2nURqaW3gCS+jiDfHs9bri7HzShe4AOfSZncTNy7k4 I6Pt4Z2HeIPZIXVYhYzQdScld0DQj37qJ9M/8Qajl+ll6h4Uyt+4IahHcRWw3WPBiHY9 OLzEJ3z5lNRx14VTtM5Hc/jedBk6a3hg4QJyufVzCWm8lo+34CrmKNB/riH84MatiHwY afYgygbXbe5WNyuNNmAcn1nCvOSN1c2c+GKmVlfJBDWFAwL4n9l0yeN2LHR73NIBk3Fo vNEMomBjCkhCIxqscUoAeiX93Xgc7nPkj55s9oxSu45JGT5MjS+RUBBTGgqiDRlqPuBN yk7g== X-Gm-Message-State: AOAM530pchTag6x9l9UkKEceVx1zJglelZaeXwdVSfeQr1hPd5pj5uRG TtM9NANgoIyk14PhGr905Aixa75UgaU= X-Google-Smtp-Source: ABdhPJwm2k2LVd9S7AubC8DWpQCqwTcX9lMNHHkGOzzh8vrNe4/fg1vh75EJLfMXiSZ6AAn25HBwvg== X-Received: by 2002:adf:d850:: with SMTP id k16mr3252633wrl.259.1601969405372; Tue, 06 Oct 2020 00:30:05 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:04 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 21/37] configure: do not clobber environment CFLAGS/CXXFLAGS/LDFLAGS Date: Tue, 6 Oct 2020 09:29:31 +0200 Message-Id: <20201006072947.487729-22-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::435; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x435.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" If the CFLAGS, CXXFLAGS or LDFLAGS variables are present in the environment, any modification made within the configure script is passed down to Meson. This is particularly undesirable for the "-pie" option, since it overrides "-shared" and thus messes up the linker flags for shared modules. Using a separate variable therefore fixes the bug, while clarifying that the scope of these CFLAGS is just the configure script. We also do not need to pass those variables in config-host.mak; they were only used for printing the summary now that all submodules are built with handwritten Meson rules). For now synthesize CFLAGS in the configuration summary, the next patch will also pass them in a cleaner way using the cross file. Reported-by: Frederic Bezies Analyzed-by: Toolybird Tested-by: Richard Henderson Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini Message-Id: <20200923092617.1593722-4-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini --- configure | 38 +++++++++++++++++--------------------- meson.build | 3 ++- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/configure b/configure index 2fdb4339e8..1b173276ea 100755 --- a/configure +++ b/configure @@ -155,7 +155,7 @@ update_cxxflags() { # options which some versions of GCC's C++ compiler complain about # because they only make sense for C programs. QEMU_CXXFLAGS="$QEMU_CXXFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS" - CXXFLAGS=$(echo "$CFLAGS" | sed s/-std=gnu99/-std=gnu++11/) + CONFIGURE_CXXFLAGS=$(echo "$CONFIGURE_CFLAGS" | sed s/-std=gnu99/-std=gnu++11/) for arg in $QEMU_CFLAGS; do case $arg in -Wstrict-prototypes|-Wmissing-prototypes|-Wnested-externs|\ @@ -170,13 +170,14 @@ update_cxxflags() { compile_object() { local_cflags="$1" - do_cc $CFLAGS $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC + do_cc $CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -c -o $TMPO $TMPC } compile_prog() { local_cflags="$1" local_ldflags="$2" - do_cc $CFLAGS $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $QEMU_LDFLAGS $local_ldflags + do_cc $CFLAGS $CONFIGURE_CFLAGS $QEMU_CFLAGS $local_cflags -o $TMPE $TMPC \ + $LDFLAGS $CONFIGURE_LDFLAGS $QEMU_LDFLAGS $local_ldflags } # symbolically link $1 to $2. Portable version of "ln -sf". @@ -537,7 +538,10 @@ QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS" QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS" QEMU_INCLUDES="-iquote . -iquote ${source_path} -iquote ${source_path}/accel/tcg -iquote ${source_path}/include" QEMU_INCLUDES="$QEMU_INCLUDES -iquote ${source_path}/disas/libvixl" -CFLAGS="-std=gnu99 -Wall" + +# Flags that are needed during configure but later taken care of by Meson +CONFIGURE_CFLAGS="-std=gnu99 -Wall" +CONFIGURE_LDFLAGS= check_define() { @@ -851,7 +855,7 @@ if test "$mingw32" = "yes" ; then EXESUF=".exe" HOST_DSOSUF=".dll" # MinGW needs -mthreads for TLS and macro _MT. - CFLAGS="-mthreads $CFLAGS" + CONFIGURE_CFLAGS="-mthreads $CONFIGURE_CFLAGS" write_c_skeleton; prefix="/qemu" qemu_suffix="" @@ -2109,7 +2113,7 @@ fi if test "$static" = "yes"; then if test "$pie" != "no" && compile_prog "-Werror -fPIE -DPIE" "-static-pie"; then - CFLAGS="-fPIE -DPIE $CFLAGS" + CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS" QEMU_LDFLAGS="-static-pie $QEMU_LDFLAGS" pie="yes" elif test "$pie" = "yes"; then @@ -2119,11 +2123,11 @@ if test "$static" = "yes"; then pie="no" fi elif test "$pie" = "no"; then - CFLAGS="$CFLAGS_NOPIE $CFLAGS" - LDFLAGS="$LDFLAGS_NOPIE $LDFLAGS" + CONFIGURE_CFLAGS="$CFLAGS_NOPIE $CONFIGURE_CFLAGS" + CONFIGURE_LDFLAGS="$LDFLAGS_NOPIE $CONFIGURE_LDFLAGS" elif compile_prog "-Werror -fPIE -DPIE" "-pie"; then - CFLAGS="-fPIE -DPIE $CFLAGS" - LDFLAGS="-pie $LDFLAGS" + CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS" + CONFIGURE_LDFLAGS="-pie $CONFIGURE_LDFLAGS" pie="yes" elif test "$pie" = "yes"; then error_exit "PIE not available due to missing toolchain support" @@ -3667,7 +3671,7 @@ EOF if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then if cc_has_warning_flag "-Wno-unknown-attributes"; then glib_cflags="-Wno-unknown-attributes $glib_cflags" - CFLAGS="-Wno-unknown-attributes $CFLAGS" + CONFIGURE_CFLAGS="-Wno-unknown-attributes $CONFIGURE_CFLAGS" fi fi @@ -3687,7 +3691,7 @@ EOF if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then if cc_has_warning_flag "-Wno-unused-function"; then glib_cflags="$glib_cflags -Wno-unused-function" - CFLAGS="$CFLAGS -Wno-unused-function" + CONFIGURE_CFLAGS="$CONFIGURE_CFLAGS -Wno-unused-function" fi fi @@ -5814,13 +5818,6 @@ elif test "$fortify_source" = "yes" ; then QEMU_CFLAGS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $QEMU_CFLAGS" debug=no fi -if test "$debug_info" = "yes"; then - CFLAGS="-g $CFLAGS" - LDFLAGS="-g $LDFLAGS" -fi -if test "$debug" = "no"; then - CFLAGS="-O2 $CFLAGS" -fi case "$ARCH" in alpha) @@ -6043,7 +6040,7 @@ EOF update_cxxflags - if do_cxx $CXXFLAGS $QEMU_CXXFLAGS -o $TMPE $TMPCXX $TMPO $QEMU_LDFLAGS; then + if do_cxx $CXXFLAGS $CONFIGURE_CXXFLAGS $QEMU_CXXFLAGS -o $TMPE $TMPCXX $TMPO $QEMU_LDFLAGS; then # C++ compiler $cxx works ok with C compiler $cc : else @@ -6953,7 +6950,6 @@ echo "RANLIB=$ranlib" >> $config_host_mak echo "NM=$nm" >> $config_host_mak echo "PKG_CONFIG=$pkg_config_exe" >> $config_host_mak echo "WINDRES=$windres" >> $config_host_mak -echo "CFLAGS=$CFLAGS" >> $config_host_mak echo "CFLAGS_NOPIE=$CFLAGS_NOPIE" >> $config_host_mak echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak diff --git a/meson.build b/meson.build index 0b8ec210f0..8904f7d79b 100644 --- a/meson.build +++ b/meson.build @@ -1771,7 +1771,8 @@ if targetos == 'darwin' summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]} endif summary_info += {'ARFLAGS': config_host['ARFLAGS']} -summary_info += {'CFLAGS': config_host['CFLAGS']} +summary_info += {'CFLAGS': '-O' + get_option('optimization') + + (get_option('debug') ? ' -g' : '')} summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']} summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']} summary_info += {'make': config_host['MAKE']} From patchwork Tue Oct 6 07:29:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=ZyU213aW; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58w4444rz9sT6 for ; Tue, 6 Oct 2020 18:57:56 +1100 (AEDT) Received: from localhost ([::1]:33964 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhr8-0003Zg-H9 for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:57:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39740) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQH-0002vB-Ux for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:09 -0400 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]:43086) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQF-0001Sp-U4 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:09 -0400 Received: by mail-wr1-x42b.google.com with SMTP id g12so6786389wrp.10 for ; Tue, 06 Oct 2020 00:30:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QD62H5XkAmpd2dqgC0nz663beoGd0ich9bGXwmd81oM=; b=ZyU213aWb/FUh7lDABIArF7Qyn6GBo/fEcAf4QoVMz2rBRatuR3k+8z2H+Ls+83Vz1 uC2Krdmx/oAQnxuJqvpYYgZoX3NgABvh4MqVztmpQHI1J7JkbxRofxAlvzzx9Q6P8jqa GE7t3zBOpDdBhWtiYlH2Z7+5HaK0NE3/TcTTjijkJM8B/3GyVcIaFhAHVbXJSgrNnbA0 xvcOREczN0Xi3KEkS5zdyAXVStoc6t3IOOr17MyLwdfptyrp9YzzwwirEQNUO0OasZcF cdvxTgaWRuVyhZ71qw6sIO20Ub6T1t8f1FkWXvJw50nQqhGtc24FLajIP1lrVfW9Z1BL GiIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=QD62H5XkAmpd2dqgC0nz663beoGd0ich9bGXwmd81oM=; b=jWgV+CFPoZ6eejDAV6gaWQEfaQYVWUdXlyqEUSRwmxmEznW9P+wnLtcDgMxg35Tt+I /C3rFtTazKTt/TpdN8qPAEwouZZnzaoFufveJkRVEoO909KtxNTYdojJPlZmwZBR6l1l VALMDMRfyqonrjA3SPrgkTrrPe3DOI8q6kXrJzVgcTmkZlnY5GWCZ01oHRbOl0WPtv5A ZJTuSz42SPySoGsDomo8G//Kc8FpCgYoLQ77EP2ZEsRE9mAxaU9bZ/RZNP3lBB4W76uk MfNga8ISl3skMYP17GSwv7lmEwGPRBV01chGvfSs7XOklx3BNcROEEGdLeLS70StyyCP /3aQ== X-Gm-Message-State: AOAM533Bee9/u30tDpCJM97TJdBxPYxjabvjsTI8M1fblPF8t+Jgw555 v9oaVDyFNC3RHk6LSt12miaivXdVNF4= X-Google-Smtp-Source: ABdhPJwXIgZ+eC+ZPkFFuy1qZ0WVh+wwNkIh0jrLe9LW77PDPVEFLnSNbMpj8rbwunDHf115eas5dg== X-Received: by 2002:a5d:51ca:: with SMTP id n10mr3339504wrv.222.1601969406311; Tue, 06 Oct 2020 00:30:06 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:05 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 22/37] configure: consistently pass CFLAGS/CXXFLAGS/LDFLAGS to meson Date: Tue, 6 Oct 2020 09:29:32 +0200 Message-Id: <20201006072947.487729-23-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42b; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42b.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Environment variables like CFLAGS are easy to accidentally change. Meson warns if that happens, but in a project with a lot of configuration that is easy to lose. It is also surprising behavior since meson caches -D options and remembers those on reconfiguration (which we rely on, since configure options become -D options). By placing the user-provided CFLAGS, CXXFLAGS and LDFLAGS in the cross file, we at least get consistent behavior. These environment variables are still ugly and not really recommended, but there are distros that rely on them. For the gory details, refer to https://github.com/mesonbuild/meson/issues/4664. Tested-by: Richard Henderson Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini Message-Id: <20200923092617.1593722-5-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini --- configure | 25 +++++++++++++++---------- meson.build | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/configure b/configure index 1b173276ea..04c8cc017c 100755 --- a/configure +++ b/configure @@ -7130,24 +7130,29 @@ echo "export PYTHON='$python'" >> "$iotests_common_env" if test "$skip_meson" = no; then cross="config-meson.cross.new" meson_quote() { - echo "['$(echo $* | sed "s/ /','/g")']" + echo "'$(echo $* | sed "s/ /','/g")'" } echo "# Automatically generated by configure - do not modify" > $cross echo "[properties]" >> $cross test -z "$cxx" && echo "link_language = 'c'" >> $cross +echo "[built-in options]" >> $cross +echo "c_args = [${CFLAGS:+$(meson_quote $CFLAGS)}]" >> $cross +echo "cpp_args = [${CXXFLAGS:+$(meson_quote $CXXFLAGS)}]" >> $cross +echo "c_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross +echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross echo "[binaries]" >> $cross -echo "c = $(meson_quote $cc)" >> $cross -test -n "$cxx" && echo "cpp = $(meson_quote $cxx)" >> $cross -echo "ar = $(meson_quote $ar)" >> $cross -echo "nm = $(meson_quote $nm)" >> $cross -echo "pkgconfig = $(meson_quote $pkg_config_exe)" >> $cross -echo "ranlib = $(meson_quote $ranlib)" >> $cross +echo "c = [$(meson_quote $cc)]" >> $cross +test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross +echo "ar = [$(meson_quote $ar)]" >> $cross +echo "nm = [$(meson_quote $nm)]" >> $cross +echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross +echo "ranlib = [$(meson_quote $ranlib)]" >> $cross if has $sdl2_config; then - echo "sdl2-config = $(meson_quote $sdl2_config)" >> $cross + echo "sdl2-config = [$(meson_quote $sdl2_config)]" >> $cross fi -echo "strip = $(meson_quote $strip)" >> $cross -echo "windres = $(meson_quote $windres)" >> $cross +echo "strip = [$(meson_quote $strip)]" >> $cross +echo "windres = [$(meson_quote $windres)]" >> $cross if test -n "$cross_prefix"; then cross_arg="--cross-file config-meson.cross" echo "[host_machine]" >> $cross diff --git a/meson.build b/meson.build index 8904f7d79b..17c89c87c6 100644 --- a/meson.build +++ b/meson.build @@ -1771,8 +1771,18 @@ if targetos == 'darwin' summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]} endif summary_info += {'ARFLAGS': config_host['ARFLAGS']} -summary_info += {'CFLAGS': '-O' + get_option('optimization') - + (get_option('debug') ? ' -g' : '')} +summary_info += {'CFLAGS': ' '.join(get_option('c_args') + + ['-O' + get_option('optimization')] + + (get_option('debug') ? ['-g'] : []))} +if link_language == 'cpp' + summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + + ['-O' + get_option('optimization')] + + (get_option('debug') ? ['-g'] : []))} +endif +link_args = get_option(link_language + '_link_args') +if link_args.length() > 0 + summary_info += {'LDFLAGS': ' '.join(link_args)} +endif summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']} summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']} summary_info += {'make': config_host['MAKE']} From patchwork Tue Oct 6 07:29:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377243 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=OJ7EvcrZ; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58QQ3GHWz9sS8 for ; Tue, 6 Oct 2020 18:35:41 +1100 (AEDT) Received: from localhost ([::1]:50468 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhVa-0000LN-Gw for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:35:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39744) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQI-0002w4-BE for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:10 -0400 Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]:46267) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQG-0001Su-NB for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:09 -0400 Received: by mail-wr1-x42c.google.com with SMTP id o5so12222378wrn.13 for ; Tue, 06 Oct 2020 00:30:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rX/2cdjF+IuOQnPp1vgFSyENqGKo+72G+GCVvdtD8j4=; b=OJ7EvcrZsBtrqbmDuOZlKzZwGCzCSBYc2kJZcrl1IlOcG5jjYSogfxeXAXwaOTT1Eg 4s/5AX9PkqWdgybN8O0RVEhmCzbhz7J0u8iB2Xf8ag13WzkLNoU/jEqsmh0ifshqcul2 VDj3RZIkvqcrdxtnS4dxZ3rnB3QQteDc+JK5zp9SaYlzA0up/wpSvZSXuVxOw5/JtX3X cYMxKveYswS7zvGfOjJOCxAfVVXt+BFHICE6ovFN1qLbZXm/+dJaqNbDX1RrTcUMiNsS P3oGMCgbks2MViCbbf3jBs9/N1wegFXx7V0SDfaiXeYsUzNdtwmGhAWpmp7UwJCfP8FH +uSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=rX/2cdjF+IuOQnPp1vgFSyENqGKo+72G+GCVvdtD8j4=; b=bj+Au3SjebL2D9o58n2T8EiwDYyCQRJyhUq6lNDHCmRM2lm/A5l1i6Nv6bfACkWRXu SC0+FI5p3BWT0VFdefAo/atMtvAOTOBlpIxFN/goxo5fHlVoOzaEHJ5sJFhW6KeNi8Lg G9wxJVDp6SiyRKb8ggroYHd+QxScTNC8VNW9kITno57MzE03oPs1TNaSQv5LF+izyX/U BXQPU+/ipt0GOY6DpGUB0bv9MpXrpk3Ae+x4Ha7qhjj/i4K46j2JUiqizrtZ+ebU1FJn ojruXJt7c2VrcDjwWx4Dh4C9KR+jA1hUDNxl7L40CLhaHvF4ElbYJ30OEUT3BYau5LJB Na4A== X-Gm-Message-State: AOAM533CHeIcQQ8+1/mMKXMA1ykjk3Eg8k9jZTczgR6LEXQueBX8x+L1 EEAU1gIPPMcUaS3b+g++hGMYCT2uGhw= X-Google-Smtp-Source: ABdhPJxgp8MbFnQ8Po0YZis6YYKlhiSbdxBD9e8P7vo8sZsb7qKn+kbeL4lwgwCPulYDD6mocoz9iA== X-Received: by 2002:adf:90a2:: with SMTP id i31mr3606709wri.276.1601969407103; Tue, 06 Oct 2020 00:30:07 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:06 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 23/37] configure: don't enable ASLR for --enable-debug Windows builds Date: Tue, 6 Oct 2020 09:29:33 +0200 Message-Id: <20201006072947.487729-24-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42c; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42c.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Cave-Ayland Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Mark Cave-Ayland Unlike other OSs it is not possible for gdb to temporarily disable ASLR when debugging executables on Windows which causes gdb to fail with memory access errors when trying to debug QEMU. Keep ASLR enabled by default on Windows via the --dynamicbase compiler flag except for --enable-debug builds when there is a clear expectation that a functioning gdb is expected at the cost of slightly less security. Signed-off-by: Mark Cave-Ayland Message-Id: <20201005133434.12614-1-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini --- configure | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 04c8cc017c..28df227db5 100755 --- a/configure +++ b/configure @@ -5882,7 +5882,14 @@ fi # Use ASLR, no-SEH and DEP if available if test "$mingw32" = "yes" ; then - for flag in --dynamicbase --no-seh --nxcompat; do + flags="--no-seh --nxcompat" + + # Disable ASLR for debug builds to allow debugging with gdb + if test "$debug" = "no" ; then + flags="--dynamicbase $flags" + fi + + for flag in $flags; do if ld_has $flag ; then QEMU_LDFLAGS="-Wl,$flag $QEMU_LDFLAGS" fi From patchwork Tue Oct 6 07:29:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377281 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=hy188HPh; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58xx5cHXz9sSs for ; Tue, 6 Oct 2020 18:59:33 +1100 (AEDT) Received: from localhost ([::1]:36388 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhsc-0004bd-AS for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:59:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39762) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQJ-0002yd-Fg for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:11 -0400 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:41041) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQH-0001T3-Kr for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:11 -0400 Received: by mail-wr1-x433.google.com with SMTP id w5so12225513wrp.8 for ; Tue, 06 Oct 2020 00:30:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tgn9X5Mgui13Q+dtY55MzZygmKQubhoFj4bw4p092H0=; b=hy188HPhkYVS2OOefQzrhKPFfpS799eBb4iLxp6A3Yaxkwv3HFlNk8vNUBEDSp469o 7vE8IJwKW8yBe8LJGNWNX8LA+H/+XxUtG06J2vsYqRXr4KyK+y/2ATTEIedp2L79bsr9 AGsl4c9wZzIVvskbTg7ILjbTsaAcMZtoQ2voDkQWpgnoDt6eAucs+JEC4q/srKEjNeQN 2hpwvpgGX4FLj2gQX2oeZowsUMG+I7T2i2AgN9xBzJUDVREILGwVFtOjgaL6zIDAp+Sn FXG09LkDhs99BZTiSfv9QZbuvrx1mI1m1Zsf7oJv0svyvCjhr4qp4kNxEHI5tJ1ymzHO 5ODA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=tgn9X5Mgui13Q+dtY55MzZygmKQubhoFj4bw4p092H0=; b=J7Q1j6kK0ldv8hkdNjG4npnSvQsK8LQbIJnn24cQunfydt5pQMvRWKLy0AlZnCn7yX Q0FwU1vzVgBkqZt9py67qPDjBj/mc+Rm3tlhd5bylBmytzS514wciR9fqm7mV8fY8Vhf txB3fvALX7Rw8YrrMfuJs1oj0Q0lagBJZME7Rb0HSS4UZfUOHfsNDWlHwHxEHiT+YI9k l832FfSt6OBYuR2pt7rv8q8OfbE0EkduE3M2LJuU957ByKPHkkn4xpOzSFPqX2LNC+DQ Juk7G249aBsCtrFri1hBMj2cq/0RveaAvaESzSp1+Zo+9CgOYEaoEEijzoMhdV23pBKI km/A== X-Gm-Message-State: AOAM532BWFlKEPC/6D7m59zTdgjkUfFcDT0O3JHnKvoSPHDWCv5FZs+M cCLWUFQ6EL+V7RblLfE5Yf06CDOoiPg= X-Google-Smtp-Source: ABdhPJxAk1CYIrx2ddZyo8Y37CV26h9DSy3VHODQf/GiBVnAG77heCVDo7JC2wphp50ANmSuEH/pYA== X-Received: by 2002:adf:d18c:: with SMTP id v12mr3241864wrc.131.1601969407980; Tue, 06 Oct 2020 00:30:07 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:07 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 24/37] replay: don't record interrupt poll Date: Tue, 6 Oct 2020 09:29:34 +0200 Message-Id: <20201006072947.487729-25-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::433; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x433.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Pavel Dovgalyuk , =?utf-8?q?Philippe_Mathieu-Dau?= =?utf-8?q?d=C3=A9?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk Interrupt poll is not a real interrupt event. It is needed only for thread safety. This interrupt is used for i386 and converted to hardware interrupt by cpu_handle_interrupt function. Therefore it is not needed to be recorded, because hardware interrupt will be recorded after converting. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé --- v4 changes: - Condition check refactoring (suggested by Alex Bennée) Message-Id: <160174517124.12451.12983410242461131737.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- accel/tcg/cpu-exec.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 0dbe67acf5..58aea605d8 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -436,8 +436,7 @@ static inline bool cpu_handle_halt(CPUState *cpu) { if (cpu->halted) { #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY) - if ((cpu->interrupt_request & CPU_INTERRUPT_POLL) - && replay_interrupt()) { + if (cpu->interrupt_request & CPU_INTERRUPT_POLL) { X86CPU *x86_cpu = X86_CPU(cpu); qemu_mutex_lock_iothread(); apic_poll_irq(x86_cpu->apic_state); @@ -533,6 +532,20 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret) return false; } +/* + * CPU_INTERRUPT_POLL is a virtual event which gets converted into a + * "real" interrupt event later. It does not need to be recorded for + * replay purposes. + */ +static inline bool need_replay_interrupt(int interrupt_request) +{ +#if defined(TARGET_I386) + return !(interrupt_request & CPU_INTERRUPT_POLL); +#else + return true; +#endif +} + static inline bool cpu_handle_interrupt(CPUState *cpu, TranslationBlock **last_tb) { @@ -594,7 +607,9 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, and via longjmp via cpu_loop_exit. */ else { if (cc->cpu_exec_interrupt(cpu, interrupt_request)) { - replay_interrupt(); + if (need_replay_interrupt(interrupt_request)) { + replay_interrupt(); + } /* * After processing the interrupt, ensure an EXCP_DEBUG is * raised when single-stepping so that GDB doesn't miss the From patchwork Tue Oct 6 07:29:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377255 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=vG67bz7e; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Wk3Bxgz9sS8 for ; Tue, 6 Oct 2020 18:40:18 +1100 (AEDT) Received: from localhost ([::1]:40558 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPha4-0007vB-D5 for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:40:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39766) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQK-00030G-5f for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:12 -0400 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]:50457) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQI-0001TB-Ew for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:11 -0400 Received: by mail-wm1-x331.google.com with SMTP id 13so1845667wmf.0 for ; Tue, 06 Oct 2020 00:30:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cpyQLJv0wdPNrXTFIzMBIsZDapctBMjUV4cbdzJBuo8=; b=vG67bz7ebTOVQJz9RT/YmTd7evzbpRD3qQJl3fsAohvrZX4eQpbbGBPe6VgEEx7ONv W1zMLyRAPjQhLgKmnyKFOflPD9PzgL6lPhrNyG3p+j6x/6xjvftVJjePBksiMbJwTaXI YStHhPZ+y88HcpkFvrDpFHDaavpMvNFBSK5jroDTS+qy1PvpHTsAEucpYGGd0ncqbG49 vm6qnQZn1Wf9KFIm1RsyiM6t8VhfNmDAUFW9BYqCrPLl4qMckK/S4rJGhVbunf6rnMZL Y15qmfA+I44kmbyqZ5C0MEB+9eNg1yHNCSPIRaeLTI4izu887mEy/nebHAALTfi+qYKZ b+8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=cpyQLJv0wdPNrXTFIzMBIsZDapctBMjUV4cbdzJBuo8=; b=DS9dbGN6RMR4ViM9EBOnCNFHIebtBTFQz/AM84/gtsWYlf3R8ST4cvp/Hh0CWRDOBK owvbupzZ8T/2zdCYfDd1VlDxdtKZ9K3hucRPOr0ok4wIgz2Z8vFEczxVBheGS1X79ZJC qra33kzmkjYa2LZM6UcTVZnLZ7IEIWW9rwy/iR3s5QTsBUGdoaqyMxVXqJbB1ZYgj0LN F9M4szsTJcJt7sngemmCf9g2Z9DJWUBP0ReJ6OFT3mSoC42lJf1b+08EmtL44citbABD 26Q8QJx6ki8TylZtPYTcwWlvt0UIgbdAjJDpuT6s/jhiQcX/NwMpjXdyVkPyObi3tjNv cyHg== X-Gm-Message-State: AOAM5339mqe3LT65qfN7p085wVx2AVref/m3C/tBwylmexjViFDCYCsC fT0Qz4StUK1FE7+92pdxFcOkLfg0Yfo= X-Google-Smtp-Source: ABdhPJyleGGaJRe8grVKKfHjm09vYC/FDyF56I2nW7N/1xd7te3g9UIR8VIm9pWMuVo1okKF7ggRMQ== X-Received: by 2002:a7b:c081:: with SMTP id r1mr3219414wmh.158.1601969408843; Tue, 06 Oct 2020 00:30:08 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:08 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 25/37] replay: provide an accessor for rr filename Date: Tue, 6 Oct 2020 09:29:35 +0200 Message-Id: <20201006072947.487729-26-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::331; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x331.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Pavel Dovgalyuk , Pavel Dovgalyuk , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds an accessor function for the name of the record/replay log file. Adding an accessor instead of making variable global, prevents accidental modification of this variable by other modules. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Message-Id: <160174517710.12451.17645787545733927488.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- include/sysemu/replay.h | 2 ++ replay/replay.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index a140d69a73..7d963139e5 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -72,6 +72,8 @@ void replay_start(void); void replay_finish(void); /*! Adds replay blocker with the specified error description */ void replay_add_blocker(Error *reason); +/* Returns name of the replay log file */ +const char *replay_get_filename(void); /* Processing the instructions */ diff --git a/replay/replay.c b/replay/replay.c index 4c1457b07e..797b6a5b15 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -399,3 +399,8 @@ void replay_add_blocker(Error *reason) { replay_blockers = g_slist_prepend(replay_blockers, reason); } + +const char *replay_get_filename(void) +{ + return replay_filename; +} From patchwork Tue Oct 6 07:29:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377282 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=KZbyErKh; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C590f5Qrqz9sS8 for ; Tue, 6 Oct 2020 19:01:53 +1100 (AEDT) Received: from localhost ([::1]:39152 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhux-0005sZ-Od for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 04:01:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39790) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQL-00034j-Jz for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:13 -0400 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]:35485) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQJ-0001TO-I4 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:13 -0400 Received: by mail-wm1-x334.google.com with SMTP id q5so1203347wmq.0 for ; Tue, 06 Oct 2020 00:30:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0sroHSxG+CDkmdBtRayI+aa5wxYg8jTsjHn44flQrBg=; b=KZbyErKhi0j2XPt4s/tuXwyy3bVQKfEx4SF+5wSa73uvUF4wzNAmbmqFFpQ3aEexkP h2386QAMsacltax89c2dro0Uth0bIiPcCaFnwuDDR/Kg8wraDlBLCShSDBTnJbvrjJ73 npE0AYxslvX6Ca90mpV2EUe1liBbWe5V5FbWxbwp+wlwooTfR9yF4uAHgRI5CoT37RZ7 hNbmshUX4g2Ptqn3ly6P/jwdwCpP80zFbfeqH5gCt7cX1MaDM4+zoVMvqSNMbOmOddrO Gjy4BbX/PCxnPgIYCbgfkbjuBJLGmHaw2M+k+hkwLs37gDnH4VddRFdGQt3Mes/jp10M aeFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=0sroHSxG+CDkmdBtRayI+aa5wxYg8jTsjHn44flQrBg=; b=EpUQJg5VOnwofpGtrrh8YcBUkad8gwgWt0/0rQTprU1FwdFT43SpW1oP9uETG/OOwI ke6Vh8FLLKAraL+tec9xv/pDXmpZDWc0STxaXy44Wi1gAQiuAbuRm5H3dV+rSqmBqNf0 zSizY+iKBVvoZQf29rRj50c39oHZJEpY9+tgvnJVrVUBft/jv0eZjONr1BPZNzLvD62b gmNw4MM5KSFTPhN9bHMaBbdzWHBMQTcpoB6APAmJOXwsoyRFQvpXvqGMucmdjkGDWE66 yUjZZQMzn+TZodGzIdxCB2TxmldR1kDKog3WBKoYiqCvli7C9oY8O0G4c7epIQv2N6Gf CSYQ== X-Gm-Message-State: AOAM533TglT14ARleVUR9cjZghLBZsm869DSXudeTlRRaKE0ZOklJxDz XsDT6v3o6Esa+06FawiXHnuARGuZ0js= X-Google-Smtp-Source: ABdhPJzKbg7lUVCv/kSkXECurZUqqLorZUhXXQ+Z4tXL1jLeN7sdbja/zF60gL6pAvcIQjYoiQwewg== X-Received: by 2002:a1c:c342:: with SMTP id t63mr3081494wmf.145.1601969409736; Tue, 06 Oct 2020 00:30:09 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:09 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 26/37] qcow2: introduce icount field for snapshots Date: Tue, 6 Oct 2020 09:29:36 +0200 Message-Id: <20201006072947.487729-27-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::334; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x334.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch introduces the icount field for saving within the snapshot. It is required for navigation between the snapshots in record/replay mode. Signed-off-by: Pavel Dovgalyuk Acked-by: Kevin Wolf --- v7 changes: - also fix the test which checks qcow2 snapshot extra data Message-Id: <160174518284.12451.2301137308458777398.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- block/qcow2-snapshot.c | 7 ++++++ block/qcow2.h | 3 +++ docs/interop/qcow2.txt | 5 ++++ tests/qemu-iotests/261 | 15 ++++++----- tests/qemu-iotests/261.out | 51 +++++++++++++++++++++++++------------- 5 files changed, 58 insertions(+), 23 deletions(-) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 9b68690f56..d68b25e0c5 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -164,6 +164,12 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair, sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; } + if (sn->extra_data_size >= endof(QCowSnapshotExtraData, icount)) { + sn->icount = be64_to_cpu(extra.icount); + } else { + sn->icount = -1ULL; + } + if (sn->extra_data_size > sizeof(extra)) { uint64_t extra_data_end; size_t unknown_extra_data_size; @@ -333,6 +339,7 @@ int qcow2_write_snapshots(BlockDriverState *bs) memset(&extra, 0, sizeof(extra)); extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size); extra.disk_size = cpu_to_be64(sn->disk_size); + extra.icount = cpu_to_be64(sn->icount); id_str_size = strlen(sn->id_str); name_size = strlen(sn->name); diff --git a/block/qcow2.h b/block/qcow2.h index b71e444fca..125ea9679b 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -206,6 +206,7 @@ typedef struct QEMU_PACKED QCowSnapshotHeader { typedef struct QEMU_PACKED QCowSnapshotExtraData { uint64_t vm_state_size_large; uint64_t disk_size; + uint64_t icount; } QCowSnapshotExtraData; @@ -219,6 +220,8 @@ typedef struct QCowSnapshot { uint32_t date_sec; uint32_t date_nsec; uint64_t vm_clock_nsec; + /* icount value for the moment when snapshot was taken */ + uint64_t icount; /* Size of all extra data, including QCowSnapshotExtraData if available */ uint32_t extra_data_size; /* Data beyond QCowSnapshotExtraData, if any */ diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt index 7da0d81df8..0463f761ef 100644 --- a/docs/interop/qcow2.txt +++ b/docs/interop/qcow2.txt @@ -707,6 +707,11 @@ Snapshot table entry: Byte 48 - 55: Virtual disk size of the snapshot in bytes + Byte 56 - 63: icount value which corresponds to + the record/replay instruction count + when the snapshot was taken. Set to -1 + if icount was disabled + Version 3 images must include extra data at least up to byte 55. diff --git a/tests/qemu-iotests/261 b/tests/qemu-iotests/261 index ddcb04f285..848ffa760d 100755 --- a/tests/qemu-iotests/261 +++ b/tests/qemu-iotests/261 @@ -91,7 +91,10 @@ print_snapshot_table() if [ $extra_len -ge 16 ]; then echo " Disk size: $(peek_file_be "$1" $((extra_ofs + 8)) 8)" fi - if [ $extra_len -gt 16 ]; then + if [ $extra_len -ge 24 ]; then + echo " Icount: $(peek_file_be "$1" $((extra_ofs + 16)) 8)" + fi + if [ $extra_len -gt 24 ]; then echo ' Unknown extra data:' \ "$(peek_file_raw "$1" $((extra_ofs + 16)) $((extra_len - 16)) \ | tr -d '\0')" @@ -198,12 +201,12 @@ truncate -s 0 "$TEST_DIR/sn0-extra" truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn0-pre") - 40)) \ "$TEST_DIR/sn0-post" -# Set sn1's extra data size to 42 -poke_file "$TEST_DIR/sn1-pre" 36 '\x00\x00\x00\x2a' -truncate -s 42 "$TEST_DIR/sn1-extra" -poke_file "$TEST_DIR/sn1-extra" 16 'very important data' +# Set sn1's extra data size to 50 +poke_file "$TEST_DIR/sn1-pre" 36 '\x00\x00\x00\x32' +truncate -s 50 "$TEST_DIR/sn1-extra" +poke_file "$TEST_DIR/sn1-extra" 24 'very important data' # Grow sn1-post to pad -truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn1-pre") - 82)) \ +truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn1-pre") - 90)) \ "$TEST_DIR/sn1-post" # Set sn2's extra data size to 8 diff --git a/tests/qemu-iotests/261.out b/tests/qemu-iotests/261.out index 2600354566..612433ae40 100644 --- a/tests/qemu-iotests/261.out +++ b/tests/qemu-iotests/261.out @@ -12,9 +12,10 @@ Snapshots in TEST_DIR/t.IMGFMT.v2.orig: [1] ID: 2 Name: sn1 - Extra data size: 42 + Extra data size: 50 VM state size: 0 Disk size: 67108864 + Icount: 0 Unknown extra data: very important data [2] ID: 3 @@ -29,22 +30,25 @@ Snapshots in TEST_DIR/t.IMGFMT.v3.orig: [0] ID: 1 Name: sn0 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 [1] ID: 2 Name: sn1 - Extra data size: 42 + Extra data size: 50 VM state size: 0 Disk size: 67108864 + Icount: 0 Unknown extra data: very important data [2] ID: 3 Name: sn2 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 === Repair botched v3 === @@ -61,22 +65,25 @@ Snapshots in TEST_DIR/t.IMGFMT: [0] ID: 1 Name: sn0 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 [1] ID: 2 Name: sn1 - Extra data size: 42 + Extra data size: 50 VM state size: 0 Disk size: 67108864 + Icount: 0 Unknown extra data: very important data [2] ID: 3 Name: sn2 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 === Add new snapshot === @@ -85,28 +92,32 @@ Snapshots in TEST_DIR/t.IMGFMT: [0] ID: 1 Name: sn0 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 [1] ID: 2 Name: sn1 - Extra data size: 42 + Extra data size: 50 VM state size: 0 Disk size: 67108864 + Icount: 0 Unknown extra data: very important data [2] ID: 3 Name: sn2 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 [3] ID: 4 Name: sn3 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 0 === Remove different snapshots === @@ -116,16 +127,18 @@ Snapshots in TEST_DIR/t.IMGFMT: [0] ID: 2 Name: sn1 - Extra data size: 42 + Extra data size: 50 VM state size: 0 Disk size: 67108864 + Icount: 0 Unknown extra data: very important data [1] ID: 3 Name: sn2 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 --- sn1 --- No errors were found on the image. @@ -133,15 +146,17 @@ Snapshots in TEST_DIR/t.IMGFMT: [0] ID: 1 Name: sn0 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 [1] ID: 3 Name: sn2 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 --- sn2 --- No errors were found on the image. @@ -149,15 +164,17 @@ Snapshots in TEST_DIR/t.IMGFMT: [0] ID: 1 Name: sn0 - Extra data size: 16 + Extra data size: 24 VM state size: 0 Disk size: 67108864 + Icount: 18446744073709551615 [1] ID: 2 Name: sn1 - Extra data size: 42 + Extra data size: 50 VM state size: 0 Disk size: 67108864 + Icount: 0 Unknown extra data: very important data === Reject too much unknown extra data === From patchwork Tue Oct 6 07:29:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377259 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=b6gz9/ay; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58ZM5XdKz9sS8 for ; Tue, 6 Oct 2020 18:42:35 +1100 (AEDT) Received: from localhost ([::1]:48626 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhcH-0002wP-LA for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:42:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39814) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQM-00038M-QZ for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:14 -0400 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]:38421) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQK-0001Ta-Ez for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:14 -0400 Received: by mail-wr1-x434.google.com with SMTP id n18so4415784wrs.5 for ; Tue, 06 Oct 2020 00:30:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vqm6/4FMvwrI7h0blvL6bknr7fh+GWarVad7IzR7GgY=; b=b6gz9/aykmhl5qKu60HMo4KR9iFUxOoeYE8B0MrBS2lSDn05UTwU2D30m4UAPpBcf1 uGp6+5PVAlaBr/yI2JwXdSM4yJa5bumRu1A6I49OiVPgEKBEwOctnrTSZmOzcPEhnDGF oLEU08WJOtPcd6Ph4lFgRXBBsXqzcVqWl4nYDSuhpkEM+iQWe/YkdzDLDmOJsTMRl6oD 5jlF8be2lmf0MdedPrSztPpC9+7HFLMjfyUmujjOosVqmsr1tLZuRNwQyTE9NNe3/1+Q 9WVHvZzoz+M+ijfSEAS/frj9aTqqqD5fsAOgWEtru4ikR+zuDgvG5ggG2aUbFKxubMl7 ooXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=vqm6/4FMvwrI7h0blvL6bknr7fh+GWarVad7IzR7GgY=; b=FN8YP4EBrjQcKY0fzMpwrX/9Cg6ERsC3cFBINGp6OIbCfNAUJLqzkptQ0CXeCqx380 1bIzIY6PggwuMUDMhjUilfZ88+X5TRZYggCcS/H7t18Ntq0uHLstFxJDFuPFA2wEVf3U v+LyuKTqKGCotHDmmlJfcFwZi5unexi52yDkJLS6mjTRhcn6VwRDZeYRokjQHD38CwnO /f/kj5kbW6DpXiKJIbL+9K18G98pDkH4K6itRYpgIpnp0sNLJbKNXJscpLcuuYwwz1NI JIt/3572WrA8ilk5t9Ug7GsUWZnhColWmmgkb+a9G3Li6M9w4TiVu684ipzGpnUBqGbv hFAg== X-Gm-Message-State: AOAM532eE6VbVXvWnuZBu+cqlMZHu9WYp4CkqHXHIuQX06rANjhhjh9x 8AbahKVuSOqZRqKLGFbP4HCRa8bwvp0= X-Google-Smtp-Source: ABdhPJyzJ8Z8DQrny924FudeajllNsT7I66BeWLFSGSsQTT3oCqalUCzfsxzN6aoA96HLwWbgrFfVQ== X-Received: by 2002:adf:e4c9:: with SMTP id v9mr3185026wrm.375.1601969410615; Tue, 06 Oct 2020 00:30:10 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:10 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 27/37] migration: introduce icount field for snapshots Date: Tue, 6 Oct 2020 09:29:37 +0200 Message-Id: <20201006072947.487729-28-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::434; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x434.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Pavel Dovgalyuk , Markus Armbruster Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk Saving icount as a parameters of the snapshot allows navigation between them in the execution replay scenario. This information can be used for finding a specific snapshot for proceeding the recorded execution to the specific moment of the time. E.g., 'reverse step' action (introduced in one of the following patches) needs to load the nearest snapshot which is prior to the current moment of time. This patch also updates snapshot test which verifies qemu monitor output. Signed-off-by: Pavel Dovgalyuk Acked-by: Markus Armbruster Acked-by: Kevin Wolf --- v4 changes: - squashed format update with test output update v7 changes: - introduced the spaces between the fields in snapshot info output - updated the test to match new field widths Message-Id: <160174518865.12451.14327573383978752463.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- block/qapi.c | 18 ++++++++++---- block/qcow2-snapshot.c | 2 ++ blockdev.c | 10 ++++++++ include/block/snapshot.h | 1 + migration/savevm.c | 5 ++++ qapi/block-core.json | 10 ++++++-- stubs/replay.c | 5 ++++ tests/qemu-iotests/261 | 4 ++-- tests/qemu-iotests/267.out | 48 +++++++++++++++++++------------------- 9 files changed, 71 insertions(+), 32 deletions(-) diff --git a/block/qapi.c b/block/qapi.c index f423ece98c..036da085ee 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -230,6 +230,8 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs, info->date_nsec = sn_tab[i].date_nsec; info->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000; info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000; + info->icount = sn_tab[i].icount; + info->has_icount = sn_tab[i].icount != -1ULL; info_list = g_new0(SnapshotInfoList, 1); info_list->value = info; @@ -694,14 +696,15 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, void bdrv_snapshot_dump(QEMUSnapshotInfo *sn) { char date_buf[128], clock_buf[128]; + char icount_buf[128] = {0}; struct tm tm; time_t ti; int64_t secs; char *sizing = NULL; if (!sn) { - qemu_printf("%-10s%-20s%11s%20s%15s", - "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); + qemu_printf("%-10s%-18s%7s%20s%13s%11s", + "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT"); } else { ti = sn->date_sec; localtime_r(&ti, &tm); @@ -715,11 +718,16 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn) (int)(secs % 60), (int)((sn->vm_clock_nsec / 1000000) % 1000)); sizing = size_to_str(sn->vm_state_size); - qemu_printf("%-10s%-20s%11s%20s%15s", + if (sn->icount != -1ULL) { + snprintf(icount_buf, sizeof(icount_buf), + "%"PRId64, sn->icount); + } + qemu_printf("%-9s %-17s %7s%20s%13s%11s", sn->id_str, sn->name, sizing, date_buf, - clock_buf); + clock_buf, + icount_buf); } g_free(sizing); } @@ -881,6 +889,8 @@ void bdrv_image_info_dump(ImageInfo *info) .date_nsec = elem->value->date_nsec, .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL + elem->value->vm_clock_nsec, + .icount = elem->value->has_icount ? + elem->value->icount : -1ULL, }; pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id); diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index d68b25e0c5..2e98c7f4b6 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -663,6 +663,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) sn->date_sec = sn_info->date_sec; sn->date_nsec = sn_info->date_nsec; sn->vm_clock_nsec = sn_info->vm_clock_nsec; + sn->icount = sn_info->icount; sn->extra_data_size = sizeof(QCowSnapshotExtraData); /* Allocate the L1 table of the snapshot and copy the current one there. */ @@ -1007,6 +1008,7 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) sn_info->date_sec = sn->date_sec; sn_info->date_nsec = sn->date_nsec; sn_info->vm_clock_nsec = sn->vm_clock_nsec; + sn_info->icount = sn->icount; } *psn_tab = sn_tab; return s->nb_snapshots; diff --git a/blockdev.c b/blockdev.c index bebd3ba1c3..a6ae475dac 100644 --- a/blockdev.c +++ b/blockdev.c @@ -59,6 +59,7 @@ #include "sysemu/arch_init.h" #include "sysemu/qtest.h" #include "sysemu/runstate.h" +#include "sysemu/replay.h" #include "qemu/cutils.h" #include "qemu/help_option.h" #include "qemu/main-loop.h" @@ -1190,6 +1191,10 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device, info->vm_state_size = sn.vm_state_size; info->vm_clock_nsec = sn.vm_clock_nsec % 1000000000; info->vm_clock_sec = sn.vm_clock_nsec / 1000000000; + if (sn.icount != -1ULL) { + info->icount = sn.icount; + info->has_icount = true; + } return info; @@ -1350,6 +1355,11 @@ static void internal_snapshot_prepare(BlkActionState *common, sn->date_sec = tv.tv_sec; sn->date_nsec = tv.tv_usec * 1000; sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (replay_mode != REPLAY_MODE_NONE) { + sn->icount = replay_get_current_icount(); + } else { + sn->icount = -1ULL; + } ret1 = bdrv_snapshot_create(bs, sn); if (ret1 < 0) { diff --git a/include/block/snapshot.h b/include/block/snapshot.h index 2bfcd57578..b0fe42993d 100644 --- a/include/block/snapshot.h +++ b/include/block/snapshot.h @@ -42,6 +42,7 @@ typedef struct QEMUSnapshotInfo { uint32_t date_sec; /* UTC date of the snapshot */ uint32_t date_nsec; uint64_t vm_clock_nsec; /* VM clock relative to boot */ + uint64_t icount; /* record/replay step */ } QEMUSnapshotInfo; int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, diff --git a/migration/savevm.c b/migration/savevm.c index 34e4b71052..0e8dc78684 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2723,6 +2723,11 @@ int save_snapshot(const char *name, Error **errp) sn->date_sec = tv.tv_sec; sn->date_nsec = tv.tv_usec * 1000; sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (replay_mode != REPLAY_MODE_NONE) { + sn->icount = replay_get_current_icount(); + } else { + sn->icount = -1ULL; + } if (name) { ret = bdrv_snapshot_find(bs, old_sn, name); diff --git a/qapi/block-core.json b/qapi/block-core.json index 12a24772b5..fdc2e5cb28 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -27,13 +27,18 @@ # # @vm-clock-nsec: fractional part in nano seconds to be used with vm-clock-sec # +# @icount: Current instruction count. Appears when execution record/replay +# is enabled. Used for "time-traveling" to match the moment +# in the recorded execution with the snapshots. (since 5.2) +# # Since: 1.3 # ## { 'struct': 'SnapshotInfo', 'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int', 'date-sec': 'int', 'date-nsec': 'int', - 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } } + 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int', + '*icount': 'int' } } ## # @ImageInfoSpecificQCow2EncryptionBase: @@ -5363,7 +5368,8 @@ # "date-sec": 1000012, # "date-nsec": 10, # "vm-clock-sec": 100, -# "vm-clock-nsec": 20 +# "vm-clock-nsec": 20, +# "icount": 220414 # } # } # diff --git a/stubs/replay.c b/stubs/replay.c index 5974ec1f50..eacb366aa8 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -88,3 +88,8 @@ int replay_read_random(void *buf, size_t len) { return 0; } + +uint64_t replay_get_current_icount(void) +{ + return 0; +} diff --git a/tests/qemu-iotests/261 b/tests/qemu-iotests/261 index 848ffa760d..847b4c6a37 100755 --- a/tests/qemu-iotests/261 +++ b/tests/qemu-iotests/261 @@ -392,7 +392,7 @@ _check_test_img -r all echo echo "$((sn_count - 1)) snapshots should remain:" -echo " qemu-img info reports $(_img_info | grep -c '^ \{34\}') snapshots" +echo " qemu-img info reports $(_img_info | grep -c '^ \{32\}') snapshots" echo " Image header reports $(peek_file_be "$TEST_IMG" 60 4) snapshots" echo @@ -519,7 +519,7 @@ _check_test_img -r all echo echo '65536 snapshots should remain:' -echo " qemu-img info reports $(_img_info | grep -c '^ \{34\}') snapshots" +echo " qemu-img info reports $(_img_info | grep -c '^ \{32\}') snapshots" echo " Image header reports $(peek_file_be "$TEST_IMG" 60 4) snapshots" # success, all done diff --git a/tests/qemu-iotests/267.out b/tests/qemu-iotests/267.out index 215902b3ad..27471ffae8 100644 --- a/tests/qemu-iotests/267.out +++ b/tests/qemu-iotests/267.out @@ -33,8 +33,8 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit @@ -44,8 +44,8 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit @@ -69,8 +69,8 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit @@ -94,8 +94,8 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit @@ -105,8 +105,8 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit @@ -119,8 +119,8 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit @@ -134,8 +134,8 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit @@ -145,15 +145,15 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit Internal snapshots on overlay: Snapshot list: -ID TAG VM SIZE DATE VM CLOCK -1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 Internal snapshots on backing file: === -blockdev with NBD server on the backing file === @@ -166,17 +166,17 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) savevm snap0 (qemu) info snapshots List of snapshots present on all disks: -ID TAG VM SIZE DATE VM CLOCK --- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 (qemu) loadvm snap0 (qemu) quit Internal snapshots on overlay: Snapshot list: -ID TAG VM SIZE DATE VM CLOCK -1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 Internal snapshots on backing file: Snapshot list: -ID TAG VM SIZE DATE VM CLOCK -1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 +ID TAG VM SIZE DATE VM CLOCK ICOUNT +1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 *** done From patchwork Tue Oct 6 07:29:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377283 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Gc2WRC44; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C593L6yVCz9sSG for ; Tue, 6 Oct 2020 19:04:14 +1100 (AEDT) Received: from localhost ([::1]:43852 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhxE-0007rD-QF for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 04:04:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39820) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQN-00039e-CG for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:15 -0400 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]:34809) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQL-0001Th-FO for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:14 -0400 Received: by mail-wr1-x432.google.com with SMTP id t10so12239321wrv.1 for ; Tue, 06 Oct 2020 00:30:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UP58U+DMNC1fmxFaM1xVgFDxaCmHGWc/Wt+u50L0cig=; b=Gc2WRC44EZpMIZtxxWauVYEb+zC0gm147KpFzkH3ikNdjnxYm1W9zMlvgHfiCE2uLn pkBfQ8zj7LqxPZ5DENL5T9iflR4KLTju/fASka0IK1k4Vf/w3NK0BNRk0SF4n0KTgw4E cvyzBakrpNUTmE9s69k31ye01nzT8PWp+wFqW2hsNyzotURnBrfP1EYDulZF21AvEoY0 zOOAf8CJDFLaO6dSePyYICo9bCHSzo3zGj/AeadVvoXAL7dDmW9ql1EqrEfLCxRV/8ul 1mJNIJ93MOL888btCh7NIQxRzI395nFytQdtJ9dbz0BYEXw9aLEiJVz4BwOly2kz9MQz ajUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=UP58U+DMNC1fmxFaM1xVgFDxaCmHGWc/Wt+u50L0cig=; b=Io7Au5ZLNuzh6wzKlb2w55kuCFbluMDSS3Y8HgsswjDZdSXUkvtNHyLcxIhAEdRZ3E 5GoUt5r53sOX1vJMRiNF58gydMyaEfyb63Bey8YrgI2X02bp0EedNoCI4B77XxJpMUhT E5gTLm9wElRx7MMFBCIcdfWSDp6JxzVGQx/TQRpE/hEVDj3uqvuiayaBIEos7Wg7avVd xiqnmkd7RALExP2oORa4MM5oxdK4F1Q9dBKvjzJxmFx6tA+ogtfEtPBIi0U2k3V5gqDO LLCTFj+YxE+s2o7Kjr7lV3MRQzgeT3f7gtE5EBzZCqmPWX1GRp4czGqf4u7hkyhgme1n nYiw== X-Gm-Message-State: AOAM531bV/aUa3x2XJPfSU/2xkI7GcGuEh+cjHgUp5Dcx4p74OYEHY3x LF0MQAI2AfufQU8lxx5ng8BHseEr4G0= X-Google-Smtp-Source: ABdhPJzxGONVgEE0bDeMRhLmO7kjwc31xnqJymwptUSY07HAQlBZK8TjGLvz5vlX9j6vH6cVxvLYGg== X-Received: by 2002:a5d:50cd:: with SMTP id f13mr3253730wrt.211.1601969411623; Tue, 06 Oct 2020 00:30:11 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:11 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 28/37] qapi: introduce replay.json for record/replay-related stuff Date: Tue, 6 Oct 2020 09:29:38 +0200 Message-Id: <20201006072947.487729-29-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x432.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Pavel Dovgalyuk , Markus Armbruster , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds replay.json file. It will be used for adding record/replay-related data structures and commands. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Markus Armbruster Reviewed-by: Alex Bennée Message-Id: <160174519444.12451.3472949430004845434.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- MAINTAINERS | 1 + include/sysemu/replay.h | 1 + qapi/meson.build | 1 + qapi/misc.json | 18 ------------------ qapi/qapi-schema.json | 1 + qapi/replay.json | 26 ++++++++++++++++++++++++++ 6 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 qapi/replay.json diff --git a/MAINTAINERS b/MAINTAINERS index 231f854437..417fca5f57 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2696,6 +2696,7 @@ F: include/sysemu/replay.h F: docs/replay.txt F: stubs/replay.c F: tests/acceptance/replay_kernel.py +F: qapi/replay.json IOVA Tree M: Peter Xu diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 7d963139e5..d6026ed8e5 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -14,6 +14,7 @@ #include "qapi/qapi-types-misc.h" #include "qapi/qapi-types-run-state.h" +#include "qapi/qapi-types-replay.h" #include "qapi/qapi-types-ui.h" #include "block/aio.h" diff --git a/qapi/meson.build b/qapi/meson.build index ea359a0148..0e98146f1f 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -39,6 +39,7 @@ qapi_all_modules = [ 'pci', 'qom', 'rdma', + 'replay', 'rocker', 'run-state', 'sockets', diff --git a/qapi/misc.json b/qapi/misc.json index 694d2142f3..7d1e2e9aae 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -757,24 +757,6 @@ 'returns': ['CommandLineOptionInfo'], 'allow-preconfig': true } -## -# @ReplayMode: -# -# Mode of the replay subsystem. -# -# @none: normal execution mode. Replay or record are not enabled. -# -# @record: record mode. All non-deterministic data is written into the -# replay log. -# -# @play: replay mode. Non-deterministic data required for system execution -# is read from the log. -# -# Since: 2.5 -## -{ 'enum': 'ReplayMode', - 'data': [ 'none', 'record', 'play' ] } - ## # @xen-load-devices-state: # diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 8d567e1386..0b444b76d2 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -85,6 +85,7 @@ { 'include': 'qdev.json' } { 'include': 'machine.json' } { 'include': 'machine-target.json' } +{ 'include': 'replay.json' } { 'include': 'misc.json' } { 'include': 'misc-target.json' } { 'include': 'audio.json' } diff --git a/qapi/replay.json b/qapi/replay.json new file mode 100644 index 0000000000..9e13551d20 --- /dev/null +++ b/qapi/replay.json @@ -0,0 +1,26 @@ +# -*- Mode: Python -*- +# + +## +# = Record/replay +## + +{ 'include': 'common.json' } + +## +# @ReplayMode: +# +# Mode of the replay subsystem. +# +# @none: normal execution mode. Replay or record are not enabled. +# +# @record: record mode. All non-deterministic data is written into the +# replay log. +# +# @play: replay mode. Non-deterministic data required for system execution +# is read from the log. +# +# Since: 2.5 +## +{ 'enum': 'ReplayMode', + 'data': [ 'none', 'record', 'play' ] } From patchwork Tue Oct 6 07:29:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377284 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=eCO4XVTg; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C59786cZ8z9sS8 for ; Tue, 6 Oct 2020 19:07:30 +1100 (AEDT) Received: from localhost ([::1]:47242 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPi0M-00013E-RV for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 04:07:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39852) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQP-0003DH-1d for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:17 -0400 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]:51964) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQM-0001UL-P9 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:16 -0400 Received: by mail-wm1-x335.google.com with SMTP id d81so1836303wmc.1 for ; Tue, 06 Oct 2020 00:30:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NxHtyaguhmZyrZzSrjBoVZDX5Qr8ne7K4mckqDbFwHo=; b=eCO4XVTgwP8Vd4y/uHgwpLxmjs3MNVtDdZ0vF/SFUi4ldO8H/JHAtsPfVIpPZliZdk b5BWfnwo7j0b7nE5zslvfrYHb3/PD8xWjbR/eF2p121r+IAd3F7qX0D97Ejvbxor9mld YOgAPGl6XWDbb5Vjy2K/4Lz03BsZCcvoXUFFu/fBxzPFJiY5ASUToM1xC+HOmGmMGYf9 rf3g5YTKcD1XK7cxHoHOwOBxL67pyIvkoHHuDlJRmCk4fTvYzBIOlhC7pEBFoWHRI3PO IhUiciKDX6GqP6FvhfgapJRP092DFdpdOtkDgw+XZLQ3KSUU7OAaLGYv7AH+oa+VJUA3 pYuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=NxHtyaguhmZyrZzSrjBoVZDX5Qr8ne7K4mckqDbFwHo=; b=MBtysHnOvuQqLQxEQheMyK0/9jnRM9jp2GNMMpAeT0XBX2NtDfyWsw+1/AXDpQy/+w Yd2EK8OVGlHdLAYyoUl9Hly7S+waKv3PDtaHZm6fX601VPH5UlbOi8QMjzdhcYUYZZUL pjz0jwNPuhTEMf+CJ8fPJBCtUOy2Ecq1yBWO7RaLcvzwCj7hTXbO7Fm7UBXRuq+g+Nb5 lWSb6mCri6DD8BrqJowqIHAbJjwjlW335cvDmnzqxQsdMIyPf2fafYZT0UyoeUw/2Hk9 /kdxO5De7+IP0+X18ULpP8GMBcP+Y8NozJVOAIl+sGLqs7Msvr4SUdCqhPJ4iPncBPAW OUHw== X-Gm-Message-State: AOAM5335m3dBPbNZBPPrRFUq8uPGfKJRJLTNFATelC0Mu8Dr+ffhu7IP KZFQ9rvUzTKAL5tUVLRovKCAS17cjY0= X-Google-Smtp-Source: ABdhPJzWE1aPmN94PEgA04c32Pi52Vmgl4vusjWNYLXDNQvOwTZcB7i9E3ednZRl1ZBri+2q7DDn6A== X-Received: by 2002:a1c:9e0e:: with SMTP id h14mr3186823wme.18.1601969412602; Tue, 06 Oct 2020 00:30:12 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:12 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 29/37] replay: introduce info hmp/qmp command Date: Tue, 6 Oct 2020 09:29:39 +0200 Message-Id: <20201006072947.487729-30-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::335; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x335.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pavel Dovgalyuk , "Dr . David Alan Gilbert" , Pavel Dovgalyuk , Markus Armbruster Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch introduces 'info replay' monitor command and corresponding qmp request. These commands request the current record/replay mode, replay log file name, and the instruction count (number of recorded/replayed instructions). The instruction count can be used with the replay_seek/replay_break commands added in the next two patches. Signed-off-by: Pavel Dovgalyuk Acked-by: Dr. David Alan Gilbert Acked-by: Markus Armbruster Message-Id: <160174520026.12451.13112161947433306561.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- hmp-commands-info.hx | 11 ++++++++++ include/monitor/hmp.h | 1 + qapi/block-core.json | 3 ++- qapi/replay.json | 39 +++++++++++++++++++++++++++++++++++ replay/meson.build | 1 + replay/replay-debugging.c | 43 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 replay/replay-debugging.c diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 30209e3903..117ba25f91 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -881,4 +881,15 @@ SRST Show SEV information. ERST + { + .name = "replay", + .args_type = "", + .params = "", + .help = "show record/replay information", + .cmd = hmp_info_replay, + }, +SRST + ``info replay`` + Display the record/replay information: mode and the current icount. +ERST diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 642e9e91f9..f297fccce8 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -129,5 +129,6 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict); void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict); void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict); void hmp_info_sev(Monitor *mon, const QDict *qdict); +void hmp_info_replay(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi/block-core.json b/qapi/block-core.json index fdc2e5cb28..3758ea9912 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -29,7 +29,8 @@ # # @icount: Current instruction count. Appears when execution record/replay # is enabled. Used for "time-traveling" to match the moment -# in the recorded execution with the snapshots. (since 5.2) +# in the recorded execution with the snapshots. This counter may +# be obtained through @query-replay command (since 5.2) # # Since: 1.3 # diff --git a/qapi/replay.json b/qapi/replay.json index 9e13551d20..e6b3f6001d 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -24,3 +24,42 @@ ## { 'enum': 'ReplayMode', 'data': [ 'none', 'record', 'play' ] } + +## +# @ReplayInfo: +# +# Record/replay information. +# +# @mode: current mode. +# +# @filename: name of the record/replay log file. +# It is present only in record or replay modes, when the log +# is recorded or replayed. +# +# @icount: current number of executed instructions. +# +# Since: 5.2 +# +## +{ 'struct': 'ReplayInfo', + 'data': { 'mode': 'ReplayMode', '*filename': 'str', 'icount': 'int' } } + +## +# @query-replay: +# +# Retrieve the record/replay information. +# It includes current instruction count which may be used for +# @replay-break and @replay-seek commands. +# +# Returns: record/replay information. +# +# Since: 5.2 +# +# Example: +# +# -> { "execute": "query-replay" } +# <- { "return": { "mode": "play", "filename": "log.rr", "icount": 220414 } } +# +## +{ 'command': 'query-replay', + 'returns': 'ReplayInfo' } diff --git a/replay/meson.build b/replay/meson.build index 8783aea7c8..f91163fb1e 100644 --- a/replay/meson.build +++ b/replay/meson.build @@ -9,4 +9,5 @@ softmmu_ss.add(files( 'replay-net.c', 'replay-audio.c', 'replay-random.c', + 'replay-debugging.c', )) diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c new file mode 100644 index 0000000000..51a6de4e81 --- /dev/null +++ b/replay/replay-debugging.c @@ -0,0 +1,43 @@ +/* + * replay-debugging.c + * + * Copyright (c) 2010-2020 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "sysemu/replay.h" +#include "replay-internal.h" +#include "monitor/hmp.h" +#include "monitor/monitor.h" +#include "qapi/qapi-commands-replay.h" + +void hmp_info_replay(Monitor *mon, const QDict *qdict) +{ + if (replay_mode == REPLAY_MODE_NONE) { + monitor_printf(mon, "Record/replay is not active\n"); + } else { + monitor_printf(mon, + "%s execution '%s': instruction count = %"PRId64"\n", + replay_mode == REPLAY_MODE_RECORD ? "Recording" : "Replaying", + replay_get_filename(), replay_get_current_icount()); + } +} + +ReplayInfo *qmp_query_replay(Error **errp) +{ + ReplayInfo *retval = g_new0(ReplayInfo, 1); + + retval->mode = replay_mode; + if (replay_get_filename()) { + retval->filename = g_strdup(replay_get_filename()); + retval->has_filename = true; + } + retval->icount = replay_get_current_icount(); + return retval; +} From patchwork Tue Oct 6 07:29:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377258 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=PGNlu6zx; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58ZG6RJRz9sS8 for ; Tue, 6 Oct 2020 18:42:30 +1100 (AEDT) Received: from localhost ([::1]:48262 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhcC-0002n3-SL for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:42:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39856) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQP-0003EL-F1 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:17 -0400 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:37488) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQN-0001Ub-87 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:17 -0400 Received: by mail-wr1-x443.google.com with SMTP id h7so8607896wre.4 for ; Tue, 06 Oct 2020 00:30:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Lx7aepaU4oeb9uUi81d1ARWCm8iq4HU6ykoV7TnaemU=; b=PGNlu6zxpVH14oq6A36NwLzFob6q8ObPwMOZKYwfy657B/3WxmKcl4OOgnkm4HU0vo ci8hNFDElMIGDzjI8hicitGOF4TKsm/HPB7ufH6KkxpZkl4GautPNiIoIezXf3cXT1Uy 7sqX/q2p9dUk9b9DW94C/pL1FEb6AuxLj3f1/hiD62OJ8sGMY0s+MA3pZaF1f0V0EU1s P7wQVBYFhpfCSEZfvqEmGhc2Bjy586Ay9BU6vk8T8FLN+XrGtWu5F4KDqDBCoCFazbGR EJpbvDPOz7TfRAEjHdtgMxBHfuNRHQuvod5gv1WRA7CAgfO4Wu7bfb14vJjUscR7f78n cMDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Lx7aepaU4oeb9uUi81d1ARWCm8iq4HU6ykoV7TnaemU=; b=MIQf7RJhmo6i4aTq2zs9m2QcRaI3KU4TfrIyPiCtWymHRbckaaDv9dFdmqLPwrwnFn SjWANEpsijhLV46etJ+Pyts/bU+eHzDMb4TuFG/5UUp443VL0T0XcSmqUixd7cxVlSsB SZN5RyD/lt84WBI5NJCjtpXfQWEsojq66QgqNVaANqVXax579I1I2IP6fev/mT/T2CZA ccEeMwqUNo9DyWSPqUJhJuGV9j96vnIBcbckxyJvGk/Pf6JhsNYvt2Af426adMeijQ46 5YiKBPmOYWzoNxgvV5TWmNUo4xpj0ywIg9znJJg+1Ov/9u6ie7uD/Ul3KdOKY/gyqNMQ RpCg== X-Gm-Message-State: AOAM531kH4dF3+gdtpN6OB+JU8ylxhq8ljqbfLTScvvB3juqYDwqbu25 FLlElU4qFpKF9tISSg4tjnH+SU3BSqk= X-Google-Smtp-Source: ABdhPJy+Sbx6KKFR+eYAA3jYg/j5sbjECPkJcQa5kwUdxXkckbqvC/4hVAh8IqUc133BAYQ9aeNChg== X-Received: by 2002:adf:ecc1:: with SMTP id s1mr3289616wro.120.1601969413371; Tue, 06 Oct 2020 00:30:13 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:12 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 30/37] replay: introduce breakpoint at the specified step Date: Tue, 6 Oct 2020 09:29:40 +0200 Message-Id: <20201006072947.487729-31-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::443; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x443.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pavel Dovgalyuk , Markus Armbruster , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch introduces replay_break, replay_delete_break qmp and hmp commands. These commands allow stopping at the specified instruction. It may be useful for debugging when there are some known events that should be investigated. replay_break command has one argument - number of instructions executed since the start of the replay. replay_delete_break removes previously set breakpoint. Signed-off-by: Pavel Dovgalyuk Acked-by: Markus Armbruster --- v4 changes: - removed useless error_free call Message-Id: <160174520606.12451.7056879546045599378.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- hmp-commands.hx | 32 +++++++++++++++ include/monitor/hmp.h | 2 + qapi/replay.json | 36 +++++++++++++++++ replay/replay-debugging.c | 84 +++++++++++++++++++++++++++++++++++++++ replay/replay-internal.h | 4 ++ replay/replay.c | 17 ++++++++ 6 files changed, 175 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 1088d64503..7680d0b380 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1804,6 +1804,38 @@ SRST Set QOM property *property* of object at location *path* to value *value* ERST + { + .name = "replay_break", + .args_type = "icount:i", + .params = "icount", + .help = "set breakpoint at the specified instruction count", + .cmd = hmp_replay_break, + }, + +SRST +``replay_break`` *icount* + Set replay breakpoint at instruction count *icount*. + Execution stops when the specified instruction is reached. + There can be at most one breakpoint. When breakpoint is set, any prior + one is removed. The breakpoint may be set only in replay mode and only + "in the future", i.e. at instruction counts greater than the current one. + The current instruction count can be observed with ``info replay``. +ERST + + { + .name = "replay_delete_break", + .args_type = "", + .params = "", + .help = "remove replay breakpoint", + .cmd = hmp_replay_delete_break, + }, + +SRST +``replay_delete_break`` + Remove replay breakpoint which was previously set with ``replay_break``. + The command is ignored when there are no replay breakpoints. +ERST + { .name = "info", .args_type = "item:s?", diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index f297fccce8..809ad638bb 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -130,5 +130,7 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict); void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict); void hmp_info_sev(Monitor *mon, const QDict *qdict); void hmp_info_replay(Monitor *mon, const QDict *qdict); +void hmp_replay_break(Monitor *mon, const QDict *qdict); +void hmp_replay_delete_break(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi/replay.json b/qapi/replay.json index e6b3f6001d..173ba76107 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -63,3 +63,39 @@ ## { 'command': 'query-replay', 'returns': 'ReplayInfo' } + +## +# @replay-break: +# +# Set replay breakpoint at instruction count @icount. +# Execution stops when the specified instruction is reached. +# There can be at most one breakpoint. When breakpoint is set, any prior +# one is removed. The breakpoint may be set only in replay mode and only +# "in the future", i.e. at instruction counts greater than the current one. +# The current instruction count can be observed with @query-replay. +# +# @icount: instruction count to stop at +# +# Since: 5.2 +# +# Example: +# +# -> { "execute": "replay-break", "data": { "icount": 220414 } } +# +## +{ 'command': 'replay-break', 'data': { 'icount': 'int' } } + +## +# @replay-delete-break: +# +# Remove replay breakpoint which was set with @replay-break. +# The command is ignored when there are no replay breakpoints. +# +# Since: 5.2 +# +# Example: +# +# -> { "execute": "replay-delete-break" } +# +## +{ 'command': 'replay-delete-break' } diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 51a6de4e81..3dc23b84fc 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -12,10 +12,13 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "sysemu/replay.h" +#include "sysemu/runstate.h" #include "replay-internal.h" #include "monitor/hmp.h" #include "monitor/monitor.h" #include "qapi/qapi-commands-replay.h" +#include "qapi/qmp/qdict.h" +#include "qemu/timer.h" void hmp_info_replay(Monitor *mon, const QDict *qdict) { @@ -41,3 +44,84 @@ ReplayInfo *qmp_query_replay(Error **errp) retval->icount = replay_get_current_icount(); return retval; } + +static void replay_break(uint64_t icount, QEMUTimerCB callback, void *opaque) +{ + assert(replay_mode == REPLAY_MODE_PLAY); + assert(replay_mutex_locked()); + assert(replay_break_icount >= replay_get_current_icount()); + assert(callback); + + replay_break_icount = icount; + + if (replay_break_timer) { + timer_del(replay_break_timer); + } + replay_break_timer = timer_new_ns(QEMU_CLOCK_REALTIME, + callback, opaque); +} + +static void replay_delete_break(void) +{ + assert(replay_mode == REPLAY_MODE_PLAY); + assert(replay_mutex_locked()); + + if (replay_break_timer) { + timer_del(replay_break_timer); + timer_free(replay_break_timer); + replay_break_timer = NULL; + } + replay_break_icount = -1ULL; +} + +static void replay_stop_vm(void *opaque) +{ + vm_stop(RUN_STATE_PAUSED); + replay_delete_break(); +} + +void qmp_replay_break(int64_t icount, Error **errp) +{ + if (replay_mode == REPLAY_MODE_PLAY) { + if (icount >= replay_get_current_icount()) { + replay_break(icount, replay_stop_vm, NULL); + } else { + error_setg(errp, + "cannot set breakpoint at the instruction in the past"); + } + } else { + error_setg(errp, "setting the breakpoint is allowed only in play mode"); + } +} + +void hmp_replay_break(Monitor *mon, const QDict *qdict) +{ + int64_t icount = qdict_get_try_int(qdict, "icount", -1LL); + Error *err = NULL; + + qmp_replay_break(icount, &err); + if (err) { + error_report_err(err); + return; + } +} + +void qmp_replay_delete_break(Error **errp) +{ + if (replay_mode == REPLAY_MODE_PLAY) { + replay_delete_break(); + } else { + error_setg(errp, "replay breakpoints are allowed only in play mode"); + } +} + +void hmp_replay_delete_break(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + + qmp_replay_delete_break(&err); + if (err) { + error_report_err(err); + return; + } +} diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 33ac551e78..2f6145ec7c 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -94,6 +94,10 @@ extern ReplayState replay_state; /* File for replay writing */ extern FILE *replay_file; +/* Instruction count of the replay breakpoint */ +extern uint64_t replay_break_icount; +/* Timer for the replay breakpoint callback */ +extern QEMUTimer *replay_break_timer; void replay_put_byte(uint8_t byte); void replay_put_event(uint8_t event); diff --git a/replay/replay.c b/replay/replay.c index 797b6a5b15..d4c228ab28 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -34,6 +34,10 @@ static char *replay_filename; ReplayState replay_state; static GSList *replay_blockers; +/* Replay breakpoints */ +uint64_t replay_break_icount = -1ULL; +QEMUTimer *replay_break_timer; + bool replay_next_event_is(int event) { bool res = false; @@ -73,6 +77,13 @@ int replay_get_instructions(void) replay_mutex_lock(); if (replay_next_event_is(EVENT_INSTRUCTION)) { res = replay_state.instruction_count; + if (replay_break_icount != -1LL) { + uint64_t current = replay_get_current_icount(); + assert(replay_break_icount >= current); + if (current + res > replay_break_icount) { + res = replay_break_icount - current; + } + } } replay_mutex_unlock(); return res; @@ -99,6 +110,12 @@ void replay_account_executed_instructions(void) will be read from the log. */ qemu_notify_event(); } + /* Execution reached the break step */ + if (replay_break_icount == replay_state.current_icount) { + /* Cannot make callback directly from the vCPU thread */ + timer_mod_ns(replay_break_timer, + qemu_clock_get_ns(QEMU_CLOCK_REALTIME)); + } } } } From patchwork Tue Oct 6 07:29:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377264 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=EA6UNSqw; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58dh5dx6z9sT6 for ; Tue, 6 Oct 2020 18:45:28 +1100 (AEDT) Received: from localhost ([::1]:56922 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhew-0006Oy-Pv for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:45:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39892) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQQ-0003HU-Oz for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:18 -0400 Received: from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c]:52303) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQO-0001Uz-2M for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:18 -0400 Received: by mail-wm1-x32c.google.com with SMTP id l11so1833553wmh.2 for ; Tue, 06 Oct 2020 00:30:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=N+wPUKHp0dEGNvIdECz+pBa71rOenQ+nUmpc905Z6ig=; b=EA6UNSqwqzdZ8XAXQJtPXgUU8Y8culRpeF90oxEyZUAg0LvemWl7MaMJyntVEo8Yig bMJWDfvpoV0I7/7boN2FpYMiFuEmlin2WOl8ULLjhqkc9gKj/iXJEc/ICTsTyypxtu0o 424dtWXBxbvp6ltBBJtTWutG/KJzNwtTbds2rbV/EvPmE0V2VQJSWJ3ZLC7ElwtrtNuv JKB+S51wtG7tRdEa/+8mrQFjEv+yC8KVCc3S88LM4vXmTdLlaO6eC1KktZLlSmKBSjIQ Sh09s55Xr6iA9amgXaVU9hEqOr2qzpfOzfnSQijwpv+S5q3iLEEvGPQ5gd4HyojHi3Re Wa8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=N+wPUKHp0dEGNvIdECz+pBa71rOenQ+nUmpc905Z6ig=; b=JeE/YIXUBXAP2owrG08K/QAF+Qji/r3/79ELcyDcw7oI/vEwYgfZ8T3aupCA3jjbO/ TV7912LW3cOuIHvXQxyohTgwbrcMWa+AuS/hVu8G74CbSgomxbHNc91vrWyDwfzUgwlf gUVrCkHSP+Lsg6YNrS6KT4Xi+89t5c+vzZ/2AkFS4uSv1KU5s3ZDCT9kbWJF9giFMhFp 8mczG1WLq5bflEmUDMQnuDHvFGa5LFyzveqIepVaYlBQnzinmgQ4PT/qk29CrcJgHAbk t1Wat874cB8YBSlCh1E54QlNpIPucIHgaWI/NVoOD0C+x0KJESm3/AwC9L9he0kGwHuN ulSQ== X-Gm-Message-State: AOAM530lCPR5UATpdO1uy1dQQ0tTo1GF0JsOARVjjSeB9C0fm3xycClq 86SJDz73INxMAoE62uhJmcrNB62TK8Q= X-Google-Smtp-Source: ABdhPJysV8kKnHiG6dxYbw8Bj+YFw/UWSwRGZZBsld5YbpsU6GjrzCersYrSoFXV+hs5gSoVfa+cpQ== X-Received: by 2002:a1c:23c2:: with SMTP id j185mr3107499wmj.136.1601969414316; Tue, 06 Oct 2020 00:30:14 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:13 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 31/37] replay: implement replay-seek command Date: Tue, 6 Oct 2020 09:29:41 +0200 Message-Id: <20201006072947.487729-32-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32c; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32c.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pavel Dovgalyuk , Markus Armbruster , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds hmp/qmp commands replay_seek/replay-seek that proceed the execution to the specified instruction count. The command automatically loads nearest snapshot and replays the execution to find the desired instruction count. Signed-off-by: Pavel Dovgalyuk Acked-by: Markus Armbruster --- v4 changes: - fixed HMP command description indent - removed useless error_free call Message-Id: <160174521180.12451.14033112911009278753.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- hmp-commands.hx | 18 ++++++++ include/monitor/hmp.h | 1 + qapi/replay.json | 20 +++++++++ replay/replay-debugging.c | 87 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 7680d0b380..e43ce600b8 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1836,6 +1836,24 @@ SRST The command is ignored when there are no replay breakpoints. ERST + { + .name = "replay_seek", + .args_type = "icount:i", + .params = "icount", + .help = "replay execution to the specified instruction count", + .cmd = hmp_replay_seek, + }, + +SRST +``replay_seek`` *icount* + Automatically proceed to the instruction count *icount*, when + replaying the execution. The command automatically loads nearest + snapshot and replays the execution to find the desired instruction. + When there is no preceding snapshot or the execution is not replayed, + then the command fails. + *icount* for the reference may be observed with ``info replay`` command. +ERST + { .name = "info", .args_type = "item:s?", diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 809ad638bb..ed2913fd18 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -132,5 +132,6 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict); void hmp_info_replay(Monitor *mon, const QDict *qdict); void hmp_replay_break(Monitor *mon, const QDict *qdict); void hmp_replay_delete_break(Monitor *mon, const QDict *qdict); +void hmp_replay_seek(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi/replay.json b/qapi/replay.json index 173ba76107..bfd83d7591 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -99,3 +99,23 @@ # ## { 'command': 'replay-delete-break' } + +## +# @replay-seek: +# +# Automatically proceed to the instruction count @icount, when +# replaying the execution. The command automatically loads nearest +# snapshot and replays the execution to find the desired instruction. +# When there is no preceding snapshot or the execution is not replayed, +# then the command fails. +# icount for the reference may be obtained with @query-replay command. +# +# @icount: target instruction count +# +# Since: 5.2 +# +# Example: +# +# -> { "execute": "replay-seek", "data": { "icount": 220414 } } +## +{ 'command': 'replay-seek', 'data': { 'icount': 'int' } } diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 3dc23b84fc..e1fe6b8661 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -19,6 +19,8 @@ #include "qapi/qapi-commands-replay.h" #include "qapi/qmp/qdict.h" #include "qemu/timer.h" +#include "block/snapshot.h" +#include "migration/snapshot.h" void hmp_info_replay(Monitor *mon, const QDict *qdict) { @@ -125,3 +127,88 @@ void hmp_replay_delete_break(Monitor *mon, const QDict *qdict) return; } } + +static char *replay_find_nearest_snapshot(int64_t icount, + int64_t *snapshot_icount) +{ + BlockDriverState *bs; + QEMUSnapshotInfo *sn_tab; + QEMUSnapshotInfo *nearest = NULL; + char *ret = NULL; + int nb_sns, i; + AioContext *aio_context; + + *snapshot_icount = -1; + + bs = bdrv_all_find_vmstate_bs(); + if (!bs) { + goto fail; + } + aio_context = bdrv_get_aio_context(bs); + + aio_context_acquire(aio_context); + nb_sns = bdrv_snapshot_list(bs, &sn_tab); + aio_context_release(aio_context); + + for (i = 0; i < nb_sns; i++) { + if (bdrv_all_find_snapshot(sn_tab[i].name, &bs) == 0) { + if (sn_tab[i].icount != -1ULL + && sn_tab[i].icount <= icount + && (!nearest || nearest->icount < sn_tab[i].icount)) { + nearest = &sn_tab[i]; + } + } + } + if (nearest) { + ret = g_strdup(nearest->name); + *snapshot_icount = nearest->icount; + } + g_free(sn_tab); + +fail: + return ret; +} + +static void replay_seek(int64_t icount, QEMUTimerCB callback, Error **errp) +{ + char *snapshot = NULL; + int64_t snapshot_icount; + + if (replay_mode != REPLAY_MODE_PLAY) { + error_setg(errp, "replay must be enabled to seek"); + return; + } + + snapshot = replay_find_nearest_snapshot(icount, &snapshot_icount); + if (snapshot) { + if (icount < replay_get_current_icount() + || replay_get_current_icount() < snapshot_icount) { + vm_stop(RUN_STATE_RESTORE_VM); + load_snapshot(snapshot, errp); + } + g_free(snapshot); + } + if (replay_get_current_icount() <= icount) { + replay_break(icount, callback, NULL); + vm_start(); + } else { + error_setg(errp, "cannot seek to the specified instruction count"); + } +} + +void qmp_replay_seek(int64_t icount, Error **errp) +{ + replay_seek(icount, replay_stop_vm, errp); +} + +void hmp_replay_seek(Monitor *mon, const QDict *qdict) +{ + int64_t icount = qdict_get_try_int(qdict, "icount", -1LL); + Error *err = NULL; + + qmp_replay_seek(icount, &err); + if (err) { + error_report_err(err); + return; + } +} From patchwork Tue Oct 6 07:29:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377253 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=EQPyvdHl; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58V41hWMz9sS8 for ; Tue, 6 Oct 2020 18:38:52 +1100 (AEDT) Received: from localhost ([::1]:33174 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhYg-0004t1-5G for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:38:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39886) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQQ-0003HN-Mh for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:18 -0400 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]:38710) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQO-0001Vt-T3 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:18 -0400 Received: by mail-wm1-x32b.google.com with SMTP id v12so1934062wmh.3 for ; Tue, 06 Oct 2020 00:30:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8fO4ARDu3GrDHWVTHIrUO17gWnruMRRKlI1vc8EA18k=; b=EQPyvdHlKqvgLsyLZq4GsMkMFz5Fp2bdZyKHdHFrAdcfDU817HHtJxubLzCNkn9jWM UnQ5SKg3kT49FT32VYlWlb63XUWqkgZ27yzuP1voCuFjR85e52oenvXdcUoam1hOG8/R 4BmReNe5v1xeleICdNLbTlSJiTFparWq0WTMoWD3OGxUqTqP/ChEUo/mUAlLbwtCPCpk 6q5O9F5J4XHi1LpM6oxMHmP/QrFWMGgzZPLFZQ8/bf4Wq0+Vk7m5HBtKWHB+A+UUULya k9MNkuTmOpTHteVWMlkomf1D5Pwt/bulrpAH/2Nbzn05WU5lp/6YWHDqxXHusfL36kUJ zArQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=8fO4ARDu3GrDHWVTHIrUO17gWnruMRRKlI1vc8EA18k=; b=HWAzCmgDgmYtegEqYi6j+TgXdNSHsAwRlX/o3/5N9ucYcNhxf5pAz3W5A6Jfr64OCc iU0EgO8bVoA9yoqFYnrv4bgVJlg8eX0Z6iTy6RBVI5zdcrajpLm9mha6/Bo5uvScIpm1 W+WljLkSHxi5taQVtC1H4sWDW7ZmY56fdji8neb/wcvPf0W39/w2Bv8ejwhSygZmC/1m O8ZMaf8LSKV7h80576g75w+KHoV15vcibBuAy3Xl7m/1SYstDOYNAuAo8U/W0/CgUEqY D2GufpCptVHKkUrSbiHHzNYYc2Lrqb6yyaoozAwI12WjkhnP0DS7abbXP2vvMikTFkVJ TSLg== X-Gm-Message-State: AOAM5315MGT+Zh508j48K0OIvViXfUTlsYSTqikg+StSFsXY/b/w+IYV Wv175jSeSQ059OA25TtQlTrGpiNYm1c= X-Google-Smtp-Source: ABdhPJwRU6Pa+K/WBLxcuEdoAVNKb00M1JtebAkuzUGoc60SoQwLtZSXQOM8BGzwM+EiS7b3Lj3A9Q== X-Received: by 2002:a7b:c2a9:: with SMTP id c9mr3259932wmk.87.1601969415222; Tue, 06 Oct 2020 00:30:15 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:14 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 32/37] replay: flush rr queue before loading the vmstate Date: Tue, 6 Oct 2020 09:29:42 +0200 Message-Id: <20201006072947.487729-33-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32b; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32b.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Pavel Dovgalyuk , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk Non-empty record/replay queue prevents saving and loading the VM state, because it includes pending bottom halves and block coroutines. But when the new VM state is loaded, we don't have to preserve the consistency of the current state anymore. Therefore this patch just flushes the queue allowing the coroutines to finish and removes checking for empty rr queue for load_snapshot function. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Alex Bennée Message-Id: <160174521762.12451.15752448887893855757.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- include/sysemu/replay.h | 2 ++ migration/savevm.c | 12 ++++++------ replay/replay-events.c | 4 ++++ replay/replay-internal.h | 2 -- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index d6026ed8e5..c486c3afb2 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -149,6 +149,8 @@ void replay_disable_events(void); void replay_enable_events(void); /*! Returns true when saving events is enabled */ bool replay_events_enabled(void); +/* Flushes events queue */ +void replay_flush_events(void); /*! Adds bottom half event to the queue */ void replay_bh_schedule_event(QEMUBH *bh); /* Adds oneshot bottom half event to the queue */ diff --git a/migration/savevm.c b/migration/savevm.c index 0e8dc78684..d2e141f7b1 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2881,12 +2881,6 @@ int load_snapshot(const char *name, Error **errp) AioContext *aio_context; MigrationIncomingState *mis = migration_incoming_get_current(); - if (!replay_can_snapshot()) { - error_setg(errp, "Record/replay does not allow loading snapshot " - "right now. Try once more later."); - return -EINVAL; - } - if (!bdrv_all_can_snapshot(&bs)) { error_setg(errp, "Device '%s' is writable but does not support snapshots", @@ -2920,6 +2914,12 @@ int load_snapshot(const char *name, Error **errp) return -EINVAL; } + /* + * Flush the record/replay queue. Now the VM state is going + * to change. Therefore we don't need to preserve its consistency + */ + replay_flush_events(); + /* Flush all IO requests so they don't interfere with the new state. */ bdrv_drain_all_begin(); diff --git a/replay/replay-events.c b/replay/replay-events.c index 302b84043a..a1c6bb934e 100644 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -77,6 +77,10 @@ bool replay_has_events(void) void replay_flush_events(void) { + if (replay_mode == REPLAY_MODE_NONE) { + return; + } + g_assert(replay_mutex_locked()); while (!QTAILQ_EMPTY(&events_list)) { diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 2f6145ec7c..97649ed8d7 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -149,8 +149,6 @@ void replay_read_next_clock(unsigned int kind); void replay_init_events(void); /*! Clears internal data structures for events handling */ void replay_finish_events(void); -/*! Flushes events queue */ -void replay_flush_events(void); /*! Returns true if there are any unsaved events in the queue */ bool replay_has_events(void); /*! Saves events from queue into the file */ From patchwork Tue Oct 6 07:29:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377285 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=LsjAkoh6; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C598J6X2hz9sS8 for ; Tue, 6 Oct 2020 19:08:32 +1100 (AEDT) Received: from localhost ([::1]:49992 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPi1O-0002DI-MC for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 04:08:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39912) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQR-0003KU-R9 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:19 -0400 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]:45351) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQP-0001WU-OR for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:19 -0400 Received: by mail-wr1-x436.google.com with SMTP id e17so3523430wru.12 for ; Tue, 06 Oct 2020 00:30:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BZEg5NVPWJDkC3vQrt886XwMNy/dNcS/j2ONP5TF7e8=; b=LsjAkoh6cNtsvcD1QeQeuEUk/CSsf2/GdgracXb2PKwlpMwws0+XVAzPZsV3Gy8EB3 8/aNrE/ctcUGibOfWU7dvxPBguK41iV9DpoTYy7ThqeH3OhXdJpusc3CNm3FJDNflaEm //exxO8RDIsdPhRuehTNrfGI+9dT7v6HGehnJSuMx0mDJg4OAlGsxwu9l0WLFi2Hndpe jMdV8ja15LYpGcSOCL7FmKKEjXd93XSRfE2KTI/XGAgFdnLA6m1EVbTcN4wrRQ8w2CaR yIX60hNaMGwz+uH11FP8mP6/W5FDmLiK+kvU/rFIkbIAWRj0xyKrMw+1+lmUBl2PkYCe Hj3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=BZEg5NVPWJDkC3vQrt886XwMNy/dNcS/j2ONP5TF7e8=; b=IsiK52E6cVAYuZREFter+37ir1ixiLJAony99uLgWMzM3m6yu7ix3OLqGWAABIp1p9 mI28af9VUL1+BGgzlS9C7igUzPNUhHvqylr9Cbxh5xDlziyhn13Yhiv3gn1WynnI9yBl fJYi21V78+G6pPMVMM1U0Fz24XeWQ6u3DWXTmBKn/JSVvYamnuxh1l2ai7A66HoCw13u pUmsjDqXwLdibel6Pkxq0O55eC7q5cBuNf3eOGDyioJ4g70VmOXhhLjnxHo9jEyqsvdV ytitxPOuSu+BU1FY2EfyLrGnN5U7w/ikvVchUrXsBK4WQkBne26KXkNo+GZ6T+14t/d2 8ipQ== X-Gm-Message-State: AOAM531zK0c/PHzdQhILILJslR+fHL6uh4MFNpGtKrx6wK6kH5Luz2jT PwDjYikektGjSHW65K/fJM5KtMG0ax0= X-Google-Smtp-Source: ABdhPJydlP/n6IY1AjZgWUZi2ANToAHE1b2xdUV2aaAMZ2RDwneiID3Ph+me4jDtnFr9YLQ8ebV6Dw== X-Received: by 2002:a5d:51ca:: with SMTP id n10mr3340342wrv.222.1601969416067; Tue, 06 Oct 2020 00:30:16 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:15 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 33/37] gdbstub: add reverse step support in replay mode Date: Tue, 6 Oct 2020 09:29:43 +0200 Message-Id: <20201006072947.487729-34-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::436; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x436.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Pavel Dovgalyuk , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk GDB remote protocol supports two reverse debugging commands: reverse step and reverse continue. This patch adds support of the first one to the gdbstub. Reverse step is intended to step one instruction in the backwards direction. This is not possible in regular execution. But replayed execution is deterministic, therefore we can load one of the prior snapshots and proceed to the desired step. It is equivalent to stepping one instruction back. There should be at least one snapshot preceding the debugged part of the replay log. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Alex Bennée --- v4 changes: - inverted condition in cpu_handle_guest_debug (suggested by Alex Bennée) Message-Id: <160174522341.12451.1498758422543765253.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- accel/tcg/translator.c | 1 + exec.c | 7 +++++ gdbstub.c | 55 +++++++++++++++++++++++++++++++++++++-- include/sysemu/replay.h | 11 ++++++++ replay/replay-debugging.c | 34 ++++++++++++++++++++++++ softmmu/cpus.c | 14 +++++++--- stubs/replay.c | 5 ++++ 7 files changed, 122 insertions(+), 5 deletions(-) diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 603d17ff83..fb1e19c585 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -17,6 +17,7 @@ #include "exec/log.h" #include "exec/translator.h" #include "exec/plugin-gen.h" +#include "sysemu/replay.h" /* Pairs with tcg_clear_temp_count. To be called by #TranslatorOps.{translate_insn,tb_stop} if diff --git a/exec.c b/exec.c index 2305f5553e..d8072668ea 100644 --- a/exec.c +++ b/exec.c @@ -2748,6 +2748,13 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len, QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) { if (watchpoint_address_matches(wp, addr, len) && (wp->flags & flags)) { + if (replay_running_debug()) { + /* + * Don't process the watchpoints when we are + * in a reverse debugging operation. + */ + return; + } if (flags == BP_MEM_READ) { wp->flags |= BP_WATCHPOINT_HIT_READ; } else { diff --git a/gdbstub.c b/gdbstub.c index 9dfb6e4142..79e8ccc050 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -51,6 +51,7 @@ #include "sysemu/runstate.h" #include "hw/semihosting/semihost.h" #include "exec/exec-all.h" +#include "sysemu/replay.h" #ifdef CONFIG_USER_ONLY #define GDB_ATTACHED "0" @@ -375,6 +376,20 @@ typedef struct GDBState { */ static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER; +/* Retrieves flags for single step mode. */ +static int get_sstep_flags(void) +{ + /* + * In replay mode all events written into the log should be replayed. + * That is why NOIRQ flag is removed in this mode. + */ + if (replay_mode != REPLAY_MODE_NONE) { + return SSTEP_ENABLE; + } else { + return sstep_flags; + } +} + static GDBState gdbserver_state; static void init_gdbserver_state(void) @@ -501,7 +516,7 @@ static int gdb_continue_partial(char *newstates) break; /* nothing to do here */ case 's': trace_gdbstub_op_stepping(cpu->cpu_index); - cpu_single_step(cpu, sstep_flags); + cpu_single_step(cpu, get_sstep_flags()); cpu_resume(cpu); flag = 1; break; @@ -1874,10 +1889,31 @@ static void handle_step(GdbCmdContext *gdb_ctx, void *user_ctx) gdb_set_cpu_pc((target_ulong)gdb_ctx->params[0].val_ull); } - cpu_single_step(gdbserver_state.c_cpu, sstep_flags); + cpu_single_step(gdbserver_state.c_cpu, get_sstep_flags()); gdb_continue(); } +static void handle_backward(GdbCmdContext *gdb_ctx, void *user_ctx) +{ + if (replay_mode != REPLAY_MODE_PLAY) { + put_packet("E22"); + } + if (gdb_ctx->num_params == 1) { + switch (gdb_ctx->params[0].opcode) { + case 's': + if (replay_reverse_step()) { + gdb_continue(); + } else { + put_packet("E14"); + } + return; + } + } + + /* Default invalid command */ + put_packet(""); +} + static void handle_v_cont_query(GdbCmdContext *gdb_ctx, void *user_ctx) { put_packet("vCont;c;C;s;S"); @@ -2124,6 +2160,10 @@ static void handle_query_supported(GdbCmdContext *gdb_ctx, void *user_ctx) g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+"); } + if (replay_mode == REPLAY_MODE_PLAY) { + g_string_append(gdbserver_state.str_buf, ";ReverseStep+"); + } + if (gdb_ctx->num_params && strstr(gdb_ctx->params[0].data, "multiprocess+")) { gdbserver_state.multiprocess = true; @@ -2460,6 +2500,17 @@ static int gdb_handle_packet(const char *line_buf) cmd_parser = &step_cmd_desc; } break; + case 'b': + { + static const GdbCmdParseEntry backward_cmd_desc = { + .handler = handle_backward, + .cmd = "b", + .cmd_startswith = 1, + .schema = "o0" + }; + cmd_parser = &backward_cmd_desc; + } + break; case 'F': { static const GdbCmdParseEntry file_io_cmd_desc = { diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index c486c3afb2..90bbb5d825 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -75,6 +75,17 @@ void replay_finish(void); void replay_add_blocker(Error *reason); /* Returns name of the replay log file */ const char *replay_get_filename(void); +/* + * Start making one step in backward direction. + * Used by gdbstub for backwards debugging. + * Returns true on success. + */ +bool replay_reverse_step(void); +/* + * Returns true if replay module is processing + * reverse_continue or reverse_step request + */ +bool replay_running_debug(void); /* Processing the instructions */ diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index e1fe6b8661..1e1dec0295 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -22,6 +22,13 @@ #include "block/snapshot.h" #include "migration/snapshot.h" +static bool replay_is_debugging; + +bool replay_running_debug(void) +{ + return replay_is_debugging; +} + void hmp_info_replay(Monitor *mon, const QDict *qdict) { if (replay_mode == REPLAY_MODE_NONE) { @@ -212,3 +219,30 @@ void hmp_replay_seek(Monitor *mon, const QDict *qdict) return; } } + +static void replay_stop_vm_debug(void *opaque) +{ + replay_is_debugging = false; + vm_stop(RUN_STATE_DEBUG); + replay_delete_break(); +} + +bool replay_reverse_step(void) +{ + Error *err = NULL; + + assert(replay_mode == REPLAY_MODE_PLAY); + + if (replay_get_current_icount() != 0) { + replay_seek(replay_get_current_icount() - 1, + replay_stop_vm_debug, &err); + if (err) { + error_free(err); + return false; + } + replay_is_debugging = true; + return true; + } + + return false; +} diff --git a/softmmu/cpus.c b/softmmu/cpus.c index f3d0c59f78..95c557fac5 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -284,9 +284,17 @@ bool cpu_can_run(CPUState *cpu) void cpu_handle_guest_debug(CPUState *cpu) { - gdb_set_stop_cpu(cpu); - qemu_system_debug_request(); - cpu->stopped = true; + if (replay_running_debug()) { + if (!cpu->singlestep_enabled) { + cpu_single_step(cpu, SSTEP_ENABLE); + } else { + cpu_single_step(cpu, 0); + } + } else { + gdb_set_stop_cpu(cpu); + qemu_system_debug_request(); + cpu->stopped = true; + } } #ifdef CONFIG_LINUX diff --git a/stubs/replay.c b/stubs/replay.c index eacb366aa8..d5b52302e9 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -93,3 +93,8 @@ uint64_t replay_get_current_icount(void) { return 0; } + +bool replay_reverse_step(void) +{ + return false; +} From patchwork Tue Oct 6 07:29:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377257 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Qmh/8Cr+; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58Wt52GRz9sSs for ; Tue, 6 Oct 2020 18:40:26 +1100 (AEDT) Received: from localhost ([::1]:41342 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhaC-0008FS-KU for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:40:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39934) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQS-0003NE-Nv for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:20 -0400 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]:55005) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQQ-0001Wu-M0 for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:20 -0400 Received: by mail-wm1-x333.google.com with SMTP id p15so1815678wmi.4 for ; Tue, 06 Oct 2020 00:30:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wM70NITwc42Whej4N3YEEzYrn9T/JQZRJIsTDSZHZoE=; b=Qmh/8Cr+8nRP6Wc4PiP/9tv05Ms5AnFm8ufjCDwjLAi/Q9oyFbgbV6hG1MQKpLPBEF jtDCTiO8vRipGlA3eecoTjg0bfmnqXFnQY4s2G8sW8skBo0dazWQFLXxN2I62CRdGplu f+I4ygXh074fNeaxIe+RSlH0eAlxGCSfsmCd9kGmhCYfN0JR/nVClwYqdCZ9gHwzyfeL 3Hvapk66wv3jkV5l053nK7HWI3dfkknF5Jhro9trTOPuUQ1CGAmfXsxoU7GvHPIwWEcw N6Xu5Pm6v+7LjsXiDS/6gVshWW9RtXBhkMW7Wyjr8m7WPE78FHfAYqgHDOBnjPBvQrSP p9SQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=wM70NITwc42Whej4N3YEEzYrn9T/JQZRJIsTDSZHZoE=; b=s7Rk7ocu1Xnn0WTfufiEjirQpFfHCMi5b2MfQiui4D515Z42bzbgOFtJPO+vGqxaFh jzddsI09xVWr3hkD2BFnp4Ui6h4Z/IVI7sNYp6Vc92yejP7G5OVLwuGgtBTFQtH++sjx 50g0sAyzqw2q5eWSXMrtgTz7vGFdbkGfN7zoop9UYKVKAmpBvPNtEM1AcaC4Ytj5QpbT 78AWY/1e0/jAG4aEJgIApp46lw1ue9LlhLSy5/2JhRfARa21WRGNZkfNc0SBR26ajvCQ vFZ6M/+iwNwL/F1wYx0yHQoz5bpWPzy150HTQJlzzEQMIzcheIMMeOh0ZRb7pIr7r9zI bVZA== X-Gm-Message-State: AOAM53295l8gp1SqkMmlIS0jTal8ufZ+8wBypi+87Gy7KDm9vQTltrU4 tTPJ7hj6LNKv5GgrvLlbqukQJsyMDYk= X-Google-Smtp-Source: ABdhPJywduqkFWtWNaOviBmnC1TdQqDDJoYRV9+dPXUcL3Yf+KTiksg2RGHcgQgqC0W7CT+7ZsJtYg== X-Received: by 2002:a05:600c:214c:: with SMTP id v12mr1505271wml.23.1601969416925; Tue, 06 Oct 2020 00:30:16 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:16 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 34/37] gdbstub: add reverse continue support in replay mode Date: Tue, 6 Oct 2020 09:29:44 +0200 Message-Id: <20201006072947.487729-35-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::333; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x333.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pavel Dovgalyuk , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds support of the reverse continue operation for gdbstub. Reverse continue finds the last breakpoint that would happen in normal execution from the beginning to the current moment. Implementation of the reverse continue replays the execution twice: to find the breakpoints that were hit and to seek to the last breakpoint. Reverse continue loads the previous snapshot and tries to find the breakpoint since that moment. If there are no such breakpoints, it proceeds to the earlier snapshot, and so on. When no breakpoints or watchpoints were hit at all, execution stops at the beginning of the replay log. Signed-off-by: Pavel Dovgalyuk Message-Id: <160174522930.12451.6994758004725016836.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- exec.c | 1 + gdbstub.c | 10 +++++- include/sysemu/replay.h | 8 +++++ replay/replay-debugging.c | 72 +++++++++++++++++++++++++++++++++++++++ softmmu/cpus.c | 5 +++ stubs/replay.c | 5 +++ 6 files changed, 100 insertions(+), 1 deletion(-) diff --git a/exec.c b/exec.c index d8072668ea..ec68f4a9ca 100644 --- a/exec.c +++ b/exec.c @@ -2753,6 +2753,7 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len, * Don't process the watchpoints when we are * in a reverse debugging operation. */ + replay_breakpoint(); return; } if (flags == BP_MEM_READ) { diff --git a/gdbstub.c b/gdbstub.c index 79e8ccc050..ac92273018 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1907,6 +1907,13 @@ static void handle_backward(GdbCmdContext *gdb_ctx, void *user_ctx) put_packet("E14"); } return; + case 'c': + if (replay_reverse_continue()) { + gdb_continue(); + } else { + put_packet("E14"); + } + return; } } @@ -2161,7 +2168,8 @@ static void handle_query_supported(GdbCmdContext *gdb_ctx, void *user_ctx) } if (replay_mode == REPLAY_MODE_PLAY) { - g_string_append(gdbserver_state.str_buf, ";ReverseStep+"); + g_string_append(gdbserver_state.str_buf, + ";ReverseStep+;ReverseContinue+"); } if (gdb_ctx->num_params && diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 90bbb5d825..172b20c60c 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -81,11 +81,19 @@ const char *replay_get_filename(void); * Returns true on success. */ bool replay_reverse_step(void); +/* + * Start searching the last breakpoint/watchpoint. + * Used by gdbstub for backwards debugging. + * Returns true if the process successfully started. + */ +bool replay_reverse_continue(void); /* * Returns true if replay module is processing * reverse_continue or reverse_step request */ bool replay_running_debug(void); +/* Called in reverse debugging mode to collect breakpoint information */ +void replay_breakpoint(void); /* Processing the instructions */ diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 1e1dec0295..30ca38e5dd 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -23,6 +23,8 @@ #include "migration/snapshot.h" static bool replay_is_debugging; +static int64_t replay_last_breakpoint; +static int64_t replay_last_snapshot; bool replay_running_debug(void) { @@ -246,3 +248,73 @@ bool replay_reverse_step(void) return false; } + +static void replay_continue_end(void) +{ + replay_is_debugging = false; + vm_stop(RUN_STATE_DEBUG); + replay_delete_break(); +} + +static void replay_continue_stop(void *opaque) +{ + Error *err = NULL; + if (replay_last_breakpoint != -1LL) { + replay_seek(replay_last_breakpoint, replay_stop_vm_debug, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + return; + } + /* + * No breakpoints since the last snapshot. + * Find previous snapshot and try again. + */ + if (replay_last_snapshot != 0) { + replay_seek(replay_last_snapshot - 1, replay_continue_stop, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + replay_last_snapshot = replay_get_current_icount(); + return; + } else { + /* Seek to the very first step */ + replay_seek(0, replay_stop_vm_debug, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + return; + } + replay_continue_end(); +} + +bool replay_reverse_continue(void) +{ + Error *err = NULL; + + assert(replay_mode == REPLAY_MODE_PLAY); + + if (replay_get_current_icount() != 0) { + replay_seek(replay_get_current_icount() - 1, + replay_continue_stop, &err); + if (err) { + error_free(err); + return false; + } + replay_last_breakpoint = -1LL; + replay_is_debugging = true; + replay_last_snapshot = replay_get_current_icount(); + return true; + } + + return false; +} + +void replay_breakpoint(void) +{ + assert(replay_mode == REPLAY_MODE_PLAY); + replay_last_breakpoint = replay_get_current_icount(); +} diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 95c557fac5..9e33416b4d 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -286,6 +286,11 @@ void cpu_handle_guest_debug(CPUState *cpu) { if (replay_running_debug()) { if (!cpu->singlestep_enabled) { + /* + * Report about the breakpoint and + * make a single step to skip it + */ + replay_breakpoint(); cpu_single_step(cpu, SSTEP_ENABLE); } else { cpu_single_step(cpu, 0); diff --git a/stubs/replay.c b/stubs/replay.c index d5b52302e9..45ebe77fb9 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -98,3 +98,8 @@ bool replay_reverse_step(void) { return false; } + +bool replay_reverse_continue(void) +{ + return false; +} From patchwork Tue Oct 6 07:29:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377262 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=R0sn1ef5; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58dK5nxyz9sS8 for ; Tue, 6 Oct 2020 18:45:09 +1100 (AEDT) Received: from localhost ([::1]:56414 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhed-0006CH-4E for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:44:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39946) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQT-0003OZ-Bp for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:21 -0400 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]:38718) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQR-0001XJ-CC for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:20 -0400 Received: by mail-wm1-x333.google.com with SMTP id v12so1934195wmh.3 for ; Tue, 06 Oct 2020 00:30:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6WD9Ks2QvGXimCjR6xfwgm6lrYby8X5mCiKe4m027WE=; b=R0sn1ef50AyVUmtCZIuzV/uNjf7h55rB0BfPToTyp2qCxgA8H7dbyFDOqLl6gSMS3Y SaAS2CzMgFSI2sSFGLnrJeeBfdKtiJinLt+Pg7o62Y53Ji2vuralqIeVtK9bUuz4mwTV d4idtc/sr33biXhpWdaRWzUpT1okxKsPo6AWcegTQt0qKsfpF7YJcEIM58MT9F0FafZp 3CkRuhlG6DrlvUSjgvXvy8B6K0SYzGKC/c2Av6jm6WrdqBgHCiEqaeAiioVbUHJz2uxc 2VPAsE9sGLrQ6Qd6n3oprWZebnsVhYNIPGL18B6BVOyo22RLFRa7AhFNh03hf5JJyS5G s1+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=6WD9Ks2QvGXimCjR6xfwgm6lrYby8X5mCiKe4m027WE=; b=ENmU+jcZTy16X7iRxU7jTKRonTGkmCZVsnmzO7Ee2GH0zQDjuZl0pS85NOi+LW5MGs orjUVgMbJ7zuUlMOmIP90KgF9qkt6srTzQEJmlI2k+92sL01A0i0dAOlCtcf+vDuBzft mvPH9jIj5hyBAh7CZ6doOChfaYcqiMpwVgcGKrZ+tsnwr56JmZG3BU4FS0wa/KmOXule GdkESJagGISNWI9v/tfEz2wdRU4HkOkyNot+JnVexBD4DxQe2V6j7aZdD3FWhVV12sX9 LN8eQ420yF+0UxcPf+Ta6hg5rLmRuo5AZ1iaYFeE9CRy2eEtfuMRgEMXlspol2zlhBjr T8TA== X-Gm-Message-State: AOAM5331/eppFZZ9x6cNO4XbDc8+MePzJN4lOqB7k60B+9BOH3AIa52U /SSegEnz1Im4G8Md8hGmBD6rlWWUPAA= X-Google-Smtp-Source: ABdhPJztGnKN3vKINbbFKytqlgzKRP8Q6EFVNGUGjqw8SI/VUpdx1ckBO/IB8Uvo6vca0SKtaOSogQ== X-Received: by 2002:a1c:6a0a:: with SMTP id f10mr3302175wmc.86.1601969417737; Tue, 06 Oct 2020 00:30:17 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:17 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 35/37] replay: describe reverse debugging in docs/replay.txt Date: Tue, 6 Oct 2020 09:29:45 +0200 Message-Id: <20201006072947.487729-36-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::333; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x333.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Pavel Dovgalyuk , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch updates the documentation and describes usage of the reverse debugging in QEMU+GDB. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Alex Bennée --- v4 changes: - added an example of the command line for reverse debugging of the diskless machine Message-Id: <160174523509.12451.1409905901920738979.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- docs/replay.txt | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/docs/replay.txt b/docs/replay.txt index 8952e6d852..87a64ae068 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -265,6 +265,16 @@ of the original disk image, use overlay files linked to the original images. Therefore all new snapshots (including the starting one) will be saved in overlays and the original image remains unchanged. +When you need to use snapshots with diskless virtual machine, +it must be started with 'orphan' qcow2 image. This image will be used +for storing VM snapshots. Here is the example of the command line for this: + + qemu-system-i386 -icount shift=3,rr=replay,rrfile=record.bin,rrsnapshot=init \ + -net none -drive file=empty.qcow2,if=none,id=rr + +empty.qcow2 drive does not connected to any virtual block device and used +for VM snapshots only. + Network devices --------------- @@ -294,6 +304,42 @@ for recording and replaying must contain identical number of ports in record and replay modes, but their backends may differ. E.g., '-serial stdio' in record mode, and '-serial null' in replay mode. +Reverse debugging +----------------- + +Reverse debugging allows "executing" the program in reverse direction. +GDB remote protocol supports "reverse step" and "reverse continue" +commands. The first one steps single instruction backwards in time, +and the second one finds the last breakpoint in the past. + +Recorded executions may be used to enable reverse debugging. QEMU can't +execute the code in backwards direction, but can load a snapshot and +replay forward to find the desired position or breakpoint. + +The following GDB commands are supported: + - reverse-stepi (or rsi) - step one instruction backwards + - reverse-continue (or rc) - find last breakpoint in the past + +Reverse step loads the nearest snapshot and replays the execution until +the required instruction is met. + +Reverse continue may include several passes of examining the execution +between the snapshots. Each of the passes include the following steps: + 1. loading the snapshot + 2. replaying to examine the breakpoints + 3. if breakpoint or watchpoint was met + - loading the snaphot again + - replaying to the required breakpoint + 4. else + - proceeding to the p.1 with the earlier snapshot + +Therefore usage of the reverse debugging requires at least one snapshot +created in advance. This can be done by omitting 'snapshot' option +for the block drives and adding 'rrsnapshot' for both record and replay +command lines. +See the "Snapshotting" section to learn more about running record/replay +and creating the snapshot in these modes. + Replay log format ----------------- From patchwork Tue Oct 6 07:29:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377261 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=RJo0/0Oi; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58ZX0xCbz9sS8 for ; Tue, 6 Oct 2020 18:42:44 +1100 (AEDT) Received: from localhost ([::1]:49572 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhcQ-0003Kt-42 for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:42:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39948) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQT-0003Q4-Sn for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:21 -0400 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:33621) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQS-0001Xr-4X for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:21 -0400 Received: by mail-wr1-x444.google.com with SMTP id m6so12258630wrn.0 for ; Tue, 06 Oct 2020 00:30:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NS6L75PHdbF1zs4u9dBK9m9xVUve0wzYaHJyBJ9jZSk=; b=RJo0/0Oid3bifvTEA8xmSe6UNU9M0jpA438xvMX1Q9D5xzAQkcJjFXTFu8R3NqmMqr 5tDVtRkOmmlJBO+wQ/G8nHYcd/ZFXtnhbN3PduUUCKwi5NXBeoN0YgWF7Cr77QauFDjH 6K0T7I3ZUtzAEkPhTAUdr6dLvqA+PWabaizfLnZ56KbvgamiHp86bAbcml5j2AfS6BpI /7TM+AV99aHjR+9D+qlmigAgWgKg4Xf5mWbYKgm97tZrWnJP9fexuJ0cKRzewB8sx7WR SKyxpQZHDuzl5kc3vFu0ynlSp0L1GJ0YlqwV0429NQOcQ+W05rCUYCFJS6vEFASluGJG HKPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=NS6L75PHdbF1zs4u9dBK9m9xVUve0wzYaHJyBJ9jZSk=; b=TNLh+rV23Ji3+8HP2xRtTpOt5fIRcMupGoaLsPfxAfiSU92PZtS9V0TfN25tGebIJH FmB37RIsitT1dukzdM3PuvvnvHaMvfu+EUT6cdAbu7BQbbGhPyVMT+9uhN+ZaCyJOILB O+Q/BreGW9uKurDQWpsufXjGxQMfrZU6WRbnSfEwxjfFV4yB/ksZQRZApYDzjJ4dQxLE e9ZkR1FlHWIWxUZfc0XQse5/eZW7ynODX88I4cQ+rfEy7QsRULTQz18niVydgwrgaXYn J5UK0KEdwTYbqMTKnwW2w37iopn9eZPhBSJB+eTLAzmYDbcYXP0QP+RIMNlL68Rh8O2J 9tJg== X-Gm-Message-State: AOAM533D1iG1CDvXtvNggpVbYkmeEgPm/uu3EOclxqGEi6B8m1zUh3FL dQ1PfZEaeYZfSaH7ELZjmoZYzUgTUB4= X-Google-Smtp-Source: ABdhPJz+NGF42xhZ/yLzjIpq2ZIEaf19/zJDXEsv7o9NDV665hJx1cFmkykMaDGS6RBZspXd2HcOxw== X-Received: by 2002:adf:dd51:: with SMTP id u17mr3243417wrm.355.1601969418495; Tue, 06 Oct 2020 00:30:18 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:18 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 36/37] replay: create temporary snapshot at debugger connection Date: Tue, 6 Oct 2020 09:29:46 +0200 Message-Id: <20201006072947.487729-37-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::444; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x444.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk When record/replay does not uses overlays for storing the snapshots, user is not capable of issuing reverse debugging commands. This patch adds creation of the VM snapshot on the temporary overlay image, when the debugger connects to QEMU. Therefore the execution can be rewind to the moment of the debugger connection while debugging the virtual machine. Signed-off-by: Pavel Dovgalyuk --- v6: - dropped unused error processing (suggested by Philippe Mathieu-Daudé) Message-Id: <160174524096.12451.11651270339216758643.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- gdbstub.c | 1 + include/sysemu/replay.h | 2 ++ replay/replay-debugging.c | 14 ++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/gdbstub.c b/gdbstub.c index ac92273018..f19f98ab1a 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -3321,6 +3321,7 @@ static void gdb_chr_event(void *opaque, QEMUChrEvent event) s->g_cpu = s->c_cpu; vm_stop(RUN_STATE_PAUSED); + replay_gdb_attached(); gdb_has_xml = false; break; default: diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 172b20c60c..56c0c17c30 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -94,6 +94,8 @@ bool replay_reverse_continue(void); bool replay_running_debug(void); /* Called in reverse debugging mode to collect breakpoint information */ void replay_breakpoint(void); +/* Called when gdb is attached to gdbstub */ +void replay_gdb_attached(void); /* Processing the instructions */ diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 30ca38e5dd..ee9e86daa9 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -318,3 +318,17 @@ void replay_breakpoint(void) assert(replay_mode == REPLAY_MODE_PLAY); replay_last_breakpoint = replay_get_current_icount(); } + +void replay_gdb_attached(void) +{ + /* + * Create VM snapshot on temporary overlay to allow reverse + * debugging even if snapshots were not enabled. + */ + if (replay_mode == REPLAY_MODE_PLAY + && !replay_snapshot) { + if (save_snapshot("start_debugging", NULL) != 0) { + /* Can't create the snapshot. Continue conventional debugging. */ + } + } +} From patchwork Tue Oct 6 07:29:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1377265 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=uoXPw1Lw; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C58hP1vJ3z9sSs for ; Tue, 6 Oct 2020 18:47:49 +1100 (AEDT) Received: from localhost ([::1]:35662 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kPhhI-0000xw-GO for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2020 03:47:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39960) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kPhQW-0003Tb-BR for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:24 -0400 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]:50453) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kPhQT-0001YD-3o for qemu-devel@nongnu.org; Tue, 06 Oct 2020 03:30:23 -0400 Received: by mail-wm1-x32b.google.com with SMTP id 13so1846208wmf.0 for ; Tue, 06 Oct 2020 00:30:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ApdyWpu0LjE2KogCc5CTk3qwN9V54L+6oyQ3jiCzQL0=; b=uoXPw1LwKRWdDussy/HD7gqwebq3WMXCadfgNqsc/woTHA9+o5XJQUcURt2Q/oP5CM r6RuobCSrzfEpeezSsZK4EdCq26Id50NBaDtEiFjg46vRonR6Qswlx68otxHRoGEjvDc LVPK3Ca6wZONrSqyRbfU7QqBMd9POMoGA5vdmHTBv03nbW88aDxyYfjai5LzTq+KINvv z2EuP0qOE5Kv1cpgmWf5JPCR+hGpTNVivXhrOfLYN0uCwgjVars6ED2KCZwZadYVd4r2 d4Pt/Q0nf0NuQ+V2jcVDOiBhBRnifm0kU53zr/t/X1VmMJUm/yMloC7H52WzJhLaXeLu 1ngw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=ApdyWpu0LjE2KogCc5CTk3qwN9V54L+6oyQ3jiCzQL0=; b=fhdjE3mVyeEA7xasc63GqSXlrvSfMPk5H4RemAXHoOA4LkokoewY+mlu0zC9mCYt2n fEMfm+x4fzg0gCcIru+Q5yTLjn+ebXdmReRJTccIx1LghQ3XPKVtwW/pDG13KBmdhiK6 blE0STlaUiftFKTL13cqlJdnzoqws0mvcv3aiZxjQat8S6hnKoNz+uozkAEgiouWKb9j JhADV463YE76jHaCY/9q/4F63bSnrE5mVFhqojoBCswtzi8XQqRvliUvpaOw3ad3RwCB i2KXQsfuVUQ9wME6CsLBsFd1YO3PB30fA7KbLLg4I+Tp0cmP80JbSuWC5b9GfUC5f3Uf 4jVw== X-Gm-Message-State: AOAM5318jRb31DwOmsROjcAQI6DFEOVLg4nYK0uH/+eaNttJOawxMLFr ZF/rWNieoCLVgWkpIdySi7RnzU0S8aM= X-Google-Smtp-Source: ABdhPJzYMC4aEgjyhKHGAB8ObKqqH05ENW0CA4tZU5ziOp7R0MzIROPJ8gwtX7gw64r2a9YvlpAZsQ== X-Received: by 2002:a1c:2394:: with SMTP id j142mr3118986wmj.3.1601969419351; Tue, 06 Oct 2020 00:30:19 -0700 (PDT) Received: from localhost.localdomain ([2001:b07:6468:f312:5aca:cd0b:c4a1:9c2e]) by smtp.gmail.com with ESMTPSA id i9sm2576329wma.47.2020.10.06.00.30.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2020 00:30:18 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 37/37] tests/acceptance: add reverse debugging test Date: Tue, 6 Oct 2020 09:29:47 +0200 Message-Id: <20201006072947.487729-38-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201006072947.487729-1-pbonzini@redhat.com> References: <20201006072947.487729-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32b; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32b.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Willian Rampazzo , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Pavel Dovgalyuk , Pavel Dovgalyuk Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This is a test for GDB reverse debugging commands: reverse step and reverse continue. Every test in this suite consists of two phases: record and replay. Recording saves the execution of some instructions and makes an initial VM snapshot to allow reverse execution. Replay saves the order of the first instructions and then checks that they are executed backwards in the correct order. After that the execution is replayed to the end, and reverse continue command is checked by setting several breakpoints, and asserting that the execution is stopped at the last of them. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Willian Rampazzo --- v5: - disabled (as some other tests) when running on gitlab due to the unidentified timeout problem Message-Id: <160174524678.12451.13258942849173670277.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- MAINTAINERS | 1 + tests/acceptance/reverse_debugging.py | 208 ++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 tests/acceptance/reverse_debugging.py diff --git a/MAINTAINERS b/MAINTAINERS index 417fca5f57..e9d85cc873 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2696,6 +2696,7 @@ F: include/sysemu/replay.h F: docs/replay.txt F: stubs/replay.c F: tests/acceptance/replay_kernel.py +F: tests/acceptance/reverse_debugging.py F: qapi/replay.json IOVA Tree diff --git a/tests/acceptance/reverse_debugging.py b/tests/acceptance/reverse_debugging.py new file mode 100644 index 0000000000..b72fdf6cdc --- /dev/null +++ b/tests/acceptance/reverse_debugging.py @@ -0,0 +1,208 @@ +# Reverse debugging test +# +# Copyright (c) 2020 ISP RAS +# +# Author: +# Pavel Dovgalyuk +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. +import os +import logging + +from avocado import skipIf +from avocado_qemu import BUILD_DIR +from avocado.utils import gdb +from avocado.utils import process +from avocado.utils.path import find_command +from boot_linux_console import LinuxKernelTest + +class ReverseDebugging(LinuxKernelTest): + """ + Test GDB reverse debugging commands: reverse step and reverse continue. + Recording saves the execution of some instructions and makes an initial + VM snapshot to allow reverse execution. + Replay saves the order of the first instructions and then checks that they + are executed backwards in the correct order. + After that the execution is replayed to the end, and reverse continue + command is checked by setting several breakpoints, and asserting + that the execution is stopped at the last of them. + """ + + timeout = 10 + STEPS = 10 + endian_is_le = True + + def run_vm(self, record, shift, args, replay_path, image_path): + logger = logging.getLogger('replay') + vm = self.get_vm() + vm.set_console() + if record: + logger.info('recording the execution...') + mode = 'record' + else: + logger.info('replaying the execution...') + mode = 'replay' + vm.add_args('-s', '-S') + vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s,rrsnapshot=init' % + (shift, mode, replay_path), + '-net', 'none') + vm.add_args('-drive', 'file=%s,if=none' % image_path) + if args: + vm.add_args(*args) + vm.launch() + return vm + + @staticmethod + def get_reg_le(g, reg): + res = g.cmd(b'p%x' % reg) + num = 0 + for i in range(len(res))[-2::-2]: + num = 0x100 * num + int(res[i:i + 2], 16) + return num + + @staticmethod + def get_reg_be(g, reg): + res = g.cmd(b'p%x' % reg) + return int(res, 16) + + def get_reg(self, g, reg): + # value may be encoded in BE or LE order + if self.endian_is_le: + return self.get_reg_le(g, reg) + else: + return self.get_reg_be(g, reg) + + def get_pc(self, g): + return self.get_reg(g, self.REG_PC) + + def check_pc(self, g, addr): + pc = self.get_pc(g) + if pc != addr: + self.fail('Invalid PC (read %x instead of %x)' % (pc, addr)) + + @staticmethod + def gdb_step(g): + g.cmd(b's', b'T05thread:01;') + + @staticmethod + def gdb_bstep(g): + g.cmd(b'bs', b'T05thread:01;') + + @staticmethod + def vm_get_icount(vm): + return vm.qmp('query-replay')['return']['icount'] + + def reverse_debugging(self, shift=7, args=None): + logger = logging.getLogger('replay') + + # create qcow2 for snapshots + logger.info('creating qcow2 image for VM snapshots') + image_path = os.path.join(self.workdir, 'disk.qcow2') + qemu_img = os.path.join(BUILD_DIR, 'qemu-img') + if not os.path.exists(qemu_img): + qemu_img = find_command('qemu-img', False) + if qemu_img is False: + self.cancel('Could not find "qemu-img", which is required to ' + 'create the temporary qcow2 image') + cmd = '%s create -f qcow2 %s 128M' % (qemu_img, image_path) + process.run(cmd) + + replay_path = os.path.join(self.workdir, 'replay.bin') + + # record the log + vm = self.run_vm(True, shift, args, replay_path, image_path) + while self.vm_get_icount(vm) <= self.STEPS: + pass + last_icount = self.vm_get_icount(vm) + vm.shutdown() + + logger.info("recorded log with %s+ steps" % last_icount) + + # replay and run debug commands + vm = self.run_vm(False, shift, args, replay_path, image_path) + logger.info('connecting to gdbstub') + g = gdb.GDBRemote('127.0.0.1', 1234, False, False) + g.connect() + r = g.cmd(b'qSupported') + if b'qXfer:features:read+' in r: + g.cmd(b'qXfer:features:read:target.xml:0,ffb') + if b'ReverseStep+' not in r: + self.fail('Reverse step is not supported by QEMU') + if b'ReverseContinue+' not in r: + self.fail('Reverse continue is not supported by QEMU') + + logger.info('stepping forward') + steps = [] + # record first instruction addresses + for _ in range(self.STEPS): + pc = self.get_pc(g) + logger.info('saving position %x' % pc) + steps.append(pc) + self.gdb_step(g) + + # visit the recorded instruction in reverse order + logger.info('stepping backward') + for addr in steps[::-1]: + self.gdb_bstep(g) + self.check_pc(g, addr) + logger.info('found position %x' % addr) + + logger.info('seeking to the end (icount %s)' % (last_icount - 1)) + vm.qmp('replay-break', icount=last_icount - 1) + # continue - will return after pausing + g.cmd(b'c', b'T02thread:01;') + + logger.info('setting breakpoints') + for addr in steps: + # hardware breakpoint at addr with len=1 + g.cmd(b'Z1,%x,1' % addr, b'OK') + + logger.info('running reverse continue to reach %x' % steps[-1]) + # reverse continue - will return after stopping at the breakpoint + g.cmd(b'bc', b'T05thread:01;') + + # assume that none of the first instructions is executed again + # breaking the order of the breakpoints + self.check_pc(g, steps[-1]) + logger.info('successfully reached %x' % steps[-1]) + + logger.info('exitting gdb and qemu') + vm.shutdown() + +class ReverseDebugging_X86_64(ReverseDebugging): + REG_PC = 0x10 + REG_CS = 0x12 + def get_pc(self, g): + return self.get_reg_le(g, self.REG_PC) \ + + self.get_reg_le(g, self.REG_CS) * 0x10 + + # unidentified gitlab timeout problem + @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') + def test_x86_64_pc(self): + """ + :avocado: tags=arch:x86_64 + :avocado: tags=machine:pc + """ + # start with BIOS only + self.reverse_debugging() + +class ReverseDebugging_AArch64(ReverseDebugging): + REG_PC = 32 + + # unidentified gitlab timeout problem + @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') + def test_aarch64_virt(self): + """ + :avocado: tags=arch:aarch64 + :avocado: tags=machine:virt + :avocado: tags=cpu:cortex-a53 + """ + kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' + '/linux/releases/29/Everything/aarch64/os/images/pxeboot' + '/vmlinuz') + kernel_hash = '8c73e469fc6ea06a58dc83a628fc695b693b8493' + kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) + + self.reverse_debugging( + args=('-kernel', kernel_path, '-cpu', 'cortex-a53'))