| /* |
| * QEMU MSHV support |
| * |
| * Copyright Microsoft, Corp. 2025 |
| * |
| * Authors: Ziqiao Zhou <ziqiaozhou@microsoft.com> |
| * Magnus Kulke <magnuskulke@microsoft.com> |
| * Jinank Jain <jinankjain@microsoft.com> |
| * |
| * SPDX-License-Identifier: GPL-2.0-or-later |
| * |
| */ |
| |
| #ifndef QEMU_MSHV_INT_H |
| #define QEMU_MSHV_INT_H |
| |
| #define MSHV_MSR_ENTRIES_COUNT 64 |
| |
| #define MSHV_MAX_MEM_SLOTS 32 |
| |
| typedef struct hyperv_message hv_message; |
| |
| typedef struct MshvHvCallArgs { |
| void *base; |
| void *input_page; |
| void *output_page; |
| } MshvHvCallArgs; |
| |
| struct AccelCPUState { |
| int cpufd; |
| bool dirty; |
| MshvHvCallArgs hvcall_args; |
| }; |
| |
| typedef struct MshvMemoryListener { |
| MemoryListener listener; |
| int as_id; |
| } MshvMemoryListener; |
| |
| typedef struct MshvAddressSpace { |
| MshvMemoryListener *ml; |
| AddressSpace *as; |
| } MshvAddressSpace; |
| |
| typedef struct MshvMemorySlotManager { |
| size_t n_slots; |
| GList *slots; |
| QemuMutex mutex; |
| } MshvMemorySlotManager; |
| |
| struct MshvState { |
| AccelState parent_obj; |
| int vm; |
| MshvMemoryListener memory_listener; |
| /* number of listeners */ |
| int nr_as; |
| MshvAddressSpace *as; |
| int fd; |
| MshvMemorySlotManager msm; |
| }; |
| |
| typedef struct MshvMsiControl { |
| bool updated; |
| GHashTable *gsi_routes; |
| } MshvMsiControl; |
| |
| #define mshv_vcpufd(cpu) (cpu->accel->cpufd) |
| |
| /* cpu */ |
| typedef struct MshvFPU { |
| uint8_t fpr[8][16]; |
| uint16_t fcw; |
| uint16_t fsw; |
| uint8_t ftwx; |
| uint8_t pad1; |
| uint16_t last_opcode; |
| uint64_t last_ip; |
| uint64_t last_dp; |
| uint8_t xmm[16][16]; |
| uint32_t mxcsr; |
| uint32_t pad2; |
| } MshvFPU; |
| |
| typedef enum MshvVmExit { |
| MshvVmExitIgnore = 0, |
| MshvVmExitShutdown = 1, |
| MshvVmExitSpecial = 2, |
| } MshvVmExit; |
| |
| typedef enum MshvRemapResult { |
| MshvRemapOk = 0, |
| MshvRemapNoMapping = 1, |
| MshvRemapNoOverlap = 2, |
| } MshvRemapResult; |
| |
| void mshv_init_mmio_emu(void); |
| int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd); |
| void mshv_remove_vcpu(int vm_fd, int cpu_fd); |
| int mshv_configure_vcpu(const CPUState *cpu, const MshvFPU *fpu, uint64_t xcr0); |
| int mshv_get_standard_regs(CPUState *cpu); |
| int mshv_get_special_regs(CPUState *cpu); |
| 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); |
| void mshv_arch_amend_proc_features( |
| union hv_partition_synthetic_processor_features *features); |
| int mshv_arch_post_init_vm(int vm_fd); |
| |
| #if defined COMPILING_PER_TARGET && defined CONFIG_MSHV_IS_POSSIBLE |
| int mshv_hvcall(int fd, const struct mshv_root_hvcall *args); |
| #endif |
| |
| /* memory */ |
| typedef struct MshvMemorySlot { |
| uint64_t guest_phys_addr; |
| uint64_t memory_size; |
| uint64_t userspace_addr; |
| bool readonly; |
| bool mapped; |
| } MshvMemorySlot; |
| |
| MshvRemapResult mshv_remap_overlap_region(int vm_fd, uint64_t gpa); |
| int mshv_guest_mem_read(uint64_t gpa, uint8_t *data, uintptr_t size, |
| bool is_secure_mode, bool instruction_fetch); |
| int mshv_guest_mem_write(uint64_t gpa, const uint8_t *data, uintptr_t size, |
| bool is_secure_mode); |
| void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section, |
| bool add); |
| void mshv_init_memory_slot_manager(MshvState *mshv_state); |
| |
| /* msr */ |
| typedef struct MshvMsrEntry { |
| uint32_t index; |
| uint32_t reserved; |
| uint64_t data; |
| } MshvMsrEntry; |
| |
| typedef struct MshvMsrEntries { |
| MshvMsrEntry entries[MSHV_MSR_ENTRIES_COUNT]; |
| uint32_t nmsrs; |
| } MshvMsrEntries; |
| |
| int mshv_configure_msr(const CPUState *cpu, const MshvMsrEntry *msrs, |
| size_t n_msrs); |
| |
| /* interrupt */ |
| void mshv_init_msicontrol(void); |
| int mshv_reserve_ioapic_msi_routes(int vm_fd); |
| |
| #endif |