[RFC PATCH 14/25] target/i386/mshv: Add CPU create and remove logic

Magnus Kulke posted 25 patches 5 months, 4 weeks ago
There is a newer version of this series
[RFC PATCH 14/25] target/i386/mshv: Add CPU create and remove logic
Posted by Magnus Kulke 5 months, 4 weeks ago
Implement MSHV-specific hooks for vCPU creation and teardown in the
i386 target. A list of locks per vCPU is maintained to lock CPU state in
MMIO operations.

Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
 target/i386/mshv/mshv-cpu.c | 61 +++++++++++++++++++++++++++++++++----
 1 file changed, 55 insertions(+), 6 deletions(-)

diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index c4b2c297e2..0ba1dacaed 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -14,6 +14,8 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/atomic.h"
+#include "qemu/lockable.h"
 #include "qemu/error-report.h"
 #include "qemu/typedefs.h"
 
@@ -30,6 +32,36 @@
 #include "trace-accel_mshv.h"
 #include "trace.h"
 
+#include <sys/ioctl.h>
+
+static QemuMutex *cpu_guards_lock;
+static GHashTable *cpu_guards;
+
+static void add_cpu_guard(int cpu_fd)
+{
+    QemuMutex *guard;
+
+    WITH_QEMU_LOCK_GUARD(cpu_guards_lock) {
+        guard = g_new0(QemuMutex, 1);
+        qemu_mutex_init(guard);
+        g_hash_table_insert(cpu_guards, GUINT_TO_POINTER(cpu_fd), guard);
+    }
+}
+
+static void remove_cpu_guard(int cpu_fd)
+{
+    QemuMutex *guard;
+
+    WITH_QEMU_LOCK_GUARD(cpu_guards_lock) {
+        guard = g_hash_table_lookup(cpu_guards, GUINT_TO_POINTER(cpu_fd));
+        if (guard) {
+            qemu_mutex_destroy(guard);
+            g_free(guard);
+            g_hash_table_remove(cpu_guards, GUINT_TO_POINTER(cpu_fd));
+        }
+    }
+}
+
 int mshv_store_regs(CPUState *cpu)
 {
 	error_report("unimplemented");
@@ -62,20 +94,37 @@ int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit)
 
 void mshv_remove_vcpu(int vm_fd, int cpu_fd)
 {
-	error_report("unimplemented");
-	abort();
+    /*
+     * TODO: don't we have to perform an ioctl to remove the vcpu?
+     * there is WHvDeleteVirtualProcessor in the WHV api
+     */
+    remove_cpu_guard(cpu_fd);
 }
 
+
 int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd)
 {
-	error_report("unimplemented");
-	abort();
+    int ret;
+    struct mshv_create_vp vp_arg = {
+        .vp_index = vp_index,
+    };
+    ret = ioctl(vm_fd, MSHV_CREATE_VP, &vp_arg);
+    if (ret < 0) {
+        error_report("failed to create mshv vcpu: %s", strerror(errno));
+        return -1;
+    }
+
+    add_cpu_guard(ret);
+    *cpu_fd = ret;
+
+    return 0;
 }
 
 void mshv_init_cpu_logic(void)
 {
-	error_report("unimplemented");
-	abort();
+    cpu_guards_lock = g_new0(QemuMutex, 1);
+    qemu_mutex_init(cpu_guards_lock);
+    cpu_guards = g_hash_table_new(g_direct_hash, g_direct_equal);
 }
 
 void mshv_arch_init_vcpu(CPUState *cpu)
-- 
2.34.1
Re: [RFC PATCH 14/25] target/i386/mshv: Add CPU create and remove logic
Posted by Wei Liu 5 months, 4 weeks ago
On Tue, May 20, 2025 at 01:30:07PM +0200, Magnus Kulke wrote:
> Implement MSHV-specific hooks for vCPU creation and teardown in the
> i386 target. A list of locks per vCPU is maintained to lock CPU state in
> MMIO operations.
> 
> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
> ---
>  target/i386/mshv/mshv-cpu.c | 61 +++++++++++++++++++++++++++++++++----
>  1 file changed, 55 insertions(+), 6 deletions(-)
> 
> diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
> index c4b2c297e2..0ba1dacaed 100644
> --- a/target/i386/mshv/mshv-cpu.c
> +++ b/target/i386/mshv/mshv-cpu.c
> @@ -14,6 +14,8 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/atomic.h"
> +#include "qemu/lockable.h"
>  #include "qemu/error-report.h"
>  #include "qemu/typedefs.h"
>  
> @@ -30,6 +32,36 @@
>  #include "trace-accel_mshv.h"
>  #include "trace.h"
>  
> +#include <sys/ioctl.h>
> +
> +static QemuMutex *cpu_guards_lock;
> +static GHashTable *cpu_guards;
> +
> +static void add_cpu_guard(int cpu_fd)
> +{
> +    QemuMutex *guard;
> +
> +    WITH_QEMU_LOCK_GUARD(cpu_guards_lock) {
> +        guard = g_new0(QemuMutex, 1);
> +        qemu_mutex_init(guard);
> +        g_hash_table_insert(cpu_guards, GUINT_TO_POINTER(cpu_fd), guard);
> +    }
> +}
> +
> +static void remove_cpu_guard(int cpu_fd)
> +{
> +    QemuMutex *guard;
> +
> +    WITH_QEMU_LOCK_GUARD(cpu_guards_lock) {
> +        guard = g_hash_table_lookup(cpu_guards, GUINT_TO_POINTER(cpu_fd));
> +        if (guard) {
> +            qemu_mutex_destroy(guard);
> +            g_free(guard);
> +            g_hash_table_remove(cpu_guards, GUINT_TO_POINTER(cpu_fd));
> +        }
> +    }
> +}
> +
>  int mshv_store_regs(CPUState *cpu)
>  {
>  	error_report("unimplemented");
> @@ -62,20 +94,37 @@ int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit)
>  
>  void mshv_remove_vcpu(int vm_fd, int cpu_fd)
>  {
> -	error_report("unimplemented");
> -	abort();
> +    /*
> +     * TODO: don't we have to perform an ioctl to remove the vcpu?
> +     * there is WHvDeleteVirtualProcessor in the WHV api
> +     */
> +    remove_cpu_guard(cpu_fd);

Can you just park that CPU and never schedule it again?

There is a DELETE_VP call but we may not have exposed that to user
space.

The code as-is seems to be leaking the cpu_fd. If it is handled
elsewhere you can ignore this comment.

Thanks,
Wei.

>  }
>  
> +
>  int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd)
>  {
> -	error_report("unimplemented");
> -	abort();
> +    int ret;
> +    struct mshv_create_vp vp_arg = {
> +        .vp_index = vp_index,
> +    };
> +    ret = ioctl(vm_fd, MSHV_CREATE_VP, &vp_arg);
> +    if (ret < 0) {
> +        error_report("failed to create mshv vcpu: %s", strerror(errno));
> +        return -1;
> +    }
> +
> +    add_cpu_guard(ret);
> +    *cpu_fd = ret;
> +
> +    return 0;
>  }
>  
>  void mshv_init_cpu_logic(void)
>  {
> -	error_report("unimplemented");
> -	abort();
> +    cpu_guards_lock = g_new0(QemuMutex, 1);
> +    qemu_mutex_init(cpu_guards_lock);
> +    cpu_guards = g_hash_table_new(g_direct_hash, g_direct_equal);
>  }
>  
>  void mshv_arch_init_vcpu(CPUState *cpu)
> -- 
> 2.34.1
>