struct kvm_caps { /* control of guest tsc rate supported? */ bool has_tsc_control; /* maximum supported tsc_khz for guests */
u32 max_guest_tsc_khz; /* number of bits of the fractional part of the TSC scaling ratio */
u8 tsc_scaling_ratio_frac_bits; /* maximum allowed value of TSC scaling ratio */
u64 max_tsc_scaling_ratio; /* 1ull << kvm_caps.tsc_scaling_ratio_frac_bits */
u64 default_tsc_scaling_ratio; /* bus lock detection supported? */ bool has_bus_lock_exit; /* notify VM exit supported? */ bool has_notify_vmexit; /* bit mask of VM types */
u32 supported_vm_types;
struct kvm_host_values { /* * The host's raw MAXPHYADDR, i.e. the number of non-reserved physical * address bits irrespective of features that repurpose legal bits, * e.g. MKTME.
*/
u8 maxphyaddr;
/* Sanity check the size of the memslot hash tables. */
static_assert(SIZE_OF_MEMSLOTS_HASHTABLE ==
(1024 * (1 + IS_ENABLED(CONFIG_X86_64)) * (1 + IS_ENABLED(CONFIG_KVM_SMM))));
/* * Assert that "struct kvm_{svm,vmx,tdx}" is an order-0 or order-1 allocation. * Spilling over to an order-2 allocation isn't fundamentally problematic, but * isn't expected to happen in the foreseeable future (O(years)). Assert that * the size is an order-0 allocation when ignoring the memslot hash tables, to * help detect and debug unexpected size increases.
*/ #define KVM_SANITY_CHECK_VM_STRUCT_SIZE(x) \ do { \
BUILD_BUG_ON(get_order(sizeof(struct x) - SIZE_OF_MEMSLOTS_HASHTABLE) && \
!IS_ENABLED(CONFIG_DEBUG_KERNEL) && !IS_ENABLED(CONFIG_KASAN)); \
BUILD_BUG_ON(get_order(sizeof(struct x)) > 1 && \
!IS_ENABLED(CONFIG_DEBUG_KERNEL) && !IS_ENABLED(CONFIG_KASAN)); \
} while (0)
/* * The first...last VMX feature MSRs that are emulated by KVM. This may or may * not cover all known VMX MSRs, as KVM doesn't emulate an MSR until there's an * associated feature that KVM supports for nested virtualization.
*/ #define KVM_FIRST_EMULATED_VMX_MSR MSR_IA32_VMX_BASIC #define KVM_LAST_EMULATED_VMX_MSR MSR_IA32_VMX_VMFUNC
void kvm_service_local_tlb_flush_requests(struct kvm_vcpu *vcpu); int kvm_check_nested_events(struct kvm_vcpu *vcpu);
/* Forcibly leave the nested mode in cases like a vCPU reset */ staticinlinevoid kvm_leave_nested(struct kvm_vcpu *vcpu)
{
kvm_x86_ops.nested_ops->leave_nested(vcpu);
}
/* * If IBRS is advertised to the vCPU, KVM must flush the indirect branch * predictors when transitioning from L2 to L1, as L1 expects hardware (KVM in * this case) to provide separate predictor modes. Bare metal isolates the host * from the guest, but doesn't isolate different guests from one another (in * this case L1 and L2). The exception is if bare metal supports same mode IBRS, * which offers protection within the same mode, and hence protects L1 from L2.
*/ staticinlinevoid kvm_nested_vmexit_handle_ibrs(struct kvm_vcpu *vcpu)
{ if (cpu_feature_enabled(X86_FEATURE_AMD_IBRS_SAME_MODE)) return;
if (guest_cpu_cap_has(vcpu, X86_FEATURE_SPEC_CTRL) ||
guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_IBRS))
indirect_branch_prediction_barrier();
}
staticinlinebool is_64_bit_mode(struct kvm_vcpu *vcpu)
{ int cs_db, cs_l;
WARN_ON_ONCE(vcpu->arch.guest_state_protected);
if (!is_long_mode(vcpu)) returnfalse;
kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l); return cs_l;
}
staticinlinebool is_64_bit_hypercall(struct kvm_vcpu *vcpu)
{ /* * If running with protected guest state, the CS register is not * accessible. The hypercall register values will have had to been * provided in 64-bit mode, so assume the guest is in 64-bit.
*/ return vcpu->arch.guest_state_protected || is_64_bit_mode(vcpu);
}
/* * x86 MSRs which contain linear addresses, x86 hidden segment bases, and * IDT/GDT bases have static canonicality checks, the size of which depends * only on the CPU's support for 5-level paging, rather than on the state of * CR4.LA57. This applies to both WRMSR and to other instructions that set * their values, e.g. SGDT. * * KVM passes through most of these MSRS and also doesn't intercept the * instructions that set the hidden segment bases. * * Because of this, to be consistent with hardware, even if the guest doesn't * have LA57 enabled in its CPUID, perform canonicality checks based on *host* * support for 5 level paging. * * Finally, instructions which are related to MMU invalidation of a given * linear address, also have a similar static canonical check on address. * This allows for example to invalidate 5-level addresses of a guest from a * host which uses 4-level paging.
*/ staticinlinebool is_noncanonical_address(u64 la, struct kvm_vcpu *vcpu, unsignedint flags)
{ if (flags & (X86EMUL_F_INVLPG | X86EMUL_F_MSR | X86EMUL_F_DT_LOAD)) return !__is_canonical_address(la, max_host_virt_addr_bits()); else return !__is_canonical_address(la, vcpu_virt_addr_bits(vcpu));
}
/* * Get a filtered version of KVM's supported XCR0 that strips out dynamic * features for which the current process doesn't (yet) have permission to use. * This is intended to be used only when enumerating support to userspace, * e.g. in KVM_GET_SUPPORTED_CPUID and KVM_CAP_XSAVE2, it does NOT need to be * used to check/restrict guest behavior as KVM rejects KVM_SET_CPUID{2} if * userspace attempts to enable unpermitted features.
*/ staticinline u64 kvm_get_filtered_xcr0(void)
{
u64 permitted_xcr0 = kvm_caps.supported_xcr0;
if (permitted_xcr0 & XFEATURE_MASK_USER_DYNAMIC) {
permitted_xcr0 &= xstate_get_guest_group_perm();
/* * Treat XTILE_CFG as unsupported if the current process isn't * allowed to use XTILE_DATA, as attempting to set XTILE_CFG in * XCR0 without setting XTILE_DATA is architecturally illegal.
*/ if (!(permitted_xcr0 & XFEATURE_MASK_XTILE_DATA))
permitted_xcr0 &= ~XFEATURE_MASK_XTILE_CFG;
} return permitted_xcr0;
}
/* * Trigger machine check on the host. We assume all the MSRs are already set up * by the CPU and that we still run on the same CPU as the MCE occurred on. * We pass a fake environment to the machine check handler because we want * the guest to be always treated like user space, no matter what context * it used internally.
*/ staticinlinevoid kvm_machine_check(void)
{ #ifdefined(CONFIG_X86_MCE) struct pt_regs regs = {
.cs = 3, /* Fake ring 3 no matter what the guest ran on */
.flags = X86_EFLAGS_IF,
};
do_machine_check(®s); #endif
}
void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu); void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu); int kvm_spec_ctrl_test_value(u64 value); int kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r, struct x86_exception *e); int kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsignedlong type, gva_t gva); bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type);
/* * Internal error codes that are used to indicate that MSR emulation encountered * an error that should result in #GP in the guest, unless userspace handles it. * Note, '1', '0', and negative numbers are off limits, as they are used by KVM * as part of KVM's lightly documented internal KVM_RUN return codes. * * UNSUPPORTED - The MSR isn't supported, either because it is completely * unknown to KVM, or because the MSR should not exist according * to the vCPU model. * * FILTERED - Access to the MSR is denied by a userspace MSR filter.
*/ #define KVM_MSR_RET_UNSUPPORTED 2 #define KVM_MSR_RET_FILTERED 3
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.