| // SPDX-License-Identifier: GPL-2.0-only |
| /* |
| * Kernel-based Virtual Machine driver for Linux |
| * |
| * This module enables machines with Intel VT-x extensions to run virtual |
| * machines without emulation or binary translation. |
| * |
| * Copyright (C) 2006 Qumranet, Inc. |
| * Copyright 2010 Red Hat, Inc. and/or its affiliates. |
| * |
| * Authors: |
| * Avi Kivity <avi@qumranet.com> |
| * Yaniv Kamay <yaniv@qumranet.com> |
| */ |
| |
| #include <linux/highmem.h> |
| #include <linux/hrtimer.h> |
| #include <linux/kernel.h> |
| #include <linux/kvm_host.h> |
| #include <linux/module.h> |
| #include <linux/moduleparam.h> |
| #include <linux/mod_devicetable.h> |
| #include <linux/mm.h> |
| #include <linux/objtool.h> |
| #include <linux/sched.h> |
| #include <linux/sched/smt.h> |
| #include <linux/slab.h> |
| #include <linux/tboot.h> |
| #include <linux/trace_events.h> |
| #include <linux/entry-kvm.h> |
| |
| #include <asm/apic.h> |
| #include <asm/asm.h> |
| #include <asm/cpu.h> |
| #include <asm/cpu_device_id.h> |
| #include <asm/debugreg.h> |
| #include <asm/desc.h> |
| #include <asm/fpu/internal.h> |
| #include <asm/idtentry.h> |
| #include <asm/io.h> |
| #include <asm/irq_remapping.h> |
| #include <asm/kexec.h> |
| #include <asm/perf_event.h> |
| #include <asm/mmu_context.h> |
| #include <asm/mshyperv.h> |
| #include <asm/mwait.h> |
| #include <asm/spec-ctrl.h> |
| #include <asm/virtext.h> |
| #include <asm/vmx.h> |
| |
| #include "capabilities.h" |
| #include "cpuid.h" |
| #include "evmcs.h" |
| #include "hyperv.h" |
| #include "kvm_onhyperv.h" |
| #include "irq.h" |
| #include "kvm_cache_regs.h" |
| #include "lapic.h" |
| #include "mmu.h" |
| #include "nested.h" |
| #include "pmu.h" |
| #include "sgx.h" |
| #include "trace.h" |
| #include "vmcs.h" |
| #include "vmcs12.h" |
| #include "vmx.h" |
| #include "x86.h" |
| |
| MODULE_AUTHOR("Qumranet"); |
| MODULE_LICENSE("GPL"); |
| |
| #ifdef MODULE |
| static const struct x86_cpu_id vmx_cpu_id[] = { |
| X86_MATCH_FEATURE(X86_FEATURE_VMX, NULL), |
| {} |
| }; |
| MODULE_DEVICE_TABLE(x86cpu, vmx_cpu_id); |
| #endif |
| |
| bool __read_mostly enable_vpid = 1; |
| module_param_named(vpid, enable_vpid, bool, 0444); |
| |
| static bool __read_mostly enable_vnmi = 1; |
| module_param_named(vnmi, enable_vnmi, bool, S_IRUGO); |
| |
| bool __read_mostly flexpriority_enabled = 1; |
| module_param_named(flexpriority, flexpriority_enabled, bool, S_IRUGO); |
| |
| bool __read_mostly enable_ept = 1; |
| module_param_named(ept, enable_ept, bool, S_IRUGO); |
| |
| bool __read_mostly enable_unrestricted_guest = 1; |
| module_param_named(unrestricted_guest, |
| enable_unrestricted_guest, bool, S_IRUGO); |
| |
| bool __read_mostly enable_ept_ad_bits = 1; |
| module_param_named(eptad, enable_ept_ad_bits, bool, S_IRUGO); |
| |
| static bool __read_mostly emulate_invalid_guest_state = true; |
| module_param(emulate_invalid_guest_state, bool, S_IRUGO); |
| |
| static bool __read_mostly fasteoi = 1; |
| module_param(fasteoi, bool, S_IRUGO); |
| |
| module_param(enable_apicv, bool, S_IRUGO); |
| |
| /* |
| * If nested=1, nested virtualization is supported, i.e., guests may use |
| * VMX and be a hypervisor for its own guests. If nested=0, guests may not |
| * use VMX instructions. |
| */ |
| static bool __read_mostly nested = 1; |
| module_param(nested, bool, S_IRUGO); |
| |
| bool __read_mostly enable_pml = 1; |
| module_param_named(pml, enable_pml, bool, S_IRUGO); |
| |
| static bool __read_mostly dump_invalid_vmcs = 0; |
| module_param(dump_invalid_vmcs, bool, 0644); |
| |
| #define MSR_BITMAP_MODE_X2APIC 1 |
| #define MSR_BITMAP_MODE_X2APIC_APICV 2 |
| |
| #define KVM_VMX_TSC_MULTIPLIER_MAX 0xffffffffffffffffULL |
| |
| /* Guest_tsc -> host_tsc conversion requires 64-bit division. */ |
| static int __read_mostly cpu_preemption_timer_multi; |
| static bool __read_mostly enable_preemption_timer = 1; |
| #ifdef CONFIG_X86_64 |
| module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO); |
| #endif |
| |
| extern bool __read_mostly allow_smaller_maxphyaddr; |
| module_param(allow_smaller_maxphyaddr, bool, S_IRUGO); |
| |
| #define KVM_VM_CR0_ALWAYS_OFF (X86_CR0_NW | X86_CR0_CD) |
| #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR0_NE |
| #define KVM_VM_CR0_ALWAYS_ON \ |
| (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) |
| |
| #define KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR4_VMXE |
| #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) |
| #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE) |
| |
| #define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM)) |
| |
| #define MSR_IA32_RTIT_STATUS_MASK (~(RTIT_STATUS_FILTEREN | \ |
| RTIT_STATUS_CONTEXTEN | RTIT_STATUS_TRIGGEREN | \ |
| RTIT_STATUS_ERROR | RTIT_STATUS_STOPPED | \ |
| RTIT_STATUS_BYTECNT)) |
| |
| /* |
| * List of MSRs that can be directly passed to the guest. |
| * In addition to these x2apic and PT MSRs are handled specially. |
| */ |
| static u32 vmx_possible_passthrough_msrs[MAX_POSSIBLE_PASSTHROUGH_MSRS] = { |
| MSR_IA32_SPEC_CTRL, |
| MSR_IA32_PRED_CMD, |
| MSR_IA32_TSC, |
| #ifdef CONFIG_X86_64 |
| MSR_FS_BASE, |
| MSR_GS_BASE, |
| MSR_KERNEL_GS_BASE, |
| #endif |
| MSR_IA32_SYSENTER_CS, |
| MSR_IA32_SYSENTER_ESP, |
| MSR_IA32_SYSENTER_EIP, |
| MSR_CORE_C1_RES, |
| MSR_CORE_C3_RESIDENCY, |
| MSR_CORE_C6_RESIDENCY, |
| MSR_CORE_C7_RESIDENCY, |
| }; |
| |
| /* |
| * These 2 parameters are used to config the controls for Pause-Loop Exiting: |
| * ple_gap: upper bound on the amount of time between two successive |
| * executions of PAUSE in a loop. Also indicate if ple enabled. |
| * According to test, this time is usually smaller than 128 cycles. |
| * ple_window: upper bound on the amount of time a guest is allowed to execute |
| * in a PAUSE loop. Tests indicate that most spinlocks are held for |
| * less than 2^12 cycles |
| * Time is measured based on a counter that runs at the same rate as the TSC, |
| * refer SDM volume 3b section 21.6.13 & 22.1.3. |
| */ |
| static unsigned int ple_gap = KVM_DEFAULT_PLE_GAP; |
| module_param(ple_gap, uint, 0444); |
| |
| static unsigned int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW; |
| module_param(ple_window, uint, 0444); |
| |
| /* Default doubles per-vcpu window every exit. */ |
| static unsigned int ple_window_grow = KVM_DEFAULT_PLE_WINDOW_GROW; |
| module_param(ple_window_grow, uint, 0444); |
| |
| /* Default resets per-vcpu window every exit to ple_window. */ |
| static unsigned int ple_window_shrink = KVM_DEFAULT_PLE_WINDOW_SHRINK; |
| module_param(ple_window_shrink, uint, 0444); |
| |
| /* Default is to compute the maximum so we can never overflow. */ |
| static unsigned int ple_window_max = KVM_VMX_DEFAULT_PLE_WINDOW_MAX; |
| module_param(ple_window_max, uint, 0444); |
| |
| /* Default is SYSTEM mode, 1 for host-guest mode */ |
| int __read_mostly pt_mode = PT_MODE_SYSTEM; |
| module_param(pt_mode, int, S_IRUGO); |
| |
| static DEFINE_STATIC_KEY_FALSE(vmx_l1d_should_flush); |
| static DEFINE_STATIC_KEY_FALSE(vmx_l1d_flush_cond); |
| static DEFINE_MUTEX(vmx_l1d_flush_mutex); |
| |
| /* Storage for pre module init parameter parsing */ |
| static enum vmx_l1d_flush_state __read_mostly vmentry_l1d_flush_param = VMENTER_L1D_FLUSH_AUTO; |
| |
| static const struct { |
| const char *option; |
| bool for_parse; |
| } vmentry_l1d_param[] = { |
| [VMENTER_L1D_FLUSH_AUTO] = {"auto", true}, |
| [VMENTER_L1D_FLUSH_NEVER] = {"never", true}, |
| [VMENTER_L1D_FLUSH_COND] = {"cond", true}, |
| [VMENTER_L1D_FLUSH_ALWAYS] = {"always", true}, |
| [VMENTER_L1D_FLUSH_EPT_DISABLED] = {"EPT disabled", false}, |
| [VMENTER_L1D_FLUSH_NOT_REQUIRED] = {"not required", false}, |
| }; |
| |
| #define L1D_CACHE_ORDER 4 |
| static void *vmx_l1d_flush_pages; |
| |
| static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf) |
| { |
| struct page *page; |
| unsigned int i; |
| |
| if (!boot_cpu_has_bug(X86_BUG_L1TF)) { |
| l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_NOT_REQUIRED; |
| return 0; |
| } |
| |
| if (!enable_ept) { |
| l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_EPT_DISABLED; |
| return 0; |
| } |
| |
| if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) { |
| u64 msr; |
| |
| rdmsrl(MSR_IA32_ARCH_CAPABILITIES, msr); |
| if (msr & ARCH_CAP_SKIP_VMENTRY_L1DFLUSH) { |
| l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_NOT_REQUIRED; |
| return 0; |
| } |
| } |
| |
| /* If set to auto use the default l1tf mitigation method */ |
| if (l1tf == VMENTER_L1D_FLUSH_AUTO) { |
| switch (l1tf_mitigation) { |
| case L1TF_MITIGATION_OFF: |
| l1tf = VMENTER_L1D_FLUSH_NEVER; |
| break; |
| case L1TF_MITIGATION_FLUSH_NOWARN: |
| case L1TF_MITIGATION_FLUSH: |
| case L1TF_MITIGATION_FLUSH_NOSMT: |
| l1tf = VMENTER_L1D_FLUSH_COND; |
| break; |
| case L1TF_MITIGATION_FULL: |
| case L1TF_MITIGATION_FULL_FORCE: |
| l1tf = VMENTER_L1D_FLUSH_ALWAYS; |
| break; |
| } |
| } else if (l1tf_mitigation == L1TF_MITIGATION_FULL_FORCE) { |
| l1tf = VMENTER_L1D_FLUSH_ALWAYS; |
| } |
| |
| if (l1tf != VMENTER_L1D_FLUSH_NEVER && !vmx_l1d_flush_pages && |
| !boot_cpu_has(X86_FEATURE_FLUSH_L1D)) { |
| /* |
| * This allocation for vmx_l1d_flush_pages is not tied to a VM |
| * lifetime and so should not be charged to a memcg. |
| */ |
| page = alloc_pages(GFP_KERNEL, L1D_CACHE_ORDER); |
| if (!page) |
| return -ENOMEM; |
| vmx_l1d_flush_pages = page_address(page); |
| |
| /* |
| * Initialize each page with a different pattern in |
| * order to protect against KSM in the nested |
| * virtualization case. |
| */ |
| for (i = 0; i < 1u << L1D_CACHE_ORDER; ++i) { |
| memset(vmx_l1d_flush_pages + i * PAGE_SIZE, i + 1, |
| PAGE_SIZE); |
| } |
| } |
| |
| l1tf_vmx_mitigation = l1tf; |
| |
| if (l1tf != VMENTER_L1D_FLUSH_NEVER) |
| static_branch_enable(&vmx_l1d_should_flush); |
| else |
| static_branch_disable(&vmx_l1d_should_flush); |
| |
| if (l1tf == VMENTER_L1D_FLUSH_COND) |
| static_branch_enable(&vmx_l1d_flush_cond); |
| else |
| static_branch_disable(&vmx_l1d_flush_cond); |
| return 0; |
| } |
| |
| static int vmentry_l1d_flush_parse(const char *s) |
| { |
| unsigned int i; |
| |
| if (s) { |
| for (i = 0; i < ARRAY_SIZE(vmentry_l1d_param); i++) { |
| if (vmentry_l1d_param[i].for_parse && |
| sysfs_streq(s, vmentry_l1d_param[i].option)) |
| return i; |
| } |
| } |
| return -EINVAL; |
| } |
| |
| static int vmentry_l1d_flush_set(const char *s, const struct kernel_param *kp) |
| { |
| int l1tf, ret; |
| |
| l1tf = vmentry_l1d_flush_parse(s); |
| if (l1tf < 0) |
| return l1tf; |
| |
| if (!boot_cpu_has(X86_BUG_L1TF)) |
| return 0; |
| |
| /* |
| * Has vmx_init() run already? If not then this is the pre init |
| * parameter parsing. In that case just store the value and let |
| * vmx_init() do the proper setup after enable_ept has been |
| * established. |
| */ |
| if (l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_AUTO) { |
| vmentry_l1d_flush_param = l1tf; |
| return 0; |
| } |
| |
| mutex_lock(&vmx_l1d_flush_mutex); |
| ret = vmx_setup_l1d_flush(l1tf); |
| mutex_unlock(&vmx_l1d_flush_mutex); |
| return ret; |
| } |
| |
| static int vmentry_l1d_flush_get(char *s, const struct kernel_param *kp) |
| { |
| if (WARN_ON_ONCE(l1tf_vmx_mitigation >= ARRAY_SIZE(vmentry_l1d_param))) |
| return sprintf(s, "???\n"); |
| |
| return sprintf(s, "%s\n", vmentry_l1d_param[l1tf_vmx_mitigation].option); |
| } |
| |
| static const struct kernel_param_ops vmentry_l1d_flush_ops = { |
| .set = vmentry_l1d_flush_set, |
| .get = vmentry_l1d_flush_get, |
| }; |
| module_param_cb(vmentry_l1d_flush, &vmentry_l1d_flush_ops, NULL, 0644); |
| |
| static u32 vmx_segment_access_rights(struct kvm_segment *var); |
| |
| void vmx_vmexit(void); |
| |
| #define vmx_insn_failed(fmt...) \ |
| do { \ |
| WARN_ONCE(1, fmt); \ |
| pr_warn_ratelimited(fmt); \ |
| } while (0) |
| |
| asmlinkage void vmread_error(unsigned long field, bool fault) |
| { |
| if (fault) |
| kvm_spurious_fault(); |
| else |
| vmx_insn_failed("kvm: vmread failed: field=%lx\n", field); |
| } |
| |
| noinline void vmwrite_error(unsigned long field, unsigned long value) |
| { |
| vmx_insn_failed("kvm: vmwrite failed: field=%lx val=%lx err=%d\n", |
| field, value, vmcs_read32(VM_INSTRUCTION_ERROR)); |
| } |
| |
| noinline void vmclear_error(struct vmcs *vmcs, u64 phys_addr) |
| { |
| vmx_insn_failed("kvm: vmclear failed: %p/%llx\n", vmcs, phys_addr); |
| } |
| |
| noinline void vmptrld_error(struct vmcs *vmcs, u64 phys_addr) |
| { |
| vmx_insn_failed("kvm: vmptrld failed: %p/%llx\n", vmcs, phys_addr); |
| } |
| |
| noinline void invvpid_error(unsigned long ext, u16 vpid, gva_t gva) |
| { |
| vmx_insn_failed("kvm: invvpid failed: ext=0x%lx vpid=%u gva=0x%lx\n", |
| ext, vpid, gva); |
| } |
| |
| noinline void invept_error(unsigned long ext, u64 eptp, gpa_t gpa) |
| { |
| vmx_insn_failed("kvm: invept failed: ext=0x%lx eptp=%llx gpa=0x%llx\n", |
| ext, eptp, gpa); |
| } |
| |
| static DEFINE_PER_CPU(struct vmcs *, vmxarea); |
| DEFINE_PER_CPU(struct vmcs *, current_vmcs); |
| /* |
| * We maintain a per-CPU linked-list of VMCS loaded on that CPU. This is needed |
| * when a CPU is brought down, and we need to VMCLEAR all VMCSs loaded on it. |
| */ |
| static DEFINE_PER_CPU(struct list_head, loaded_vmcss_on_cpu); |
| |
| static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); |
| static DEFINE_SPINLOCK(vmx_vpid_lock); |
| |
| struct vmcs_config vmcs_config; |
| struct vmx_capability vmx_capability; |
| |
| #define VMX_SEGMENT_FIELD(seg) \ |
| [VCPU_SREG_##seg] = { \ |
| .selector = GUEST_##seg##_SELECTOR, \ |
| .base = GUEST_##seg##_BASE, \ |
| .limit = GUEST_##seg##_LIMIT, \ |
| .ar_bytes = GUEST_##seg##_AR_BYTES, \ |
| } |
| |
| static const struct kvm_vmx_segment_field { |
| unsigned selector; |
| unsigned base; |
| unsigned limit; |
| unsigned ar_bytes; |
| } kvm_vmx_segment_fields[] = { |
| VMX_SEGMENT_FIELD(CS), |
| VMX_SEGMENT_FIELD(DS), |
| VMX_SEGMENT_FIELD(ES), |
| VMX_SEGMENT_FIELD(FS), |
| VMX_SEGMENT_FIELD(GS), |
| VMX_SEGMENT_FIELD(SS), |
| VMX_SEGMENT_FIELD(TR), |
| VMX_SEGMENT_FIELD(LDTR), |
| }; |
| |
| static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx) |
| { |
| vmx->segment_cache.bitmask = 0; |
| } |
| |
| static unsigned long host_idt_base; |
| |
| #if IS_ENABLED(CONFIG_HYPERV) |
| static bool __read_mostly enlightened_vmcs = true; |
| module_param(enlightened_vmcs, bool, 0444); |
| |
| static int hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu) |
| { |
| struct hv_enlightened_vmcs *evmcs; |
| struct hv_partition_assist_pg **p_hv_pa_pg = |
| &to_kvm_hv(vcpu->kvm)->hv_pa_pg; |
| /* |
| * Synthetic VM-Exit is not enabled in current code and so All |
| * evmcs in singe VM shares same assist page. |
| */ |
| if (!*p_hv_pa_pg) |
| *p_hv_pa_pg = kzalloc(PAGE_SIZE, GFP_KERNEL_ACCOUNT); |
| |
| if (!*p_hv_pa_pg) |
| return -ENOMEM; |
| |
| evmcs = (struct hv_enlightened_vmcs *)to_vmx(vcpu)->loaded_vmcs->vmcs; |
| |
| evmcs->partition_assist_page = |
| __pa(*p_hv_pa_pg); |
| evmcs->hv_vm_id = (unsigned long)vcpu->kvm; |
| evmcs->hv_enlightenments_control.nested_flush_hypercall = 1; |
| |
| return 0; |
| } |
| |
| #endif /* IS_ENABLED(CONFIG_HYPERV) */ |
| |
| /* |
| * Comment's format: document - errata name - stepping - processor name. |
| * Refer from |
| * https://www.virtualbox.org/svn/vbox/trunk/src/VBox/VMM/VMMR0/HMR0.cpp |
| */ |
| static u32 vmx_preemption_cpu_tfms[] = { |
| /* 323344.pdf - BA86 - D0 - Xeon 7500 Series */ |
| 0x000206E6, |
| /* 323056.pdf - AAX65 - C2 - Xeon L3406 */ |
| /* 322814.pdf - AAT59 - C2 - i7-600, i5-500, i5-400 and i3-300 Mobile */ |
| /* 322911.pdf - AAU65 - C2 - i5-600, i3-500 Desktop and Pentium G6950 */ |
| 0x00020652, |
| /* 322911.pdf - AAU65 - K0 - i5-600, i3-500 Desktop and Pentium G6950 */ |
| 0x00020655, |
| /* 322373.pdf - AAO95 - B1 - Xeon 3400 Series */ |
| /* 322166.pdf - AAN92 - B1 - i7-800 and i5-700 Desktop */ |
| /* |
| * 320767.pdf - AAP86 - B1 - |
| * i7-900 Mobile Extreme, i7-800 and i7-700 Mobile |
| */ |
| 0x000106E5, |
| /* 321333.pdf - AAM126 - C0 - Xeon 3500 */ |
| 0x000106A0, |
| /* 321333.pdf - AAM126 - C1 - Xeon 3500 */ |
| 0x000106A1, |
| /* 320836.pdf - AAJ124 - C0 - i7-900 Desktop Extreme and i7-900 Desktop */ |
| 0x000106A4, |
| /* 321333.pdf - AAM126 - D0 - Xeon 3500 */ |
| /* 321324.pdf - AAK139 - D0 - Xeon 5500 */ |
| /* 320836.pdf - AAJ124 - D0 - i7-900 Extreme and i7-900 Desktop */ |
| 0x000106A5, |
| /* Xeon E3-1220 V2 */ |
| 0x000306A8, |
| }; |
| |
| static inline bool cpu_has_broken_vmx_preemption_timer(void) |
| { |
| u32 eax = cpuid_eax(0x00000001), i; |
| |
| /* Clear the reserved bits */ |
| eax &= ~(0x3U << 14 | 0xfU << 28); |
| for (i = 0; i < ARRAY_SIZE(vmx_preemption_cpu_tfms); i++) |
| if (eax == vmx_preemption_cpu_tfms[i]) |
| return true; |
| |
| return false; |
| } |
| |
| static inline bool cpu_need_virtualize_apic_accesses(struct kvm_vcpu *vcpu) |
| { |
| return flexpriority_enabled && lapic_in_kernel(vcpu); |
| } |
| |
| static inline bool report_flexpriority(void) |
| { |
| return flexpriority_enabled; |
| } |
| |
| static int possible_passthrough_msr_slot(u32 msr) |
| { |
| u32 i; |
| |
| for (i = 0; i < ARRAY_SIZE(vmx_possible_passthrough_msrs); i++) |
| if (vmx_possible_passthrough_msrs[i] == msr) |
| return i; |
| |
| return -ENOENT; |
| } |
| |
| static bool is_valid_passthrough_msr(u32 msr) |
| { |
| bool r; |
| |
| switch (msr) { |
| case 0x800 ... 0x8ff: |
| /* x2APIC MSRs. These are handled in vmx_update_msr_bitmap_x2apic() */ |
| return true; |
| case MSR_IA32_RTIT_STATUS: |
| case MSR_IA32_RTIT_OUTPUT_BASE: |
| case MSR_IA32_RTIT_OUTPUT_MASK: |
| case MSR_IA32_RTIT_CR3_MATCH: |
| case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B: |
| /* PT MSRs. These are handled in pt_update_intercept_for_msr() */ |
| case MSR_LBR_SELECT: |
| case MSR_LBR_TOS: |
| case MSR_LBR_INFO_0 ... MSR_LBR_INFO_0 + 31: |
| case MSR_LBR_NHM_FROM ... MSR_LBR_NHM_FROM + 31: |
| case MSR_LBR_NHM_TO ... MSR_LBR_NHM_TO + 31: |
| case MSR_LBR_CORE_FROM ... MSR_LBR_CORE_FROM + 8: |
| case MSR_LBR_CORE_TO ... MSR_LBR_CORE_TO + 8: |
| /* LBR MSRs. These are handled in vmx_update_intercept_for_lbr_msrs() */ |
| return true; |
| } |
| |
| r = possible_passthrough_msr_slot(msr) != -ENOENT; |
| |
| WARN(!r, "Invalid MSR %x, please adapt vmx_possible_passthrough_msrs[]", msr); |
| |
| return r; |
| } |
| |
| struct vmx_uret_msr *vmx_find_uret_msr(struct vcpu_vmx *vmx, u32 msr) |
| { |
| int i; |
| |
| i = kvm_find_user_return_msr(msr); |
| if (i >= 0) |
| return &vmx->guest_uret_msrs[i]; |
| return NULL; |
| } |
| |
| static int vmx_set_guest_uret_msr(struct vcpu_vmx *vmx, |
| struct vmx_uret_msr *msr, u64 data) |
| { |
| unsigned int slot = msr - vmx->guest_uret_msrs; |
| int ret = 0; |
| |
| u64 old_msr_data = msr->data; |
| msr->data = data; |
| if (msr->load_into_hardware) { |
| preempt_disable(); |
| ret = kvm_set_user_return_msr(slot, msr->data, msr->mask); |
| preempt_enable(); |
| if (ret) |
| msr->data = old_msr_data; |
| } |
| return ret; |
| } |
| |
| #ifdef CONFIG_KEXEC_CORE |
| static void crash_vmclear_local_loaded_vmcss(void) |
| { |
| int cpu = raw_smp_processor_id(); |
| struct loaded_vmcs *v; |
| |
| list_for_each_entry(v, &per_cpu(loaded_vmcss_on_cpu, cpu), |
| loaded_vmcss_on_cpu_link) |
| vmcs_clear(v->vmcs); |
| } |
| #endif /* CONFIG_KEXEC_CORE */ |
| |
| static void __loaded_vmcs_clear(void *arg) |
| { |
| struct loaded_vmcs *loaded_vmcs = arg; |
| int cpu = raw_smp_processor_id(); |
| |
| if (loaded_vmcs->cpu != cpu) |
| return; /* vcpu migration can race with cpu offline */ |
| if (per_cpu(current_vmcs, cpu) == loaded_vmcs->vmcs) |
| per_cpu(current_vmcs, cpu) = NULL; |
| |
| vmcs_clear(loaded_vmcs->vmcs); |
| if (loaded_vmcs->shadow_vmcs && loaded_vmcs->launched) |
| vmcs_clear(loaded_vmcs->shadow_vmcs); |
| |
| list_del(&loaded_vmcs->loaded_vmcss_on_cpu_link); |
| |
| /* |
| * Ensure all writes to loaded_vmcs, including deleting it from its |
| * current percpu list, complete before setting loaded_vmcs->vcpu to |
| * -1, otherwise a different cpu can see vcpu == -1 first and add |
| * loaded_vmcs to its percpu list before it's deleted from this cpu's |
| * list. Pairs with the smp_rmb() in vmx_vcpu_load_vmcs(). |
| */ |
| smp_wmb(); |
| |
| loaded_vmcs->cpu = -1; |
| loaded_vmcs->launched = 0; |
| } |
| |
| void loaded_vmcs_clear(struct loaded_vmcs *loaded_vmcs) |
| { |
| int cpu = loaded_vmcs->cpu; |
| |
| if (cpu != -1) |
| smp_call_function_single(cpu, |
| __loaded_vmcs_clear, loaded_vmcs, 1); |
| } |
| |
| static bool vmx_segment_cache_test_set(struct vcpu_vmx *vmx, unsigned seg, |
| unsigned field) |
| { |
| bool ret; |
| u32 mask = 1 << (seg * SEG_FIELD_NR + field); |
| |
| if (!kvm_register_is_available(&vmx->vcpu, VCPU_EXREG_SEGMENTS)) { |
| kvm_register_mark_available(&vmx->vcpu, VCPU_EXREG_SEGMENTS); |
| vmx->segment_cache.bitmask = 0; |
| } |
| ret = vmx->segment_cache.bitmask & mask; |
| vmx->segment_cache.bitmask |= mask; |
| return ret; |
| } |
| |
| static u16 vmx_read_guest_seg_selector(struct vcpu_vmx *vmx, unsigned seg) |
| { |
| u16 *p = &vmx->segment_cache.seg[seg].selector; |
| |
| if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_SEL)) |
| *p = vmcs_read16(kvm_vmx_segment_fields[seg].selector); |
| return *p; |
| } |
| |
| static ulong vmx_read_guest_seg_base(struct vcpu_vmx *vmx, unsigned seg) |
| { |
| ulong *p = &vmx->segment_cache.seg[seg].base; |
| |
| if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_BASE)) |
| *p = vmcs_readl(kvm_vmx_segment_fields[seg].base); |
| return *p; |
| } |
| |
| static u32 vmx_read_guest_seg_limit(struct vcpu_vmx *vmx, unsigned seg) |
| { |
| u32 *p = &vmx->segment_cache.seg[seg].limit; |
| |
| if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_LIMIT)) |
| *p = vmcs_read32(kvm_vmx_segment_fields[seg].limit); |
| return *p; |
| } |
| |
| static u32 vmx_read_guest_seg_ar(struct vcpu_vmx *vmx, unsigned seg) |
| { |
| u32 *p = &vmx->segment_cache.seg[seg].ar; |
| |
| if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_AR)) |
| *p = vmcs_read32(kvm_vmx_segment_fields[seg].ar_bytes); |
| return *p; |
| } |
| |
| void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu) |
| { |
| u32 eb; |
| |
| eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) | |
| (1u << DB_VECTOR) | (1u << AC_VECTOR); |
| /* |
| * Guest access to VMware backdoor ports could legitimately |
| * trigger #GP because of TSS I/O permission bitmap. |
| * We intercept those #GP and allow access to them anyway |
| * as VMware does. |
| */ |
| if (enable_vmware_backdoor) |
| eb |= (1u << GP_VECTOR); |
| if ((vcpu->guest_debug & |
| (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) == |
| (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) |
| eb |= 1u << BP_VECTOR; |
| if (to_vmx(vcpu)->rmode.vm86_active) |
| eb = ~0; |
| if (!vmx_need_pf_intercept(vcpu)) |
| eb &= ~(1u << PF_VECTOR); |
| |
| /* When we are running a nested L2 guest and L1 specified for it a |
| * certain exception bitmap, we must trap the same exceptions and pass |
| * them to L1. When running L2, we will only handle the exceptions |
| * specified above if L1 did not want them. |
| */ |
| if (is_guest_mode(vcpu)) |
| eb |= get_vmcs12(vcpu)->exception_bitmap; |
| else { |
| int mask = 0, match = 0; |
| |
| if (enable_ept && (eb & (1u << PF_VECTOR))) { |
| /* |
| * If EPT is enabled, #PF is currently only intercepted |
| * if MAXPHYADDR is smaller on the guest than on the |
| * host. In that case we only care about present, |
| * non-reserved faults. For vmcs02, however, PFEC_MASK |
| * and PFEC_MATCH are set in prepare_vmcs02_rare. |
| */ |
| mask = PFERR_PRESENT_MASK | PFERR_RSVD_MASK; |
| match = PFERR_PRESENT_MASK; |
| } |
| vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, mask); |
| vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, match); |
| } |
| |
| vmcs_write32(EXCEPTION_BITMAP, eb); |
| } |
| |
| /* |
| * Check if MSR is intercepted for currently loaded MSR bitmap. |
| */ |
| static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr) |
| { |
| unsigned long *msr_bitmap; |
| int f = sizeof(unsigned long); |
| |
| if (!cpu_has_vmx_msr_bitmap()) |
| return true; |
| |
| msr_bitmap = to_vmx(vcpu)->loaded_vmcs->msr_bitmap; |
| |
| if (msr <= 0x1fff) { |
| return !!test_bit(msr, msr_bitmap + 0x800 / f); |
| } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { |
| msr &= 0x1fff; |
| return !!test_bit(msr, msr_bitmap + 0xc00 / f); |
| } |
| |
| return true; |
| } |
| |
| static void clear_atomic_switch_msr_special(struct vcpu_vmx *vmx, |
| unsigned long entry, unsigned long exit) |
| { |
| vm_entry_controls_clearbit(vmx, entry); |
| vm_exit_controls_clearbit(vmx, exit); |
| } |
| |
| int vmx_find_loadstore_msr_slot(struct vmx_msrs *m, u32 msr) |
| { |
| unsigned int i; |
| |
| for (i = 0; i < m->nr; ++i) { |
| if (m->val[i].index == msr) |
| return i; |
| } |
| return -ENOENT; |
| } |
| |
| static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr) |
| { |
| int i; |
| struct msr_autoload *m = &vmx->msr_autoload; |
| |
| switch (msr) { |
| case MSR_EFER: |
| if (cpu_has_load_ia32_efer()) { |
| clear_atomic_switch_msr_special(vmx, |
| VM_ENTRY_LOAD_IA32_EFER, |
| VM_EXIT_LOAD_IA32_EFER); |
| return; |
| } |
| break; |
| case MSR_CORE_PERF_GLOBAL_CTRL: |
| if (cpu_has_load_perf_global_ctrl()) { |
| clear_atomic_switch_msr_special(vmx, |
| VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL, |
| VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL); |
| return; |
| } |
| break; |
| } |
| i = vmx_find_loadstore_msr_slot(&m->guest, msr); |
| if (i < 0) |
| goto skip_guest; |
| --m->guest.nr; |
| m->guest.val[i] = m->guest.val[m->guest.nr]; |
| vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->guest.nr); |
| |
| skip_guest: |
| i = vmx_find_loadstore_msr_slot(&m->host, msr); |
| if (i < 0) |
| return; |
| |
| --m->host.nr; |
| m->host.val[i] = m->host.val[m->host.nr]; |
| vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->host.nr); |
| } |
| |
| static void add_atomic_switch_msr_special(struct vcpu_vmx *vmx, |
| unsigned long entry, unsigned long exit, |
| unsigned long guest_val_vmcs, unsigned long host_val_vmcs, |
| u64 guest_val, u64 host_val) |
| { |
| vmcs_write64(guest_val_vmcs, guest_val); |
| if (host_val_vmcs != HOST_IA32_EFER) |
| vmcs_write64(host_val_vmcs, host_val); |
| vm_entry_controls_setbit(vmx, entry); |
| vm_exit_controls_setbit(vmx, exit); |
| } |
| |
| static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, |
| u64 guest_val, u64 host_val, bool entry_only) |
| { |
| int i, j = 0; |
| struct msr_autoload *m = &vmx->msr_autoload; |
| |
| switch (msr) { |
| case MSR_EFER: |
| if (cpu_has_load_ia32_efer()) { |
| add_atomic_switch_msr_special(vmx, |
| VM_ENTRY_LOAD_IA32_EFER, |
| VM_EXIT_LOAD_IA32_EFER, |
| GUEST_IA32_EFER, |
| HOST_IA32_EFER, |
| guest_val, host_val); |
| return; |
| } |
| break; |
| case MSR_CORE_PERF_GLOBAL_CTRL: |
| if (cpu_has_load_perf_global_ctrl()) { |
| add_atomic_switch_msr_special(vmx, |
| VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL, |
| VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL, |
| GUEST_IA32_PERF_GLOBAL_CTRL, |
| HOST_IA32_PERF_GLOBAL_CTRL, |
| guest_val, host_val); |
| return; |
| } |
| break; |
| case MSR_IA32_PEBS_ENABLE: |
| /* PEBS needs a quiescent period after being disabled (to write |
| * a record). Disabling PEBS through VMX MSR swapping doesn't |
| * provide that period, so a CPU could write host's record into |
| * guest's memory. |
| */ |
| wrmsrl(MSR_IA32_PEBS_ENABLE, 0); |
| } |
| |
| i = vmx_find_loadstore_msr_slot(&m->guest, msr); |
| if (!entry_only) |
| j = vmx_find_loadstore_msr_slot(&m->host, msr); |
| |
| if ((i < 0 && m->guest.nr == MAX_NR_LOADSTORE_MSRS) || |
| (j < 0 && m->host.nr == MAX_NR_LOADSTORE_MSRS)) { |
| printk_once(KERN_WARNING "Not enough msr switch entries. " |
| "Can't add msr %x\n", msr); |
| return; |
| } |
| if (i < 0) { |
| i = m->guest.nr++; |
| vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->guest.nr); |
| } |
| m->guest.val[i].index = msr; |
| m->guest.val[i].value = guest_val; |
| |
| if (entry_only) |
| return; |
| |
| if (j < 0) { |
| j = m->host.nr++; |
| vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->host.nr); |
| } |
| m->host.val[j].index = msr; |
| m->host.val[j].value = host_val; |
| } |
| |
| static bool update_transition_efer(struct vcpu_vmx *vmx) |
| { |
| u64 guest_efer = vmx->vcpu.arch.efer; |
| u64 ignore_bits = 0; |
| int i; |
| |
| /* Shadow paging assumes NX to be available. */ |
| if (!enable_ept) |
| guest_efer |= EFER_NX; |
| |
| /* |
| * LMA and LME handled by hardware; SCE meaningless outside long mode. |
| */ |
| ignore_bits |= EFER_SCE; |
| #ifdef CONFIG_X86_64 |
| ignore_bits |= EFER_LMA | EFER_LME; |
| /* SCE is meaningful only in long mode on Intel */ |
| if (guest_efer & EFER_LMA) |
| ignore_bits &= ~(u64)EFER_SCE; |
| #endif |
| |
| /* |
| * On EPT, we can't emulate NX, so we must switch EFER atomically. |
| * On CPUs that support "load IA32_EFER", always switch EFER |
| * atomically, since it's faster than switching it manually. |
| */ |
| if (cpu_has_load_ia32_efer() || |
| (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) { |
| if (!(guest_efer & EFER_LMA)) |
| guest_efer &= ~EFER_LME; |
| if (guest_efer != host_efer) |
| add_atomic_switch_msr(vmx, MSR_EFER, |
| guest_efer, host_efer, false); |
| else |
| clear_atomic_switch_msr(vmx, MSR_EFER); |
| return false; |
| } |
| |
| i = kvm_find_user_return_msr(MSR_EFER); |
| if (i < 0) |
| return false; |
| |
| clear_atomic_switch_msr(vmx, MSR_EFER); |
| |
| guest_efer &= ~ignore_bits; |
| guest_efer |= host_efer & ignore_bits; |
| |
| vmx->guest_uret_msrs[i].data = guest_efer; |
| vmx->guest_uret_msrs[i].mask = ~ignore_bits; |
| |
| return true; |
| } |
| |
| #ifdef CONFIG_X86_32 |
| /* |
| * On 32-bit kernels, VM exits still load the FS and GS bases from the |
| * VMCS rather than the segment table. KVM uses this helper to figure |
| * out the current bases to poke them into the VMCS before entry. |
| */ |
| static unsigned long segment_base(u16 selector) |
| { |
| struct desc_struct *table; |
| unsigned long v; |
| |
| if (!(selector & ~SEGMENT_RPL_MASK)) |
| return 0; |
| |
| table = get_current_gdt_ro(); |
| |
| if ((selector & SEGMENT_TI_MASK) == SEGMENT_LDT) { |
| u16 ldt_selector = kvm_read_ldt(); |
| |
| if (!(ldt_selector & ~SEGMENT_RPL_MASK)) |
| return 0; |
| |
| table = (struct desc_struct *)segment_base(ldt_selector); |
| } |
| v = get_desc_base(&table[selector >> 3]); |
| return v; |
| } |
| #endif |
| |
| static inline bool pt_can_write_msr(struct vcpu_vmx *vmx) |
| { |
| return vmx_pt_mode_is_host_guest() && |
| !(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN); |
| } |
| |
| static inline bool pt_output_base_valid(struct kvm_vcpu *vcpu, u64 base) |
| { |
| /* The base must be 128-byte aligned and a legal physical address. */ |
| return kvm_vcpu_is_legal_aligned_gpa(vcpu, base, 128); |
| } |
| |
| static inline void pt_load_msr(struct pt_ctx *ctx, u32 addr_range) |
| { |
| u32 i; |
| |
| wrmsrl(MSR_IA32_RTIT_STATUS, ctx->status); |
| wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, ctx->output_base); |
| wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, ctx->output_mask); |
| wrmsrl(MSR_IA32_RTIT_CR3_MATCH, ctx->cr3_match); |
| for (i = 0; i < addr_range; i++) { |
| wrmsrl(MSR_IA32_RTIT_ADDR0_A + i * 2, ctx->addr_a[i]); |
| wrmsrl(MSR_IA32_RTIT_ADDR0_B + i * 2, ctx->addr_b[i]); |
| } |
| } |
| |
| static inline void pt_save_msr(struct pt_ctx *ctx, u32 addr_range) |
| { |
| u32 i; |
| |
| rdmsrl(MSR_IA32_RTIT_STATUS, ctx->status); |
| rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, ctx->output_base); |
| rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, ctx->output_mask); |
| rdmsrl(MSR_IA32_RTIT_CR3_MATCH, ctx->cr3_match); |
| for (i = 0; i < addr_range; i++) { |
| rdmsrl(MSR_IA32_RTIT_ADDR0_A + i * 2, ctx->addr_a[i]); |
| rdmsrl(MSR_IA32_RTIT_ADDR0_B + i * 2, ctx->addr_b[i]); |
| } |
| } |
| |
| static void pt_guest_enter(struct vcpu_vmx *vmx) |
| { |
| if (vmx_pt_mode_is_system()) |
| return; |
| |
| /* |
| * GUEST_IA32_RTIT_CTL is already set in the VMCS. |
| * Save host state before VM entry. |
| */ |
| rdmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl); |
| if (vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) { |
| wrmsrl(MSR_IA32_RTIT_CTL, 0); |
| pt_save_msr(&vmx->pt_desc.host, vmx->pt_desc.addr_range); |
| pt_load_msr(&vmx->pt_desc.guest, vmx->pt_desc.addr_range); |
| } |
| } |
| |
| static void pt_guest_exit(struct vcpu_vmx *vmx) |
| { |
| if (vmx_pt_mode_is_system()) |
| return; |
| |
| if (vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) { |
| pt_save_msr(&vmx->pt_desc.guest, vmx->pt_desc.addr_range); |
| pt_load_msr(&vmx->pt_desc.host, vmx->pt_desc.addr_range); |
| } |
| |
| /* Reload host state (IA32_RTIT_CTL will be cleared on VM exit). */ |
| wrmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl); |
| } |
| |
| void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel, |
| unsigned long fs_base, unsigned long gs_base) |
| { |
| if (unlikely(fs_sel != host->fs_sel)) { |
| if (!(fs_sel & 7)) |
| vmcs_write16(HOST_FS_SELECTOR, fs_sel); |
| else |
| vmcs_write16(HOST_FS_SELECTOR, 0); |
| host->fs_sel = fs_sel; |
| } |
| if (unlikely(gs_sel != host->gs_sel)) { |
| if (!(gs_sel & 7)) |
| vmcs_write16(HOST_GS_SELECTOR, gs_sel); |
| else |
| vmcs_write16(HOST_GS_SELECTOR, 0); |
| host->gs_sel = gs_sel; |
| } |
| if (unlikely(fs_base != host->fs_base)) { |
| vmcs_writel(HOST_FS_BASE, fs_base); |
| host->fs_base = fs_base; |
| } |
| if (unlikely(gs_base != host->gs_base)) { |
| vmcs_writel(HOST_GS_BASE, gs_base); |
| host->gs_base = gs_base; |
| } |
| } |
| |
| void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| struct vmcs_host_state *host_state; |
| #ifdef CONFIG_X86_64 |
| int cpu = raw_smp_processor_id(); |
| #endif |
| unsigned long fs_base, gs_base; |
| u16 fs_sel, gs_sel; |
| int i; |
| |
| vmx->req_immediate_exit = false; |
| |
| /* |
| * Note that guest MSRs to be saved/restored can also be changed |
| * when guest state is loaded. This happens when guest transitions |
| * to/from long-mode by setting MSR_EFER.LMA. |
| */ |
| if (!vmx->guest_uret_msrs_loaded) { |
| vmx->guest_uret_msrs_loaded = true; |
| for (i = 0; i < kvm_nr_uret_msrs; ++i) { |
| if (!vmx->guest_uret_msrs[i].load_into_hardware) |
| continue; |
| |
| kvm_set_user_return_msr(i, |
| vmx->guest_uret_msrs[i].data, |
| vmx->guest_uret_msrs[i].mask); |
| } |
| } |
| |
| if (vmx->nested.need_vmcs12_to_shadow_sync) |
| nested_sync_vmcs12_to_shadow(vcpu); |
| |
| if (vmx->guest_state_loaded) |
| return; |
| |
| host_state = &vmx->loaded_vmcs->host_state; |
| |
| /* |
| * Set host fs and gs selectors. Unfortunately, 22.2.3 does not |
| * allow segment selectors with cpl > 0 or ti == 1. |
| */ |
| host_state->ldt_sel = kvm_read_ldt(); |
| |
| #ifdef CONFIG_X86_64 |
| savesegment(ds, host_state->ds_sel); |
| savesegment(es, host_state->es_sel); |
| |
| gs_base = cpu_kernelmode_gs_base(cpu); |
| if (likely(is_64bit_mm(current->mm))) { |
| current_save_fsgs(); |
| fs_sel = current->thread.fsindex; |
| gs_sel = current->thread.gsindex; |
| fs_base = current->thread.fsbase; |
| vmx->msr_host_kernel_gs_base = current->thread.gsbase; |
| } else { |
| savesegment(fs, fs_sel); |
| savesegment(gs, gs_sel); |
| fs_base = read_msr(MSR_FS_BASE); |
| vmx->msr_host_kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE); |
| } |
| |
| wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); |
| #else |
| savesegment(fs, fs_sel); |
| savesegment(gs, gs_sel); |
| fs_base = segment_base(fs_sel); |
| gs_base = segment_base(gs_sel); |
| #endif |
| |
| vmx_set_host_fs_gs(host_state, fs_sel, gs_sel, fs_base, gs_base); |
| vmx->guest_state_loaded = true; |
| } |
| |
| static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx) |
| { |
| struct vmcs_host_state *host_state; |
| |
| if (!vmx->guest_state_loaded) |
| return; |
| |
| host_state = &vmx->loaded_vmcs->host_state; |
| |
| ++vmx->vcpu.stat.host_state_reload; |
| |
| #ifdef CONFIG_X86_64 |
| rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); |
| #endif |
| if (host_state->ldt_sel || (host_state->gs_sel & 7)) { |
| kvm_load_ldt(host_state->ldt_sel); |
| #ifdef CONFIG_X86_64 |
| load_gs_index(host_state->gs_sel); |
| #else |
| loadsegment(gs, host_state->gs_sel); |
| #endif |
| } |
| if (host_state->fs_sel & 7) |
| loadsegment(fs, host_state->fs_sel); |
| #ifdef CONFIG_X86_64 |
| if (unlikely(host_state->ds_sel | host_state->es_sel)) { |
| loadsegment(ds, host_state->ds_sel); |
| loadsegment(es, host_state->es_sel); |
| } |
| #endif |
| invalidate_tss_limit(); |
| #ifdef CONFIG_X86_64 |
| wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); |
| #endif |
| load_fixmap_gdt(raw_smp_processor_id()); |
| vmx->guest_state_loaded = false; |
| vmx->guest_uret_msrs_loaded = false; |
| } |
| |
| #ifdef CONFIG_X86_64 |
| static u64 vmx_read_guest_kernel_gs_base(struct vcpu_vmx *vmx) |
| { |
| preempt_disable(); |
| if (vmx->guest_state_loaded) |
| rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); |
| preempt_enable(); |
| return vmx->msr_guest_kernel_gs_base; |
| } |
| |
| static void vmx_write_guest_kernel_gs_base(struct vcpu_vmx *vmx, u64 data) |
| { |
| preempt_disable(); |
| if (vmx->guest_state_loaded) |
| wrmsrl(MSR_KERNEL_GS_BASE, data); |
| preempt_enable(); |
| vmx->msr_guest_kernel_gs_base = data; |
| } |
| #endif |
| |
| void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, |
| struct loaded_vmcs *buddy) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| bool already_loaded = vmx->loaded_vmcs->cpu == cpu; |
| struct vmcs *prev; |
| |
| if (!already_loaded) { |
| loaded_vmcs_clear(vmx->loaded_vmcs); |
| local_irq_disable(); |
| |
| /* |
| * Ensure loaded_vmcs->cpu is read before adding loaded_vmcs to |
| * this cpu's percpu list, otherwise it may not yet be deleted |
| * from its previous cpu's percpu list. Pairs with the |
| * smb_wmb() in __loaded_vmcs_clear(). |
| */ |
| smp_rmb(); |
| |
| list_add(&vmx->loaded_vmcs->loaded_vmcss_on_cpu_link, |
| &per_cpu(loaded_vmcss_on_cpu, cpu)); |
| local_irq_enable(); |
| } |
| |
| prev = per_cpu(current_vmcs, cpu); |
| if (prev != vmx->loaded_vmcs->vmcs) { |
| per_cpu(current_vmcs, cpu) = vmx->loaded_vmcs->vmcs; |
| vmcs_load(vmx->loaded_vmcs->vmcs); |
| |
| /* |
| * No indirect branch prediction barrier needed when switching |
| * the active VMCS within a guest, e.g. on nested VM-Enter. |
| * The L1 VMM can protect itself with retpolines, IBPB or IBRS. |
| */ |
| if (!buddy || WARN_ON_ONCE(buddy->vmcs != prev)) |
| indirect_branch_prediction_barrier(); |
| } |
| |
| if (!already_loaded) { |
| void *gdt = get_current_gdt_ro(); |
| unsigned long sysenter_esp; |
| |
| /* |
| * Flush all EPTP/VPID contexts, the new pCPU may have stale |
| * TLB entries from its previous association with the vCPU. |
| */ |
| kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); |
| |
| /* |
| * Linux uses per-cpu TSS and GDT, so set these when switching |
| * processors. See 22.2.4. |
| */ |
| vmcs_writel(HOST_TR_BASE, |
| (unsigned long)&get_cpu_entry_area(cpu)->tss.x86_tss); |
| vmcs_writel(HOST_GDTR_BASE, (unsigned long)gdt); /* 22.2.4 */ |
| |
| rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); |
| vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ |
| |
| vmx->loaded_vmcs->cpu = cpu; |
| } |
| } |
| |
| /* |
| * Switches to specified vcpu, until a matching vcpu_put(), but assumes |
| * vcpu mutex is already taken. |
| */ |
| static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| |
| vmx_vcpu_load_vmcs(vcpu, cpu, NULL); |
| |
| vmx_vcpu_pi_load(vcpu, cpu); |
| |
| vmx->host_debugctlmsr = get_debugctlmsr(); |
| } |
| |
| static void vmx_vcpu_put(struct kvm_vcpu *vcpu) |
| { |
| vmx_vcpu_pi_put(vcpu); |
| |
| vmx_prepare_switch_to_host(to_vmx(vcpu)); |
| } |
| |
| bool vmx_emulation_required(struct kvm_vcpu *vcpu) |
| { |
| return emulate_invalid_guest_state && !vmx_guest_state_valid(vcpu); |
| } |
| |
| unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| unsigned long rflags, save_rflags; |
| |
| if (!kvm_register_is_available(vcpu, VCPU_EXREG_RFLAGS)) { |
| kvm_register_mark_available(vcpu, VCPU_EXREG_RFLAGS); |
| rflags = vmcs_readl(GUEST_RFLAGS); |
| if (vmx->rmode.vm86_active) { |
| rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS; |
| save_rflags = vmx->rmode.save_rflags; |
| rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; |
| } |
| vmx->rflags = rflags; |
| } |
| return vmx->rflags; |
| } |
| |
| void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| unsigned long old_rflags; |
| |
| if (is_unrestricted_guest(vcpu)) { |
| kvm_register_mark_available(vcpu, VCPU_EXREG_RFLAGS); |
| vmx->rflags = rflags; |
| vmcs_writel(GUEST_RFLAGS, rflags); |
| return; |
| } |
| |
| old_rflags = vmx_get_rflags(vcpu); |
| vmx->rflags = rflags; |
| if (vmx->rmode.vm86_active) { |
| vmx->rmode.save_rflags = rflags; |
| rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
| } |
| vmcs_writel(GUEST_RFLAGS, rflags); |
| |
| if ((old_rflags ^ vmx->rflags) & X86_EFLAGS_VM) |
| vmx->emulation_required = vmx_emulation_required(vcpu); |
| } |
| |
| u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu) |
| { |
| u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); |
| int ret = 0; |
| |
| if (interruptibility & GUEST_INTR_STATE_STI) |
| ret |= KVM_X86_SHADOW_INT_STI; |
| if (interruptibility & GUEST_INTR_STATE_MOV_SS) |
| ret |= KVM_X86_SHADOW_INT_MOV_SS; |
| |
| return ret; |
| } |
| |
| void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) |
| { |
| u32 interruptibility_old = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); |
| u32 interruptibility = interruptibility_old; |
| |
| interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS); |
| |
| if (mask & KVM_X86_SHADOW_INT_MOV_SS) |
| interruptibility |= GUEST_INTR_STATE_MOV_SS; |
| else if (mask & KVM_X86_SHADOW_INT_STI) |
| interruptibility |= GUEST_INTR_STATE_STI; |
| |
| if ((interruptibility != interruptibility_old)) |
| vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, interruptibility); |
| } |
| |
| static int vmx_rtit_ctl_check(struct kvm_vcpu *vcpu, u64 data) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| unsigned long value; |
| |
| /* |
| * Any MSR write that attempts to change bits marked reserved will |
| * case a #GP fault. |
| */ |
| if (data & vmx->pt_desc.ctl_bitmask) |
| return 1; |
| |
| /* |
| * Any attempt to modify IA32_RTIT_CTL while TraceEn is set will |
| * result in a #GP unless the same write also clears TraceEn. |
| */ |
| if ((vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) && |
| ((vmx->pt_desc.guest.ctl ^ data) & ~RTIT_CTL_TRACEEN)) |
| return 1; |
| |
| /* |
| * WRMSR to IA32_RTIT_CTL that sets TraceEn but clears this bit |
| * and FabricEn would cause #GP, if |
| * CPUID.(EAX=14H, ECX=0):ECX.SNGLRGNOUT[bit 2] = 0 |
| */ |
| if ((data & RTIT_CTL_TRACEEN) && !(data & RTIT_CTL_TOPA) && |
| !(data & RTIT_CTL_FABRIC_EN) && |
| !intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_single_range_output)) |
| return 1; |
| |
| /* |
| * MTCFreq, CycThresh and PSBFreq encodings check, any MSR write that |
| * utilize encodings marked reserved will cause a #GP fault. |
| */ |
| value = intel_pt_validate_cap(vmx->pt_desc.caps, PT_CAP_mtc_periods); |
| if (intel_pt_validate_cap(vmx->pt_desc.caps, PT_CAP_mtc) && |
| !test_bit((data & RTIT_CTL_MTC_RANGE) >> |
| RTIT_CTL_MTC_RANGE_OFFSET, &value)) |
| return 1; |
| value = intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_cycle_thresholds); |
| if (intel_pt_validate_cap(vmx->pt_desc.caps, PT_CAP_psb_cyc) && |
| !test_bit((data & RTIT_CTL_CYC_THRESH) >> |
| RTIT_CTL_CYC_THRESH_OFFSET, &value)) |
| return 1; |
| value = intel_pt_validate_cap(vmx->pt_desc.caps, PT_CAP_psb_periods); |
| if (intel_pt_validate_cap(vmx->pt_desc.caps, PT_CAP_psb_cyc) && |
| !test_bit((data & RTIT_CTL_PSB_FREQ) >> |
| RTIT_CTL_PSB_FREQ_OFFSET, &value)) |
| return 1; |
| |
| /* |
| * If ADDRx_CFG is reserved or the encodings is >2 will |
| * cause a #GP fault. |
| */ |
| value = (data & RTIT_CTL_ADDR0) >> RTIT_CTL_ADDR0_OFFSET; |
| if ((value && (vmx->pt_desc.addr_range < 1)) || (value > 2)) |
| return 1; |
| value = (data & RTIT_CTL_ADDR1) >> RTIT_CTL_ADDR1_OFFSET; |
| if ((value && (vmx->pt_desc.addr_range < 2)) || (value > 2)) |
| return 1; |
| value = (data & RTIT_CTL_ADDR2) >> RTIT_CTL_ADDR2_OFFSET; |
| if ((value && (vmx->pt_desc.addr_range < 3)) || (value > 2)) |
| return 1; |
| value = (data & RTIT_CTL_ADDR3) >> RTIT_CTL_ADDR3_OFFSET; |
| if ((value && (vmx->pt_desc.addr_range < 4)) || (value > 2)) |
| return 1; |
| |
| return 0; |
| } |
| |
| static bool vmx_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int insn_len) |
| { |
| /* |
| * Emulation of instructions in SGX enclaves is impossible as RIP does |
| * not point tthe failing instruction, and even if it did, the code |
| * stream is inaccessible. Inject #UD instead of exiting to userspace |
| * so that guest userspace can't DoS the guest simply by triggering |
| * emulation (enclaves are CPL3 only). |
| */ |
| if (to_vmx(vcpu)->exit_reason.enclave_mode) { |
| kvm_queue_exception(vcpu, UD_VECTOR); |
| return false; |
| } |
| return true; |
| } |
| |
| static int skip_emulated_instruction(struct kvm_vcpu *vcpu) |
| { |
| union vmx_exit_reason exit_reason = to_vmx(vcpu)->exit_reason; |
| unsigned long rip, orig_rip; |
| u32 instr_len; |
| |
| /* |
| * Using VMCS.VM_EXIT_INSTRUCTION_LEN on EPT misconfig depends on |
| * undefined behavior: Intel's SDM doesn't mandate the VMCS field be |
| * set when EPT misconfig occurs. In practice, real hardware updates |
| * VM_EXIT_INSTRUCTION_LEN on EPT misconfig, but other hypervisors |
| * (namely Hyper-V) don't set it due to it being undefined behavior, |
| * i.e. we end up advancing IP with some random value. |
| */ |
| if (!static_cpu_has(X86_FEATURE_HYPERVISOR) || |
| exit_reason.basic != EXIT_REASON_EPT_MISCONFIG) { |
| instr_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN); |
| |
| /* |
| * Emulating an enclave's instructions isn't supported as KVM |
| * cannot access the enclave's memory or its true RIP, e.g. the |
| * vmcs.GUEST_RIP points at the exit point of the enclave, not |
| * the RIP that actually triggered the VM-Exit. But, because |
| * most instructions that cause VM-Exit will #UD in an enclave, |
| * most instruction-based VM-Exits simply do not occur. |
| * |
| * There are a few exceptions, notably the debug instructions |
| * INT1ICEBRK and INT3, as they are allowed in debug enclaves |
| * and generate #DB/#BP as expected, which KVM might intercept. |
| * But again, the CPU does the dirty work and saves an instr |
| * length of zero so VMMs don't shoot themselves in the foot. |
| * WARN if KVM tries to skip a non-zero length instruction on |
| * a VM-Exit from an enclave. |
| */ |
| if (!instr_len) |
| goto rip_updated; |
| |
| WARN(exit_reason.enclave_mode, |
| "KVM: skipping instruction after SGX enclave VM-Exit"); |
| |
| orig_rip = kvm_rip_read(vcpu); |
| rip = orig_rip + instr_len; |
| #ifdef CONFIG_X86_64 |
| /* |
| * We need to mask out the high 32 bits of RIP if not in 64-bit |
| * mode, but just finding out that we are in 64-bit mode is |
| * quite expensive. Only do it if there was a carry. |
| */ |
| if (unlikely(((rip ^ orig_rip) >> 31) == 3) && !is_64_bit_mode(vcpu)) |
| rip = (u32)rip; |
| #endif |
| kvm_rip_write(vcpu, rip); |
| } else { |
| if (!kvm_emulate_instruction(vcpu, EMULTYPE_SKIP)) |
| return 0; |
| } |
| |
| rip_updated: |
| /* skipping an emulated instruction also counts */ |
| vmx_set_interrupt_shadow(vcpu, 0); |
| |
| return 1; |
| } |
| |
| /* |
| * Recognizes a pending MTF VM-exit and records the nested state for later |
| * delivery. |
| */ |
| static void vmx_update_emulated_instruction(struct kvm_vcpu *vcpu) |
| { |
| struct vmcs12 *vmcs12 = get_vmcs12(vcpu); |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| |
| if (!is_guest_mode(vcpu)) |
| return; |
| |
| /* |
| * Per the SDM, MTF takes priority over debug-trap exceptions besides |
| * T-bit traps. As instruction emulation is completed (i.e. at the |
| * instruction boundary), any #DB exception pending delivery must be a |
| * debug-trap. Record the pending MTF state to be delivered in |
| * vmx_check_nested_events(). |
| */ |
| if (nested_cpu_has_mtf(vmcs12) && |
| (!vcpu->arch.exception.pending || |
| vcpu->arch.exception.nr == DB_VECTOR)) |
| vmx->nested.mtf_pending = true; |
| else |
| vmx->nested.mtf_pending = false; |
| } |
| |
| static int vmx_skip_emulated_instruction(struct kvm_vcpu *vcpu) |
| { |
| vmx_update_emulated_instruction(vcpu); |
| return skip_emulated_instruction(vcpu); |
| } |
| |
| static void vmx_clear_hlt(struct kvm_vcpu *vcpu) |
| { |
| /* |
| * Ensure that we clear the HLT state in the VMCS. We don't need to |
| * explicitly skip the instruction because if the HLT state is set, |
| * then the instruction is already executing and RIP has already been |
| * advanced. |
| */ |
| if (kvm_hlt_in_guest(vcpu->kvm) && |
| vmcs_read32(GUEST_ACTIVITY_STATE) == GUEST_ACTIVITY_HLT) |
| vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); |
| } |
| |
| static void vmx_queue_exception(struct kvm_vcpu *vcpu) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| unsigned nr = vcpu->arch.exception.nr; |
| bool has_error_code = vcpu->arch.exception.has_error_code; |
| u32 error_code = vcpu->arch.exception.error_code; |
| u32 intr_info = nr | INTR_INFO_VALID_MASK; |
| |
| kvm_deliver_exception_payload(vcpu); |
| |
| if (has_error_code) { |
| vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); |
| intr_info |= INTR_INFO_DELIVER_CODE_MASK; |
| } |
| |
| if (vmx->rmode.vm86_active) { |
| int inc_eip = 0; |
| if (kvm_exception_is_soft(nr)) |
| inc_eip = vcpu->arch.event_exit_inst_len; |
| kvm_inject_realmode_interrupt(vcpu, nr, inc_eip); |
| return; |
| } |
| |
| WARN_ON_ONCE(vmx->emulation_required); |
| |
| if (kvm_exception_is_soft(nr)) { |
| vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, |
| vmx->vcpu.arch.event_exit_inst_len); |
| intr_info |= INTR_TYPE_SOFT_EXCEPTION; |
| } else |
| intr_info |= INTR_TYPE_HARD_EXCEPTION; |
| |
| vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); |
| |
| vmx_clear_hlt(vcpu); |
| } |
| |
| static void vmx_setup_uret_msr(struct vcpu_vmx *vmx, unsigned int msr, |
| bool load_into_hardware) |
| { |
| struct vmx_uret_msr *uret_msr; |
| |
| uret_msr = vmx_find_uret_msr(vmx, msr); |
| if (!uret_msr) |
| return; |
| |
| uret_msr->load_into_hardware = load_into_hardware; |
| } |
| |
| /* |
| * Configuring user return MSRs to automatically save, load, and restore MSRs |
| * that need to be shoved into hardware when running the guest. Note, omitting |
| * an MSR here does _NOT_ mean it's not emulated, only that it will not be |
| * loaded into hardware when running the guest. |
| */ |
| static void vmx_setup_uret_msrs(struct vcpu_vmx *vmx) |
| { |
| #ifdef CONFIG_X86_64 |
| bool load_syscall_msrs; |
| |
| /* |
| * The SYSCALL MSRs are only needed on long mode guests, and only |
| * when EFER.SCE is set. |
| */ |
| load_syscall_msrs = is_long_mode(&vmx->vcpu) && |
| (vmx->vcpu.arch.efer & EFER_SCE); |
| |
| vmx_setup_uret_msr(vmx, MSR_STAR, load_syscall_msrs); |
| vmx_setup_uret_msr(vmx, MSR_LSTAR, load_syscall_msrs); |
| vmx_setup_uret_msr(vmx, MSR_SYSCALL_MASK, load_syscall_msrs); |
| #endif |
| vmx_setup_uret_msr(vmx, MSR_EFER, update_transition_efer(vmx)); |
| |
| vmx_setup_uret_msr(vmx, MSR_TSC_AUX, |
| guest_cpuid_has(&vmx->vcpu, X86_FEATURE_RDTSCP) || |
| guest_cpuid_has(&vmx->vcpu, X86_FEATURE_RDPID)); |
| |
| /* |
| * hle=0, rtm=0, tsx_ctrl=1 can be found with some combinations of new |
| * kernel and old userspace. If those guests run on a tsx=off host, do |
| * allow guests to use TSX_CTRL, but don't change the value in hardware |
| * so that TSX remains always disabled. |
| */ |
| vmx_setup_uret_msr(vmx, MSR_IA32_TSX_CTRL, boot_cpu_has(X86_FEATURE_RTM)); |
| |
| /* |
| * The set of MSRs to load may have changed, reload MSRs before the |
| * next VM-Enter. |
| */ |
| vmx->guest_uret_msrs_loaded = false; |
| } |
| |
| u64 vmx_get_l2_tsc_offset(struct kvm_vcpu *vcpu) |
| { |
| struct vmcs12 *vmcs12 = get_vmcs12(vcpu); |
| |
| if (nested_cpu_has(vmcs12, CPU_BASED_USE_TSC_OFFSETTING)) |
| return vmcs12->tsc_offset; |
| |
| return 0; |
| } |
| |
| u64 vmx_get_l2_tsc_multiplier(struct kvm_vcpu *vcpu) |
| { |
| struct vmcs12 *vmcs12 = get_vmcs12(vcpu); |
| |
| if (nested_cpu_has(vmcs12, CPU_BASED_USE_TSC_OFFSETTING) && |
| nested_cpu_has2(vmcs12, SECONDARY_EXEC_TSC_SCALING)) |
| return vmcs12->tsc_multiplier; |
| |
| return kvm_default_tsc_scaling_ratio; |
| } |
| |
| static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) |
| { |
| vmcs_write64(TSC_OFFSET, offset); |
| } |
| |
| static void vmx_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier) |
| { |
| vmcs_write64(TSC_MULTIPLIER, multiplier); |
| } |
| |
| /* |
| * nested_vmx_allowed() checks whether a guest should be allowed to use VMX |
| * instructions and MSRs (i.e., nested VMX). Nested VMX is disabled for |
| * all guests if the "nested" module option is off, and can also be disabled |
| * for a single guest by disabling its VMX cpuid bit. |
| */ |
| bool nested_vmx_allowed(struct kvm_vcpu *vcpu) |
| { |
| return nested && guest_cpuid_has(vcpu, X86_FEATURE_VMX); |
| } |
| |
| static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu, |
| uint64_t val) |
| { |
| uint64_t valid_bits = to_vmx(vcpu)->msr_ia32_feature_control_valid_bits; |
| |
| return !(val & ~valid_bits); |
| } |
| |
| static int vmx_get_msr_feature(struct kvm_msr_entry *msr) |
| { |
| switch (msr->index) { |
| case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC: |
| if (!nested) |
| return 1; |
| return vmx_get_vmx_msr(&vmcs_config.nested, msr->index, &msr->data); |
| case MSR_IA32_PERF_CAPABILITIES: |
| msr->data = vmx_get_perf_capabilities(); |
| return 0; |
| default: |
| return KVM_MSR_RET_INVALID; |
| } |
| } |
| |
| /* |
| * Reads an msr value (of 'msr_index') into 'pdata'. |
| * Returns 0 on success, non-0 otherwise. |
| * Assumes vcpu_load() was already called. |
| */ |
| static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| struct vmx_uret_msr *msr; |
| u32 index; |
| |
| switch (msr_info->index) { |
| #ifdef CONFIG_X86_64 |
| case MSR_FS_BASE: |
| msr_info->data = vmcs_readl(GUEST_FS_BASE); |
| break; |
| case MSR_GS_BASE: |
| msr_info->data = vmcs_readl(GUEST_GS_BASE); |
| break; |
| case MSR_KERNEL_GS_BASE: |
| msr_info->data = vmx_read_guest_kernel_gs_base(vmx); |
| break; |
| #endif |
| case MSR_EFER: |
| return kvm_get_msr_common(vcpu, msr_info); |
| case MSR_IA32_TSX_CTRL: |
| if (!msr_info->host_initiated && |
| !(vcpu->arch.arch_capabilities & ARCH_CAP_TSX_CTRL_MSR)) |
| return 1; |
| goto find_uret_msr; |
| case MSR_IA32_UMWAIT_CONTROL: |
| if (!msr_info->host_initiated && !vmx_has_waitpkg(vmx)) |
| return 1; |
| |
| msr_info->data = vmx->msr_ia32_umwait_control; |
| break; |
| case MSR_IA32_SPEC_CTRL: |
| if (!msr_info->host_initiated && |
| !guest_has_spec_ctrl_msr(vcpu)) |
| return 1; |
| |
| msr_info->data = to_vmx(vcpu)->spec_ctrl; |
| break; |
| case MSR_IA32_SYSENTER_CS: |
| msr_info->data = vmcs_read32(GUEST_SYSENTER_CS); |
| break; |
| case MSR_IA32_SYSENTER_EIP: |
| msr_info->data = vmcs_readl(GUEST_SYSENTER_EIP); |
| break; |
| case MSR_IA32_SYSENTER_ESP: |
| msr_info->data = vmcs_readl(GUEST_SYSENTER_ESP); |
| break; |
| case MSR_IA32_BNDCFGS: |
| if (!kvm_mpx_supported() || |
| (!msr_info->host_initiated && |
| !guest_cpuid_has(vcpu, X86_FEATURE_MPX))) |
| return 1; |
| msr_info->data = vmcs_read64(GUEST_BNDCFGS); |
| break; |
| case MSR_IA32_MCG_EXT_CTL: |
| if (!msr_info->host_initiated && |
| !(vmx->msr_ia32_feature_control & |
| FEAT_CTL_LMCE_ENABLED)) |
| return 1; |
| msr_info->data = vcpu->arch.mcg_ext_ctl; |
| break; |
| case MSR_IA32_FEAT_CTL: |
| msr_info->data = vmx->msr_ia32_feature_control; |
| break; |
| case MSR_IA32_SGXLEPUBKEYHASH0 ... MSR_IA32_SGXLEPUBKEYHASH3: |
| if (!msr_info->host_initiated && |
| !guest_cpuid_has(vcpu, X86_FEATURE_SGX_LC)) |
| return 1; |
| msr_info->data = to_vmx(vcpu)->msr_ia32_sgxlepubkeyhash |
| [msr_info->index - MSR_IA32_SGXLEPUBKEYHASH0]; |
| break; |
| case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC: |
| if (!nested_vmx_allowed(vcpu)) |
| return 1; |
| if (vmx_get_vmx_msr(&vmx->nested.msrs, msr_info->index, |
| &msr_info->data)) |
| return 1; |
| /* |
| * Enlightened VMCS v1 doesn't have certain VMCS fields but |
| * instead of just ignoring the features, different Hyper-V |
| * versions are either trying to use them and fail or do some |
| * sanity checking and refuse to boot. Filter all unsupported |
| * features out. |
| */ |
| if (!msr_info->host_initiated && |
| vmx->nested.enlightened_vmcs_enabled) |
| nested_evmcs_filter_control_msr(msr_info->index, |
| &msr_info->data); |
| break; |
| case MSR_IA32_RTIT_CTL: |
| if (!vmx_pt_mode_is_host_guest()) |
| return 1; |
| msr_info->data = vmx->pt_desc.guest.ctl; |
| break; |
| case MSR_IA32_RTIT_STATUS: |
| if (!vmx_pt_mode_is_host_guest()) |
| return 1; |
| msr_info->data = vmx->pt_desc.guest.status; |
| break; |
| case MSR_IA32_RTIT_CR3_MATCH: |
| if (!vmx_pt_mode_is_host_guest() || |
| !intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_cr3_filtering)) |
| return 1; |
| msr_info->data = vmx->pt_desc.guest.cr3_match; |
| break; |
| case MSR_IA32_RTIT_OUTPUT_BASE: |
| if (!vmx_pt_mode_is_host_guest() || |
| (!intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_topa_output) && |
| !intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_single_range_output))) |
| return 1; |
| msr_info->data = vmx->pt_desc.guest.output_base; |
| break; |
| case MSR_IA32_RTIT_OUTPUT_MASK: |
| if (!vmx_pt_mode_is_host_guest() || |
| (!intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_topa_output) && |
| !intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_single_range_output))) |
| return 1; |
| msr_info->data = vmx->pt_desc.guest.output_mask; |
| break; |
| case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B: |
| index = msr_info->index - MSR_IA32_RTIT_ADDR0_A; |
| if (!vmx_pt_mode_is_host_guest() || |
| (index >= 2 * intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_num_address_ranges))) |
| return 1; |
| if (index % 2) |
| msr_info->data = vmx->pt_desc.guest.addr_b[index / 2]; |
| else |
| msr_info->data = vmx->pt_desc.guest.addr_a[index / 2]; |
| break; |
| case MSR_IA32_DEBUGCTLMSR: |
| msr_info->data = vmcs_read64(GUEST_IA32_DEBUGCTL); |
| break; |
| default: |
| find_uret_msr: |
| msr = vmx_find_uret_msr(vmx, msr_info->index); |
| if (msr) { |
| msr_info->data = msr->data; |
| break; |
| } |
| return kvm_get_msr_common(vcpu, msr_info); |
| } |
| |
| return 0; |
| } |
| |
| static u64 nested_vmx_truncate_sysenter_addr(struct kvm_vcpu *vcpu, |
| u64 data) |
| { |
| #ifdef CONFIG_X86_64 |
| if (!guest_cpuid_has(vcpu, X86_FEATURE_LM)) |
| return (u32)data; |
| #endif |
| return (unsigned long)data; |
| } |
| |
| static u64 vcpu_supported_debugctl(struct kvm_vcpu *vcpu) |
| { |
| u64 debugctl = vmx_supported_debugctl(); |
| |
| if (!intel_pmu_lbr_is_enabled(vcpu)) |
| debugctl &= ~DEBUGCTLMSR_LBR_MASK; |
| |
| if (!guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT)) |
| debugctl &= ~DEBUGCTLMSR_BUS_LOCK_DETECT; |
| |
| return debugctl; |
| } |
| |
| /* |
| * Writes msr value into the appropriate "register". |
| * Returns 0 on success, non-0 otherwise. |
| * Assumes vcpu_load() was already called. |
| */ |
| static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| struct vmx_uret_msr *msr; |
| int ret = 0; |
| u32 msr_index = msr_info->index; |
| u64 data = msr_info->data; |
| u32 index; |
| |
| switch (msr_index) { |
| case MSR_EFER: |
| ret = kvm_set_msr_common(vcpu, msr_info); |
| break; |
| #ifdef CONFIG_X86_64 |
| case MSR_FS_BASE: |
| vmx_segment_cache_clear(vmx); |
| vmcs_writel(GUEST_FS_BASE, data); |
| break; |
| case MSR_GS_BASE: |
| vmx_segment_cache_clear(vmx); |
| vmcs_writel(GUEST_GS_BASE, data); |
| break; |
| case MSR_KERNEL_GS_BASE: |
| vmx_write_guest_kernel_gs_base(vmx, data); |
| break; |
| #endif |
| case MSR_IA32_SYSENTER_CS: |
| if (is_guest_mode(vcpu)) |
| get_vmcs12(vcpu)->guest_sysenter_cs = data; |
| vmcs_write32(GUEST_SYSENTER_CS, data); |
| break; |
| case MSR_IA32_SYSENTER_EIP: |
| if (is_guest_mode(vcpu)) { |
| data = nested_vmx_truncate_sysenter_addr(vcpu, data); |
| get_vmcs12(vcpu)->guest_sysenter_eip = data; |
| } |
| vmcs_writel(GUEST_SYSENTER_EIP, data); |
| break; |
| case MSR_IA32_SYSENTER_ESP: |
| if (is_guest_mode(vcpu)) { |
| data = nested_vmx_truncate_sysenter_addr(vcpu, data); |
| get_vmcs12(vcpu)->guest_sysenter_esp = data; |
| } |
| vmcs_writel(GUEST_SYSENTER_ESP, data); |
| break; |
| case MSR_IA32_DEBUGCTLMSR: { |
| u64 invalid = data & ~vcpu_supported_debugctl(vcpu); |
| if (invalid & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) { |
| if (report_ignored_msrs) |
| vcpu_unimpl(vcpu, "%s: BTF|LBR in IA32_DEBUGCTLMSR 0x%llx, nop\n", |
| __func__, data); |
| data &= ~(DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR); |
| invalid &= ~(DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR); |
| } |
| |
| if (invalid) |
| return 1; |
| |
| if (is_guest_mode(vcpu) && get_vmcs12(vcpu)->vm_exit_controls & |
| VM_EXIT_SAVE_DEBUG_CONTROLS) |
| get_vmcs12(vcpu)->guest_ia32_debugctl = data; |
| |
| vmcs_write64(GUEST_IA32_DEBUGCTL, data); |
| if (intel_pmu_lbr_is_enabled(vcpu) && !to_vmx(vcpu)->lbr_desc.event && |
| (data & DEBUGCTLMSR_LBR)) |
| intel_pmu_create_guest_lbr_event(vcpu); |
| return 0; |
| } |
| case MSR_IA32_BNDCFGS: |
| if (!kvm_mpx_supported() || |
| (!msr_info->host_initiated && |
| !guest_cpuid_has(vcpu, X86_FEATURE_MPX))) |
| return 1; |
| if (is_noncanonical_address(data & PAGE_MASK, vcpu) || |
| (data & MSR_IA32_BNDCFGS_RSVD)) |
| return 1; |
| vmcs_write64(GUEST_BNDCFGS, data); |
| break; |
| case MSR_IA32_UMWAIT_CONTROL: |
| if (!msr_info->host_initiated && !vmx_has_waitpkg(vmx)) |
| return 1; |
| |
| /* The reserved bit 1 and non-32 bit [63:32] should be zero */ |
| if (data & (BIT_ULL(1) | GENMASK_ULL(63, 32))) |
| return 1; |
| |
| vmx->msr_ia32_umwait_control = data; |
| break; |
| case MSR_IA32_SPEC_CTRL: |
| if (!msr_info->host_initiated && |
| !guest_has_spec_ctrl_msr(vcpu)) |
| return 1; |
| |
| if (kvm_spec_ctrl_test_value(data)) |
| return 1; |
| |
| vmx->spec_ctrl = data; |
| if (!data) |
| break; |
| |
| /* |
| * For non-nested: |
| * When it's written (to non-zero) for the first time, pass |
| * it through. |
| * |
| * For nested: |
| * The handling of the MSR bitmap for L2 guests is done in |
| * nested_vmx_prepare_msr_bitmap. We should not touch the |
| * vmcs02.msr_bitmap here since it gets completely overwritten |
| * in the merging. We update the vmcs01 here for L1 as well |
| * since it will end up touching the MSR anyway now. |
| */ |
| vmx_disable_intercept_for_msr(vcpu, |
| MSR_IA32_SPEC_CTRL, |
| MSR_TYPE_RW); |
| break; |
| case MSR_IA32_TSX_CTRL: |
| if (!msr_info->host_initiated && |
| !(vcpu->arch.arch_capabilities & ARCH_CAP_TSX_CTRL_MSR)) |
| return 1; |
| if (data & ~(TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR)) |
| return 1; |
| goto find_uret_msr; |
| case MSR_IA32_PRED_CMD: |
| if (!msr_info->host_initiated && |
| !guest_has_pred_cmd_msr(vcpu)) |
| return 1; |
| |
| if (data & ~PRED_CMD_IBPB) |
| return 1; |
| if (!boot_cpu_has(X86_FEATURE_IBPB)) |
| return 1; |
| if (!data) |
| break; |
| |
| wrmsrl(MSR_IA32_PRED_CMD, PRED_CMD_IBPB); |
| |
| /* |
| * For non-nested: |
| * When it's written (to non-zero) for the first time, pass |
| * it through. |
| * |
| * For nested: |
| * The handling of the MSR bitmap for L2 guests is done in |
| * nested_vmx_prepare_msr_bitmap. We should not touch the |
| * vmcs02.msr_bitmap here since it gets completely overwritten |
| * in the merging. |
| */ |
| vmx_disable_intercept_for_msr(vcpu, MSR_IA32_PRED_CMD, MSR_TYPE_W); |
| break; |
| case MSR_IA32_CR_PAT: |
| if (!kvm_pat_valid(data)) |
| return 1; |
| |
| if (is_guest_mode(vcpu) && |
| get_vmcs12(vcpu)->vm_exit_controls & VM_EXIT_SAVE_IA32_PAT) |
| get_vmcs12(vcpu)->guest_ia32_pat = data; |
| |
| if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { |
| vmcs_write64(GUEST_IA32_PAT, data); |
| vcpu->arch.pat = data; |
| break; |
| } |
| ret = kvm_set_msr_common(vcpu, msr_info); |
| break; |
| case MSR_IA32_TSC_ADJUST: |
| ret = kvm_set_msr_common(vcpu, msr_info); |
| break; |
| case MSR_IA32_MCG_EXT_CTL: |
| if ((!msr_info->host_initiated && |
| !(to_vmx(vcpu)->msr_ia32_feature_control & |
| FEAT_CTL_LMCE_ENABLED)) || |
| (data & ~MCG_EXT_CTL_LMCE_EN)) |
| return 1; |
| vcpu->arch.mcg_ext_ctl = data; |
| break; |
| case MSR_IA32_FEAT_CTL: |
| if (!vmx_feature_control_msr_valid(vcpu, data) || |
| (to_vmx(vcpu)->msr_ia32_feature_control & |
| FEAT_CTL_LOCKED && !msr_info->host_initiated)) |
| return 1; |
| vmx->msr_ia32_feature_control = data; |
| if (msr_info->host_initiated && data == 0) |
| vmx_leave_nested(vcpu); |
| |
| /* SGX may be enabled/disabled by guest's firmware */ |
| vmx_write_encls_bitmap(vcpu, NULL); |
| break; |
| case MSR_IA32_SGXLEPUBKEYHASH0 ... MSR_IA32_SGXLEPUBKEYHASH3: |
| /* |
| * On real hardware, the LE hash MSRs are writable before |
| * the firmware sets bit 0 in MSR 0x7a ("activating" SGX), |
| * at which point SGX related bits in IA32_FEATURE_CONTROL |
| * become writable. |
| * |
| * KVM does not emulate SGX activation for simplicity, so |
| * allow writes to the LE hash MSRs if IA32_FEATURE_CONTROL |
| * is unlocked. This is technically not architectural |
| * behavior, but it's close enough. |
| */ |
| if (!msr_info->host_initiated && |
| (!guest_cpuid_has(vcpu, X86_FEATURE_SGX_LC) || |
| ((vmx->msr_ia32_feature_control & FEAT_CTL_LOCKED) && |
| !(vmx->msr_ia32_feature_control & FEAT_CTL_SGX_LC_ENABLED)))) |
| return 1; |
| vmx->msr_ia32_sgxlepubkeyhash |
| [msr_index - MSR_IA32_SGXLEPUBKEYHASH0] = data; |
| break; |
| case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC: |
| if (!msr_info->host_initiated) |
| return 1; /* they are read-only */ |
| if (!nested_vmx_allowed(vcpu)) |
| return 1; |
| return vmx_set_vmx_msr(vcpu, msr_index, data); |
| case MSR_IA32_RTIT_CTL: |
| if (!vmx_pt_mode_is_host_guest() || |
| vmx_rtit_ctl_check(vcpu, data) || |
| vmx->nested.vmxon) |
| return 1; |
| vmcs_write64(GUEST_IA32_RTIT_CTL, data); |
| vmx->pt_desc.guest.ctl = data; |
| pt_update_intercept_for_msr(vcpu); |
| break; |
| case MSR_IA32_RTIT_STATUS: |
| if (!pt_can_write_msr(vmx)) |
| return 1; |
| if (data & MSR_IA32_RTIT_STATUS_MASK) |
| return 1; |
| vmx->pt_desc.guest.status = data; |
| break; |
| case MSR_IA32_RTIT_CR3_MATCH: |
| if (!pt_can_write_msr(vmx)) |
| return 1; |
| if (!intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_cr3_filtering)) |
| return 1; |
| vmx->pt_desc.guest.cr3_match = data; |
| break; |
| case MSR_IA32_RTIT_OUTPUT_BASE: |
| if (!pt_can_write_msr(vmx)) |
| return 1; |
| if (!intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_topa_output) && |
| !intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_single_range_output)) |
| return 1; |
| if (!pt_output_base_valid(vcpu, data)) |
| return 1; |
| vmx->pt_desc.guest.output_base = data; |
| break; |
| case MSR_IA32_RTIT_OUTPUT_MASK: |
| if (!pt_can_write_msr(vmx)) |
| return 1; |
| if (!intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_topa_output) && |
| !intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_single_range_output)) |
| return 1; |
| vmx->pt_desc.guest.output_mask = data; |
| break; |
| case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B: |
| if (!pt_can_write_msr(vmx)) |
| return 1; |
| index = msr_info->index - MSR_IA32_RTIT_ADDR0_A; |
| if (index >= 2 * intel_pt_validate_cap(vmx->pt_desc.caps, |
| PT_CAP_num_address_ranges)) |
| return 1; |
| if (is_noncanonical_address(data, vcpu)) |
| return 1; |
| if (index % 2) |
| vmx->pt_desc.guest.addr_b[index / 2] = data; |
| else |
| vmx->pt_desc.guest.addr_a[index / 2] = data; |
| break; |
| case MSR_IA32_PERF_CAPABILITIES: |
| if (data && !vcpu_to_pmu(vcpu)->version) |
| return 1; |
| if (data & PMU_CAP_LBR_FMT) { |
| if ((data & PMU_CAP_LBR_FMT) != |
| (vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT)) |
| return 1; |
| if (!intel_pmu_lbr_is_compatible(vcpu)) |
| return 1; |
| } |
| ret = kvm_set_msr_common(vcpu, msr_info); |
| break; |
| |
| default: |
| find_uret_msr: |
| msr = vmx_find_uret_msr(vmx, msr_index); |
| if (msr) |
| ret = vmx_set_guest_uret_msr(vmx, msr, data); |
| else |
| ret = kvm_set_msr_common(vcpu, msr_info); |
| } |
| |
| return ret; |
| } |
| |
| static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) |
| { |
| unsigned long guest_owned_bits; |
| |
| kvm_register_mark_available(vcpu, reg); |
| |
| switch (reg) { |
| case VCPU_REGS_RSP: |
| vcpu->arch.regs[VCPU_REGS_RSP] = vmcs_readl(GUEST_RSP); |
| break; |
| case VCPU_REGS_RIP: |
| vcpu->arch.regs[VCPU_REGS_RIP] = vmcs_readl(GUEST_RIP); |
| break; |
| case VCPU_EXREG_PDPTR: |
| if (enable_ept) |
| ept_save_pdptrs(vcpu); |
| break; |
| case VCPU_EXREG_CR0: |
| guest_owned_bits = vcpu->arch.cr0_guest_owned_bits; |
| |
| vcpu->arch.cr0 &= ~guest_owned_bits; |
| vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & guest_owned_bits; |
| break; |
| case VCPU_EXREG_CR3: |
| /* |
| * When intercepting CR3 loads, e.g. for shadowing paging, KVM's |
| * CR3 is loaded into hardware, not the guest's CR3. |
| */ |
| if (!(exec_controls_get(to_vmx(vcpu)) & CPU_BASED_CR3_LOAD_EXITING)) |
| vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); |
| break; |
| case VCPU_EXREG_CR4: |
| guest_owned_bits = vcpu->arch.cr4_guest_owned_bits; |
| |
| vcpu->arch.cr4 &= ~guest_owned_bits; |
| vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & guest_owned_bits; |
| break; |
| default: |
| KVM_BUG_ON(1, vcpu->kvm); |
| break; |
| } |
| } |
| |
| static __init int cpu_has_kvm_support(void) |
| { |
| return cpu_has_vmx(); |
| } |
| |
| static __init int vmx_disabled_by_bios(void) |
| { |
| return !boot_cpu_has(X86_FEATURE_MSR_IA32_FEAT_CTL) || |
| !boot_cpu_has(X86_FEATURE_VMX); |
| } |
| |
| static int kvm_cpu_vmxon(u64 vmxon_pointer) |
| { |
| u64 msr; |
| |
| cr4_set_bits(X86_CR4_VMXE); |
| |
| asm_volatile_goto("1: vmxon %[vmxon_pointer]\n\t" |
| _ASM_EXTABLE(1b, %l[fault]) |
| : : [vmxon_pointer] "m"(vmxon_pointer) |
| : : fault); |
| return 0; |
| |
| fault: |
| WARN_ONCE(1, "VMXON faulted, MSR_IA32_FEAT_CTL (0x3a) = 0x%llx\n", |
| rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr) ? 0xdeadbeef : msr); |
| cr4_clear_bits(X86_CR4_VMXE); |
| |
| return -EFAULT; |
| } |
| |
| static int hardware_enable(void) |
| { |
| int cpu = raw_smp_processor_id(); |
| u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); |
| int r; |
| |
| if (cr4_read_shadow() & X86_CR4_VMXE) |
| return -EBUSY; |
| |
| /* |
| * This can happen if we hot-added a CPU but failed to allocate |
| * VP assist page for it. |
| */ |
| if (static_branch_unlikely(&enable_evmcs) && |
| !hv_get_vp_assist_page(cpu)) |
| return -EFAULT; |
| |
| intel_pt_handle_vmx(1); |
| |
| r = kvm_cpu_vmxon(phys_addr); |
| if (r) { |
| intel_pt_handle_vmx(0); |
| return r; |
| } |
| |
| if (enable_ept) |
| ept_sync_global(); |
| |
| return 0; |
| } |
| |
| static void vmclear_local_loaded_vmcss(void) |
| { |
| int cpu = raw_smp_processor_id(); |
| struct loaded_vmcs *v, *n; |
| |
| list_for_each_entry_safe(v, n, &per_cpu(loaded_vmcss_on_cpu, cpu), |
| loaded_vmcss_on_cpu_link) |
| __loaded_vmcs_clear(v); |
| } |
| |
| static void hardware_disable(void) |
| { |
| vmclear_local_loaded_vmcss(); |
| |
| if (cpu_vmxoff()) |
| kvm_spurious_fault(); |
| |
| intel_pt_handle_vmx(0); |
| } |
| |
| /* |
| * There is no X86_FEATURE for SGX yet, but anyway we need to query CPUID |
| * directly instead of going through cpu_has(), to ensure KVM is trapping |
| * ENCLS whenever it's supported in hardware. It does not matter whether |
| * the host OS supports or has enabled SGX. |
| */ |
| static bool cpu_has_sgx(void) |
| { |
| return cpuid_eax(0) >= 0x12 && (cpuid_eax(0x12) & BIT(0)); |
| } |
| |
| static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, |
| u32 msr, u32 *result) |
| { |
| u32 vmx_msr_low, vmx_msr_high; |
| u32 ctl = ctl_min | ctl_opt; |
| |
| rdmsr(msr, vmx_msr_low, vmx_msr_high); |
| |
| ctl &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */ |
| ctl |= vmx_msr_low; /* bit == 1 in low word ==> must be one */ |
| |
| /* Ensure minimum (required) set of control bits are supported. */ |
| if (ctl_min & ~ctl) |
| return -EIO; |
| |
| *result = ctl; |
| return 0; |
| } |
| |
| static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, |
| struct vmx_capability *vmx_cap) |
| { |
| u32 vmx_msr_low, vmx_msr_high; |
| u32 min, opt, min2, opt2; |
| u32 _pin_based_exec_control = 0; |
| u32 _cpu_based_exec_control = 0; |
| u32 _cpu_based_2nd_exec_control = 0; |
| u32 _vmexit_control = 0; |
| u32 _vmentry_control = 0; |
| |
| memset(vmcs_conf, 0, sizeof(*vmcs_conf)); |
| min = CPU_BASED_HLT_EXITING | |
| #ifdef CONFIG_X86_64 |
| CPU_BASED_CR8_LOAD_EXITING | |
| CPU_BASED_CR8_STORE_EXITING | |
| #endif |
| CPU_BASED_CR3_LOAD_EXITING | |
| CPU_BASED_CR3_STORE_EXITING | |
| CPU_BASED_UNCOND_IO_EXITING | |
| CPU_BASED_MOV_DR_EXITING | |
| CPU_BASED_USE_TSC_OFFSETTING | |
| CPU_BASED_MWAIT_EXITING | |
| CPU_BASED_MONITOR_EXITING | |
| CPU_BASED_INVLPG_EXITING | |
| CPU_BASED_RDPMC_EXITING; |
| |
| opt = CPU_BASED_TPR_SHADOW | |
| CPU_BASED_USE_MSR_BITMAPS | |
| CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; |
| if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS, |
| &_cpu_based_exec_control) < 0) |
| return -EIO; |
| #ifdef CONFIG_X86_64 |
| if ((_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)) |
| _cpu_based_exec_control &= ~CPU_BASED_CR8_LOAD_EXITING & |
| ~CPU_BASED_CR8_STORE_EXITING; |
| #endif |
| if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) { |
| min2 = 0; |
| opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
| SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | |
| SECONDARY_EXEC_WBINVD_EXITING | |
| SECONDARY_EXEC_ENABLE_VPID | |
| SECONDARY_EXEC_ENABLE_EPT | |
| SECONDARY_EXEC_UNRESTRICTED_GUEST | |
| SECONDARY_EXEC_PAUSE_LOOP_EXITING | |
| SECONDARY_EXEC_DESC | |
| SECONDARY_EXEC_ENABLE_RDTSCP | |
| SECONDARY_EXEC_ENABLE_INVPCID | |
| SECONDARY_EXEC_APIC_REGISTER_VIRT | |
| SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | |
| SECONDARY_EXEC_SHADOW_VMCS | |
| SECONDARY_EXEC_XSAVES | |
| SECONDARY_EXEC_RDSEED_EXITING | |
| SECONDARY_EXEC_RDRAND_EXITING | |
| SECONDARY_EXEC_ENABLE_PML | |
| SECONDARY_EXEC_TSC_SCALING | |
| SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | |
| SECONDARY_EXEC_PT_USE_GPA | |
| SECONDARY_EXEC_PT_CONCEAL_VMX | |
| SECONDARY_EXEC_ENABLE_VMFUNC | |
| SECONDARY_EXEC_BUS_LOCK_DETECTION; |
| if (cpu_has_sgx()) |
| opt2 |= SECONDARY_EXEC_ENCLS_EXITING; |
| if (adjust_vmx_controls(min2, opt2, |
| MSR_IA32_VMX_PROCBASED_CTLS2, |
| &_cpu_based_2nd_exec_control) < 0) |
| return -EIO; |
| } |
| #ifndef CONFIG_X86_64 |
| if (!(_cpu_based_2nd_exec_control & |
| SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) |
| _cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW; |
| #endif |
| |
| if (!(_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)) |
| _cpu_based_2nd_exec_control &= ~( |
| SECONDARY_EXEC_APIC_REGISTER_VIRT | |
| SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | |
| SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY); |
| |
| rdmsr_safe(MSR_IA32_VMX_EPT_VPID_CAP, |
| &vmx_cap->ept, &vmx_cap->vpid); |
| |
| if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) { |
| /* CR3 accesses and invlpg don't need to cause VM Exits when EPT |
| enabled */ |
| _cpu_based_exec_control &= ~(CPU_BASED_CR3_LOAD_EXITING | |
| CPU_BASED_CR3_STORE_EXITING | |
| CPU_BASED_INVLPG_EXITING); |
| } else if (vmx_cap->ept) { |
| vmx_cap->ept = 0; |
| pr_warn_once("EPT CAP should not exist if not support " |
| "1-setting enable EPT VM-execution control\n"); |
| } |
| if (!(_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_VPID) && |
| vmx_cap->vpid) { |
| vmx_cap->vpid = 0; |
| pr_warn_once("VPID CAP should not exist if not support " |
| "1-setting enable VPID VM-execution control\n"); |
| } |
| |
| min = VM_EXIT_SAVE_DEBUG_CONTROLS | VM_EXIT_ACK_INTR_ON_EXIT; |
| #ifdef CONFIG_X86_64 |
| min |= VM_EXIT_HOST_ADDR_SPACE_SIZE; |
| #endif |
| opt = VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | |
| VM_EXIT_LOAD_IA32_PAT | |
| VM_EXIT_LOAD_IA32_EFER | |
| VM_EXIT_CLEAR_BNDCFGS | |
| VM_EXIT_PT_CONCEAL_PIP | |
| VM_EXIT_CLEAR_IA32_RTIT_CTL; |
| if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS, |
| &_vmexit_control) < 0) |
| return -EIO; |
| |
| min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING; |
| opt = PIN_BASED_VIRTUAL_NMIS | PIN_BASED_POSTED_INTR | |
| PIN_BASED_VMX_PREEMPTION_TIMER; |
| if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PINBASED_CTLS, |
| &_pin_based_exec_control) < 0) |
| return -EIO; |
| |
| if (cpu_has_broken_vmx_preemption_timer()) |
| _pin_based_exec_control &= ~PIN_BASED_VMX_PREEMPTION_TIMER; |
| if (!(_cpu_based_2nd_exec_control & |
| SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)) |
| _pin_based_exec_control &= ~PIN_BASED_POSTED_INTR; |
| |
| min = VM_ENTRY_LOAD_DEBUG_CONTROLS; |
| opt = VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | |
| VM_ENTRY_LOAD_IA32_PAT | |
| VM_ENTRY_LOAD_IA32_EFER | |
| VM_ENTRY_LOAD_BNDCFGS | |
| VM_ENTRY_PT_CONCEAL_PIP | |
| VM_ENTRY_LOAD_IA32_RTIT_CTL; |
| if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS, |
| &_vmentry_control) < 0) |
| return -EIO; |
| |
| /* |
| * Some cpus support VM_{ENTRY,EXIT}_IA32_PERF_GLOBAL_CTRL but they |
| * can't be used due to an errata where VM Exit may incorrectly clear |
| * IA32_PERF_GLOBAL_CTRL[34:32]. Workaround the errata by using the |
| * MSR load mechanism to switch IA32_PERF_GLOBAL_CTRL. |
| */ |
| if (boot_cpu_data.x86 == 0x6) { |
| switch (boot_cpu_data.x86_model) { |
| case 26: /* AAK155 */ |
| case 30: /* AAP115 */ |
| case 37: /* AAT100 */ |
| case 44: /* BC86,AAY89,BD102 */ |
| case 46: /* BA97 */ |
| _vmentry_control &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; |
| _vmexit_control &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL; |
| pr_warn_once("kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL " |
| "does not work properly. Using workaround\n"); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| |
| rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high); |
| |
| /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */ |
| if ((vmx_msr_high & 0x1fff) > PAGE_SIZE) |
| return -EIO; |
| |
| #ifdef CONFIG_X86_64 |
| /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */ |
| if (vmx_msr_high & (1u<<16)) |
| return -EIO; |
| #endif |
| |
| /* Require Write-Back (WB) memory type for VMCS accesses. */ |
| if (((vmx_msr_high >> 18) & 15) != 6) |
| return -EIO; |
| |
| vmcs_conf->size = vmx_msr_high & 0x1fff; |
| vmcs_conf->order = get_order(vmcs_conf->size); |
| vmcs_conf->basic_cap = vmx_msr_high & ~0x1fff; |
| |
| vmcs_conf->revision_id = vmx_msr_low; |
| |
| vmcs_conf->pin_based_exec_ctrl = _pin_based_exec_control; |
| vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control; |
| vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control; |
| vmcs_conf->vmexit_ctrl = _vmexit_control; |
| vmcs_conf->vmentry_ctrl = _vmentry_control; |
| |
| #if IS_ENABLED(CONFIG_HYPERV) |
| if (enlightened_vmcs) |
| evmcs_sanitize_exec_ctrls(vmcs_conf); |
| #endif |
| |
| return 0; |
| } |
| |
| struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags) |
| { |
| int node = cpu_to_node(cpu); |
| struct page *pages; |
| struct vmcs *vmcs; |
| |
| pages = __alloc_pages_node(node, flags, vmcs_config.order); |
| if (!pages) |
| return NULL; |
| vmcs = page_address(pages); |
| memset(vmcs, 0, vmcs_config.size); |
| |
| /* KVM supports Enlightened VMCS v1 only */ |
| if (static_branch_unlikely(&enable_evmcs)) |
| vmcs->hdr.revision_id = KVM_EVMCS_VERSION; |
| else |
| vmcs->hdr.revision_id = vmcs_config.revision_id; |
| |
| if (shadow) |
| vmcs->hdr.shadow_vmcs = 1; |
| return vmcs; |
| } |
| |
| void free_vmcs(struct vmcs *vmcs) |
| { |
| free_pages((unsigned long)vmcs, vmcs_config.order); |
| } |
| |
| /* |
| * Free a VMCS, but before that VMCLEAR it on the CPU where it was last loaded |
| */ |
| void free_loaded_vmcs(struct loaded_vmcs *loaded_vmcs) |
| { |
| if (!loaded_vmcs->vmcs) |
| return; |
| loaded_vmcs_clear(loaded_vmcs); |
| free_vmcs(loaded_vmcs->vmcs); |
| loaded_vmcs->vmcs = NULL; |
| if (loaded_vmcs->msr_bitmap) |
| free_page((unsigned long)loaded_vmcs->msr_bitmap); |
| WARN_ON(loaded_vmcs->shadow_vmcs != NULL); |
| } |
| |
| int alloc_loaded_vmcs(struct loaded_vmcs *loaded_vmcs) |
| { |
| loaded_vmcs->vmcs = alloc_vmcs(false); |
| if (!loaded_vmcs->vmcs) |
| return -ENOMEM; |
| |
| vmcs_clear(loaded_vmcs->vmcs); |
| |
| loaded_vmcs->shadow_vmcs = NULL; |
| loaded_vmcs->hv_timer_soft_disabled = false; |
| loaded_vmcs->cpu = -1; |
| loaded_vmcs->launched = 0; |
| |
| if (cpu_has_vmx_msr_bitmap()) { |
| loaded_vmcs->msr_bitmap = (unsigned long *) |
| __get_free_page(GFP_KERNEL_ACCOUNT); |
| if (!loaded_vmcs->msr_bitmap) |
| goto out_vmcs; |
| memset(loaded_vmcs->msr_bitmap, 0xff, PAGE_SIZE); |
| |
| if (IS_ENABLED(CONFIG_HYPERV) && |
| static_branch_unlikely(&enable_evmcs) && |
| (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) { |
| struct hv_enlightened_vmcs *evmcs = |
| (struct hv_enlightened_vmcs *)loaded_vmcs->vmcs; |
| |
| evmcs->hv_enlightenments_control.msr_bitmap = 1; |
| } |
| } |
| |
| memset(&loaded_vmcs->host_state, 0, sizeof(struct vmcs_host_state)); |
| memset(&loaded_vmcs->controls_shadow, 0, |
| sizeof(struct vmcs_controls_shadow)); |
| |
| return 0; |
| |
| out_vmcs: |
| free_loaded_vmcs(loaded_vmcs); |
| return -ENOMEM; |
| } |
| |
| static void free_kvm_area(void) |
| { |
| int cpu; |
| |
| for_each_possible_cpu(cpu) { |
| free_vmcs(per_cpu(vmxarea, cpu)); |
| per_cpu(vmxarea, cpu) = NULL; |
| } |
| } |
| |
| static __init int alloc_kvm_area(void) |
| { |
| int cpu; |
| |
| for_each_possible_cpu(cpu) { |
| struct vmcs *vmcs; |
| |
| vmcs = alloc_vmcs_cpu(false, cpu, GFP_KERNEL); |
| if (!vmcs) { |
| free_kvm_area(); |
| return -ENOMEM; |
| } |
| |
| /* |
| * When eVMCS is enabled, alloc_vmcs_cpu() sets |
| * vmcs->revision_id to KVM_EVMCS_VERSION instead of |
| * revision_id reported by MSR_IA32_VMX_BASIC. |
| * |
| * However, even though not explicitly documented by |
| * TLFS, VMXArea passed as VMXON argument should |
| * still be marked with revision_id reported by |
| * physical CPU. |
| */ |
| if (static_branch_unlikely(&enable_evmcs)) |
| vmcs->hdr.revision_id = vmcs_config.revision_id; |
| |
| per_cpu(vmxarea, cpu) = vmcs; |
| } |
| return 0; |
| } |
| |
| static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg, |
| struct kvm_segment *save) |
| { |
| if (!emulate_invalid_guest_state) { |
| /* |
| * CS and SS RPL should be equal during guest entry according |
| * to VMX spec, but in reality it is not always so. Since vcpu |
| * is in the middle of the transition from real mode to |
| * protected mode it is safe to assume that RPL 0 is a good |
| * default value. |
| */ |
| if (seg == VCPU_SREG_CS || seg == VCPU_SREG_SS) |
| save->selector &= ~SEGMENT_RPL_MASK; |
| save->dpl = save->selector & SEGMENT_RPL_MASK; |
| save->s = 1; |
| } |
| __vmx_set_segment(vcpu, save, seg); |
| } |
| |
| static void enter_pmode(struct kvm_vcpu *vcpu) |
| { |
| unsigned long flags; |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| |
| /* |
| * Update real mode segment cache. It may be not up-to-date if segment |
| * register was written while vcpu was in a guest mode. |
| */ |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_ES], VCPU_SREG_ES); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_FS], VCPU_SREG_FS); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_GS], VCPU_SREG_GS); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_SS], VCPU_SREG_SS); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_CS], VCPU_SREG_CS); |
| |
| vmx->rmode.vm86_active = 0; |
| |
| __vmx_set_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR); |
| |
| flags = vmcs_readl(GUEST_RFLAGS); |
| flags &= RMODE_GUEST_OWNED_EFLAGS_BITS; |
| flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; |
| vmcs_writel(GUEST_RFLAGS, flags); |
| |
| vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | |
| (vmcs_readl(CR4_READ_SHADOW) & X86_CR4_VME)); |
| |
| vmx_update_exception_bitmap(vcpu); |
| |
| fix_pmode_seg(vcpu, VCPU_SREG_CS, &vmx->rmode.segs[VCPU_SREG_CS]); |
| fix_pmode_seg(vcpu, VCPU_SREG_SS, &vmx->rmode.segs[VCPU_SREG_SS]); |
| fix_pmode_seg(vcpu, VCPU_SREG_ES, &vmx->rmode.segs[VCPU_SREG_ES]); |
| fix_pmode_seg(vcpu, VCPU_SREG_DS, &vmx->rmode.segs[VCPU_SREG_DS]); |
| fix_pmode_seg(vcpu, VCPU_SREG_FS, &vmx->rmode.segs[VCPU_SREG_FS]); |
| fix_pmode_seg(vcpu, VCPU_SREG_GS, &vmx->rmode.segs[VCPU_SREG_GS]); |
| } |
| |
| static void fix_rmode_seg(int seg, struct kvm_segment *save) |
| { |
| const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; |
| struct kvm_segment var = *save; |
| |
| var.dpl = 0x3; |
| if (seg == VCPU_SREG_CS) |
| var.type = 0x3; |
| |
| if (!emulate_invalid_guest_state) { |
| var.selector = var.base >> 4; |
| var.base = var.base & 0xffff0; |
| var.limit = 0xffff; |
| var.g = 0; |
| var.db = 0; |
| var.present = 1; |
| var.s = 1; |
| var.l = 0; |
| var.unusable = 0; |
| var.type = 0x3; |
| var.avl = 0; |
| if (save->base & 0xf) |
| printk_once(KERN_WARNING "kvm: segment base is not " |
| "paragraph aligned when entering " |
| "protected mode (seg=%d)", seg); |
| } |
| |
| vmcs_write16(sf->selector, var.selector); |
| vmcs_writel(sf->base, var.base); |
| vmcs_write32(sf->limit, var.limit); |
| vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(&var)); |
| } |
| |
| static void enter_rmode(struct kvm_vcpu *vcpu) |
| { |
| unsigned long flags; |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| struct kvm_vmx *kvm_vmx = to_kvm_vmx(vcpu->kvm); |
| |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_ES], VCPU_SREG_ES); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_FS], VCPU_SREG_FS); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_GS], VCPU_SREG_GS); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_SS], VCPU_SREG_SS); |
| vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_CS], VCPU_SREG_CS); |
| |
| vmx->rmode.vm86_active = 1; |
| |
| /* |
| * Very old userspace does not call KVM_SET_TSS_ADDR before entering |
| * vcpu. Warn the user that an update is overdue. |
| */ |
| if (!kvm_vmx->tss_addr) |
| printk_once(KERN_WARNING "kvm: KVM_SET_TSS_ADDR need to be " |
| "called before entering vcpu\n"); |
| |
| vmx_segment_cache_clear(vmx); |
| |
| vmcs_writel(GUEST_TR_BASE, kvm_vmx->tss_addr); |
| vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1); |
| vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); |
| |
| flags = vmcs_readl(GUEST_RFLAGS); |
| vmx->rmode.save_rflags = flags; |
| |
| flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
| |
| vmcs_writel(GUEST_RFLAGS, flags); |
| vmcs_writel(GUEST_CR4, vmcs_readl(GUEST_CR4) | X86_CR4_VME); |
| vmx_update_exception_bitmap(vcpu); |
| |
| fix_rmode_seg(VCPU_SREG_SS, &vmx->rmode.segs[VCPU_SREG_SS]); |
| fix_rmode_seg(VCPU_SREG_CS, &vmx->rmode.segs[VCPU_SREG_CS]); |
| fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.segs[VCPU_SREG_ES]); |
| fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.segs[VCPU_SREG_DS]); |
| fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.segs[VCPU_SREG_GS]); |
| fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.segs[VCPU_SREG_FS]); |
| } |
| |
| int vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| struct vmx_uret_msr *msr = vmx_find_uret_msr(vmx, MSR_EFER); |
| |
| /* Nothing to do if hardware doesn't support EFER. */ |
| if (!msr) |
| return 0; |
| |
| vcpu->arch.efer = efer; |
| if (efer & EFER_LMA) { |
| vm_entry_controls_setbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE); |
| msr->data = efer; |
| } else { |
| vm_entry_controls_clearbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE); |
| |
| msr->data = efer & ~EFER_LME; |
| } |
| vmx_setup_uret_msrs(vmx); |
| return 0; |
| } |
| |
| #ifdef CONFIG_X86_64 |
| |
| static void enter_lmode(struct kvm_vcpu *vcpu) |
| { |
| u32 guest_tr_ar; |
| |
| vmx_segment_cache_clear(to_vmx(vcpu)); |
| |
| guest_tr_ar = vmcs_read32(GUEST_TR_AR_BYTES); |
| if ((guest_tr_ar & VMX_AR_TYPE_MASK) != VMX_AR_TYPE_BUSY_64_TSS) { |
| pr_debug_ratelimited("%s: tss fixup for long mode. \n", |
| __func__); |
| vmcs_write32(GUEST_TR_AR_BYTES, |
| (guest_tr_ar & ~VMX_AR_TYPE_MASK) |
| | VMX_AR_TYPE_BUSY_64_TSS); |
| } |
| vmx_set_efer(vcpu, vcpu->arch.efer | EFER_LMA); |
| } |
| |
| static void exit_lmode(struct kvm_vcpu *vcpu) |
| { |
| vm_entry_controls_clearbit(to_vmx(vcpu), VM_ENTRY_IA32E_MODE); |
| vmx_set_efer(vcpu, vcpu->arch.efer & ~EFER_LMA); |
| } |
| |
| #endif |
| |
| static void vmx_flush_tlb_all(struct kvm_vcpu *vcpu) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| |
| /* |
| * INVEPT must be issued when EPT is enabled, irrespective of VPID, as |
| * the CPU is not required to invalidate guest-physical mappings on |
| * VM-Entry, even if VPID is disabled. Guest-physical mappings are |
| * associated with the root EPT structure and not any particular VPID |
| * (INVVPID also isn't required to invalidate guest-physical mappings). |
| */ |
| if (enable_ept) { |
| ept_sync_global(); |
| } else if (enable_vpid) { |
| if (cpu_has_vmx_invvpid_global()) { |
| vpid_sync_vcpu_global(); |
| } else { |
| vpid_sync_vcpu_single(vmx->vpid); |
| vpid_sync_vcpu_single(vmx->nested.vpid02); |
| } |
| } |
| } |
| |
| static void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) |
| { |
| struct kvm_mmu *mmu = vcpu->arch.mmu; |
| u64 root_hpa = mmu->root_hpa; |
| |
| /* No flush required if the current context is invalid. */ |
| if (!VALID_PAGE(root_hpa)) |
| return; |
| |
| if (enable_ept) |
| ept_sync_context(construct_eptp(vcpu, root_hpa, |
| mmu->shadow_root_level)); |
| else if (!is_guest_mode(vcpu)) |
| vpid_sync_context(to_vmx(vcpu)->vpid); |
| else |
| vpid_sync_context(nested_get_vpid02(vcpu)); |
| } |
| |
| static void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr) |
| { |
| /* |
| * vpid_sync_vcpu_addr() is a nop if vmx->vpid==0, see the comment in |
| * vmx_flush_tlb_guest() for an explanation of why this is ok. |
| */ |
| vpid_sync_vcpu_addr(to_vmx(vcpu)->vpid, addr); |
| } |
| |
| static void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu) |
| { |
| /* |
| * vpid_sync_context() is a nop if vmx->vpid==0, e.g. if enable_vpid==0 |
| * or a vpid couldn't be allocated for this vCPU. VM-Enter and VM-Exit |
| * are required to flush GVA->{G,H}PA mappings from the TLB if vpid is |
| * disabled (VM-Enter with vpid enabled and vpid==0 is disallowed), |
| * i.e. no explicit INVVPID is necessary. |
| */ |
| vpid_sync_context(to_vmx(vcpu)->vpid); |
| } |
| |
| void vmx_ept_load_pdptrs(struct kvm_vcpu *vcpu) |
| { |
| struct kvm_mmu *mmu = vcpu->arch.walk_mmu; |
| |
| if (!kvm_register_is_dirty(vcpu, VCPU_EXREG_PDPTR)) |
| return; |
| |
| if (is_pae_paging(vcpu)) { |
| vmcs_write64(GUEST_PDPTR0, mmu->pdptrs[0]); |
| vmcs_write64(GUEST_PDPTR1, mmu->pdptrs[1]); |
| vmcs_write64(GUEST_PDPTR2, mmu->pdptrs[2]); |
| vmcs_write64(GUEST_PDPTR3, mmu->pdptrs[3]); |
| } |
| } |
| |
| void ept_save_pdptrs(struct kvm_vcpu *vcpu) |
| { |
| struct kvm_mmu *mmu = vcpu->arch.walk_mmu; |
| |
| if (WARN_ON_ONCE(!is_pae_paging(vcpu))) |
| return; |
| |
| mmu->pdptrs[0] = vmcs_read64(GUEST_PDPTR0); |
| mmu->pdptrs[1] = vmcs_read64(GUEST_PDPTR1); |
| mmu->pdptrs[2] = vmcs_read64(GUEST_PDPTR2); |
| mmu->pdptrs[3] = vmcs_read64(GUEST_PDPTR3); |
| |
| kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR); |
| } |
| |
| #define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \ |
| CPU_BASED_CR3_STORE_EXITING) |
| |
| void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) |
| { |
| struct vcpu_vmx *vmx = to_vmx(vcpu); |
| unsigned long hw_cr0, old_cr0_pg; |
| u32 tmp; |
| |
| old_cr0_pg = kvm_read_cr0_bits(vcpu, X86_CR0_PG); |
| |
| hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF); |
| if (is_unrestricted_guest(vcpu)) |
| hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST; |
| else { |
| hw_cr0 |= KVM_VM_CR0_ALWAYS_ON; |
| if (!enable_ept) |
| hw_cr0 |= X86_CR0_WP; |
| |
| if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE)) |
| enter_pmode(vcpu); |
| |
| if (!vmx->rmode.vm86_active && !(cr0 & X86_CR0_PE)) |
| enter_rmode(vcpu); |
| } |
| |
| vmcs_writel(CR0_READ_SHADOW, cr0); |
| vmcs_writel(GUEST_CR0, hw_cr0); |
| vcpu->arch.cr0 = cr0; |
| kvm_register_mark_available(vcpu, VCPU_EXREG_CR0); |
| |
| #ifdef CONFIG_X86_64 |
| if (vcpu->arch.efer & EFER_LME) { |
| if (!old_cr0_pg && (cr0 & X86_CR0_PG)) |
| enter_lmode(vcpu); |
| else if (old_cr0_pg && !(cr0 & X86_CR0_PG)) |
| exit_lmode(vcpu); |
| } |
| #endif |
| |
| if (enable_ept && !is_unrestricted_guest(vcpu)) { |
| /* |
| * Ensure KVM has an up-to-date snapshot of the guest's CR3. If |
| * the below code _enables_ CR3 exiting, vmx_cache_reg() will |
| * (correctly) stop reading vmcs.GUEST_CR3 because it thinks |
| * KVM's CR3 is installed. |
| */ |
| if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3)) |
| vmx_cache_reg(vcpu, VCPU_EXREG_CR3); |
| |
| /* |
| * When running with EPT but not unrestricted guest, KVM must |
| * intercept CR3 accesses when paging is _disabled_. This is |
| * necessary because restricted guests can't actually run with |
| * paging disabled, and so KVM stuffs its own CR3 in order to |
| * run the guest when identity mapped page tables. |
| * |
| * Do _NOT_ check the old CR0.PG, e.g. to optimize away the |
| * update, it may be stale with respect to CR3 interception, |
| * e.g. after nested VM-Enter. |
| * |
| * Lastly, honor L1's desires, i.e. intercept CR3 loads and/or |
| * stores to forward them to L1, even if KVM does not need to |
| * intercept them to preserve its identity mapped page tables. |
| */ |
| if (!(cr0 & X86_CR0_PG)) { |
| exec_controls_setbit(vmx, CR3_EXITING_BITS); |
| } else if (!is_guest_mode(vcpu)) { |
| exec_controls_clearbit(vmx, CR3_EXITING_BITS); |
| } else { |
| tmp = exec_controls_get(vmx); |
| tmp &= ~CR3_EXITING_BITS; |
| tmp |= get_vmcs12(vcpu)->cpu_based_vm_exec_control & CR3_EXITING_BITS; |
| exec_controls_set(vmx, tmp); |
| } |
| |
| /* Note, vmx_set_cr4() consumes the new vcpu->arch.cr0. */ |
| if ((old_cr0_pg ^ cr0) & X86_CR0_PG) |
| vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); |
| } |
| |
| /* depends on vcpu->arch.cr0 to be set to a new value */ |
| vmx->emulation_required = vmx_emulation_required(vcpu); |
| } |
| |
| static int vmx_get_max_tdp_level(void) |
| { |
| if (cpu_has_vmx_ept_5levels()) |
| return 5; |
| return 4; |
| } |
| |
| u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level) |
| { |
| u64 eptp = VMX_EPTP_MT_WB; |
| |
| eptp |= (root_level == 5) ? VMX_EPTP_PWL_5 : VMX_EPTP_PWL_4; |
| |
| if (enable_ept_ad_bits && |
| (!is_guest_mode(vcpu) || nested_ept_ad_enabled(vcpu))) |
| eptp |= VMX_EPTP_AD_ENABLE_BIT; |
| eptp |= root_hpa; |
| |
| return eptp; |
| } |
| |
| static void vmx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, |
| int root_level) |
| { |
| struct kvm *kvm = vcpu->kvm; |
| bool update_guest_cr3 = true; |
| unsigned long guest_cr3; |
| u64 eptp; |
| |
| if (enable_ept) { |
| eptp = construct_eptp(vcpu, root_hpa, root_level); |
| vmcs_write64(EPT_POINTER, eptp); |
| |
| hv_track_root_tdp(vcpu, root_hpa); |
| |
| if (!enable_unrestricted_guest && !is_paging(vcpu)) |
| guest_cr3 = to_kvm_vmx(kvm)->ept_identity_map_addr; |
| else if (test_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail)) |
| guest_cr3 = vcpu->arch.cr3; |
| else /* vmcs01.GUEST_CR3 is already up-to-date. */ |
| update_guest_cr3 = false; |
| vmx_ept_load_pdptrs(vcpu); |
| } else { |
| guest_cr3 = root_hpa | kvm_get_active_pcid(vcpu); |
| } |
| |
| if (update_guest_cr3)
|