qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: berrange@redhat.com, magnus.kulke@linux.microsoft.com,
	wei.liu@kernel.org,
	Magnus Kulke <magnuskulke@linux.microsoft.com>
Subject: [PATCH 13/27] target/i386/mshv: Implement mshv_store_regs()
Date: Thu,  2 Oct 2025 19:15:22 +0200	[thread overview]
Message-ID: <20251002171536.1460049-14-pbonzini@redhat.com> (raw)
In-Reply-To: <20251002171536.1460049-1-pbonzini@redhat.com>

From: Magnus Kulke <magnuskulke@linux.microsoft.com>

Add support for writing general-purpose registers to MSHV vCPUs
during initialization or migration using the MSHV register interface. A
generic set_register call is introduced to abstract the HV call over
the various register types.

Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Link: https://lore.kernel.org/r/20250916164847.77883-14-magnuskulke@linux.microsoft.com
[mshv.h/mshv_int.h split. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/system/mshv.h       |   1 +
 include/system/mshv_int.h   |   2 +
 target/i386/mshv/mshv-cpu.c | 116 +++++++++++++++++++++++++++++++++++-
 3 files changed, 117 insertions(+), 2 deletions(-)

diff --git a/include/system/mshv.h b/include/system/mshv.h
index bbc42f4dc3a..8b1fc20c80d 100644
--- a/include/system/mshv.h
+++ b/include/system/mshv.h
@@ -18,6 +18,7 @@
 #include "qemu/accel.h"
 #include "hw/hyperv/hyperv-proto.h"
 #include "hw/hyperv/hvhdk.h"
+#include "hw/hyperv/hvgdk_mini.h"
 #include "qapi/qapi-types-common.h"
 #include "system/memory.h"
 #include "accel/accel-ops.h"
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
index fb80f69772b..731841af929 100644
--- a/include/system/mshv_int.h
+++ b/include/system/mshv_int.h
@@ -61,6 +61,8 @@ void mshv_remove_vcpu(int vm_fd, int cpu_fd);
 int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit);
 int mshv_load_regs(CPUState *cpu);
 int mshv_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);
 void mshv_arch_init_vcpu(CPUState *cpu);
 void mshv_arch_destroy_vcpu(CPUState *cpu);
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 5069ab7a22f..9ead03ca2d8 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -32,12 +32,124 @@
 
 #include <sys/ioctl.h>
 
