Hyper-V identifies vCPUs by Virtual Processor (VP) index which can be queried by the guest via HV_X64_MSR_VP_INDEX msr. It is defined by the spec as a sequential number which can't exceed the maximum number of vCPUs per VM. It has to be owned by QEMU in order to preserve it across migration. However, the initial implementation in KVM didn't allow to set this msr, and KVM used its own notion of VP index. Fortunately, the way vCPUs are created in QEMU/KVM makes it likely that the KVM value is equal to QEMU cpu_index. So choose cpu_index as the value for vp_index, and push that to KVM on kernels that support setting the msr. On older ones that don't, query the kernel value and assert that it's in sync with QEMU. Besides, since handling errors from vCPU init at hotplug time is impossible, disable vCPU hotplug. This patch also introduces accessor functions to encapsulate the mapping between a vCPU and its vp_index. Signed-off-by: Roman Kagan <rkagan@virtuozzo.com> Message-Id: <20180702134156.13404-3-rkagan@virtuozzo.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
69 lines
2.1 KiB
C
69 lines
2.1 KiB
C
/*
|
|
* QEMU KVM support -- x86 specific functions.
|
|
*
|
|
* Copyright (c) 2012 Linaro Limited
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
* See the COPYING file in the top-level directory.
|
|
*
|
|
*/
|
|
|
|
#ifndef QEMU_KVM_I386_H
|
|
#define QEMU_KVM_I386_H
|
|
|
|
#include "sysemu/kvm.h"
|
|
|
|
#define kvm_apic_in_kernel() (kvm_irqchip_in_kernel())
|
|
|
|
#ifdef CONFIG_KVM
|
|
|
|
#define kvm_pit_in_kernel() \
|
|
(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
|
|
#define kvm_pic_in_kernel() \
|
|
(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
|
|
#define kvm_ioapic_in_kernel() \
|
|
(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
|
|
|
|
#else
|
|
|
|
#define kvm_pit_in_kernel() 0
|
|
#define kvm_pic_in_kernel() 0
|
|
#define kvm_ioapic_in_kernel() 0
|
|
|
|
#endif /* CONFIG_KVM */
|
|
|
|
bool kvm_allows_irq0_override(void);
|
|
bool kvm_has_smm(void);
|
|
bool kvm_has_adjust_clock_stable(void);
|
|
void kvm_synchronize_all_tsc(void);
|
|
void kvm_arch_reset_vcpu(X86CPU *cs);
|
|
void kvm_arch_do_init_vcpu(X86CPU *cs);
|
|
|
|
int kvm_device_pci_assign(KVMState *s, PCIHostDeviceAddress *dev_addr,
|
|
uint32_t flags, uint32_t *dev_id);
|
|
int kvm_device_pci_deassign(KVMState *s, uint32_t dev_id);
|
|
|
|
int kvm_device_intx_assign(KVMState *s, uint32_t dev_id,
|
|
bool use_host_msi, uint32_t guest_irq);
|
|
int kvm_device_intx_set_mask(KVMState *s, uint32_t dev_id, bool masked);
|
|
int kvm_device_intx_deassign(KVMState *s, uint32_t dev_id, bool use_host_msi);
|
|
|
|
int kvm_device_msi_assign(KVMState *s, uint32_t dev_id, int virq);
|
|
int kvm_device_msi_deassign(KVMState *s, uint32_t dev_id);
|
|
|
|
bool kvm_device_msix_supported(KVMState *s);
|
|
int kvm_device_msix_init_vectors(KVMState *s, uint32_t dev_id,
|
|
uint32_t nr_vectors);
|
|
int kvm_device_msix_set_vector(KVMState *s, uint32_t dev_id, uint32_t vector,
|
|
int virq);
|
|
int kvm_device_msix_assign(KVMState *s, uint32_t dev_id);
|
|
int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id);
|
|
|
|
void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
|
|
|
|
bool kvm_enable_x2apic(void);
|
|
bool kvm_has_x2apic_api(void);
|
|
|
|
bool kvm_hv_vpindex_settable(void);
|
|
#endif
|