master
h 152 lines 4.66 KB
Raw
1 /*
2 * QEMU MSHV support
3 *
4 * Copyright Microsoft, Corp. 2025
5 *
6 * Authors: Ziqiao Zhou <ziqiaozhou@microsoft.com>
7 * Magnus Kulke <magnuskulke@microsoft.com>
8 * Jinank Jain <jinankjain@microsoft.com>
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 *
12 */
13
14 #ifndef QEMU_MSHV_INT_H
15 #define QEMU_MSHV_INT_H
16
17 #include "hw/hyperv/hvhdk.h"
18
19 #define MSHV_MSR_ENTRIES_COUNT 64
20
21 /*
22 * Interruption-type encoding, used by the hypervisor in
23 * hv_x64_pending_interruption_register.interruption_type
24 * See TLFS 6.0 section 7.9.2, p55
25 * https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs
26 */
27 #define MSHV_HV_INTERRUPTION_TYPE_EXT_INT 0
28 #define MSHV_HV_INTERRUPTION_TYPE_NMI 2
29 #define MSHV_HV_INTERRUPTION_TYPE_HW_EXC 3
30 #define MSHV_HV_INTERRUPTION_TYPE_SW_INT 4
31 #define MSHV_HV_INTERRUPTION_TYPE_PRIV_SW_EXC 5
32 #define MSHV_HV_INTERRUPTION_TYPE_SW_EXC 6
33
34 #define MSHV_DIRTY_PAGES_BATCH_SIZE 0x10000
35
36 typedef struct hyperv_message hv_message;
37
38 typedef struct MshvHvCallArgs {
39 void *base;
40 void *input_page;
41 void *output_page;
42 } MshvHvCallArgs;
43
44 struct AccelCPUState {
45 int cpufd;
46 MshvHvCallArgs hvcall_args;
47 };
48
49 typedef struct MshvMemoryListener {
50 MemoryListener listener;
51 int as_id;
52 } MshvMemoryListener;
53
54 typedef struct MshvAddressSpace {
55 MshvMemoryListener *ml;
56 AddressSpace *as;
57 } MshvAddressSpace;
58
59 struct MshvState {
60 AccelState parent_obj;
61 int vm;
62 MshvMemoryListener memory_listener;
63 /* number of listeners */
64 int nr_as;
65 MshvAddressSpace *as;
66 int fd;
67 /* irqchip routing */
68 struct mshv_user_irq_table *irq_routes;
69 int nr_allocated_irq_routes;
70 unsigned long *used_gsi_bitmap;
71 unsigned int gsi_count;
72 union hv_partition_processor_features processor_features;
73 };
74
75 typedef struct MshvMsiControl {
76 bool updated;
77 GHashTable *gsi_routes;
78 } MshvMsiControl;
79
80 #define mshv_vcpufd(cpu) (cpu->accel->cpufd)
81
82 /* cpu */
83
84 typedef enum MshvVmExit {
85 MshvVmExitIgnore = 0,
86 MshvVmExitShutdown = 1,
87 MshvVmExitSpecial = 2,
88 } MshvVmExit;
89
90 void mshv_init_mmio_emu(void);
91 int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd);
92 void mshv_remove_vcpu(int vm_fd, int cpu_fd);
93 int mshv_configure_vcpu(const CPUState *cpu);
94 int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit);
95 int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
96 size_t n_regs);
97 int mshv_get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,
98 size_t n_regs);
99 int mshv_arch_store_vcpu_state(const CPUState *cpu);
100 int mshv_arch_load_vcpu_state(CPUState *cpu);
101 int mshv_arch_set_partition_msrs(const CPUState *cpu);
102 int mshv_arch_set_mp_state(const CPUState *cpu);
103 void mshv_arch_init_vcpu(CPUState *cpu);
104 void mshv_arch_destroy_vcpu(CPUState *cpu);
105 void mshv_arch_amend_proc_features(
106 union hv_partition_synthetic_processor_features *features);
107 void mshv_arch_disable_partition_proc_features(
108 union hv_partition_processor_features *disabled_features);
109 int mshv_arch_post_init_vm(int vm_fd);
110 int mshv_get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state);
111 int mshv_set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state);
112 typedef struct mshv_root_hvcall mshv_root_hvcall;
113 int mshv_hvcall(int fd, const mshv_root_hvcall *args);
114
115 /* apic */
116 int mshv_init_lint(CPUState *cpu);
117 int mshv_set_lapic(const CPUState *cpu);
118 int mshv_get_lapic(CPUState *cpu);
119
120 /* memory */
121 typedef struct MshvMemoryRegion {
122 uint64_t guest_phys_addr;
123 uint64_t memory_size;
124 uint64_t userspace_addr;
125 bool readonly;
126 } MshvMemoryRegion;
127
128 int mshv_guest_mem_read(uint64_t gpa, uint8_t *data, uintptr_t size,
129 bool is_secure_mode, bool instruction_fetch);
130 int mshv_guest_mem_write(uint64_t gpa, const uint8_t *data, uintptr_t size,
131 bool is_secure_mode);
132 void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section,
133 bool add);
134 void mshv_log_sync(MemoryListener *listener, MemoryRegionSection *section);
135 bool mshv_log_global_start(MemoryListener *listener, Error **errp);
136 void mshv_log_global_stop(MemoryListener *listener);
137
138 /* msr */
139 int mshv_init_msrs(const CPUState *cpu);
140 int mshv_get_msrs(CPUState *cpu);
141 int mshv_set_msrs(const CPUState *cpu);
142
143 /* synic */
144 int mshv_get_simp(int cpu_fd, uint8_t *page);
145 int mshv_set_simp(int cpu_fd, const uint8_t *page);
146 int mshv_get_siefp(int cpu_fd, uint8_t *page);
147 int mshv_set_siefp(int cpu_fd, const uint8_t *page);
148 bool mshv_synic_enabled(const CPUState *cpu);
149 int mshv_get_synthetic_timers(int cpu_fd, uint8_t *state);
150 int mshv_set_synthetic_timers(int cpu_fd, const uint8_t *state);
151
152 #endif