2012-07-26 18:35:13 +04:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
|
2012-12-17 21:20:04 +04:00
|
|
|
#include "sysemu/kvm.h"
|
2012-08-27 10:28:40 +04:00
|
|
|
|
2015-12-17 19:16:08 +03:00
|
|
|
#define kvm_apic_in_kernel() (kvm_irqchip_in_kernel())
|
|
|
|
|
2017-06-26 08:22:53 +03:00
|
|
|
#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 */
|
|
|
|
|
2015-06-18 19:30:52 +03:00
|
|
|
bool kvm_has_smm(void);
|
2020-09-22 18:19:34 +03:00
|
|
|
bool kvm_has_adjust_clock(void);
|
2016-11-21 13:50:04 +03:00
|
|
|
bool kvm_has_adjust_clock_stable(void);
|
target/i386: kvm: Demand nested migration kernel capabilities only when vCPU may have enabled VMX
Previous to this change, a vCPU exposed with VMX running on a kernel
without KVM_CAP_NESTED_STATE or KVM_CAP_EXCEPTION_PAYLOAD resulted in
adding a migration blocker. This was because when the code was written
it was thought there is no way to reliably know if a vCPU is utilising
VMX or not at runtime. However, it turns out that this can be known to
some extent:
In order for a vCPU to enter VMX operation it must have CR4.VMXE set.
Since it was set, CR4.VMXE must remain set as long as the vCPU is in
VMX operation. This is because CR4.VMXE is one of the bits set
in MSR_IA32_VMX_CR4_FIXED1.
There is one exception to the above statement when vCPU enters SMM mode.
When a vCPU enters SMM mode, it temporarily exits VMX operation and
may also reset CR4.VMXE during execution in SMM mode.
When the vCPU exits SMM mode, vCPU state is restored to be in VMX operation
and CR4.VMXE is restored to its original state of being set.
Therefore, when the vCPU is not in SMM mode, we can infer whether
VMX is being used by examining CR4.VMXE. Otherwise, we cannot
know for certain but assume the worse that vCPU may utilise VMX.
Summaring all the above, a vCPU may have enabled VMX in case
CR4.VMXE is set or vCPU is in SMM mode.
Therefore, remove migration blocker and check before migration
(cpu_pre_save()) if the vCPU may have enabled VMX. If true, only then
require relevant kernel capabilities.
While at it, demand KVM_CAP_EXCEPTION_PAYLOAD only when the vCPU is in
guest-mode and there is a pending/injected exception. Otherwise, this
kernel capability is not required for proper migration.
Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
Reviewed-by: Maran Wilson <maran.wilson@oracle.com>
Tested-by: Maran Wilson <maran.wilson@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2019-07-06 00:06:36 +03:00
|
|
|
bool kvm_has_exception_payload(void);
|
2015-11-05 06:51:03 +03:00
|
|
|
void kvm_synchronize_all_tsc(void);
|
2013-03-20 16:11:56 +04:00
|
|
|
void kvm_arch_reset_vcpu(X86CPU *cs);
|
2022-09-30 18:52:03 +03:00
|
|
|
void kvm_arch_after_reset_vcpu(X86CPU *cpu);
|
2013-03-08 22:21:50 +04:00
|
|
|
void kvm_arch_do_init_vcpu(X86CPU *cs);
|
2012-07-26 18:35:13 +04:00
|
|
|
|
2016-09-22 15:49:17 +03:00
|
|
|
void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
|
|
|
|
|
intel_iommu: reject broken EIM
Cluster x2APIC cannot work without KVM's x2apic API when the maximal
APIC ID is greater than 8 and only KVM's LAPIC can support x2APIC, so we
forbid other APICs and also the old KVM case with less than 9, to
simplify the code.
There is no point in enabling EIM in forbidden APICs, so we keep it
enabled only for the KVM APIC; unconditionally, because making the
option depend on KVM version would be a maintanance burden.
Old QEMUs would enable eim whenever intremap was on, which would trick
guests into thinking that they can enable cluster x2APIC even if any
interrupt destination would get clamped to 8 bits.
Depending on your configuration, QEMU could notice that the destination
LAPIC is not present and report it with a very non-obvious:
KVM: injection failed, MSI lost (Operation not permitted)
Or the guest could say something about unexpected interrupts, because
clamping leads to aliasing so interrupts were being delivered to
incorrect VCPUs.
KVM_X2APIC_API is the feature that allows us to enable EIM for KVM.
QEMU 2.7 allowed EIM whenever interrupt remapping was enabled. In order
to keep backward compatibility, we again allow guests to misbehave in
non-obvious ways, and make it the default for old machine types.
A user can enable the buggy mode it with "x-buggy-eim=on".
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2016-10-10 18:28:47 +03:00
|
|
|
bool kvm_enable_x2apic(void);
|
2016-10-19 15:05:38 +03:00
|
|
|
bool kvm_has_x2apic_api(void);
|
2020-06-30 16:49:27 +03:00
|
|
|
bool kvm_has_waitpkg(void);
|
2018-07-02 16:41:56 +03:00
|
|
|
|
|
|
|
bool kvm_hv_vpindex_settable(void);
|
2021-06-08 15:08:13 +03:00
|
|
|
bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp);
|
2020-01-20 21:21:42 +03:00
|
|
|
|
2020-10-05 17:18:19 +03:00
|
|
|
uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address);
|
|
|
|
|
2021-07-19 14:21:16 +03:00
|
|
|
bool kvm_enable_sgx_provisioning(KVMState *s);
|
2022-02-17 09:04:29 +03:00
|
|
|
void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask);
|
2021-07-19 14:21:16 +03:00
|
|
|
|
2022-10-05 01:56:42 +03:00
|
|
|
typedef bool QEMURDMSRHandler(X86CPU *cpu, uint32_t msr, uint64_t *val);
|
|
|
|
typedef bool QEMUWRMSRHandler(X86CPU *cpu, uint32_t msr, uint64_t val);
|
|
|
|
typedef struct kvm_msr_handlers {
|
|
|
|
uint32_t msr;
|
|
|
|
QEMURDMSRHandler *rdmsr;
|
|
|
|
QEMUWRMSRHandler *wrmsr;
|
|
|
|
} KVMMSRHandlers;
|
|
|
|
|
|
|
|
bool kvm_filter_msr(KVMState *s, uint32_t msr, QEMURDMSRHandler *rdmsr,
|
|
|
|
QEMUWRMSRHandler *wrmsr);
|
|
|
|
|
2022-08-25 05:52:46 +03:00
|
|
|
void kvm_set_max_apic_id(uint32_t max_apic_id);
|
|
|
|
|
2012-07-26 18:35:13 +04:00
|
|
|
#endif
|