[PATCH 07/14] accel/mshv: add arch-specific accelerator init hook

Anirudh Rayabharam (Microsoft) posted 14 patches 3 weeks, 6 days ago
Maintainers: Magnus Kulke <magnuskulke@linux.microsoft.com>, Wei Liu <wei.liu@kernel.org>, Peter Maydell <peter.maydell@linaro.org>, Anirudh Rayabharam <anirudh@anirudhrb.com>, Aastha Rawat <aastharawat@linux.microsoft.com>, Paolo Bonzini <pbonzini@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
There is a newer version of this series
[PATCH 07/14] accel/mshv: add arch-specific accelerator init hook
Posted by Anirudh Rayabharam (Microsoft) 3 weeks, 6 days ago
Introduce mshv_arch_accel_init() as an arch-specific hook called early
in mshv_init(), before VM creation. This allows each architecture to
perform platform-specific initialization at accelerator init time.

For arm64, the hook queries the hypervisor for the supported IPA bit
size and validates it against the guest memory map via the machine's
get_physical_address_range callback, following the same pattern used by
HVF and WHPX. This also populates the memory map which comes in handy
later when retreiving the vGIC layout.

For x86, the hook calls mshv_init_mmio_emu() which was previously called
directly from the common init path. Also move set_unimplemented_msr_action()
and mshv_arch_post_init_vm() from mshv-cpu.c to the new mshv-all.c, as
they are not vCPU-specific.

Signed-off-by: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com>
---
 accel/mshv/mshv-all.c        |  5 ++-
 include/system/mshv_int.h    |  1 +
 target/arm/mshv/mshv-all.c   | 25 ++++++++++----
 target/i386/mshv/meson.build |  1 +
 target/i386/mshv/mshv-all.c  | 80 ++++++++++++++++++++++++++++++++++++++++++++
 target/i386/mshv/mshv-cpu.c  | 40 ----------------------
 6 files changed, 105 insertions(+), 47 deletions(-)

diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
index c6dad18d2f..d63b3a53bf 100644
--- a/accel/mshv/mshv-all.c
+++ b/accel/mshv/mshv-all.c
@@ -477,7 +477,10 @@ static int mshv_init(AccelState *as, MachineState *ms)
         return -1;
     }
 
-    mshv_init_mmio_emu();
+    ret = mshv_arch_accel_init(as, ms, mshv_fd);
+    if (ret < 0) {
+        return -1;
+    }
 
     mshv_init_msicontrol();
 
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
index ff3ab957b5..c72c91cd23 100644
--- a/include/system/mshv_int.h
+++ b/include/system/mshv_int.h
@@ -96,6 +96,7 @@ void mshv_arch_init_vcpu(CPUState *cpu);
 void mshv_arch_destroy_vcpu(CPUState *cpu);
 void mshv_arch_amend_proc_features(
     union hv_partition_synthetic_processor_features *features);
+int mshv_arch_accel_init(AccelState *as, MachineState *ms, int mshv_fd);
 int mshv_arch_post_init_vm(int vm_fd);
 void mshv_setup_hvcall_args(AccelCPUState *state);
 
diff --git a/target/arm/mshv/mshv-all.c b/target/arm/mshv/mshv-all.c
index 0102297305..2b983845d3 100644
--- a/target/arm/mshv/mshv-all.c
+++ b/target/arm/mshv/mshv-all.c
@@ -9,12 +9,13 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
 
 #include "qemu/error-report.h"
 #include "qemu/memalign.h"
+#include "hw/arm/bsa.h"
+#include "hw/arm/virt.h"
 
 #include "system/cpus.h"
 #include "target/arm/cpu.h"
@@ -188,11 +189,6 @@ void mshv_arch_destroy_vcpu(CPUState *cpu)
     state->hvcall_args = (MshvHvCallArgs){0};
 }
 
-void mshv_init_mmio_emu(void)
-{
-
-}
-
 void mshv_arch_amend_proc_features(
     union hv_partition_synthetic_processor_features *features)
 {
@@ -390,3 +386,20 @@ void mshv_arm_set_cpu_features_from_host(ARMCPU *cpu)
     cpu->midr = arm_host_cpu_features.midr;
     cpu->reset_sctlr = arm_host_cpu_features.reset_sctlr;
 }
+
+int mshv_arch_accel_init(AccelState *as, MachineState *ms, int mshv_fd)
+{
+    MachineClass *mc = MACHINE_GET_CLASS(ms);
+    int pa_range;
+    uint32_t ipa_size;
+
+    if (mc->get_physical_address_range) {
+        ipa_size = mshv_arm_get_ipa_bit_size(mshv_fd);
+        pa_range = mc->get_physical_address_range(ms, ipa_size, ipa_size);
+        if (pa_range < 0) {
+            return -EINVAL;
+        }
+    }
+
+    return 0;
+}
diff --git a/target/i386/mshv/meson.build b/target/i386/mshv/meson.build
index 6091c21887..ce54e134cb 100644
--- a/target/i386/mshv/meson.build
+++ b/target/i386/mshv/meson.build
@@ -1,6 +1,7 @@
 i386_mshv_ss = ss.source_set()
 
 i386_mshv_ss.add(files(
+  'mshv-all.c',
   'mshv-cpu.c',
   'msr.c',
 ))
