Use a new file to unclutter the vcpu code gradually from APIC related
logic.
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
include/system/mshv_int.h | 8 ++++
target/i386/mshv/meson.build | 1 +
target/i386/mshv/mshv-apic.c | 78 ++++++++++++++++++++++++++++++++++++
target/i386/mshv/mshv-cpu.c | 66 +++---------------------------
4 files changed, 92 insertions(+), 61 deletions(-)
create mode 100644 target/i386/mshv/mshv-apic.c
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
index 7af5bcf022..f86c7a3be6 100644
--- a/include/system/mshv_int.h
+++ b/include/system/mshv_int.h
@@ -16,6 +16,8 @@
#define MSHV_MSR_ENTRIES_COUNT 64
+struct mshv_get_set_vp_state;
+
typedef struct hyperv_message hv_message;
typedef struct MshvHvCallArgs {
@@ -84,6 +86,12 @@ void mshv_arch_destroy_vcpu(CPUState *cpu);
void mshv_arch_amend_proc_features(
union hv_partition_synthetic_processor_features *features);
int mshv_arch_post_init_vm(int vm_fd);
+int mshv_set_lapic(int cpu_fd,
+ const struct hv_local_interrupt_controller_state *state);
+int mshv_get_lapic(int cpu_fd,
+ struct hv_local_interrupt_controller_state *state);
+int mshv_get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state);
+int mshv_set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state);
typedef struct mshv_root_hvcall mshv_root_hvcall;
int mshv_hvcall(int fd, const mshv_root_hvcall *args);
diff --git a/target/i386/mshv/meson.build b/target/i386/mshv/meson.build
index 49f28d4a5b..5eb6e833a6 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-apic.c',
'mshv-cpu.c',
))
diff --git a/target/i386/mshv/mshv-apic.c b/target/i386/mshv/mshv-apic.c
new file mode 100644
index 0000000000..e0e8b8cacf
--- /dev/null
+++ b/target/i386/mshv/mshv-apic.c
@@ -0,0 +1,78 @@
+/*
+ * QEMU MSHV support
+ *
+ * Copyright Microsoft, Corp. 2026
+ *
+ * Authors: Magnus Kulke <magnuskulke@microsoft.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/memalign.h"
+#include "qemu/error-report.h"
+
+#include "system/mshv.h"
+#include "system/mshv_int.h"
+
+#include "linux/mshv.h"
+#include "hw/hyperv/hvgdk.h"
+#include "hw/hyperv/hvhdk_mini.h"
+#include "hw/hyperv/hvgdk_mini.h"
+
+#include <sys/ioctl.h>
+
+int mshv_get_lapic(int cpu_fd,
+ struct hv_local_interrupt_controller_state *state)
+{
+ int ret;
+ size_t size = 4096;
+ /* buffer aligned to 4k, as *state requires that */
+ void *buffer = qemu_memalign(size, size);
+ struct mshv_get_set_vp_state mshv_state = { 0 };
+
+ mshv_state.buf_ptr = (uint64_t) buffer;
+ mshv_state.buf_sz = size;
+ mshv_state.type = MSHV_VP_STATE_LAPIC;
+
+ ret = mshv_get_vp_state(cpu_fd, &mshv_state);
+ if (ret == 0) {
+ memcpy(state, buffer, sizeof(*state));
+ }
+ qemu_vfree(buffer);
+ if (ret < 0) {
+ error_report("failed to get lapic");
+ return -1;
+ }
+
+ return 0;
+}
+
+int mshv_set_lapic(int cpu_fd,
+ const struct hv_local_interrupt_controller_state *state)
+{
+ int ret;
+ size_t size = 4096;
+ /* buffer aligned to 4k, as *state requires that */
+ void *buffer = qemu_memalign(size, size);
+ struct mshv_get_set_vp_state mshv_state = { 0 };
+
+ if (!state) {
+ error_report("lapic state is NULL");
+ return -1;
+ }
+ memcpy(buffer, state, sizeof(*state));
+
+ mshv_state.buf_ptr = (uint64_t) buffer;
+ mshv_state.buf_sz = size;
+ mshv_state.type = MSHV_VP_STATE_LAPIC;
+
+ ret = mshv_set_vp_state(cpu_fd, &mshv_state);
+ qemu_vfree(buffer);
+ if (ret < 0) {
+ error_report("failed to set lapic: %s", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 56656ac0b0..54c262d8bc 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -919,7 +919,7 @@ static int set_xc_reg(const CPUState *cpu)
return 0;
}
-static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state)
+int mshv_get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state)
{
int ret;
@@ -932,39 +932,12 @@ static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state)
return 0;
}
-static int get_lapic(const CPUState *cpu,
- struct hv_local_interrupt_controller_state *state)
-{
- int ret;
- size_t size = 4096;
- /* 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;
- mshv_state.type = MSHV_VP_STATE_LAPIC;
-
- ret = get_vp_state(cpu_fd, &mshv_state);
- if (ret == 0) {
- memcpy(state, buffer, sizeof(*state));
- }
- qemu_vfree(buffer);
- if (ret < 0) {
- error_report("failed to get lapic");
- return -1;
- }
-
- return 0;
-}
-
static uint32_t set_apic_delivery_mode(uint32_t reg, uint32_t mode)
{
return ((reg) & ~0x700) | ((mode) << 8);
}
-static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state)
+int mshv_set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state)
{
int ret;
@@ -977,43 +950,14 @@ static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state)
return 0;
}
-static int set_lapic(const CPUState *cpu,
- const struct hv_local_interrupt_controller_state *state)
-{
- int ret;
- size_t size = 4096;
- /* 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");
- return -1;
- }
- memcpy(buffer, state, sizeof(*state));
-
- mshv_state.buf_ptr = (uint64_t) buffer;
- mshv_state.buf_sz = size;
- mshv_state.type = MSHV_VP_STATE_LAPIC;
-
- ret = set_vp_state(cpu_fd, &mshv_state);
- qemu_vfree(buffer);
- if (ret < 0) {
- error_report("failed to set lapic: %s", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
static int init_lint(const CPUState *cpu)
{
int ret;
uint32_t *lvt_lint0, *lvt_lint1;
+ int cpu_fd = mshv_vcpufd(cpu);
struct hv_local_interrupt_controller_state lapic_state = { 0 };
- ret = get_lapic(cpu, &lapic_state);
+ ret = mshv_get_lapic(cpu_fd, &lapic_state);
if (ret < 0) {
return ret;
}
@@ -1026,7 +970,7 @@ static int init_lint(const CPUState *cpu)
/* TODO: should we skip setting lapic if the values are the same? */
- return set_lapic(cpu, &lapic_state);
+ return mshv_set_lapic(cpu_fd, &lapic_state);
}
int mshv_arch_store_vcpu_state(const CPUState *cpu)
--
2.34.1