From nobody Fri Apr 3 22:34:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.microsoft.com ARC-Seal: i=1; a=rsa-sha256; t=1774274609; cv=none; d=zohomail.com; s=zohoarc; b=dPqUQSZNWTuLBg3ZftFXDK3mXz9oL0C+7Xj9nD8c/PAG7apPYJ2Mh+PgQmIJt5zD6j+Cm6p85JE210fooeDNVlr8EeTcOagbMAu5yLib8PBaPueINkueFMsAwc27WURvGiD1CHPK3YdqS9Zb1IxzTX40T8o+jQmCGFchDFdpxNQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774274609; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=9BS8GXf6VR6ZaAFlkE7y0tvwO0EDUtmobElH9h7DNf8=; b=UpAPnxZ4ecx3H0FaHLny1JLk2oX5+y+Sg8rCKMX9I8X6SPvz9DF912k3Y4Ccv4XUeVaJ5dwzxU76xz+eg/ya8MrwyXMrgPR+N6fRsOcNZJHgQJc5Is4vwL+yTyctJo6gisnjb9P9pSR1ruvRTx2J7pktevQ48kAV/kvh1hrYG3E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774274609697670.7118838019842; Mon, 23 Mar 2026 07:03:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fsH-0003mx-8b; Mon, 23 Mar 2026 10:03:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w4fpS-0000ws-Ly for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:29 -0400 Received: from linux.microsoft.com ([13.77.154.182]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w4fpR-0007JF-1i for qemu-devel@nongnu.org; Mon, 23 Mar 2026 10:00:26 -0400 Received: from DESKTOP-TUU1E5L.localdomain (unknown [167.220.208.76]) by linux.microsoft.com (Postfix) with ESMTPSA id 25AB420B6F1B; Mon, 23 Mar 2026 07:00:10 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 25AB420B6F1B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1774274414; bh=9BS8GXf6VR6ZaAFlkE7y0tvwO0EDUtmobElH9h7DNf8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OIoGS9GKpf2Umk6z462NM92lu9gamDiTmGQtjQ/nKrxFTDphm8IElsq/7FcPNUMK9 L6SxxFIeWcR/ozR2uJ+v6ksidX1l1NfVLw88XDwip7QLRk7dV+MWttY2oVu83Cw/5M Y38sZ0w+b+uYSLl5FreenHD/iE8rXgbGOLN3Rix4= From: Magnus Kulke To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, Wei Liu , Richard Henderson , Marcelo Tosatti , Marcel Apfelbaum , Wei Liu , Alex Williamson , Paolo Bonzini , Zhao Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Magnus Kulke , Magnus Kulke , "Michael S. Tsirkin" Subject: [RFC 31/32] target/i386/mshv: migrate MP_STATE Date: Mon, 23 Mar 2026 14:58:11 +0100 Message-Id: <20260323135812.383509-32-magnuskulke@linux.microsoft.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> References: <20260323135812.383509-1-magnuskulke@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=13.77.154.182; envelope-from=magnuskulke@linux.microsoft.com; helo=linux.microsoft.com X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.microsoft.com) X-ZM-MESSAGEID: 1774274610493158500 Content-Type: text/plain; charset="utf-8" MSHV's "internal activity state" roughly maps to QEMU's env->mp_state and cpu->halted states that describe state of APs in a guest. We don't invoke set_mp_state as part of store_vcpu_state() b/c we would put all BSP + APs in a RUNNABLE (0) state immediately, breaking SMP boot Instead we store the mp state as part of the load_cleanup() routine after a migration. Signed-off-by: Magnus Kulke --- accel/mshv/mshv-all.c | 10 +++++ include/system/mshv_int.h | 1 + target/i386/mshv/mshv-cpu.c | 80 +++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 3927a82925..45fe1ef468 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -205,6 +205,7 @@ static int mshv_load_setup(QEMUFile *f, void *opaque, E= rror **errp) static int mshv_load_cleanup(void *opaque) { MshvState *s =3D opaque; + CPUState *cpu; int ret; =20 ret =3D mshv_arch_set_partition_msrs(first_cpu); @@ -213,6 +214,15 @@ static int mshv_load_cleanup(void *opaque) return -1; } =20 + CPU_FOREACH(cpu) { + ret =3D mshv_arch_set_mp_state(cpu); + if (ret < 0) { + error_report("Failed to set mp state for vCPU %d: %s", + cpu->cpu_index, strerror(-ret)); + return -1; + } + } + resume_vm(s->vm); =20 return 0; diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h index bc16b794b2..c24efc8675 100644 --- a/include/system/mshv_int.h +++ b/include/system/mshv_int.h @@ -98,6 +98,7 @@ int mshv_get_generic_regs(CPUState *cpu, hv_register_asso= c *assocs, int mshv_arch_store_vcpu_state(const CPUState *cpu); int mshv_arch_load_vcpu_state(CPUState *cpu); int mshv_arch_set_partition_msrs(const CPUState *cpu); +int mshv_arch_set_mp_state(const CPUState *cpu); void mshv_arch_init_vcpu(CPUState *cpu); void mshv_arch_destroy_vcpu(CPUState *cpu); void mshv_arch_amend_proc_features( diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c index 80e5dd5a4b..c2c217372a 100644 --- a/target/i386/mshv/mshv-cpu.c +++ b/target/i386/mshv/mshv-cpu.c @@ -33,6 +33,11 @@ =20 #include =20 +#define MSHV_MP_STATE_RUNNABLE 0 +#define MSHV_MP_STATE_UNINITIALIZED 1 +#define MSHV_MP_STATE_INIT_RECEIVED 2 +#define MSHV_MP_STATE_HALTED 3 + #define MAX_REGISTER_COUNT (MAX_CONST(ARRAY_SIZE(STANDARD_REGISTER_NAMES),= \ MAX_CONST(ARRAY_SIZE(SPECIAL_REGISTER_NAMES), \ ARRAY_SIZE(FPU_REGISTER_NAMES)))) @@ -814,6 +819,76 @@ static int set_vcpu_events(const CPUState *cpu) return 0; } =20 +static int get_mp_state(CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + struct hv_register_assoc assoc =3D { + .name =3D HV_REGISTER_INTERNAL_ACTIVITY_STATE, + }; + union hv_internal_activity_register activity; + int ret; + + ret =3D mshv_get_generic_regs(cpu, &assoc, 1); + if (ret < 0) { + error_report("failed to get internal activity state"); + return -1; + } + + activity.as_uint64 =3D assoc.value.reg64; + + /* + * map MSHV activity state to KVM mp_state values, which are used as t= he + * shared representation in env->mp_state and serialized by vmstate_x8= 6_cpu. + */ + + if (activity.startup_suspend) { + env->mp_state =3D MSHV_MP_STATE_UNINITIALIZED; + } else if (activity.halt_suspend) { + env->mp_state =3D MSHV_MP_STATE_HALTED; + } else { + env->mp_state =3D MSHV_MP_STATE_RUNNABLE; + } + + cpu->halted =3D (env->mp_state =3D=3D MSHV_MP_STATE_HALTED); + + return 0; +} + +int mshv_arch_set_mp_state(const CPUState *cpu) +{ + X86CPU *x86cpu =3D X86_CPU(cpu); + CPUX86State *env =3D &x86cpu->env; + union hv_internal_activity_register activity =3D { 0 }; + struct hv_register_assoc assoc =3D { + .name =3D HV_REGISTER_INTERNAL_ACTIVITY_STATE, + }; + int ret; + + switch (env->mp_state) { + case MSHV_MP_STATE_HALTED: + activity.halt_suspend =3D 1; + break; + case MSHV_MP_STATE_UNINITIALIZED: + case MSHV_MP_STATE_INIT_RECEIVED: + activity.startup_suspend =3D 1; + break; + case MSHV_MP_STATE_RUNNABLE: + default: + break; + } + + assoc.value.reg64 =3D activity.as_uint64; + + ret =3D mshv_set_generic_regs(cpu, &assoc, 1); + if (ret < 0) { + error_report("failed to set internal activity state"); + return -1; + } + + return 0; +} + static int update_hflags(CPUState *cpu) { X86CPU *x86cpu =3D X86_CPU(cpu); @@ -876,6 +951,11 @@ int mshv_arch_load_vcpu_state(CPUState *cpu) return ret; } =20 + ret =3D get_mp_state(cpu); + if (ret < 0) { + return ret; + } + return 0; } =20 --=20 2.34.1