diff --git a/target/i386/mshv/mshv-all.c b/target/i386/mshv/mshv-all.c
new file mode 100644
index 0000000000..f0b43aa86f
--- /dev/null
+++ b/target/i386/mshv/mshv-all.c
@@ -0,0 +1,80 @@
+/*
+ * QEMU MSHV support
+ *
+ * Copyright Microsoft, Corp. 2026
+ *
+ * Authors: Ziqiao Zhou   <ziqiaozhou@microsoft.com>
+ *          Magnus Kulke  <magnuskulke@microsoft.com>
+ *          Jinank Jain   <jinankjain@microsoft.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qemu/memalign.h"
+
+#include "system/mshv.h"
+#include "system/mshv_int.h"
+#include "system/address-spaces.h"
+#include "linux/mshv.h"
+#include "hw/hyperv/hvgdk.h"
+#include "hw/hyperv/hvgdk_mini.h"
+#include "hw/hyperv/hvhdk_mini.h"
+#include "hw/i386/apic_internal.h"
+
+#include "cpu.h"
+#include "emulate/x86_decode.h"
+#include "emulate/x86_emu.h"
+#include "emulate/x86_flags.h"
+
+#include "trace-accel_mshv.h"
+#include "trace.h"
+
+#include <sys/ioctl.h>
+
+int mshv_arch_accel_init(AccelState *as, MachineState *ms, int mshv_fd)
+{
+    mshv_init_mmio_emu();
+    return 0;
+}
+
+/*
+ * Default Microsoft Hypervisor behavior for unimplemented MSR is to send a
+ * fault to the guest if it tries to access it. It is possible to override
+ * this behavior with a more suitable option i.e., ignore writes from the guest
+ * and return zero in attempt to read unimplemented.
+ */
+static int set_unimplemented_msr_action(int vm_fd)
+{
+    struct hv_input_set_partition_property in = {0};
+    struct mshv_root_hvcall args = {0};
+
+    in.property_code  = HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION;
+    in.property_value = HV_UNIMPLEMENTED_MSR_ACTION_IGNORE_WRITE_READ_ZERO;
+
+    args.code   = HVCALL_SET_PARTITION_PROPERTY;
+    args.in_sz  = sizeof(in);
+    args.in_ptr = (uint64_t)&in;
+
+    trace_mshv_hvcall_args("unimplemented_msr_action", args.code, args.in_sz);
+
+    int ret = mshv_hvcall(vm_fd, &args);
+    if (ret < 0) {
+        error_report("Failed to set unimplemented MSR action");
+        return -1;
+    }
+    return 0;
+}
+
+int mshv_arch_post_init_vm(int vm_fd)
+{
+    int ret;
+
+    ret = set_unimplemented_msr_action(vm_fd);
+    if (ret < 0) {
+        error_report("Failed to set unimplemented MSR action");
+    }
+
+    return ret;
+}
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 9a80dc34d0..8325ac74a3 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -1482,43 +1482,3 @@ void mshv_arch_destroy_vcpu(CPUState *cpu)
     state->hvcall_args = (MshvHvCallArgs){0};
     g_clear_pointer(&env->emu_mmio_buf, g_free);
 }
-
-/*
- * Default Microsoft Hypervisor behavior for unimplemented MSR is to send a
- * fault to the guest if it tries to access it. It is possible to override
- * this behavior with a more suitable option i.e., ignore writes from the guest
- * and return zero in attempt to read unimplemented.
- */
-static int set_unimplemented_msr_action(int vm_fd)
-{
-    struct hv_input_set_partition_property in = {0};
-    struct mshv_root_hvcall args = {0};
-
-    in.property_code  = HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION;
-    in.property_value = HV_UNIMPLEMENTED_MSR_ACTION_IGNORE_WRITE_READ_ZERO;
-
-    args.code   = HVCALL_SET_PARTITION_PROPERTY;
-    args.in_sz  = sizeof(in);
-    args.in_ptr = (uint64_t)&in;
-
-    trace_mshv_hvcall_args("unimplemented_msr_action", args.code, args.in_sz);
-
-    int ret = mshv_hvcall(vm_fd, &args);
-    if (ret < 0) {
-        error_report("Failed to set unimplemented MSR action");
-        return -1;
-    }
-    return 0;
-}
-
-int mshv_arch_post_init_vm(int vm_fd)
-{
-    int ret;
-
-    ret = set_unimplemented_msr_action(vm_fd);
-    if (ret < 0) {
-        error_report("Failed to set unimplemented MSR action");
-    }
-
-    return ret;
-}

-- 
2.43.0