* i386: fix migration issues in 10.1

* target/i386/mshv: new accelerator
 * rust: use glib-sys-rs
 * rust: fixes for docker tests
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmjnaOwUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroNsFQf/WXKxZLLnItHwDz3UdwjzewPWpz5N
 fpS0E4C03J8pACDgyfl7PQl47P7NlJ08Ig2Lc5l3Z9KiAKgh0orR7Cqd0BY5f9lo
 uk4FgXfXpQyApywAlctadrTfcH8sRv2tMaP6EJ9coLtJtHW9RUGFPaZeMsqrjpAl
 TpwAXPYNDDvvy1ih1LPh5DzOPDXE4pin2tDa94gJei56gY95auK4zppoNYLdB3kR
 GOyR4QK43/yhuxPHOmQCZOE3HK2XrKgMZHWIjAovjZjZFiJs49FaHBOpRfFpsUlG
 PB3UbIMtu69VY20LqbbyInPnyATRQzqIGnDGTErP6lfCGTKTy2ulQYWvHA==
 =KM5O
 -----END PGP SIGNATURE-----

Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging

* i386: fix migration issues in 10.1
* target/i386/mshv: new accelerator
* rust: use glib-sys-rs
* rust: fixes for docker tests

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmjnaOwUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroNsFQf/WXKxZLLnItHwDz3UdwjzewPWpz5N
# fpS0E4C03J8pACDgyfl7PQl47P7NlJ08Ig2Lc5l3Z9KiAKgh0orR7Cqd0BY5f9lo
# uk4FgXfXpQyApywAlctadrTfcH8sRv2tMaP6EJ9coLtJtHW9RUGFPaZeMsqrjpAl
# TpwAXPYNDDvvy1ih1LPh5DzOPDXE4pin2tDa94gJei56gY95auK4zppoNYLdB3kR
# GOyR4QK43/yhuxPHOmQCZOE3HK2XrKgMZHWIjAovjZjZFiJs49FaHBOpRfFpsUlG
# PB3UbIMtu69VY20LqbbyInPnyATRQzqIGnDGTErP6lfCGTKTy2ulQYWvHA==
# =KM5O
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 09 Oct 2025 12:49:00 AM PDT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [unknown]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (35 commits)
  rust: fix path to rust_root_crate.sh
  tests/docker: make --enable-rust overridable with EXTRA_CONFIGURE_OPTS
  MAINTAINERS: Add maintainers for mshv accelerator
  docs: Add mshv to documentation
  target/i386/mshv: Use preallocated page for hvcall
  qapi/accel: Allow to query mshv capabilities
  accel/mshv: Handle overlapping mem mappings
  target/i386/mshv: Implement mshv_vcpu_run()
  target/i386/mshv: Write MSRs to the hypervisor
  target/i386/mshv: Integrate x86 instruction decoder/emulator
  target/i386/mshv: Register MSRs with MSHV
  target/i386/mshv: Register CPUID entries with MSHV
  target/i386/mshv: Set local interrupt controller state
  target/i386/mshv: Implement mshv_arch_put_registers()
  target/i386/mshv: Implement mshv_get_special_regs()
  target/i386/mshv: Implement mshv_get_standard_regs()
  target/i386/mshv: Implement mshv_store_regs()
  target/i386/mshv: Add CPU create and remove logic
  accel/mshv: Add vCPU signal handling
  accel/mshv: Add vCPU creation and execution loop
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-10-09 07:59:00 -07:00
commit 1188b07e60
87 changed files with 6617 additions and 79 deletions

View file

@ -0,0 +1,37 @@
/*
* Accelerated irqchip abstraction
*
* Copyright Microsoft, Corp. 2025
*
* Authors: Ziqiao Zhou <ziqiaozhou@microsoft.com>
* Magnus Kulke <magnuskulke@microsoft.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef SYSTEM_ACCEL_IRQ_H
#define SYSTEM_ACCEL_IRQ_H
#include "hw/pci/msi.h"
#include "qemu/osdep.h"
#include "system/kvm.h"
#include "system/mshv.h"
static inline bool accel_msi_via_irqfd_enabled(void)
{
return mshv_msi_via_irqfd_enabled() || kvm_msi_via_irqfd_enabled();
}
static inline bool accel_irqchip_is_split(void)
{
return mshv_msi_via_irqfd_enabled() || kvm_irqchip_is_split();
}
int accel_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev);
int accel_irqchip_update_msi_route(int vector, MSIMessage msg, PCIDevice *dev);
void accel_irqchip_commit_route_changes(KVMRouteChange *c);
void accel_irqchip_commit_routes(void);
void accel_irqchip_release_virq(int virq);
int accel_irqchip_add_irqfd_notifier_gsi(EventNotifier *n, EventNotifier *rn,
int virq);
int accel_irqchip_remove_irqfd_notifier_gsi(EventNotifier *n, int virq);
#endif

View file

@ -14,6 +14,7 @@
#include "hw/core/cpu.h"
#include "system/kvm.h"
#include "system/hvf.h"
#include "system/mshv.h"
#include "system/whpx.h"
#include "system/nvmm.h"

64
include/system/mshv.h Normal file
View file

@ -0,0 +1,64 @@
/*
* 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_H
#define QEMU_MSHV_H
#include "qemu/osdep.h"
#include "qemu/accel.h"
#include "hw/hyperv/hyperv-proto.h"
#include "hw/hyperv/hvhdk.h"
#include "hw/hyperv/hvgdk_mini.h"
#include "qapi/qapi-types-common.h"
#include "system/memory.h"
#include "accel/accel-ops.h"
#ifdef COMPILING_PER_TARGET
#ifdef CONFIG_MSHV
#include <linux/mshv.h>
#define CONFIG_MSHV_IS_POSSIBLE
#endif
#else
#define CONFIG_MSHV_IS_POSSIBLE
#endif
#define MSHV_MAX_MSI_ROUTES 4096
#define MSHV_PAGE_SHIFT 12
#ifdef CONFIG_MSHV_IS_POSSIBLE
extern bool mshv_allowed;
#define mshv_enabled() (mshv_allowed)
#define mshv_msi_via_irqfd_enabled() mshv_enabled()
#else /* CONFIG_MSHV_IS_POSSIBLE */
#define mshv_enabled() false
#define mshv_msi_via_irqfd_enabled() mshv_enabled()
#endif
typedef struct MshvState MshvState;
extern MshvState *mshv_state;
/* interrupt */
int mshv_request_interrupt(MshvState *mshv_state, uint32_t interrupt_type, uint32_t vector,
uint32_t vp_index, bool logical_destination_mode,
bool level_triggered);
int mshv_irqchip_add_msi_route(int vector, PCIDevice *dev);
int mshv_irqchip_update_msi_route(int virq, MSIMessage msg, PCIDevice *dev);
void mshv_irqchip_commit_routes(void);
void mshv_irqchip_release_virq(int virq);
int mshv_irqchip_add_irqfd_notifier_gsi(const EventNotifier *n,
const EventNotifier *rn, int virq);
int mshv_irqchip_remove_irqfd_notifier_gsi(const EventNotifier *n, int virq);
#endif

155
include/system/mshv_int.h Normal file
View file

@ -0,0 +1,155 @@
/*
* 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