1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Type definitions for the Microsoft Hypervisor. 4 */ 5 #ifndef _HV_HVHDK_MINI_H 6 #define _HV_HVHDK_MINI_H 7 8 #include "hvgdk_mini.h" 9 10 /* 11 * Doorbell connection_info flags. 12 */ 13 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_MASK 0x00000007 14 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_ANY 0x00000000 15 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_BYTE 0x00000001 16 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_WORD 0x00000002 17 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_DWORD 0x00000003 18 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_QWORD 0x00000004 19 #define HV_DOORBELL_FLAG_TRIGGER_ANY_VALUE 0x80000000 20 21 /* Each generic set contains 64 elements */ 22 #define HV_GENERIC_SET_SHIFT (6) 23 #define HV_GENERIC_SET_MASK (63) 24 25 enum hv_generic_set_format { 26 HV_GENERIC_SET_SPARSE_4K, 27 HV_GENERIC_SET_ALL, 28 }; 29 #define HV_GENERIC_SET_FORMAT hv_generic_set_format 30 31 enum hv_scheduler_type { 32 HV_SCHEDULER_TYPE_LP = 1, /* Classic scheduler w/o SMT */ 33 HV_SCHEDULER_TYPE_LP_SMT = 2, /* Classic scheduler w/ SMT */ 34 HV_SCHEDULER_TYPE_CORE_SMT = 3, /* Core scheduler */ 35 HV_SCHEDULER_TYPE_ROOT = 4, /* Root / integrated scheduler */ 36 HV_SCHEDULER_TYPE_MAX 37 }; 38 39 /* HV_STATS_AREA_TYPE */ 40 enum hv_stats_area_type { 41 HV_STATS_AREA_SELF = 0, 42 HV_STATS_AREA_PARENT = 1, 43 HV_STATS_AREA_INTERNAL = 2, 44 HV_STATS_AREA_COUNT 45 }; 46 47 enum hv_stats_object_type { 48 HV_STATS_OBJECT_HYPERVISOR = 0x00000001, 49 HV_STATS_OBJECT_LOGICAL_PROCESSOR = 0x00000002, 50 HV_STATS_OBJECT_PARTITION = 0x00010001, 51 HV_STATS_OBJECT_VP = 0x00010002 52 }; 53 54 union hv_stats_object_identity { 55 /* hv_stats_hypervisor */ 56 struct { 57 u8 reserved[15]; 58 u8 stats_area_type; 59 } __packed hv; 60 61 /* hv_stats_logical_processor */ 62 struct { 63 u32 lp_index; 64 u8 reserved[11]; 65 u8 stats_area_type; 66 } __packed lp; 67 68 /* hv_stats_partition */ 69 struct { 70 u64 partition_id; 71 u8 reserved[7]; 72 u8 stats_area_type; 73 } __packed partition; 74 75 /* hv_stats_vp */ 76 struct { 77 u64 partition_id; 78 u32 vp_index; 79 u16 flags; 80 u8 reserved; 81 u8 stats_area_type; 82 } __packed vp; 83 }; 84 85 enum hv_partition_property_code { 86 /* Privilege properties */ 87 HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS = 0x00010000, 88 HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES = 0x00010001, 89 90 /* Integrated scheduling properties */ 91 HV_PARTITION_PROPERTY_INTEGRATED_SCHEDULER_ENABLED = 0x00020005, 92 93 /* Resource properties */ 94 HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING = 0x00050005, 95 HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION = 0x00050017, 96 97 /* Compatibility properties */ 98 HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES = 0x00060002, 99 HV_PARTITION_PROPERTY_XSAVE_STATES = 0x00060007, 100 HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE = 0x00060008, 101 HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY = 0x00060009, 102 103 /* Extended properties with larger property values */ 104 HV_PARTITION_PROPERTY_VMM_CAPABILITIES = 0x00090007, 105 }; 106 107 #define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT 1 108 #define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT 57 109 110 struct hv_partition_property_vmm_capabilities { 111 u16 bank_count; 112 u16 reserved[3]; 113 union { 114 u64 as_uint64[HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT]; 115 struct { 116 u64 map_gpa_preserve_adjustable: 1; 117 u64 vmm_can_provide_overlay_gpfn: 1; 118 u64 vp_affinity_property: 1; 119 #if IS_ENABLED(CONFIG_ARM64) 120 u64 vmm_can_provide_gic_overlay_locations: 1; 121 #else 122 u64 reservedbit3: 1; 123 #endif 124 u64 assignable_synthetic_proc_features: 1; 125 u64 reservedbit5: 1; 126 u64 vmm_enable_integrated_scheduler : 1; 127 u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT; 128 } __packed; 129 }; 130 } __packed; 131 132 enum hv_snp_status { 133 HV_SNP_STATUS_NONE = 0, 134 HV_SNP_STATUS_AVAILABLE = 1, 135 HV_SNP_STATUS_INCOMPATIBLE = 2, 136 HV_SNP_STATUS_PSP_UNAVAILABLE = 3, 137 HV_SNP_STATUS_PSP_INIT_FAILED = 4, 138 HV_SNP_STATUS_PSP_BAD_FW_VERSION = 5, 139 HV_SNP_STATUS_BAD_CONFIGURATION = 6, 140 HV_SNP_STATUS_PSP_FW_UPDATE_IN_PROGRESS = 7, 141 HV_SNP_STATUS_PSP_RB_INIT_FAILED = 8, 142 HV_SNP_STATUS_PSP_PLATFORM_STATUS_FAILED = 9, 143 HV_SNP_STATUS_PSP_INIT_LATE_FAILED = 10, 144 }; 145 146 enum hv_system_property { 147 /* Add more values when needed */ 148 HV_SYSTEM_PROPERTY_SLEEP_STATE = 3, 149 HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15, 150 HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21, 151 HV_SYSTEM_PROPERTY_CRASHDUMPAREA = 47, 152 }; 153 154 #define HV_PFN_RANGE_PGBITS 24 /* HV_SPA_PAGE_RANGE_ADDITIONAL_PAGES_BITS */ 155 union hv_pfn_range { /* HV_SPA_PAGE_RANGE */ 156 u64 as_uint64; 157 struct { 158 /* 39:0: base pfn. 63:40: additional pages */ 159 u64 base_pfn : 64 - HV_PFN_RANGE_PGBITS; 160 u64 add_pfns : HV_PFN_RANGE_PGBITS; 161 } __packed; 162 }; 163 164 enum hv_sleep_state { 165 HV_SLEEP_STATE_S1 = 1, 166 HV_SLEEP_STATE_S2 = 2, 167 HV_SLEEP_STATE_S3 = 3, 168 HV_SLEEP_STATE_S4 = 4, 169 HV_SLEEP_STATE_S5 = 5, 170 /* 171 * After hypervisor has received this, any follow up sleep 172 * state registration requests will be rejected. 173 */ 174 HV_SLEEP_STATE_LOCK = 6 175 }; 176 177 enum hv_dynamic_processor_feature_property { 178 /* Add more values when needed */ 179 HV_X64_DYNAMIC_PROCESSOR_FEATURE_MAX_ENCRYPTED_PARTITIONS = 13, 180 HV_X64_DYNAMIC_PROCESSOR_FEATURE_SNP_STATUS = 16, 181 }; 182 183 struct hv_input_get_system_property { 184 u32 property_id; /* enum hv_system_property */ 185 union { 186 u32 as_uint32; 187 #if IS_ENABLED(CONFIG_X86) 188 /* enum hv_dynamic_processor_feature_property */ 189 u32 hv_processor_feature; 190 #endif 191 /* More fields to be filled in when needed */ 192 }; 193 } __packed; 194 195 struct hv_output_get_system_property { 196 union { 197 u32 scheduler_type; /* enum hv_scheduler_type */ 198 #if IS_ENABLED(CONFIG_X86) 199 u64 hv_processor_feature_value; 200 #endif 201 union hv_pfn_range hv_cda_info; /* CrashdumpAreaAddress */ 202 u64 hv_tramp_pa; /* CrashdumpTrampolineAddress */ 203 }; 204 } __packed; 205 206 struct hv_sleep_state_info { 207 u32 sleep_state; /* enum hv_sleep_state */ 208 u8 pm1a_slp_typ; 209 u8 pm1b_slp_typ; 210 } __packed; 211 212 struct hv_input_set_system_property { 213 u32 property_id; /* enum hv_system_property */ 214 u32 reserved; 215 union { 216 /* More fields to be filled in when needed */ 217 struct hv_sleep_state_info set_sleep_state_info; 218 219 /* 220 * Add a reserved field to ensure the union is 8-byte aligned as 221 * existing members may not be. This is a temporary measure 222 * until all remaining members are added. 223 */ 224 u64 reserved0[8]; 225 }; 226 } __packed; 227 228 struct hv_input_enter_sleep_state { /* HV_INPUT_ENTER_SLEEP_STATE */ 229 u32 sleep_state; /* enum hv_sleep_state */ 230 } __packed; 231 232 struct hv_input_map_stats_page { 233 u32 type; /* enum hv_stats_object_type */ 234 u32 padding; 235 union hv_stats_object_identity identity; 236 } __packed; 237 238 struct hv_input_map_stats_page2 { 239 u32 type; /* enum hv_stats_object_type */ 240 u32 padding; 241 union hv_stats_object_identity identity; 242 u64 map_location; 243 } __packed; 244 245 struct hv_output_map_stats_page { 246 u64 map_location; 247 } __packed; 248 249 struct hv_input_unmap_stats_page { 250 u32 type; /* enum hv_stats_object_type */ 251 u32 padding; 252 union hv_stats_object_identity identity; 253 } __packed; 254 255 struct hv_proximity_domain_flags { 256 u32 proximity_preferred : 1; 257 u32 reserved : 30; 258 u32 proximity_info_valid : 1; 259 } __packed; 260 261 struct hv_proximity_domain_info { 262 u32 domain_id; 263 struct hv_proximity_domain_flags flags; 264 } __packed; 265 266 /* HvDepositMemory hypercall */ 267 struct hv_deposit_memory { /* HV_INPUT_DEPOSIT_MEMORY */ 268 u64 partition_id; 269 u64 gpa_page_list[]; 270 } __packed; 271 272 struct hv_input_withdraw_memory { 273 u64 partition_id; 274 struct hv_proximity_domain_info proximity_domain_info; 275 } __packed; 276 277 struct hv_output_withdraw_memory { 278 DECLARE_FLEX_ARRAY(u64, gpa_page_list); 279 } __packed; 280 281 /* HV Map GPA (Guest Physical Address) Flags */ 282 #define HV_MAP_GPA_PERMISSIONS_NONE 0x0 283 #define HV_MAP_GPA_READABLE 0x1 284 #define HV_MAP_GPA_WRITABLE 0x2 285 #define HV_MAP_GPA_KERNEL_EXECUTABLE 0x4 286 #define HV_MAP_GPA_USER_EXECUTABLE 0x8 287 #define HV_MAP_GPA_EXECUTABLE 0xC 288 #define HV_MAP_GPA_PERMISSIONS_MASK 0xF 289 #define HV_MAP_GPA_ADJUSTABLE 0x8000 290 #define HV_MAP_GPA_NO_ACCESS 0x10000 291 #define HV_MAP_GPA_NOT_CACHED 0x200000 292 #define HV_MAP_GPA_LARGE_PAGE 0x80000000 293 294 struct hv_input_map_gpa_pages { 295 u64 target_partition_id; 296 u64 target_gpa_base; 297 u32 map_flags; 298 u32 padding; 299 u64 source_gpa_page_list[]; 300 } __packed; 301 302 union hv_gpa_page_access_state_flags { 303 struct { 304 u64 clear_accessed : 1; 305 u64 set_accessed : 1; 306 u64 clear_dirty : 1; 307 u64 set_dirty : 1; 308 u64 reserved : 60; 309 } __packed; 310 u64 as_uint64; 311 }; 312 313 struct hv_input_get_gpa_pages_access_state { 314 u64 partition_id; 315 union hv_gpa_page_access_state_flags flags; 316 u64 hv_gpa_page_number; 317 } __packed; 318 319 union hv_gpa_page_access_state { 320 struct { 321 u8 accessed : 1; 322 u8 dirty : 1; 323 u8 reserved: 6; 324 }; 325 u8 as_uint8; 326 } __packed; 327 328 enum hv_crashdump_action { 329 HV_CRASHDUMP_NONE = 0, 330 HV_CRASHDUMP_SUSPEND_ALL_VPS, 331 HV_CRASHDUMP_PREPARE_FOR_STATE_SAVE, 332 HV_CRASHDUMP_STATE_SAVED, 333 HV_CRASHDUMP_ENTRY, 334 }; 335 336 struct hv_partition_event_root_crashdump_input { 337 u32 crashdump_action; /* enum hv_crashdump_action */ 338 } __packed; 339 340 struct hv_input_disable_hyp_ex { /* HV_X64_INPUT_DISABLE_HYPERVISOR_EX */ 341 u64 rip; 342 u64 arg; 343 } __packed; 344 345 struct hv_crashdump_area { /* HV_CRASHDUMP_AREA */ 346 u32 version; 347 union { 348 u32 flags_as_uint32; 349 struct { 350 u32 cda_valid : 1; 351 u32 cda_unused : 31; 352 } __packed; 353 }; 354 /* more unused fields */ 355 } __packed; 356 357 union hv_partition_event_input { 358 struct hv_partition_event_root_crashdump_input crashdump_input; 359 }; 360 361 enum hv_partition_event { 362 HV_PARTITION_EVENT_ROOT_CRASHDUMP = 2, 363 }; 364 365 struct hv_input_notify_partition_event { 366 u32 event; /* enum hv_partition_event */ 367 union hv_partition_event_input input; 368 } __packed; 369 370 struct hv_lp_startup_status { 371 u64 hv_status; 372 u64 substatus1; 373 u64 substatus2; 374 u64 substatus3; 375 u64 substatus4; 376 u64 substatus5; 377 u64 substatus6; 378 } __packed; 379 380 struct hv_input_add_logical_processor { 381 u32 lp_index; 382 u32 apic_id; 383 struct hv_proximity_domain_info proximity_domain_info; 384 } __packed; 385 386 struct hv_output_add_logical_processor { 387 struct hv_lp_startup_status startup_status; 388 } __packed; 389 390 enum { /* HV_SUBNODE_TYPE */ 391 HV_SUBNODE_ANY = 0, 392 HV_SUBNODE_SOCKET, 393 HV_SUBNODE_CLUSTER, 394 HV_SUBNODE_L3, 395 HV_SUBNODE_COUNT, 396 HV_SUBNODE_INVALID = -1 397 }; 398 399 struct hv_create_vp { /* HV_INPUT_CREATE_VP */ 400 u64 partition_id; 401 u32 vp_index; 402 u8 padding[3]; 403 u8 subnode_type; 404 u64 subnode_id; 405 struct hv_proximity_domain_info proximity_domain_info; 406 u64 flags; 407 } __packed; 408 409 /* HV_INTERRUPT_TRIGGER_MODE */ 410 enum hv_interrupt_trigger_mode { 411 HV_INTERRUPT_TRIGGER_MODE_EDGE = 0, 412 HV_INTERRUPT_TRIGGER_MODE_LEVEL = 1, 413 }; 414 415 /* HV_DEVICE_INTERRUPT_DESCRIPTOR */ 416 struct hv_device_interrupt_descriptor { 417 u32 interrupt_type; 418 u32 trigger_mode; 419 u32 vector_count; 420 u32 reserved; 421 struct hv_device_interrupt_target target; 422 } __packed; 423 424 /* HV_INPUT_MAP_DEVICE_INTERRUPT */ 425 struct hv_input_map_device_interrupt { 426 u64 partition_id; 427 u64 device_id; 428 u32 flags; 429 u32 base_irt_idx; 430 struct hv_interrupt_entry logical_interrupt_entry; 431 struct hv_device_interrupt_descriptor interrupt_descriptor; 432 } __packed; 433 434 /* HV_OUTPUT_MAP_DEVICE_INTERRUPT */ 435 struct hv_output_map_device_interrupt { 436 struct hv_interrupt_entry interrupt_entry; 437 u64 ext_status_deprecated[5]; 438 } __packed; 439 440 /* HV_INPUT_UNMAP_DEVICE_INTERRUPT */ 441 struct hv_input_unmap_device_interrupt { 442 u64 partition_id; 443 u64 device_id; 444 struct hv_interrupt_entry interrupt_entry; 445 u32 flags; 446 } __packed; 447 448 #define HV_SOURCE_SHADOW_NONE 0x0 449 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1 450 451 struct hv_send_ipi_ex { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI_EX */ 452 u32 vector; 453 u32 reserved; 454 struct hv_vpset vp_set; 455 } __packed; 456 457 typedef u16 hv_pci_rid; /* HV_PCI_RID */ 458 typedef u16 hv_pci_segment; /* HV_PCI_SEGMENT */ 459 typedef u64 hv_logical_device_id; 460 union hv_pci_bdf { /* HV_PCI_BDF */ 461 u16 as_uint16; 462 463 struct { 464 u8 function : 3; 465 u8 device : 5; 466 u8 bus; 467 }; 468 } __packed; 469 470 union hv_pci_bus_range { 471 u16 as_uint16; 472 473 struct { 474 u8 subordinate_bus; 475 u8 secondary_bus; 476 }; 477 } __packed; 478 479 enum hv_device_type { /* HV_DEVICE_TYPE */ 480 HV_DEVICE_TYPE_LOGICAL = 0, 481 HV_DEVICE_TYPE_PCI = 1, 482 HV_DEVICE_TYPE_IOAPIC = 2, 483 HV_DEVICE_TYPE_ACPI = 3, 484 }; 485 486 union hv_device_id { /* HV_DEVICE_ID */ 487 u64 as_uint64; 488 489 struct { 490 u64 reserved0 : 62; 491 u64 device_type : 2; 492 }; 493 494 /* HV_DEVICE_TYPE_LOGICAL */ 495 struct { 496 u64 id : 62; 497 u64 device_type : 2; 498 } logical; 499 500 /* HV_DEVICE_TYPE_PCI */ 501 struct { 502 union { 503 hv_pci_rid rid; 504 union hv_pci_bdf bdf; 505 }; 506 507 hv_pci_segment segment; 508 union hv_pci_bus_range shadow_bus_range; 509 510 u16 phantom_function_bits : 2; 511 u16 source_shadow : 1; 512 513 u16 rsvdz0 : 11; 514 u16 device_type : 2; 515 } pci; 516 517 /* HV_DEVICE_TYPE_IOAPIC */ 518 struct { 519 u8 ioapic_id; 520 u8 rsvdz0; 521 u16 rsvdz1; 522 u16 rsvdz2; 523 524 u16 rsvdz3 : 14; 525 u16 device_type : 2; 526 } ioapic; 527 528 /* HV_DEVICE_TYPE_ACPI */ 529 struct { 530 u32 input_mapping_base; 531 u32 input_mapping_count : 30; 532 u32 device_type : 2; 533 } acpi; 534 } __packed; 535 536 #endif /* _HV_HVHDK_MINI_H */ 537