365 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * tools/testing/selftests/kvm/include/x86_64/hyperv.h4 *5 * Copyright (C) 2021, Red Hat, Inc.6 *7 */8 9#ifndef SELFTEST_KVM_HYPERV_H10#define SELFTEST_KVM_HYPERV_H11 12#include "processor.h"13 14#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS 0x4000000015#define HYPERV_CPUID_INTERFACE 0x4000000116#define HYPERV_CPUID_VERSION 0x4000000217#define HYPERV_CPUID_FEATURES 0x4000000318#define HYPERV_CPUID_ENLIGHTMENT_INFO 0x4000000419#define HYPERV_CPUID_IMPLEMENT_LIMITS 0x4000000520#define HYPERV_CPUID_CPU_MANAGEMENT_FEATURES 0x4000000721#define HYPERV_CPUID_NESTED_FEATURES 0x4000000A22#define HYPERV_CPUID_SYNDBG_VENDOR_AND_MAX_FUNCTIONS 0x4000008023#define HYPERV_CPUID_SYNDBG_INTERFACE 0x4000008124#define HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES 0x4000008225 26#define HV_X64_MSR_GUEST_OS_ID 0x4000000027#define HV_X64_MSR_HYPERCALL 0x4000000128#define HV_X64_MSR_VP_INDEX 0x4000000229#define HV_X64_MSR_RESET 0x4000000330#define HV_X64_MSR_VP_RUNTIME 0x4000001031#define HV_X64_MSR_TIME_REF_COUNT 0x4000002032#define HV_X64_MSR_REFERENCE_TSC 0x4000002133#define HV_X64_MSR_TSC_FREQUENCY 0x4000002234#define HV_X64_MSR_APIC_FREQUENCY 0x4000002335#define HV_X64_MSR_EOI 0x4000007036#define HV_X64_MSR_ICR 0x4000007137#define HV_X64_MSR_TPR 0x4000007238#define HV_X64_MSR_VP_ASSIST_PAGE 0x4000007339#define HV_X64_MSR_SCONTROL 0x4000008040#define HV_X64_MSR_SVERSION 0x4000008141#define HV_X64_MSR_SIEFP 0x4000008242#define HV_X64_MSR_SIMP 0x4000008343#define HV_X64_MSR_EOM 0x4000008444#define HV_X64_MSR_SINT0 0x4000009045#define HV_X64_MSR_SINT1 0x4000009146#define HV_X64_MSR_SINT2 0x4000009247#define HV_X64_MSR_SINT3 0x4000009348#define HV_X64_MSR_SINT4 0x4000009449#define HV_X64_MSR_SINT5 0x4000009550#define HV_X64_MSR_SINT6 0x4000009651#define HV_X64_MSR_SINT7 0x4000009752#define HV_X64_MSR_SINT8 0x4000009853#define HV_X64_MSR_SINT9 0x4000009954#define HV_X64_MSR_SINT10 0x4000009A55#define HV_X64_MSR_SINT11 0x4000009B56#define HV_X64_MSR_SINT12 0x4000009C57#define HV_X64_MSR_SINT13 0x4000009D58#define HV_X64_MSR_SINT14 0x4000009E59#define HV_X64_MSR_SINT15 0x4000009F60#define HV_X64_MSR_STIMER0_CONFIG 0x400000B061#define HV_X64_MSR_STIMER0_COUNT 0x400000B162#define HV_X64_MSR_STIMER1_CONFIG 0x400000B263#define HV_X64_MSR_STIMER1_COUNT 0x400000B364#define HV_X64_MSR_STIMER2_CONFIG 0x400000B465#define HV_X64_MSR_STIMER2_COUNT 0x400000B566#define HV_X64_MSR_STIMER3_CONFIG 0x400000B667#define HV_X64_MSR_STIMER3_COUNT 0x400000B768#define HV_X64_MSR_GUEST_IDLE 0x400000F069#define HV_X64_MSR_CRASH_P0 0x4000010070#define HV_X64_MSR_CRASH_P1 0x4000010171#define HV_X64_MSR_CRASH_P2 0x4000010272#define HV_X64_MSR_CRASH_P3 0x4000010373#define HV_X64_MSR_CRASH_P4 0x4000010474#define HV_X64_MSR_CRASH_CTL 0x4000010575#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x4000010676#define HV_X64_MSR_TSC_EMULATION_CONTROL 0x4000010777#define HV_X64_MSR_TSC_EMULATION_STATUS 0x4000010878#define HV_X64_MSR_TSC_INVARIANT_CONTROL 0x4000011879 80#define HV_X64_MSR_SYNDBG_CONTROL 0x400000F181#define HV_X64_MSR_SYNDBG_STATUS 0x400000F282#define HV_X64_MSR_SYNDBG_SEND_BUFFER 0x400000F383#define HV_X64_MSR_SYNDBG_RECV_BUFFER 0x400000F484#define HV_X64_MSR_SYNDBG_PENDING_BUFFER 0x400000F585#define HV_X64_MSR_SYNDBG_OPTIONS 0x400000FF86 87/* HYPERV_CPUID_FEATURES.EAX */88#define HV_MSR_VP_RUNTIME_AVAILABLE \89 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 0)90#define HV_MSR_TIME_REF_COUNT_AVAILABLE \91 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 1)92#define HV_MSR_SYNIC_AVAILABLE \93 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 2)94#define HV_MSR_SYNTIMER_AVAILABLE \95 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 3)96#define HV_MSR_APIC_ACCESS_AVAILABLE \97 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 4)98#define HV_MSR_HYPERCALL_AVAILABLE \99 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 5)100#define HV_MSR_VP_INDEX_AVAILABLE \101 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 6)102#define HV_MSR_RESET_AVAILABLE \103 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 7)104#define HV_MSR_STAT_PAGES_AVAILABLE \105 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 8)106#define HV_MSR_REFERENCE_TSC_AVAILABLE \107 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 9)108#define HV_MSR_GUEST_IDLE_AVAILABLE \109 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 10)110#define HV_ACCESS_FREQUENCY_MSRS \111 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 11)112#define HV_ACCESS_REENLIGHTENMENT \113 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 13)114#define HV_ACCESS_TSC_INVARIANT \115 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EAX, 15)116 117/* HYPERV_CPUID_FEATURES.EBX */118#define HV_CREATE_PARTITIONS \119 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 0)120#define HV_ACCESS_PARTITION_ID \121 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 1)122#define HV_ACCESS_MEMORY_POOL \123 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 2)124#define HV_ADJUST_MESSAGE_BUFFERS \125 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 3)126#define HV_POST_MESSAGES \127 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 4)128#define HV_SIGNAL_EVENTS \129 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 5)130#define HV_CREATE_PORT \131 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 6)132#define HV_CONNECT_PORT \133 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 7)134#define HV_ACCESS_STATS \135 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 8)136#define HV_DEBUGGING \137 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 11)138#define HV_CPU_MANAGEMENT \139 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 12)140#define HV_ENABLE_EXTENDED_HYPERCALLS \141 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 20)142#define HV_ISOLATION \143 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EBX, 22)144 145/* HYPERV_CPUID_FEATURES.EDX */146#define HV_X64_MWAIT_AVAILABLE \147 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 0)148#define HV_X64_GUEST_DEBUGGING_AVAILABLE \149 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 1)150#define HV_X64_PERF_MONITOR_AVAILABLE \151 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 2)152#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE \153 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 3)154#define HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE \155 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 4)156#define HV_X64_GUEST_IDLE_STATE_AVAILABLE \157 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 5)158#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE \159 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 8)160#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE \161 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 10)162#define HV_FEATURE_DEBUG_MSRS_AVAILABLE \163 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 11)164#define HV_STIMER_DIRECT_MODE_AVAILABLE \165 KVM_X86_CPU_FEATURE(HYPERV_CPUID_FEATURES, 0, EDX, 19)166 167/* HYPERV_CPUID_ENLIGHTMENT_INFO.EAX */168#define HV_X64_AS_SWITCH_RECOMMENDED \169 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 0)170#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED \171 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 1)172#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED \173 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 2)174#define HV_X64_APIC_ACCESS_RECOMMENDED \175 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 3)176#define HV_X64_SYSTEM_RESET_RECOMMENDED \177 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 4)178#define HV_X64_RELAXED_TIMING_RECOMMENDED \179 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 5)180#define HV_DEPRECATING_AEOI_RECOMMENDED \181 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 9)182#define HV_X64_CLUSTER_IPI_RECOMMENDED \183 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 10)184#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED \185 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 11)186#define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED \187 KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 14)188 189/* HYPERV_CPUID_NESTED_FEATURES.EAX */190#define HV_X64_NESTED_DIRECT_FLUSH \191 KVM_X86_CPU_FEATURE(HYPERV_CPUID_NESTED_FEATURES, 0, EAX, 17)192#define HV_X64_NESTED_GUEST_MAPPING_FLUSH \193 KVM_X86_CPU_FEATURE(HYPERV_CPUID_NESTED_FEATURES, 0, EAX, 18)194#define HV_X64_NESTED_MSR_BITMAP \195 KVM_X86_CPU_FEATURE(HYPERV_CPUID_NESTED_FEATURES, 0, EAX, 19)196 197/* HYPERV_CPUID_NESTED_FEATURES.EBX */198#define HV_X64_NESTED_EVMCS1_PERF_GLOBAL_CTRL \199 KVM_X86_CPU_FEATURE(HYPERV_CPUID_NESTED_FEATURES, 0, EBX, 0)200 201/* HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES.EAX */202#define HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING \203 KVM_X86_CPU_FEATURE(HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES, 0, EAX, 1)204 205/* Hypercalls */206#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002207#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003208#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008209#define HVCALL_SEND_IPI 0x000b210#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013211#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014212#define HVCALL_SEND_IPI_EX 0x0015213#define HVCALL_GET_PARTITION_ID 0x0046214#define HVCALL_DEPOSIT_MEMORY 0x0048215#define HVCALL_CREATE_VP 0x004e216#define HVCALL_GET_VP_REGISTERS 0x0050217#define HVCALL_SET_VP_REGISTERS 0x0051218#define HVCALL_POST_MESSAGE 0x005c219#define HVCALL_SIGNAL_EVENT 0x005d220#define HVCALL_POST_DEBUG_DATA 0x0069221#define HVCALL_RETRIEVE_DEBUG_DATA 0x006a222#define HVCALL_RESET_DEBUG_SESSION 0x006b223#define HVCALL_ADD_LOGICAL_PROCESSOR 0x0076224#define HVCALL_MAP_DEVICE_INTERRUPT 0x007c225#define HVCALL_UNMAP_DEVICE_INTERRUPT 0x007d226#define HVCALL_RETARGET_INTERRUPT 0x007e227#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af228#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0229 230/* Extended hypercalls */231#define HV_EXT_CALL_QUERY_CAPABILITIES 0x8001232 233#define HV_FLUSH_ALL_PROCESSORS BIT(0)234#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)235#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)236#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)237 238/* hypercall status code */239#define HV_STATUS_SUCCESS 0240#define HV_STATUS_INVALID_HYPERCALL_CODE 2241#define HV_STATUS_INVALID_HYPERCALL_INPUT 3242#define HV_STATUS_INVALID_ALIGNMENT 4243#define HV_STATUS_INVALID_PARAMETER 5244#define HV_STATUS_ACCESS_DENIED 6245#define HV_STATUS_OPERATION_DENIED 8246#define HV_STATUS_INSUFFICIENT_MEMORY 11247#define HV_STATUS_INVALID_PORT_ID 17248#define HV_STATUS_INVALID_CONNECTION_ID 18249#define HV_STATUS_INSUFFICIENT_BUFFERS 19250 251/* hypercall options */252#define HV_HYPERCALL_FAST_BIT BIT(16)253#define HV_HYPERCALL_VARHEAD_OFFSET 17254#define HV_HYPERCALL_REP_COMP_OFFSET 32255 256/*257 * Issue a Hyper-V hypercall. Returns exception vector raised or 0, 'hv_status'258 * is set to the hypercall status (if no exception occurred).259 */260static inline uint8_t __hyperv_hypercall(u64 control, vm_vaddr_t input_address,261 vm_vaddr_t output_address,262 uint64_t *hv_status)263{264 uint64_t error_code;265 uint8_t vector;266 267 /* Note both the hypercall and the "asm safe" clobber r9-r11. */268 asm volatile("mov %[output_address], %%r8\n\t"269 KVM_ASM_SAFE("vmcall")270 : "=a" (*hv_status),271 "+c" (control), "+d" (input_address),272 KVM_ASM_SAFE_OUTPUTS(vector, error_code)273 : [output_address] "r"(output_address),274 "a" (-EFAULT)275 : "cc", "memory", "r8", KVM_ASM_SAFE_CLOBBERS);276 return vector;277}278 279/* Issue a Hyper-V hypercall and assert that it succeeded. */280static inline void hyperv_hypercall(u64 control, vm_vaddr_t input_address,281 vm_vaddr_t output_address)282{283 uint64_t hv_status;284 uint8_t vector;285 286 vector = __hyperv_hypercall(control, input_address, output_address, &hv_status);287 288 GUEST_ASSERT(!vector);289 GUEST_ASSERT((hv_status & 0xffff) == 0);290}291 292/* Write 'Fast' hypercall input 'data' to the first 'n_sse_regs' SSE regs */293static inline void hyperv_write_xmm_input(void *data, int n_sse_regs)294{295 int i;296 297 for (i = 0; i < n_sse_regs; i++)298 write_sse_reg(i, (sse128_t *)(data + sizeof(sse128_t) * i));299}300 301/* Proper HV_X64_MSR_GUEST_OS_ID value */302#define HYPERV_LINUX_OS_ID ((u64)0x8100 << 48)303 304#define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073305#define HV_X64_MSR_VP_ASSIST_PAGE_ENABLE 0x00000001306#define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT 12307#define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK \308 (~((1ull << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT) - 1))309 310struct hv_nested_enlightenments_control {311 struct {312 __u32 directhypercall:1;313 __u32 reserved:31;314 } features;315 struct {316 __u32 reserved;317 } hypercallControls;318} __packed;319 320/* Define virtual processor assist page structure. */321struct hv_vp_assist_page {322 __u32 apic_assist;323 __u32 reserved1;324 __u64 vtl_control[3];325 struct hv_nested_enlightenments_control nested_control;326 __u8 enlighten_vmentry;327 __u8 reserved2[7];328 __u64 current_nested_vmcs;329} __packed;330 331extern struct hv_vp_assist_page *current_vp_assist;332 333int enable_vp_assist(uint64_t vp_assist_pa, void *vp_assist);334 335struct hyperv_test_pages {336 /* VP assist page */337 void *vp_assist_hva;338 uint64_t vp_assist_gpa;339 void *vp_assist;340 341 /* Partition assist page */342 void *partition_assist_hva;343 uint64_t partition_assist_gpa;344 void *partition_assist;345 346 /* Enlightened VMCS */347 void *enlightened_vmcs_hva;348 uint64_t enlightened_vmcs_gpa;349 void *enlightened_vmcs;350};351 352struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm,353 vm_vaddr_t *p_hv_pages_gva);354 355/* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */356#define HV_INVARIANT_TSC_EXPOSED BIT_ULL(0)357 358const struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void);359const struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vcpu *vcpu);360void vcpu_set_hv_cpuid(struct kvm_vcpu *vcpu);361 362bool kvm_hv_cpu_has(struct kvm_x86_cpu_feature feature);363 364#endif /* !SELFTEST_KVM_HYPERV_H */365