From: Magnus Kulke <magnuskulke@linux.microsoft.com>
To: qemu-devel@nongnu.org
Cc: kvm@vger.kernel.org, "Magnus Kulke" <magnuskulke@microsoft.com>,
"Wei Liu" <liuwe@microsoft.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Cédric Le Goater" <clg@redhat.com>,
"Zhao Liu" <zhao1.liu@intel.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Wei Liu" <wei.liu@kernel.org>,
"Magnus Kulke" <magnuskulke@linux.microsoft.com>,
"Alex Williamson" <alex@shazbot.org>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Marcelo Tosatti" <mtosatti@redhat.com>
Subject: [PATCH 03/34] target/i386/mshv: impl init/load/store_vcpu_state
Date: Fri, 17 Apr 2026 12:55:47 +0200 [thread overview]
Message-ID: <20260417105618.3621-4-magnuskulke@linux.microsoft.com> (raw)
In-Reply-To: <20260417105618.3621-1-magnuskulke@linux.microsoft.com>
In migration we will handle more than registers, so we rework the
routines that were used to load & store CPU registers from/to the
hypervisor into more explicit init/load/store_vcpu_state() functions
that can be called from the appropriate hooks.
load/store_regs() still exists for the purpose of MMIO emulation, but it
will only address standard and special x86 registers.
Functions to retrieve FPU and XCR0 state from the hypervsisor have been
introduced.
MSR and APIC state covered are covered only as part of init_vcpu(). They
are not yet part of the load/store routines.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
accel/mshv/mshv-all.c | 10 +-
include/system/mshv_int.h | 5 +-
target/i386/mshv/mshv-cpu.c | 354 ++++++++++++++++++------------------
3 files changed, 185 insertions(+), 184 deletions(-)
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
index 7c0eb68a5b..04d248fe1d 100644
--- a/accel/mshv/mshv-all.c
+++ b/accel/mshv/mshv-all.c
@@ -400,13 +400,13 @@ static int mshv_init_vcpu(CPUState *cpu)
int ret;
cpu->accel = g_new0(AccelCPUState, 1);
- mshv_arch_init_vcpu(cpu);
ret = mshv_create_vcpu(vm_fd, vp_index, &cpu->accel->cpufd);
if (ret < 0) {
return -1;
}
+ mshv_arch_init_vcpu(cpu);
cpu->accel->dirty = true;
return 0;
@@ -488,7 +488,7 @@ static int mshv_cpu_exec(CPUState *cpu)
do {
if (cpu->accel->dirty) {
- ret = mshv_arch_put_registers(cpu);
+ ret = mshv_arch_store_vcpu_state(cpu);
if (ret) {
error_report("Failed to put registers after init: %s",
strerror(-ret));
@@ -610,7 +610,7 @@ static void mshv_start_vcpu_thread(CPUState *cpu)
static void do_mshv_cpu_synchronize_post_init(CPUState *cpu,
run_on_cpu_data arg)
{
- int ret = mshv_arch_put_registers(cpu);
+ int ret = mshv_arch_store_vcpu_state(cpu);
if (ret < 0) {
error_report("Failed to put registers after init: %s", strerror(-ret));
abort();
@@ -626,7 +626,7 @@ static void mshv_cpu_synchronize_post_init(CPUState *cpu)
static void mshv_cpu_synchronize_post_reset(CPUState *cpu)
{
- int ret = mshv_arch_put_registers(cpu);
+ int ret = mshv_arch_store_vcpu_state(cpu);
if (ret) {
error_report("Failed to put registers after reset: %s",
strerror(-ret));
@@ -650,7 +650,7 @@ static void mshv_cpu_synchronize_pre_loadvm(CPUState *cpu)
static void do_mshv_cpu_synchronize(CPUState *cpu, run_on_cpu_data arg)
{
if (!cpu->accel->dirty) {
- int ret = mshv_arch_load_regs(cpu);
+ int ret = mshv_arch_load_vcpu_state(cpu);
if (ret < 0) {
error_report("Failed to load registers for vcpu %d",
cpu->cpu_index);
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
index e3d1867a77..70631ca6ba 100644
--- a/include/system/mshv_int.h
+++ b/include/system/mshv_int.h
@@ -70,11 +70,10 @@ int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd);
void mshv_remove_vcpu(int vm_fd, int cpu_fd);
int mshv_configure_vcpu(const CPUState *cpu);
int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit);
-int mshv_arch_load_regs(CPUState *cpu);
-int mshv_arch_store_regs(CPUState *cpu);
int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
size_t n_regs);
-int mshv_arch_put_registers(const CPUState *cpu);
+int mshv_arch_store_vcpu_state(const CPUState *cpu);
+int mshv_arch_load_vcpu_state(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 78b218e596..56656ac0b0 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -112,6 +112,92 @@ static int get_generic_regs(CPUState *cpu,
struct hv_register_assoc *assocs,
size_t n_regs);
+static void populate_fpu(const hv_register_assoc *assocs, X86CPU *x86cpu)
+{
+ union hv_register_value value;
+ const union hv_x64_fp_control_status_register *ctrl_status;
+ const union hv_x64_xmm_control_status_register *xmm_ctrl;
+ CPUX86State *env = &x86cpu->env;
+ size_t i, fp_i;
+ bool valid;
+
+ /* first 16 registers are xmm0-xmm15 */
+ for (i = 0; i < 16; i++) {
+ value = assocs[i].value;
+ env->xmm_regs[i].ZMM_Q(0) = value.reg128.low_part;
+ env->xmm_regs[i].ZMM_Q(1) = value.reg128.high_part;
+ }
+
+ /* next 8 registers are fp_mmx0-fp_mmx7 */
+ for (i = 16; i < 24; i++) {
+ fp_i = i - 16;
+ value = assocs[i].value;
+ env->fpregs[fp_i].d.low = value.fp.mantissa;
+ env->fpregs[fp_i].d.high = (value.fp.sign << 15)
+ | (value.fp.biased_exponent & 0x7FFF);
+ }
+
+ /* last two registers are fp_control_status and xmm_control_status */
+ ctrl_status = &assocs[24].value.fp_control_status;
+ env->fpuc = ctrl_status->fp_control;
+
+ env->fpus = ctrl_status->fp_status & ~0x3800;
+ /* bits 11,12,13 are the top of stack pointer */
+ env->fpstt = (ctrl_status->fp_status >> 11) & 0x7;
+
+ for (i = 0; i < 8; i++) {
+ valid = ctrl_status->fp_tag & (1 << i);
+ env->fptags[i] = valid ? 0 : 1;
+ }
+
+ env->fpop = ctrl_status->last_fp_op;
+ env->fpip = ctrl_status->last_fp_rip;
+
+ xmm_ctrl = &assocs[25].value.xmm_control_status;
+ env->mxcsr = xmm_ctrl->xmm_status_control;
+ env->fpdp = xmm_ctrl->last_fp_rdp;
+}
+
+static int get_fpu(CPUState *cpu)
+{
+ struct hv_register_assoc assocs[ARRAY_SIZE(FPU_REGISTER_NAMES)];
+ int ret;
+ X86CPU *x86cpu = X86_CPU(cpu);
+ size_t n_regs = ARRAY_SIZE(FPU_REGISTER_NAMES);
+
+ for (size_t i = 0; i < n_regs; i++) {
+ assocs[i].name = FPU_REGISTER_NAMES[i];
+ }
+ ret = get_generic_regs(cpu, assocs, n_regs);
+ if (ret < 0) {
+ error_report("failed to get special registers");
+ return -errno;
+ }
+
+ populate_fpu(assocs, x86cpu);
+
+ return 0;
+}
+
+static int get_xc_reg(CPUState *cpu)
+{
+ int ret;
+ X86CPU *x86cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86cpu->env;
+ struct hv_register_assoc assocs[1];
+
+ assocs[0].name = HV_X64_REGISTER_XFEM;
+
+ ret = get_generic_regs(cpu, assocs, 1);
+ if (ret < 0) {
+ error_report("failed to get xcr0");
+ return -1;
+ }
+ env->xcr0 = assocs[0].value.reg64;
+
+ return 0;
+}
+
static int translate_gva(const CPUState *cpu, uint64_t gva, uint64_t *gpa,
uint64_t flags)
{
@@ -290,7 +376,7 @@ static int set_standard_regs(const CPUState *cpu)
return 0;
}
-int mshv_arch_store_regs(CPUState *cpu)
+static int store_regs(CPUState *cpu)
{
int ret;
@@ -432,20 +518,45 @@ static int get_special_regs(CPUState *cpu)
return 0;
}
-int mshv_arch_load_regs(CPUState *cpu)
+static int load_regs(CPUState *cpu)
{
int ret;
ret = get_standard_regs(cpu);
if (ret < 0) {
- error_report("Failed to load standard registers");
- return -1;
+ return ret;
}
ret = get_special_regs(cpu);
if (ret < 0) {
- error_report("Failed to load special registers");
- return -1;
+ return ret;
+ }
+
+ return 0;
+}
+
+int mshv_arch_load_vcpu_state(CPUState *cpu)
+{
+ int ret;
+
+ ret = get_standard_regs(cpu);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = get_special_regs(cpu);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = get_xc_reg(cpu);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = get_fpu(cpu);
+ if (ret < 0) {
+ return ret;
}
return 0;
@@ -617,7 +728,7 @@ static int register_intercept_result_cpuid(const CPUState *cpu,
return ret;
}
-static int set_cpuid2(const CPUState *cpu)
+static int init_cpuid2(const CPUState *cpu)
{
int ret;
size_t n_entries, cpuid_size;
@@ -808,29 +919,6 @@ static int set_xc_reg(const CPUState *cpu)
return 0;
}
-static int set_cpu_state(const CPUState *cpu)
-{
- int ret;
-
- ret = set_standard_regs(cpu);
- if (ret < 0) {
- return ret;
- }
- ret = set_special_regs(cpu);
- if (ret < 0) {
- return ret;
- }
- ret = set_fpu(cpu);
- if (ret < 0) {
- return ret;
- }
- ret = set_xc_reg(cpu);
- if (ret < 0) {
- return ret;
- }
- return 0;
-}
-
static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state)
{
int ret;
@@ -844,7 +932,7 @@ static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state)
return 0;
}
-static int get_lapic(int cpu_fd,
+static int get_lapic(const CPUState *cpu,
struct hv_local_interrupt_controller_state *state)
{
int ret;
@@ -852,6 +940,7 @@ static int get_lapic(int cpu_fd,
/* buffer aligned to 4k, as *state requires that */
void *buffer = qemu_memalign(size, size);
struct mshv_get_set_vp_state mshv_state = { 0 };
+ int cpu_fd = mshv_vcpufd(cpu);
mshv_state.buf_ptr = (uint64_t) buffer;
mshv_state.buf_sz = size;
@@ -888,7 +977,7 @@ static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state)
return 0;
}
-static int set_lapic(int cpu_fd,
+static int set_lapic(const CPUState *cpu,
const struct hv_local_interrupt_controller_state *state)
{
int ret;
@@ -896,6 +985,7 @@ static int set_lapic(int cpu_fd,
/* buffer aligned to 4k, as *state requires that */
void *buffer = qemu_memalign(size, size);
struct mshv_get_set_vp_state mshv_state = { 0 };
+ int cpu_fd = mshv_vcpufd(cpu);
if (!state) {
error_report("lapic state is NULL");
@@ -917,13 +1007,13 @@ static int set_lapic(int cpu_fd,
return 0;
}
-static int set_lint(int cpu_fd)
+static int init_lint(const CPUState *cpu)
{
int ret;
uint32_t *lvt_lint0, *lvt_lint1;
struct hv_local_interrupt_controller_state lapic_state = { 0 };
- ret = get_lapic(cpu_fd, &lapic_state);
+ ret = get_lapic(cpu, &lapic_state);
if (ret < 0) {
return ret;
}
@@ -936,161 +1026,31 @@ static int set_lint(int cpu_fd)
/* TODO: should we skip setting lapic if the values are the same? */
- return set_lapic(cpu_fd, &lapic_state);
+ return set_lapic(cpu, &lapic_state);
}
-static int setup_msrs(const CPUState *cpu)
-{
- int ret;
- uint64_t default_type = MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB;
-
- /* boot msr entries */
- MshvMsrEntry msrs[9] = {
- { .index = IA32_MSR_SYSENTER_CS, .data = 0x0, },
- { .index = IA32_MSR_SYSENTER_ESP, .data = 0x0, },
- { .index = IA32_MSR_SYSENTER_EIP, .data = 0x0, },
- { .index = IA32_MSR_STAR, .data = 0x0, },
- { .index = IA32_MSR_CSTAR, .data = 0x0, },
- { .index = IA32_MSR_LSTAR, .data = 0x0, },
- { .index = IA32_MSR_KERNEL_GS_BASE, .data = 0x0, },
- { .index = IA32_MSR_SFMASK, .data = 0x0, },
- { .index = IA32_MSR_MTRR_DEF_TYPE, .data = default_type, },
- };
-
- ret = mshv_configure_msr(cpu, msrs, 9);
- if (ret < 0) {
- error_report("failed to setup msrs");
- return -1;
- }
-
- return 0;
-}
-
-/*
- * TODO: populate topology info:
- *
- * X86CPU *x86cpu = X86_CPU(cpu);
- * CPUX86State *env = &x86cpu->env;
- * X86CPUTopoInfo *topo_info = &env->topo_info;
- */
-int mshv_configure_vcpu(const CPUState *cpu)
+int mshv_arch_store_vcpu_state(const CPUState *cpu)
{
int ret;
- int cpu_fd = mshv_vcpufd(cpu);
-
- ret = set_cpuid2(cpu);
- if (ret < 0) {
- error_report("failed to set cpuid");
- return -1;
- }
-
- ret = setup_msrs(cpu);
- if (ret < 0) {
- error_report("failed to setup msrs");
- return -1;
- }
-
- ret = set_cpu_state(cpu);
- if (ret < 0) {
- error_report("failed to set cpu state");
- return -1;
- }
- ret = set_lint(cpu_fd);
+ ret = set_standard_regs(cpu);
if (ret < 0) {
- error_report("failed to set lpic int");
- return -1;
+ return ret;
}
- return 0;
-}
-
-static int put_regs(const CPUState *cpu)
-{
- int ret;
-
- ret = mshv_configure_vcpu(cpu);
+ ret = set_special_regs(cpu);
if (ret < 0) {
- error_report("failed to configure vcpu");
return ret;
}
- return 0;
-}
-
-struct MsrPair {
- uint32_t index;
- uint64_t value;
-};
-
-static int put_msrs(const CPUState *cpu)
-{
- int ret = 0;
- X86CPU *x86cpu = X86_CPU(cpu);
- CPUX86State *env = &x86cpu->env;
- MshvMsrEntries *msrs = g_malloc0(sizeof(MshvMsrEntries));
-
- struct MsrPair pairs[] = {
- { MSR_IA32_SYSENTER_CS, env->sysenter_cs },
- { MSR_IA32_SYSENTER_ESP, env->sysenter_esp },
- { MSR_IA32_SYSENTER_EIP, env->sysenter_eip },
- { MSR_EFER, env->efer },
- { MSR_PAT, env->pat },
- { MSR_STAR, env->star },
- { MSR_CSTAR, env->cstar },
- { MSR_LSTAR, env->lstar },
- { MSR_KERNELGSBASE, env->kernelgsbase },
- { MSR_FMASK, env->fmask },
- { MSR_MTRRdefType, env->mtrr_deftype },
- { MSR_VM_HSAVE_PA, env->vm_hsave },
- { MSR_SMI_COUNT, env->msr_smi_count },
- { MSR_IA32_PKRS, env->pkrs },
- { MSR_IA32_BNDCFGS, env->msr_bndcfgs },
- { MSR_IA32_XSS, env->xss },
- { MSR_IA32_UMWAIT_CONTROL, env->umwait },
- { MSR_IA32_TSX_CTRL, env->tsx_ctrl },
- { MSR_AMD64_TSC_RATIO, env->amd_tsc_scale_msr },
- { MSR_TSC_AUX, env->tsc_aux },
- { MSR_TSC_ADJUST, env->tsc_adjust },
- { MSR_IA32_SMBASE, env->smbase },
- { MSR_IA32_SPEC_CTRL, env->spec_ctrl },
- { MSR_VIRT_SSBD, env->virt_ssbd },
- };
-
- if (ARRAY_SIZE(pairs) > MSHV_MSR_ENTRIES_COUNT) {
- error_report("MSR entries exceed maximum size");
- g_free(msrs);
- return -1;
- }
-
- for (size_t i = 0; i < ARRAY_SIZE(pairs); i++) {
- MshvMsrEntry *entry = &msrs->entries[i];
- entry->index = pairs[i].index;
- entry->reserved = 0;
- entry->data = pairs[i].value;
- msrs->nmsrs++;
- }
-
- ret = mshv_configure_msr(cpu, &msrs->entries[0], msrs->nmsrs);
- g_free(msrs);
- return ret;
-}
-
-
-int mshv_arch_put_registers(const CPUState *cpu)
-{
- int ret;
-
- ret = put_regs(cpu);
+ ret = set_xc_reg(cpu);
if (ret < 0) {
- error_report("Failed to put registers");
- return -1;
+ return ret;
}
- ret = put_msrs(cpu);
+ ret = set_fpu(cpu);
if (ret < 0) {
- error_report("Failed to put msrs");
- return -1;
+ return ret;
}
return 0;
@@ -1126,7 +1086,7 @@ static int emulate_instruction(CPUState *cpu,
int ret;
x86_insn_stream stream = { .bytes = insn_bytes, .len = insn_len };
- ret = mshv_arch_load_regs(cpu);
+ ret = load_regs(cpu);
if (ret < 0) {
error_report("Failed to load registers");
return -1;
@@ -1135,7 +1095,7 @@ static int emulate_instruction(CPUState *cpu,
decode_instruction_stream(env, &decode, &stream);
exec_instruction(env, &decode);
- ret = mshv_arch_store_regs(cpu);
+ ret = store_regs(cpu);
if (ret < 0) {
error_report("failed to store registers");
return -1;
@@ -1433,7 +1393,7 @@ static int handle_pio_str(CPUState *cpu, hv_x64_io_port_intercept_message *info)
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
- ret = mshv_arch_load_regs(cpu);
+ ret = load_regs(cpu);
if (ret < 0) {
error_report("Failed to load registers");
return -1;
@@ -1579,6 +1539,33 @@ void mshv_init_mmio_emu(void)
init_emu(&mshv_x86_emul_ops);
}
+static int init_msrs(const CPUState *cpu)
+{
+ int ret;
+ uint64_t d_t = MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB;
+
+ const struct hv_register_assoc assocs[] = {
+ { .name = HV_X64_REGISTER_SYSENTER_CS, .value.reg64 = 0x0 },
+ { .name = HV_X64_REGISTER_SYSENTER_ESP, .value.reg64 = 0x0 },
+ { .name = HV_X64_REGISTER_SYSENTER_EIP, .value.reg64 = 0x0 },
+ { .name = HV_X64_REGISTER_STAR, .value.reg64 = 0x0 },
+ { .name = HV_X64_REGISTER_CSTAR, .value.reg64 = 0x0 },
+ { .name = HV_X64_REGISTER_LSTAR, .value.reg64 = 0x0 },
+ { .name = HV_X64_REGISTER_KERNEL_GS_BASE, .value.reg64 = 0x0 },
+ { .name = HV_X64_REGISTER_SFMASK, .value.reg64 = 0x0 },
+ { .name = HV_X64_REGISTER_MSR_MTRR_DEF_TYPE, .value.reg64 = d_t },
+ };
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(assocs) > MSHV_MSR_ENTRIES_COUNT);
+
+ ret = mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs));
+ if (ret < 0) {
+ error_report("failed to put msrs");
+ return -1;
+ }
+
+ return 0;
+}
+
void mshv_arch_init_vcpu(CPUState *cpu)
{
X86CPU *x86_cpu = X86_CPU(cpu);
@@ -1586,6 +1573,7 @@ void mshv_arch_init_vcpu(CPUState *cpu)
AccelCPUState *state = cpu->accel;
size_t page = HV_HYP_PAGE_SIZE;
void *mem = qemu_memalign(page, 2 * page);
+ int ret;
/* sanity check, to make sure we don't overflow the page */
QEMU_BUILD_BUG_ON((MAX_REGISTER_COUNT
@@ -1598,6 +1586,20 @@ void mshv_arch_init_vcpu(CPUState *cpu)
state->hvcall_args.output_page = (uint8_t *)mem + page;
env->emu_mmio_buf = g_new(char, 4096);
+
+ /*
+ * TODO: populate topology info:
+ * X86CPUTopoInfo *topo_info = &env->topo_info;
+ */
+
+ ret = init_cpuid2(cpu);
+ assert(ret == 0);
+
+ ret = init_msrs(cpu);
+ assert(ret == 0);
+
+ ret = init_lint(cpu);
+ assert(ret == 0);
}
void mshv_arch_destroy_vcpu(CPUState *cpu)
--
2.34.1
next prev parent reply other threads:[~2026-04-17 10:56 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-17 10:55 [PATCH 00/34] Add migration support to the MSHV accelerator Magnus Kulke
2026-04-17 10:55 ` [PATCH 01/34] target/i386/mshv: use arch_load/store_reg fns Magnus Kulke
2026-04-17 10:55 ` [PATCH 02/34] target/i386/mshv: use generic FPU/xcr0 state Magnus Kulke
2026-04-17 10:55 ` Magnus Kulke [this message]
2026-04-17 10:55 ` [PATCH 04/34] accel/accel-irq: add AccelRouteChange abstraction Magnus Kulke
2026-04-17 10:55 ` [PATCH 05/34] accel/accel-irq: add generic begin_route_changes Magnus Kulke
2026-04-17 10:55 ` [PATCH 06/34] accel/accel-irq: add generic commit_route_changes Magnus Kulke
2026-04-17 10:55 ` [PATCH 07/34] accel/mshv: add irq_routes to state Magnus Kulke
2026-04-17 10:55 ` [PATCH 08/34] accel/mshv: update s->irq_routes in add_msi_route Magnus Kulke
2026-04-17 10:55 ` [PATCH 09/34] accel/mshv: update s->irq_routes in update_msi_route Magnus Kulke
2026-04-17 10:55 ` [PATCH 10/34] accel/mshv: update s->irq_routes in release_virq Magnus Kulke
2026-04-17 10:55 ` [PATCH 11/34] accel/mshv: use s->irq_routes in commit_routes Magnus Kulke
2026-04-17 10:55 ` [PATCH 12/34] accel/mshv: reserve ioapic routes on s->irq_routes Magnus Kulke
2026-04-17 10:55 ` [PATCH 13/34] accel/mshv: remove redundant msi controller Magnus Kulke
2026-04-17 10:55 ` [PATCH 14/34] target/i386/mshv: move apic logic into own file Magnus Kulke
2026-04-17 10:55 ` [PATCH 15/34] target/i386/mshv: remove redundant apic helpers Magnus Kulke
2026-04-17 10:56 ` [PATCH 16/34] target/i386/mshv: migrate LAPIC state Magnus Kulke
2026-04-17 11:54 ` Mohamed Mediouni
2026-04-20 11:37 ` Magnus Kulke
2026-04-17 10:56 ` [PATCH 17/34] target/i386/mshv: move msr code to arch Magnus Kulke
2026-04-17 10:56 ` [PATCH 18/34] accel/mshv: store partition proc features Magnus Kulke
2026-04-17 10:56 ` [PATCH 19/34] target/i386/mshv: expose msvh_get_generic_regs Magnus Kulke
2026-04-17 10:56 ` [PATCH 20/34] target/i386/mshv: migrate MSRs Magnus Kulke
2026-04-17 10:56 ` [PATCH 21/34] target/i386/mshv: migrate MTRR MSRs Magnus Kulke
2026-04-17 10:56 ` [PATCH 22/34] target/i386/mshv: migrate Synic SINT MSRs Magnus Kulke
2026-04-17 10:56 ` [PATCH 23/34] target/i386/mshv: migrate CET/SS MSRs Magnus Kulke
2026-04-17 10:56 ` [PATCH 24/34] target/i386/mshv: migrate SIMP and SIEFP state Magnus Kulke
2026-04-17 10:56 ` [PATCH 25/34] target/i386/mshv: migrate STIMER state Magnus Kulke
2026-04-17 10:56 ` [PATCH 26/34] accel/mshv: introduce SaveVMHandler Magnus Kulke
2026-04-17 10:56 ` [PATCH 27/34] accel/mshv: write synthetic MSRs after migration Magnus Kulke
2026-04-17 10:56 ` [PATCH 28/34] accel/mshv: migrate REFERENCE_TIME Magnus Kulke
2026-04-17 10:56 ` [PATCH 29/34] target/i386/mshv: migrate pending ints/excs Magnus Kulke
2026-04-17 10:56 ` [PATCH 30/34] target/i386: add de/compaction to xsave_helper Magnus Kulke
2026-04-17 11:56 ` Mohamed Mediouni
2026-04-18 17:46 ` Mohamed Mediouni
2026-04-20 12:02 ` Magnus Kulke
2026-04-17 10:56 ` [PATCH 31/34] target/i386/mshv: migrate XSAVE state Magnus Kulke
2026-04-17 10:56 ` [PATCH 32/34] target/i386/mshv: reconstruct hflags after load Magnus Kulke
2026-04-17 10:56 ` [PATCH 33/34] target/i386/mshv: migrate MP_STATE Magnus Kulke
2026-04-17 10:56 ` [PATCH 34/34] accel/mshv: enable dirty page tracking Magnus Kulke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260417105618.3621-4-magnuskulke@linux.microsoft.com \
--to=magnuskulke@linux.microsoft.com \
--cc=alex@shazbot.org \
--cc=clg@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=liuwe@microsoft.com \
--cc=magnuskulke@microsoft.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=mtosatti@redhat.com \
--cc=pbonzini@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=wei.liu@kernel.org \
--cc=zhao1.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox