From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 481C1C44539 for ; Wed, 22 Jul 2026 14:25:59 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmXsq-0004Ux-KU; Wed, 22 Jul 2026 10:25:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmXsj-0004QF-1h for qemu-devel@nongnu.org; Wed, 22 Jul 2026 10:25:09 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmXsd-0001GO-1U for qemu-devel@nongnu.org; Wed, 22 Jul 2026 10:25:04 -0400 Received: from linux.microsoft.com (unknown [86.121.140.206]) by linux.microsoft.com (Postfix) with ESMTPSA id 4BE1320B7168; Wed, 22 Jul 2026 07:24:46 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 4BE1320B7168 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1784730288; bh=f3cJw8Zo5m9uh58CHRy69IGU7LCw66uicDe5Y655PCc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=OZNe01CkOI7NvYn88r/JjrkH22fXAZtPZTn8+0obsLsHhydMEfpcux8/adYKiT2BK dRUV3Y1DRmoAi/QTgGU6ORu5kSF0g/PXl65NQPpJ4Q6uLGd14vAQ9LtxhEdojU/T7q AYn6iVpiCz/5gld90MewrEKAnBR9Sw7unOSqYEgU= Date: Wed, 22 Jul 2026 17:24:51 +0300 From: Doru =?iso-8859-1?Q?Bl=E2nzeanu?= To: Magnus Kulke Cc: qemu-devel@nongnu.org, Paolo Bonzini , Zhao Liu , Richard Henderson , Magnus Kulke , "Michael S. Tsirkin" , Wei Liu , Doru =?iso-8859-1?Q?Bl=E2nzeanu?= , Wei Liu Subject: Re: [PATCH 08/12] target/i386/mshv: migrate STIMER state Message-ID: References: <20260710101534.664604-1-magnuskulke@linux.microsoft.com> <20260710101534.664604-9-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20260710101534.664604-9-magnuskulke@linux.microsoft.com> Received-SPF: pass client-ip=13.77.154.182; envelope-from=dblanzeanu@linux.microsoft.com; helo=linux.microsoft.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org On Fri, Jul 10, 2026 at 12:15:30PM +0200, Magnus Kulke wrote: > This part of Synic state is retrieved via a mem-aligned page. We declare > the required space (size reference: rust-vmm/mshv) as a buffer on the VM > state struct for inclusion in a migration. > > Other than other SynIC features, STIMER doesn't depend on SCONTROL being > set. > > Signed-off-by: Magnus Kulke > --- > include/system/mshv_int.h | 2 ++ > target/i386/cpu.h | 5 ++++ > target/i386/machine.c | 20 +++++++++++++++ > target/i386/mshv/mshv-cpu.c | 12 +++++++++ > target/i386/mshv/synic.c | 51 +++++++++++++++++++++++++++++++++++++ > 5 files changed, 90 insertions(+) > > diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h > index bc023d3535..063852115e 100644 > --- a/include/system/mshv_int.h > +++ b/include/system/mshv_int.h > @@ -144,5 +144,7 @@ int mshv_set_simp(int cpu_fd, const uint8_t *page); > int mshv_get_siefp(int cpu_fd, uint8_t *page); > int mshv_set_siefp(int cpu_fd, const uint8_t *page); > bool mshv_synic_enabled(const CPUState *cpu); > +int mshv_get_synthetic_timers(int cpu_fd, uint8_t *state); > +int mshv_set_synthetic_timers(int cpu_fd, const uint8_t *state); > > #endif > diff --git a/target/i386/cpu.h b/target/i386/cpu.h > index 9270ae95d0..6c9e674e81 100644 > --- a/target/i386/cpu.h > +++ b/target/i386/cpu.h > @@ -45,6 +45,10 @@ > #define ELF_MACHINE_UNAME "i686" > #endif > > +#ifdef CONFIG_MSHV > +#define MSHV_STIMERS_STATE_SIZE 200 > +#endif > + > enum { > R_EAX = 0, > R_ECX = 1, > @@ -2303,6 +2307,7 @@ typedef struct CPUArchState { > #if defined(CONFIG_MSHV) > uint8_t hv_simp_page[HV_HYP_PAGE_SIZE]; > uint8_t hv_siefp_page[HV_HYP_PAGE_SIZE]; > + uint8_t hv_synthetic_timers_state[MSHV_STIMERS_STATE_SIZE]; > #endif > > uint64_t mcg_cap; > diff --git a/target/i386/machine.c b/target/i386/machine.c > index 023a397ab8..8d69d7e25e 100644 > --- a/target/i386/machine.c > +++ b/target/i386/machine.c > @@ -10,6 +10,7 @@ > #include "exec/watchpoint.h" > #include "system/kvm.h" > #include "system/kvm_xen.h" > +#include "system/mshv.h" > #include "system/tcg.h" > > #include "qemu/error-report.h" > @@ -952,6 +953,24 @@ static const VMStateDescription vmstate_msr_hyperv_reenlightenment = { > }; > > #ifdef CONFIG_MSHV > + > +static bool mshv_synthetic_timers_needed(void *opaque) > +{ > + /* Always migrate synthetic timers */ > + return mshv_enabled(); > +} > + > +static const VMStateDescription vmstate_mshv_synthetic_timers = { > + .name = "cpu/mshv_synthetic_timers", > + .version_id = 1, > + .minimum_version_id = 1, > + .needed = mshv_synthetic_timers_needed, > + .fields = (const VMStateField[]) { > + VMSTATE_BUFFER(env.hv_synthetic_timers_state, X86CPU), > + VMSTATE_END_OF_LIST() > + } > +}; > + > static bool mshv_synic_vp_state_needed(void *opaque) > { > X86CPU *cpu = opaque; > @@ -1941,6 +1960,7 @@ const VMStateDescription vmstate_x86_cpu = { > #endif > #ifdef CONFIG_MSHV > &vmstate_mshv_synic_vp_state, > + &vmstate_mshv_synthetic_timers, > #endif > NULL > } > diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c > index 57244bc667..ce6cfccc0a 100644 > --- a/target/i386/mshv/mshv-cpu.c > +++ b/target/i386/mshv/mshv-cpu.c > @@ -118,6 +118,12 @@ static int get_synic_state(CPUState *cpu) > int cpu_fd = mshv_vcpufd(cpu); > int ret; > > + ret = mshv_get_synthetic_timers(cpu_fd, env->hv_synthetic_timers_state); > + if (ret < 0) { > + error_report("failed to get synthetic timers"); > + return -1; > + } > + > /* SIMP/SIEFP can only be read when SynIC is enabled */ > if (!mshv_synic_enabled(cpu)) { > return 0; > @@ -1420,6 +1426,12 @@ static int set_synic_state(const CPUState *cpu) > int cpu_fd = mshv_vcpufd(cpu); > int ret; > > + ret = mshv_set_synthetic_timers(cpu_fd, env->hv_synthetic_timers_state); > + if (ret < 0) { > + error_report("failed to set synthetic timers state"); > + return -1; > + } > + > /* SIMP/SIEFP can only be written when SynIC is enabled */ > if (!mshv_synic_enabled(cpu)) { > return 0; > diff --git a/target/i386/mshv/synic.c b/target/i386/mshv/synic.c > index 8f9fee6ed7..4c629adc3a 100644 > --- a/target/i386/mshv/synic.c > +++ b/target/i386/mshv/synic.c > @@ -54,6 +54,57 @@ static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state) > return 0; > } > > +int mshv_get_synthetic_timers(int cpu_fd, uint8_t *state) > +{ > + int ret; > + void *buffer; > + struct mshv_get_set_vp_state args = {0}; > + > + buffer = qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); > + args.buf_ptr = (uint64_t)buffer; > + args.buf_sz = HV_HYP_PAGE_SIZE; > + args.type = MSHV_VP_STATE_SYNTHETIC_TIMERS; > + > + ret = get_vp_state(cpu_fd, &args); > + > + if (ret < 0) { > + qemu_vfree(buffer); > + error_report("failed to get synthetic timers"); > + return -1; > + } > + > + memcpy(state, buffer, MSHV_STIMERS_STATE_SIZE); > + qemu_vfree(buffer); > + > + return 0; > +} > + > +int mshv_set_synthetic_timers(int cpu_fd, const uint8_t *state) > +{ > + int ret; > + void *buffer; > + struct mshv_get_set_vp_state args = {0}; > + > + buffer = qemu_memalign(HV_HYP_PAGE_SIZE, HV_HYP_PAGE_SIZE); > + memset(buffer, 0, HV_HYP_PAGE_SIZE); > + args.buf_ptr = (uint64_t)buffer; > + args.buf_sz = HV_HYP_PAGE_SIZE; > + args.type = MSHV_VP_STATE_SYNTHETIC_TIMERS; > + > + assert(state); > + memcpy(buffer, state, MSHV_STIMERS_STATE_SIZE); > + > + ret = set_vp_state(cpu_fd, &args); > + qemu_vfree(buffer); > + > + if (ret < 0) { > + error_report("failed to set synthetic timers"); > + return -1; > + } > + > + return 0; > +} > + > int mshv_get_simp(int cpu_fd, uint8_t *page) > { > int ret; > -- > 2.34.1 Reviewed-by: Doru Blânzeanu