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