162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/errno.h> 562306a36Sopenharmony_ci#include <linux/smp.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include "../cpuid.h" 862306a36Sopenharmony_ci#include "hyperv.h" 962306a36Sopenharmony_ci#include "nested.h" 1062306a36Sopenharmony_ci#include "vmcs.h" 1162306a36Sopenharmony_ci#include "vmx.h" 1262306a36Sopenharmony_ci#include "trace.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define CC KVM_NESTED_VMENTER_CONSISTENCY_CHECK 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * Enlightened VMCSv1 doesn't support these: 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * POSTED_INTR_NV = 0x00000002, 2062306a36Sopenharmony_ci * GUEST_INTR_STATUS = 0x00000810, 2162306a36Sopenharmony_ci * APIC_ACCESS_ADDR = 0x00002014, 2262306a36Sopenharmony_ci * POSTED_INTR_DESC_ADDR = 0x00002016, 2362306a36Sopenharmony_ci * EOI_EXIT_BITMAP0 = 0x0000201c, 2462306a36Sopenharmony_ci * EOI_EXIT_BITMAP1 = 0x0000201e, 2562306a36Sopenharmony_ci * EOI_EXIT_BITMAP2 = 0x00002020, 2662306a36Sopenharmony_ci * EOI_EXIT_BITMAP3 = 0x00002022, 2762306a36Sopenharmony_ci * GUEST_PML_INDEX = 0x00000812, 2862306a36Sopenharmony_ci * PML_ADDRESS = 0x0000200e, 2962306a36Sopenharmony_ci * VM_FUNCTION_CONTROL = 0x00002018, 3062306a36Sopenharmony_ci * EPTP_LIST_ADDRESS = 0x00002024, 3162306a36Sopenharmony_ci * VMREAD_BITMAP = 0x00002026, 3262306a36Sopenharmony_ci * VMWRITE_BITMAP = 0x00002028, 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci * TSC_MULTIPLIER = 0x00002032, 3562306a36Sopenharmony_ci * PLE_GAP = 0x00004020, 3662306a36Sopenharmony_ci * PLE_WINDOW = 0x00004022, 3762306a36Sopenharmony_ci * VMX_PREEMPTION_TIMER_VALUE = 0x0000482E, 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * Currently unsupported in KVM: 4062306a36Sopenharmony_ci * GUEST_IA32_RTIT_CTL = 0x00002814, 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_ci#define EVMCS1_SUPPORTED_PINCTRL \ 4362306a36Sopenharmony_ci (PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR | \ 4462306a36Sopenharmony_ci PIN_BASED_EXT_INTR_MASK | \ 4562306a36Sopenharmony_ci PIN_BASED_NMI_EXITING | \ 4662306a36Sopenharmony_ci PIN_BASED_VIRTUAL_NMIS) 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#define EVMCS1_SUPPORTED_EXEC_CTRL \ 4962306a36Sopenharmony_ci (CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR | \ 5062306a36Sopenharmony_ci CPU_BASED_HLT_EXITING | \ 5162306a36Sopenharmony_ci CPU_BASED_CR3_LOAD_EXITING | \ 5262306a36Sopenharmony_ci CPU_BASED_CR3_STORE_EXITING | \ 5362306a36Sopenharmony_ci CPU_BASED_UNCOND_IO_EXITING | \ 5462306a36Sopenharmony_ci CPU_BASED_MOV_DR_EXITING | \ 5562306a36Sopenharmony_ci CPU_BASED_USE_TSC_OFFSETTING | \ 5662306a36Sopenharmony_ci CPU_BASED_MWAIT_EXITING | \ 5762306a36Sopenharmony_ci CPU_BASED_MONITOR_EXITING | \ 5862306a36Sopenharmony_ci CPU_BASED_INVLPG_EXITING | \ 5962306a36Sopenharmony_ci CPU_BASED_RDPMC_EXITING | \ 6062306a36Sopenharmony_ci CPU_BASED_INTR_WINDOW_EXITING | \ 6162306a36Sopenharmony_ci CPU_BASED_CR8_LOAD_EXITING | \ 6262306a36Sopenharmony_ci CPU_BASED_CR8_STORE_EXITING | \ 6362306a36Sopenharmony_ci CPU_BASED_RDTSC_EXITING | \ 6462306a36Sopenharmony_ci CPU_BASED_TPR_SHADOW | \ 6562306a36Sopenharmony_ci CPU_BASED_USE_IO_BITMAPS | \ 6662306a36Sopenharmony_ci CPU_BASED_MONITOR_TRAP_FLAG | \ 6762306a36Sopenharmony_ci CPU_BASED_USE_MSR_BITMAPS | \ 6862306a36Sopenharmony_ci CPU_BASED_NMI_WINDOW_EXITING | \ 6962306a36Sopenharmony_ci CPU_BASED_PAUSE_EXITING | \ 7062306a36Sopenharmony_ci CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define EVMCS1_SUPPORTED_2NDEXEC \ 7362306a36Sopenharmony_ci (SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | \ 7462306a36Sopenharmony_ci SECONDARY_EXEC_WBINVD_EXITING | \ 7562306a36Sopenharmony_ci SECONDARY_EXEC_ENABLE_VPID | \ 7662306a36Sopenharmony_ci SECONDARY_EXEC_ENABLE_EPT | \ 7762306a36Sopenharmony_ci SECONDARY_EXEC_UNRESTRICTED_GUEST | \ 7862306a36Sopenharmony_ci SECONDARY_EXEC_DESC | \ 7962306a36Sopenharmony_ci SECONDARY_EXEC_ENABLE_RDTSCP | \ 8062306a36Sopenharmony_ci SECONDARY_EXEC_ENABLE_INVPCID | \ 8162306a36Sopenharmony_ci SECONDARY_EXEC_ENABLE_XSAVES | \ 8262306a36Sopenharmony_ci SECONDARY_EXEC_RDSEED_EXITING | \ 8362306a36Sopenharmony_ci SECONDARY_EXEC_RDRAND_EXITING | \ 8462306a36Sopenharmony_ci SECONDARY_EXEC_TSC_SCALING | \ 8562306a36Sopenharmony_ci SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | \ 8662306a36Sopenharmony_ci SECONDARY_EXEC_PT_USE_GPA | \ 8762306a36Sopenharmony_ci SECONDARY_EXEC_PT_CONCEAL_VMX | \ 8862306a36Sopenharmony_ci SECONDARY_EXEC_BUS_LOCK_DETECTION | \ 8962306a36Sopenharmony_ci SECONDARY_EXEC_NOTIFY_VM_EXITING | \ 9062306a36Sopenharmony_ci SECONDARY_EXEC_ENCLS_EXITING) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define EVMCS1_SUPPORTED_3RDEXEC (0ULL) 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci#define EVMCS1_SUPPORTED_VMEXIT_CTRL \ 9562306a36Sopenharmony_ci (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | \ 9662306a36Sopenharmony_ci VM_EXIT_SAVE_DEBUG_CONTROLS | \ 9762306a36Sopenharmony_ci VM_EXIT_ACK_INTR_ON_EXIT | \ 9862306a36Sopenharmony_ci VM_EXIT_HOST_ADDR_SPACE_SIZE | \ 9962306a36Sopenharmony_ci VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \ 10062306a36Sopenharmony_ci VM_EXIT_SAVE_IA32_PAT | \ 10162306a36Sopenharmony_ci VM_EXIT_LOAD_IA32_PAT | \ 10262306a36Sopenharmony_ci VM_EXIT_SAVE_IA32_EFER | \ 10362306a36Sopenharmony_ci VM_EXIT_LOAD_IA32_EFER | \ 10462306a36Sopenharmony_ci VM_EXIT_CLEAR_BNDCFGS | \ 10562306a36Sopenharmony_ci VM_EXIT_PT_CONCEAL_PIP | \ 10662306a36Sopenharmony_ci VM_EXIT_CLEAR_IA32_RTIT_CTL) 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#define EVMCS1_SUPPORTED_VMENTRY_CTRL \ 10962306a36Sopenharmony_ci (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | \ 11062306a36Sopenharmony_ci VM_ENTRY_LOAD_DEBUG_CONTROLS | \ 11162306a36Sopenharmony_ci VM_ENTRY_IA32E_MODE | \ 11262306a36Sopenharmony_ci VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | \ 11362306a36Sopenharmony_ci VM_ENTRY_LOAD_IA32_PAT | \ 11462306a36Sopenharmony_ci VM_ENTRY_LOAD_IA32_EFER | \ 11562306a36Sopenharmony_ci VM_ENTRY_LOAD_BNDCFGS | \ 11662306a36Sopenharmony_ci VM_ENTRY_PT_CONCEAL_PIP | \ 11762306a36Sopenharmony_ci VM_ENTRY_LOAD_IA32_RTIT_CTL) 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#define EVMCS1_SUPPORTED_VMFUNC (0) 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci#define EVMCS1_OFFSET(x) offsetof(struct hv_enlightened_vmcs, x) 12262306a36Sopenharmony_ci#define EVMCS1_FIELD(number, name, clean_field)[ROL16(number, 6)] = \ 12362306a36Sopenharmony_ci {EVMCS1_OFFSET(name), clean_field} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ciconst struct evmcs_field vmcs_field_to_evmcs_1[] = { 12662306a36Sopenharmony_ci /* 64 bit rw */ 12762306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_RIP, guest_rip, 12862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 12962306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_RSP, guest_rsp, 13062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC), 13162306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_RFLAGS, guest_rflags, 13262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC), 13362306a36Sopenharmony_ci EVMCS1_FIELD(HOST_IA32_PAT, host_ia32_pat, 13462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 13562306a36Sopenharmony_ci EVMCS1_FIELD(HOST_IA32_EFER, host_ia32_efer, 13662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 13762306a36Sopenharmony_ci EVMCS1_FIELD(HOST_IA32_PERF_GLOBAL_CTRL, host_ia32_perf_global_ctrl, 13862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 13962306a36Sopenharmony_ci EVMCS1_FIELD(HOST_CR0, host_cr0, 14062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 14162306a36Sopenharmony_ci EVMCS1_FIELD(HOST_CR3, host_cr3, 14262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 14362306a36Sopenharmony_ci EVMCS1_FIELD(HOST_CR4, host_cr4, 14462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 14562306a36Sopenharmony_ci EVMCS1_FIELD(HOST_IA32_SYSENTER_ESP, host_ia32_sysenter_esp, 14662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 14762306a36Sopenharmony_ci EVMCS1_FIELD(HOST_IA32_SYSENTER_EIP, host_ia32_sysenter_eip, 14862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 14962306a36Sopenharmony_ci EVMCS1_FIELD(HOST_RIP, host_rip, 15062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 15162306a36Sopenharmony_ci EVMCS1_FIELD(IO_BITMAP_A, io_bitmap_a, 15262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_IO_BITMAP), 15362306a36Sopenharmony_ci EVMCS1_FIELD(IO_BITMAP_B, io_bitmap_b, 15462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_IO_BITMAP), 15562306a36Sopenharmony_ci EVMCS1_FIELD(MSR_BITMAP, msr_bitmap, 15662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP), 15762306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_ES_BASE, guest_es_base, 15862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 15962306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_CS_BASE, guest_cs_base, 16062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 16162306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_SS_BASE, guest_ss_base, 16262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 16362306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_DS_BASE, guest_ds_base, 16462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 16562306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_FS_BASE, guest_fs_base, 16662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 16762306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_GS_BASE, guest_gs_base, 16862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 16962306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_LDTR_BASE, guest_ldtr_base, 17062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 17162306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_TR_BASE, guest_tr_base, 17262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 17362306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_GDTR_BASE, guest_gdtr_base, 17462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 17562306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_IDTR_BASE, guest_idtr_base, 17662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 17762306a36Sopenharmony_ci EVMCS1_FIELD(TSC_OFFSET, tsc_offset, 17862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP2), 17962306a36Sopenharmony_ci EVMCS1_FIELD(VIRTUAL_APIC_PAGE_ADDR, virtual_apic_page_addr, 18062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP2), 18162306a36Sopenharmony_ci EVMCS1_FIELD(VMCS_LINK_POINTER, vmcs_link_pointer, 18262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 18362306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_IA32_DEBUGCTL, guest_ia32_debugctl, 18462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 18562306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_IA32_PAT, guest_ia32_pat, 18662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 18762306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_IA32_EFER, guest_ia32_efer, 18862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 18962306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_IA32_PERF_GLOBAL_CTRL, guest_ia32_perf_global_ctrl, 19062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 19162306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_PDPTR0, guest_pdptr0, 19262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 19362306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_PDPTR1, guest_pdptr1, 19462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 19562306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_PDPTR2, guest_pdptr2, 19662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 19762306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_PDPTR3, guest_pdptr3, 19862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 19962306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_PENDING_DBG_EXCEPTIONS, guest_pending_dbg_exceptions, 20062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 20162306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_SYSENTER_ESP, guest_sysenter_esp, 20262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 20362306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_SYSENTER_EIP, guest_sysenter_eip, 20462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 20562306a36Sopenharmony_ci EVMCS1_FIELD(CR0_GUEST_HOST_MASK, cr0_guest_host_mask, 20662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR), 20762306a36Sopenharmony_ci EVMCS1_FIELD(CR4_GUEST_HOST_MASK, cr4_guest_host_mask, 20862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR), 20962306a36Sopenharmony_ci EVMCS1_FIELD(CR0_READ_SHADOW, cr0_read_shadow, 21062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR), 21162306a36Sopenharmony_ci EVMCS1_FIELD(CR4_READ_SHADOW, cr4_read_shadow, 21262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR), 21362306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_CR0, guest_cr0, 21462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR), 21562306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_CR3, guest_cr3, 21662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR), 21762306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_CR4, guest_cr4, 21862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR), 21962306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_DR7, guest_dr7, 22062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR), 22162306a36Sopenharmony_ci EVMCS1_FIELD(HOST_FS_BASE, host_fs_base, 22262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER), 22362306a36Sopenharmony_ci EVMCS1_FIELD(HOST_GS_BASE, host_gs_base, 22462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER), 22562306a36Sopenharmony_ci EVMCS1_FIELD(HOST_TR_BASE, host_tr_base, 22662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER), 22762306a36Sopenharmony_ci EVMCS1_FIELD(HOST_GDTR_BASE, host_gdtr_base, 22862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER), 22962306a36Sopenharmony_ci EVMCS1_FIELD(HOST_IDTR_BASE, host_idtr_base, 23062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER), 23162306a36Sopenharmony_ci EVMCS1_FIELD(HOST_RSP, host_rsp, 23262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER), 23362306a36Sopenharmony_ci EVMCS1_FIELD(EPT_POINTER, ept_pointer, 23462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_XLAT), 23562306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_BNDCFGS, guest_bndcfgs, 23662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 23762306a36Sopenharmony_ci EVMCS1_FIELD(XSS_EXIT_BITMAP, xss_exit_bitmap, 23862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP2), 23962306a36Sopenharmony_ci EVMCS1_FIELD(ENCLS_EXITING_BITMAP, encls_exiting_bitmap, 24062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP2), 24162306a36Sopenharmony_ci EVMCS1_FIELD(TSC_MULTIPLIER, tsc_multiplier, 24262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP2), 24362306a36Sopenharmony_ci /* 24462306a36Sopenharmony_ci * Not used by KVM: 24562306a36Sopenharmony_ci * 24662306a36Sopenharmony_ci * EVMCS1_FIELD(0x00006828, guest_ia32_s_cet, 24762306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 24862306a36Sopenharmony_ci * EVMCS1_FIELD(0x0000682A, guest_ssp, 24962306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC), 25062306a36Sopenharmony_ci * EVMCS1_FIELD(0x0000682C, guest_ia32_int_ssp_table_addr, 25162306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 25262306a36Sopenharmony_ci * EVMCS1_FIELD(0x00002816, guest_ia32_lbr_ctl, 25362306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 25462306a36Sopenharmony_ci * EVMCS1_FIELD(0x00006C18, host_ia32_s_cet, 25562306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 25662306a36Sopenharmony_ci * EVMCS1_FIELD(0x00006C1A, host_ssp, 25762306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 25862306a36Sopenharmony_ci * EVMCS1_FIELD(0x00006C1C, host_ia32_int_ssp_table_addr, 25962306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 26062306a36Sopenharmony_ci */ 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci /* 64 bit read only */ 26362306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_PHYSICAL_ADDRESS, guest_physical_address, 26462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 26562306a36Sopenharmony_ci EVMCS1_FIELD(EXIT_QUALIFICATION, exit_qualification, 26662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 26762306a36Sopenharmony_ci /* 26862306a36Sopenharmony_ci * Not defined in KVM: 26962306a36Sopenharmony_ci * 27062306a36Sopenharmony_ci * EVMCS1_FIELD(0x00006402, exit_io_instruction_ecx, 27162306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE); 27262306a36Sopenharmony_ci * EVMCS1_FIELD(0x00006404, exit_io_instruction_esi, 27362306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE); 27462306a36Sopenharmony_ci * EVMCS1_FIELD(0x00006406, exit_io_instruction_esi, 27562306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE); 27662306a36Sopenharmony_ci * EVMCS1_FIELD(0x00006408, exit_io_instruction_eip, 27762306a36Sopenharmony_ci * HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE); 27862306a36Sopenharmony_ci */ 27962306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_LINEAR_ADDRESS, guest_linear_address, 28062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci /* 28362306a36Sopenharmony_ci * No mask defined in the spec as Hyper-V doesn't currently support 28462306a36Sopenharmony_ci * these. Future proof by resetting the whole clean field mask on 28562306a36Sopenharmony_ci * access. 28662306a36Sopenharmony_ci */ 28762306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_MSR_STORE_ADDR, vm_exit_msr_store_addr, 28862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 28962306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_MSR_LOAD_ADDR, vm_exit_msr_load_addr, 29062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 29162306a36Sopenharmony_ci EVMCS1_FIELD(VM_ENTRY_MSR_LOAD_ADDR, vm_entry_msr_load_addr, 29262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* 32 bit rw */ 29562306a36Sopenharmony_ci EVMCS1_FIELD(TPR_THRESHOLD, tpr_threshold, 29662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 29762306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_INTERRUPTIBILITY_INFO, guest_interruptibility_info, 29862306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC), 29962306a36Sopenharmony_ci EVMCS1_FIELD(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control, 30062306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC), 30162306a36Sopenharmony_ci EVMCS1_FIELD(EXCEPTION_BITMAP, exception_bitmap, 30262306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EXCPN), 30362306a36Sopenharmony_ci EVMCS1_FIELD(VM_ENTRY_CONTROLS, vm_entry_controls, 30462306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_ENTRY), 30562306a36Sopenharmony_ci EVMCS1_FIELD(VM_ENTRY_INTR_INFO_FIELD, vm_entry_intr_info_field, 30662306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT), 30762306a36Sopenharmony_ci EVMCS1_FIELD(VM_ENTRY_EXCEPTION_ERROR_CODE, 30862306a36Sopenharmony_ci vm_entry_exception_error_code, 30962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT), 31062306a36Sopenharmony_ci EVMCS1_FIELD(VM_ENTRY_INSTRUCTION_LEN, vm_entry_instruction_len, 31162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT), 31262306a36Sopenharmony_ci EVMCS1_FIELD(HOST_IA32_SYSENTER_CS, host_ia32_sysenter_cs, 31362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 31462306a36Sopenharmony_ci EVMCS1_FIELD(PIN_BASED_VM_EXEC_CONTROL, pin_based_vm_exec_control, 31562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP1), 31662306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_CONTROLS, vm_exit_controls, 31762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP1), 31862306a36Sopenharmony_ci EVMCS1_FIELD(SECONDARY_VM_EXEC_CONTROL, secondary_vm_exec_control, 31962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP1), 32062306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_ES_LIMIT, guest_es_limit, 32162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 32262306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_CS_LIMIT, guest_cs_limit, 32362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 32462306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_SS_LIMIT, guest_ss_limit, 32562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 32662306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_DS_LIMIT, guest_ds_limit, 32762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 32862306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_FS_LIMIT, guest_fs_limit, 32962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 33062306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_GS_LIMIT, guest_gs_limit, 33162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 33262306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_LDTR_LIMIT, guest_ldtr_limit, 33362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 33462306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_TR_LIMIT, guest_tr_limit, 33562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 33662306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_GDTR_LIMIT, guest_gdtr_limit, 33762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 33862306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_IDTR_LIMIT, guest_idtr_limit, 33962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 34062306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_ES_AR_BYTES, guest_es_ar_bytes, 34162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 34262306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_CS_AR_BYTES, guest_cs_ar_bytes, 34362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 34462306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_SS_AR_BYTES, guest_ss_ar_bytes, 34562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 34662306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_DS_AR_BYTES, guest_ds_ar_bytes, 34762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 34862306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_FS_AR_BYTES, guest_fs_ar_bytes, 34962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 35062306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_GS_AR_BYTES, guest_gs_ar_bytes, 35162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 35262306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_LDTR_AR_BYTES, guest_ldtr_ar_bytes, 35362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 35462306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_TR_AR_BYTES, guest_tr_ar_bytes, 35562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 35662306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_ACTIVITY_STATE, guest_activity_state, 35762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 35862306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_SYSENTER_CS, guest_sysenter_cs, 35962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1), 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci /* 32 bit read only */ 36262306a36Sopenharmony_ci EVMCS1_FIELD(VM_INSTRUCTION_ERROR, vm_instruction_error, 36362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 36462306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_REASON, vm_exit_reason, 36562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 36662306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_INTR_INFO, vm_exit_intr_info, 36762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 36862306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_INTR_ERROR_CODE, vm_exit_intr_error_code, 36962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 37062306a36Sopenharmony_ci EVMCS1_FIELD(IDT_VECTORING_INFO_FIELD, idt_vectoring_info_field, 37162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 37262306a36Sopenharmony_ci EVMCS1_FIELD(IDT_VECTORING_ERROR_CODE, idt_vectoring_error_code, 37362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 37462306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_INSTRUCTION_LEN, vm_exit_instruction_len, 37562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 37662306a36Sopenharmony_ci EVMCS1_FIELD(VMX_INSTRUCTION_INFO, vmx_instruction_info, 37762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE), 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci /* No mask defined in the spec (not used) */ 38062306a36Sopenharmony_ci EVMCS1_FIELD(PAGE_FAULT_ERROR_CODE_MASK, page_fault_error_code_mask, 38162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 38262306a36Sopenharmony_ci EVMCS1_FIELD(PAGE_FAULT_ERROR_CODE_MATCH, page_fault_error_code_match, 38362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 38462306a36Sopenharmony_ci EVMCS1_FIELD(CR3_TARGET_COUNT, cr3_target_count, 38562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 38662306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_MSR_STORE_COUNT, vm_exit_msr_store_count, 38762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 38862306a36Sopenharmony_ci EVMCS1_FIELD(VM_EXIT_MSR_LOAD_COUNT, vm_exit_msr_load_count, 38962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 39062306a36Sopenharmony_ci EVMCS1_FIELD(VM_ENTRY_MSR_LOAD_COUNT, vm_entry_msr_load_count, 39162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL), 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci /* 16 bit rw */ 39462306a36Sopenharmony_ci EVMCS1_FIELD(HOST_ES_SELECTOR, host_es_selector, 39562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 39662306a36Sopenharmony_ci EVMCS1_FIELD(HOST_CS_SELECTOR, host_cs_selector, 39762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 39862306a36Sopenharmony_ci EVMCS1_FIELD(HOST_SS_SELECTOR, host_ss_selector, 39962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 40062306a36Sopenharmony_ci EVMCS1_FIELD(HOST_DS_SELECTOR, host_ds_selector, 40162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 40262306a36Sopenharmony_ci EVMCS1_FIELD(HOST_FS_SELECTOR, host_fs_selector, 40362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 40462306a36Sopenharmony_ci EVMCS1_FIELD(HOST_GS_SELECTOR, host_gs_selector, 40562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 40662306a36Sopenharmony_ci EVMCS1_FIELD(HOST_TR_SELECTOR, host_tr_selector, 40762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1), 40862306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_ES_SELECTOR, guest_es_selector, 40962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 41062306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_CS_SELECTOR, guest_cs_selector, 41162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 41262306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_SS_SELECTOR, guest_ss_selector, 41362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 41462306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_DS_SELECTOR, guest_ds_selector, 41562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 41662306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_FS_SELECTOR, guest_fs_selector, 41762306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 41862306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_GS_SELECTOR, guest_gs_selector, 41962306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 42062306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_LDTR_SELECTOR, guest_ldtr_selector, 42162306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 42262306a36Sopenharmony_ci EVMCS1_FIELD(GUEST_TR_SELECTOR, guest_tr_selector, 42362306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2), 42462306a36Sopenharmony_ci EVMCS1_FIELD(VIRTUAL_PROCESSOR_ID, virtual_processor_id, 42562306a36Sopenharmony_ci HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_XLAT), 42662306a36Sopenharmony_ci}; 42762306a36Sopenharmony_ciconst unsigned int nr_evmcs_1_fields = ARRAY_SIZE(vmcs_field_to_evmcs_1); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ciu64 nested_get_evmptr(struct kvm_vcpu *vcpu) 43062306a36Sopenharmony_ci{ 43162306a36Sopenharmony_ci struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci if (unlikely(kvm_hv_get_assist_page(vcpu))) 43462306a36Sopenharmony_ci return EVMPTR_INVALID; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci if (unlikely(!hv_vcpu->vp_assist_page.enlighten_vmentry)) 43762306a36Sopenharmony_ci return EVMPTR_INVALID; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci return hv_vcpu->vp_assist_page.current_nested_vmcs; 44062306a36Sopenharmony_ci} 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ciuint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu) 44362306a36Sopenharmony_ci{ 44462306a36Sopenharmony_ci /* 44562306a36Sopenharmony_ci * vmcs_version represents the range of supported Enlightened VMCS 44662306a36Sopenharmony_ci * versions: lower 8 bits is the minimal version, higher 8 bits is the 44762306a36Sopenharmony_ci * maximum supported version. KVM supports versions from 1 to 44862306a36Sopenharmony_ci * KVM_EVMCS_VERSION. 44962306a36Sopenharmony_ci * 45062306a36Sopenharmony_ci * Note, do not check the Hyper-V is fully enabled in guest CPUID, this 45162306a36Sopenharmony_ci * helper is used to _get_ the vCPU's supported CPUID. 45262306a36Sopenharmony_ci */ 45362306a36Sopenharmony_ci if (kvm_cpu_cap_get(X86_FEATURE_VMX) && 45462306a36Sopenharmony_ci (!vcpu || to_vmx(vcpu)->nested.enlightened_vmcs_enabled)) 45562306a36Sopenharmony_ci return (KVM_EVMCS_VERSION << 8) | 1; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci return 0; 45862306a36Sopenharmony_ci} 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_cienum evmcs_revision { 46162306a36Sopenharmony_ci EVMCSv1_LEGACY, 46262306a36Sopenharmony_ci NR_EVMCS_REVISIONS, 46362306a36Sopenharmony_ci}; 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_cienum evmcs_ctrl_type { 46662306a36Sopenharmony_ci EVMCS_EXIT_CTRLS, 46762306a36Sopenharmony_ci EVMCS_ENTRY_CTRLS, 46862306a36Sopenharmony_ci EVMCS_EXEC_CTRL, 46962306a36Sopenharmony_ci EVMCS_2NDEXEC, 47062306a36Sopenharmony_ci EVMCS_3RDEXEC, 47162306a36Sopenharmony_ci EVMCS_PINCTRL, 47262306a36Sopenharmony_ci EVMCS_VMFUNC, 47362306a36Sopenharmony_ci NR_EVMCS_CTRLS, 47462306a36Sopenharmony_ci}; 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_cistatic const u32 evmcs_supported_ctrls[NR_EVMCS_CTRLS][NR_EVMCS_REVISIONS] = { 47762306a36Sopenharmony_ci [EVMCS_EXIT_CTRLS] = { 47862306a36Sopenharmony_ci [EVMCSv1_LEGACY] = EVMCS1_SUPPORTED_VMEXIT_CTRL, 47962306a36Sopenharmony_ci }, 48062306a36Sopenharmony_ci [EVMCS_ENTRY_CTRLS] = { 48162306a36Sopenharmony_ci [EVMCSv1_LEGACY] = EVMCS1_SUPPORTED_VMENTRY_CTRL, 48262306a36Sopenharmony_ci }, 48362306a36Sopenharmony_ci [EVMCS_EXEC_CTRL] = { 48462306a36Sopenharmony_ci [EVMCSv1_LEGACY] = EVMCS1_SUPPORTED_EXEC_CTRL, 48562306a36Sopenharmony_ci }, 48662306a36Sopenharmony_ci [EVMCS_2NDEXEC] = { 48762306a36Sopenharmony_ci [EVMCSv1_LEGACY] = EVMCS1_SUPPORTED_2NDEXEC & ~SECONDARY_EXEC_TSC_SCALING, 48862306a36Sopenharmony_ci }, 48962306a36Sopenharmony_ci [EVMCS_3RDEXEC] = { 49062306a36Sopenharmony_ci [EVMCSv1_LEGACY] = EVMCS1_SUPPORTED_3RDEXEC, 49162306a36Sopenharmony_ci }, 49262306a36Sopenharmony_ci [EVMCS_PINCTRL] = { 49362306a36Sopenharmony_ci [EVMCSv1_LEGACY] = EVMCS1_SUPPORTED_PINCTRL, 49462306a36Sopenharmony_ci }, 49562306a36Sopenharmony_ci [EVMCS_VMFUNC] = { 49662306a36Sopenharmony_ci [EVMCSv1_LEGACY] = EVMCS1_SUPPORTED_VMFUNC, 49762306a36Sopenharmony_ci }, 49862306a36Sopenharmony_ci}; 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_cistatic u32 evmcs_get_supported_ctls(enum evmcs_ctrl_type ctrl_type) 50162306a36Sopenharmony_ci{ 50262306a36Sopenharmony_ci enum evmcs_revision evmcs_rev = EVMCSv1_LEGACY; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci return evmcs_supported_ctrls[ctrl_type][evmcs_rev]; 50562306a36Sopenharmony_ci} 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_cistatic bool evmcs_has_perf_global_ctrl(struct kvm_vcpu *vcpu) 50862306a36Sopenharmony_ci{ 50962306a36Sopenharmony_ci struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci /* 51262306a36Sopenharmony_ci * PERF_GLOBAL_CTRL has a quirk where some Windows guests may fail to 51362306a36Sopenharmony_ci * boot if a PV CPUID feature flag is not also set. Treat the fields 51462306a36Sopenharmony_ci * as unsupported if the flag is not set in guest CPUID. This should 51562306a36Sopenharmony_ci * be called only for guest accesses, and all guest accesses should be 51662306a36Sopenharmony_ci * gated on Hyper-V being enabled and initialized. 51762306a36Sopenharmony_ci */ 51862306a36Sopenharmony_ci if (WARN_ON_ONCE(!hv_vcpu)) 51962306a36Sopenharmony_ci return false; 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci return hv_vcpu->cpuid_cache.nested_ebx & HV_X64_NESTED_EVMCS1_PERF_GLOBAL_CTRL; 52262306a36Sopenharmony_ci} 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_civoid nested_evmcs_filter_control_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) 52562306a36Sopenharmony_ci{ 52662306a36Sopenharmony_ci u32 ctl_low = (u32)*pdata; 52762306a36Sopenharmony_ci u32 ctl_high = (u32)(*pdata >> 32); 52862306a36Sopenharmony_ci u32 supported_ctrls; 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci /* 53162306a36Sopenharmony_ci * Hyper-V 2016 and 2019 try using these features even when eVMCS 53262306a36Sopenharmony_ci * is enabled but there are no corresponding fields. 53362306a36Sopenharmony_ci */ 53462306a36Sopenharmony_ci switch (msr_index) { 53562306a36Sopenharmony_ci case MSR_IA32_VMX_EXIT_CTLS: 53662306a36Sopenharmony_ci case MSR_IA32_VMX_TRUE_EXIT_CTLS: 53762306a36Sopenharmony_ci supported_ctrls = evmcs_get_supported_ctls(EVMCS_EXIT_CTRLS); 53862306a36Sopenharmony_ci if (!evmcs_has_perf_global_ctrl(vcpu)) 53962306a36Sopenharmony_ci supported_ctrls &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL; 54062306a36Sopenharmony_ci ctl_high &= supported_ctrls; 54162306a36Sopenharmony_ci break; 54262306a36Sopenharmony_ci case MSR_IA32_VMX_ENTRY_CTLS: 54362306a36Sopenharmony_ci case MSR_IA32_VMX_TRUE_ENTRY_CTLS: 54462306a36Sopenharmony_ci supported_ctrls = evmcs_get_supported_ctls(EVMCS_ENTRY_CTRLS); 54562306a36Sopenharmony_ci if (!evmcs_has_perf_global_ctrl(vcpu)) 54662306a36Sopenharmony_ci supported_ctrls &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; 54762306a36Sopenharmony_ci ctl_high &= supported_ctrls; 54862306a36Sopenharmony_ci break; 54962306a36Sopenharmony_ci case MSR_IA32_VMX_PROCBASED_CTLS: 55062306a36Sopenharmony_ci case MSR_IA32_VMX_TRUE_PROCBASED_CTLS: 55162306a36Sopenharmony_ci ctl_high &= evmcs_get_supported_ctls(EVMCS_EXEC_CTRL); 55262306a36Sopenharmony_ci break; 55362306a36Sopenharmony_ci case MSR_IA32_VMX_PROCBASED_CTLS2: 55462306a36Sopenharmony_ci ctl_high &= evmcs_get_supported_ctls(EVMCS_2NDEXEC); 55562306a36Sopenharmony_ci break; 55662306a36Sopenharmony_ci case MSR_IA32_VMX_TRUE_PINBASED_CTLS: 55762306a36Sopenharmony_ci case MSR_IA32_VMX_PINBASED_CTLS: 55862306a36Sopenharmony_ci ctl_high &= evmcs_get_supported_ctls(EVMCS_PINCTRL); 55962306a36Sopenharmony_ci break; 56062306a36Sopenharmony_ci case MSR_IA32_VMX_VMFUNC: 56162306a36Sopenharmony_ci ctl_low &= evmcs_get_supported_ctls(EVMCS_VMFUNC); 56262306a36Sopenharmony_ci break; 56362306a36Sopenharmony_ci } 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci *pdata = ctl_low | ((u64)ctl_high << 32); 56662306a36Sopenharmony_ci} 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_cistatic bool nested_evmcs_is_valid_controls(enum evmcs_ctrl_type ctrl_type, 56962306a36Sopenharmony_ci u32 val) 57062306a36Sopenharmony_ci{ 57162306a36Sopenharmony_ci return !(val & ~evmcs_get_supported_ctls(ctrl_type)); 57262306a36Sopenharmony_ci} 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ciint nested_evmcs_check_controls(struct vmcs12 *vmcs12) 57562306a36Sopenharmony_ci{ 57662306a36Sopenharmony_ci if (CC(!nested_evmcs_is_valid_controls(EVMCS_PINCTRL, 57762306a36Sopenharmony_ci vmcs12->pin_based_vm_exec_control))) 57862306a36Sopenharmony_ci return -EINVAL; 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci if (CC(!nested_evmcs_is_valid_controls(EVMCS_EXEC_CTRL, 58162306a36Sopenharmony_ci vmcs12->cpu_based_vm_exec_control))) 58262306a36Sopenharmony_ci return -EINVAL; 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci if (CC(!nested_evmcs_is_valid_controls(EVMCS_2NDEXEC, 58562306a36Sopenharmony_ci vmcs12->secondary_vm_exec_control))) 58662306a36Sopenharmony_ci return -EINVAL; 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci if (CC(!nested_evmcs_is_valid_controls(EVMCS_EXIT_CTRLS, 58962306a36Sopenharmony_ci vmcs12->vm_exit_controls))) 59062306a36Sopenharmony_ci return -EINVAL; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci if (CC(!nested_evmcs_is_valid_controls(EVMCS_ENTRY_CTRLS, 59362306a36Sopenharmony_ci vmcs12->vm_entry_controls))) 59462306a36Sopenharmony_ci return -EINVAL; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci /* 59762306a36Sopenharmony_ci * VM-Func controls are 64-bit, but KVM currently doesn't support any 59862306a36Sopenharmony_ci * controls in bits 63:32, i.e. dropping those bits on the consistency 59962306a36Sopenharmony_ci * check is intentional. 60062306a36Sopenharmony_ci */ 60162306a36Sopenharmony_ci if (WARN_ON_ONCE(vmcs12->vm_function_control >> 32)) 60262306a36Sopenharmony_ci return -EINVAL; 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci if (CC(!nested_evmcs_is_valid_controls(EVMCS_VMFUNC, 60562306a36Sopenharmony_ci vmcs12->vm_function_control))) 60662306a36Sopenharmony_ci return -EINVAL; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci return 0; 60962306a36Sopenharmony_ci} 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_HYPERV) 61262306a36Sopenharmony_ciDEFINE_STATIC_KEY_FALSE(__kvm_is_using_evmcs); 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci/* 61562306a36Sopenharmony_ci * KVM on Hyper-V always uses the latest known eVMCSv1 revision, the assumption 61662306a36Sopenharmony_ci * is: in case a feature has corresponding fields in eVMCS described and it was 61762306a36Sopenharmony_ci * exposed in VMX feature MSRs, KVM is free to use it. Warn if KVM meets a 61862306a36Sopenharmony_ci * feature which has no corresponding eVMCS field, this likely means that KVM 61962306a36Sopenharmony_ci * needs to be updated. 62062306a36Sopenharmony_ci */ 62162306a36Sopenharmony_ci#define evmcs_check_vmcs_conf(field, ctrl) \ 62262306a36Sopenharmony_ci do { \ 62362306a36Sopenharmony_ci typeof(vmcs_conf->field) unsupported; \ 62462306a36Sopenharmony_ci \ 62562306a36Sopenharmony_ci unsupported = vmcs_conf->field & ~EVMCS1_SUPPORTED_ ## ctrl; \ 62662306a36Sopenharmony_ci if (unsupported) { \ 62762306a36Sopenharmony_ci pr_warn_once(#field " unsupported with eVMCS: 0x%llx\n",\ 62862306a36Sopenharmony_ci (u64)unsupported); \ 62962306a36Sopenharmony_ci vmcs_conf->field &= EVMCS1_SUPPORTED_ ## ctrl; \ 63062306a36Sopenharmony_ci } \ 63162306a36Sopenharmony_ci } \ 63262306a36Sopenharmony_ci while (0) 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_civoid evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf) 63562306a36Sopenharmony_ci{ 63662306a36Sopenharmony_ci evmcs_check_vmcs_conf(cpu_based_exec_ctrl, EXEC_CTRL); 63762306a36Sopenharmony_ci evmcs_check_vmcs_conf(pin_based_exec_ctrl, PINCTRL); 63862306a36Sopenharmony_ci evmcs_check_vmcs_conf(cpu_based_2nd_exec_ctrl, 2NDEXEC); 63962306a36Sopenharmony_ci evmcs_check_vmcs_conf(cpu_based_3rd_exec_ctrl, 3RDEXEC); 64062306a36Sopenharmony_ci evmcs_check_vmcs_conf(vmentry_ctrl, VMENTRY_CTRL); 64162306a36Sopenharmony_ci evmcs_check_vmcs_conf(vmexit_ctrl, VMEXIT_CTRL); 64262306a36Sopenharmony_ci} 64362306a36Sopenharmony_ci#endif 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ciint nested_enable_evmcs(struct kvm_vcpu *vcpu, 64662306a36Sopenharmony_ci uint16_t *vmcs_version) 64762306a36Sopenharmony_ci{ 64862306a36Sopenharmony_ci struct vcpu_vmx *vmx = to_vmx(vcpu); 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci vmx->nested.enlightened_vmcs_enabled = true; 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci if (vmcs_version) 65362306a36Sopenharmony_ci *vmcs_version = nested_get_evmcs_version(vcpu); 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci return 0; 65662306a36Sopenharmony_ci} 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_cibool nested_evmcs_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu) 65962306a36Sopenharmony_ci{ 66062306a36Sopenharmony_ci struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); 66162306a36Sopenharmony_ci struct vcpu_vmx *vmx = to_vmx(vcpu); 66262306a36Sopenharmony_ci struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci if (!hv_vcpu || !evmcs) 66562306a36Sopenharmony_ci return false; 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_ci if (!evmcs->hv_enlightenments_control.nested_flush_hypercall) 66862306a36Sopenharmony_ci return false; 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci return hv_vcpu->vp_assist_page.nested_control.features.directhypercall; 67162306a36Sopenharmony_ci} 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_civoid vmx_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu) 67462306a36Sopenharmony_ci{ 67562306a36Sopenharmony_ci nested_vmx_vmexit(vcpu, HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH, 0, 0); 67662306a36Sopenharmony_ci} 677