+static enum hv_register_name STANDARD_REGISTER_NAMES[18] = {
+    HV_X64_REGISTER_RAX,
+    HV_X64_REGISTER_RBX,
+    HV_X64_REGISTER_RCX,
+    HV_X64_REGISTER_RDX,
+    HV_X64_REGISTER_RSI,
+    HV_X64_REGISTER_RDI,
+    HV_X64_REGISTER_RSP,
+    HV_X64_REGISTER_RBP,
+    HV_X64_REGISTER_R8,
+    HV_X64_REGISTER_R9,
+    HV_X64_REGISTER_R10,
+    HV_X64_REGISTER_R11,
+    HV_X64_REGISTER_R12,
+    HV_X64_REGISTER_R13,
+    HV_X64_REGISTER_R14,
+    HV_X64_REGISTER_R15,
+    HV_X64_REGISTER_RIP,
+    HV_X64_REGISTER_RFLAGS,
+};
+
+int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
+                          size_t n_regs)
+{
+    int cpu_fd = mshv_vcpufd(cpu);
+    int vp_index = cpu->cpu_index;
+    size_t in_sz, assocs_sz;
+    hv_input_set_vp_registers *in;
+    struct mshv_root_hvcall args = {0};
+    int ret;
+
+    /* find out the size of the struct w/ a flexible array at the tail */
+    assocs_sz = n_regs * sizeof(hv_register_assoc);
+    in_sz = sizeof(hv_input_set_vp_registers) + assocs_sz;
+
+    /* fill the input struct */
+    in = g_malloc0(in_sz);
+    in->vp_index = vp_index;
+    memcpy(in->elements, assocs, assocs_sz);
+
+    /* create the hvcall envelope */
+    args.code = HVCALL_SET_VP_REGISTERS;
+    args.in_sz = in_sz;
+    args.in_ptr = (uint64_t) in;
+    args.reps = (uint16_t) n_regs;
+
+    /* perform the call */
+    ret = mshv_hvcall(cpu_fd, &args);
+    g_free(in);
+    if (ret < 0) {
+        error_report("Failed to set registers");
+        return -1;
+    }
+
+    /* assert we set all registers */
+    if (args.reps != n_regs) {
+        error_report("Failed to set registers: expected %zu elements"
+                     ", got %u", n_regs, args.reps);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int set_standard_regs(const CPUState *cpu)
+{
+    X86CPU *x86cpu = X86_CPU(cpu);
+    CPUX86State *env = &x86cpu->env;
+    hv_register_assoc assocs[ARRAY_SIZE(STANDARD_REGISTER_NAMES)];
+    int ret;
+    size_t n_regs = ARRAY_SIZE(STANDARD_REGISTER_NAMES);
+
+    /* set names */
+    for (size_t i = 0; i < ARRAY_SIZE(STANDARD_REGISTER_NAMES); i++) {
+        assocs[i].name = STANDARD_REGISTER_NAMES[i];
+    }
+    assocs[0].value.reg64 = env->regs[R_EAX];
+    assocs[1].value.reg64 = env->regs[R_EBX];
+    assocs[2].value.reg64 = env->regs[R_ECX];
+    assocs[3].value.reg64 = env->regs[R_EDX];
+    assocs[4].value.reg64 = env->regs[R_ESI];
+    assocs[5].value.reg64 = env->regs[R_EDI];
+    assocs[6].value.reg64 = env->regs[R_ESP];
+    assocs[7].value.reg64 = env->regs[R_EBP];
+    assocs[8].value.reg64 = env->regs[R_R8];
+    assocs[9].value.reg64 = env->regs[R_R9];
+    assocs[10].value.reg64 = env->regs[R_R10];
+    assocs[11].value.reg64 = env->regs[R_R11];
+    assocs[12].value.reg64 = env->regs[R_R12];
+    assocs[13].value.reg64 = env->regs[R_R13];
+    assocs[14].value.reg64 = env->regs[R_R14];
+    assocs[15].value.reg64 = env->regs[R_R15];
+    assocs[16].value.reg64 = env->eip;
+    lflags_to_rflags(env);
+    assocs[17].value.reg64 = env->eflags;
+
+    ret = mshv_set_generic_regs(cpu, assocs, n_regs);
+    if (ret < 0) {
+        error_report("failed to set standard registers");
+        return -errno;
+    }
+    return 0;
+}
+
 int mshv_store_regs(CPUState *cpu)
 {
-    error_report("unimplemented");
-    abort();
+    int ret;
+
+    ret = set_standard_regs(cpu);
+    if (ret < 0) {
+        error_report("Failed to store standard registers");
+        return -1;
+    }
+
+    return 0;
 }
 
+
 int mshv_load_regs(CPUState *cpu)
 {
     error_report("unimplemented");
-- 
2.51.0



  parent reply	other threads:[~2025-10-02 17:20 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-02 17:15 [PATCH v5 00/27] Implementing a MSHV (Microsoft Hypervisor) accelerator Paolo Bonzini
2025-10-02 17:15 ` [PATCH 01/27] accel: Add Meson and config support for MSHV accelerator Paolo Bonzini
2025-10-08 17:15   ` Magnus Kulke
2025-10-02 17:15 ` [PATCH 02/27] target/i386/emulate: Allow instruction decoding from stream Paolo Bonzini
2025-10-02 17:15 ` [PATCH 03/27] target/i386/mshv: Add x86 decoder/emu implementation Paolo Bonzini
2025-10-02 17:15 ` [PATCH 04/27] hw/intc: Generalize APIC helper names from kvm_* to accel_* Paolo Bonzini
2025-10-02 17:15 ` [PATCH 05/27] include/hw/hyperv: Add MSHV ABI header definitions Paolo Bonzini
2025-10-02 17:15 ` [PATCH 06/27] linux-headers/linux: Add mshv.h headers Paolo Bonzini
2025-10-02 17:15 ` [PATCH 07/27] accel/mshv: Add accelerator skeleton Paolo Bonzini
2025-10-02 17:15 ` [PATCH 08/27] accel/mshv: Register memory region listeners Paolo Bonzini
2025-10-02 17:15 ` [PATCH 09/27] accel/mshv: Initialize VM partition Paolo Bonzini
2025-10-02 17:15 ` [PATCH 10/27] accel/mshv: Add vCPU creation and execution loop Paolo Bonzini
2025-10-02 17:15 ` [PATCH 11/27] accel/mshv: Add vCPU signal handling Paolo Bonzini
2025-10-02 17:15 ` [PATCH 12/27] target/i386/mshv: Add CPU create and remove logic Paolo Bonzini
2025-10-02 17:15 ` Paolo Bonzini [this message]
2025-10-02 17:15 ` [PATCH 14/27] target/i386/mshv: Implement mshv_get_standard_regs() Paolo Bonzini
2025-10-02 17:15 ` [PATCH 15/27] target/i386/mshv: Implement mshv_get_special_regs() Paolo Bonzini
2025-10-02 17:15 ` [PATCH 16/27] target/i386/mshv: Implement mshv_arch_put_registers() Paolo Bonzini
2025-10-02 17:15 ` [PATCH 17/27] target/i386/mshv: Set local interrupt controller state Paolo Bonzini
2025-10-02 17:15 ` [PATCH 18/27] target/i386/mshv: Register CPUID entries with MSHV Paolo Bonzini
2025-10-02 17:15 ` [PATCH 19/27] target/i386/mshv: Register MSRs " Paolo Bonzini
2025-10-02 17:15 ` [PATCH 20/27] target/i386/mshv: Integrate x86 instruction decoder/emulator Paolo Bonzini
2025-10-02 17:15 ` [PATCH 21/27] target/i386/mshv: Write MSRs to the hypervisor Paolo Bonzini
2025-10-02 17:15 ` [PATCH 22/27] target/i386/mshv: Implement mshv_vcpu_run() Paolo Bonzini
2025-10-02 17:15 ` [PATCH 23/27] accel/mshv: Handle overlapping mem mappings Paolo Bonzini
2025-10-02 17:15 ` [PATCH 24/27] qapi/accel: Allow to query mshv capabilities Paolo Bonzini
2025-10-02 17:15 ` [PATCH 25/27] target/i386/mshv: Use preallocated page for hvcall Paolo Bonzini
2025-10-02 17:15 ` [PATCH 26/27] docs: Add mshv to documentation Paolo Bonzini
2025-10-08 19:13   ` Wei Liu
2025-10-02 17:15 ` [PATCH 27/27] MAINTAINERS: Add maintainers for mshv accelerator Paolo Bonzini
2025-10-08 17:13 ` [PATCH v5 00/27] Implementing a MSHV (Microsoft Hypervisor) accelerator 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=20251002171536.1460049-14-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=berrange@redhat.com \
    --cc=magnus.kulke@linux.microsoft.com \
    --cc=magnuskulke@linux.microsoft.com \
    --cc=qemu-devel@nongnu.org \
    --cc=wei.liu@kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).