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 union { 188 u32 as_uint32; 189 #if IS_ENABLED(CONFIG_X86) 190 /* enum hv_dynamic_processor_feature_property */ 191 u32 hv_processor_feature; 192 #endif 193 /* More fields to be filled in when needed */ 194 }; 195 } __packed; 196 197 struct hv_output_get_system_property { 198 union { 199 u32 scheduler_type; /* enum hv_scheduler_type */ 200 #if IS_ENABLED(CONFIG_X86) 201 u64 hv_processor_feature_value; 202 #endif 203 union hv_pfn_range hv_cda_info; /* CrashdumpAreaAddress */ 204 u64 hv_tramp_pa; /* CrashdumpTrampolineAddress */ 205 }; 206 } __packed; 207 208 struct hv_sleep_state_info { 209 u32 sleep_state; /* enum hv_sleep_state */ 210 u8 pm1a_slp_typ; 211 u8 pm1b_slp_typ; 212 } __packed; 213 214 struct hv_input_set_system_property { 215 u32 property_id; /* enum hv_system_property */ 216 u32 reserved; 217 union { 218 /* More fields to be filled in when needed */ 219 struct hv_sleep_state_info set_sleep_state_info; 220 221 /* 222 * Add a reserved field to ensure the union is 8-byte aligned as 223 * existing members may not be. This is a temporary measure 224 * until all remaining members are added. 225 */ 226 u64 reserved0[8]; 227 }; 228 } __packed; 229 230 struct hv_input_enter_sleep_state { /* HV_INPUT_ENTER_SLEEP_STATE */ 231 u32 sleep_state; /* enum hv_sleep_state */ 232 } __packed; 233 234 struct hv_input_map_stats_page { 235 u32 type; /* enum hv_stats_object_type */ 236 u32 padding; 237 union hv_stats_object_identity identity; 238 } __packed; 239 240 struct hv_input_map_stats_page2 { 241 u32 type; /* enum hv_stats_object_type */ 242 u32 padding; 243 union hv_stats_object_identity identity; 244 u64 map_location; 245 } __packed; 246 247 struct hv_output_map_stats_page { 248 u64 map_location; 249 } __packed; 250 251 struct hv_input_unmap_stats_page { 252 u32 type; /* enum hv_stats_object_type */ 253 u32 padding; 254 union hv_stats_object_identity identity; 255 } __packed; 256 257 struct hv_proximity_domain_flags { 258 u32 proximity_preferred : 1; 259 u32 reserved : 30; 260 u32 proximity_info_valid : 1; 261 } __packed; 262 263 struct hv_proximity_domain_info { 264 u32 domain_id; 265 struct hv_proximity_domain_flags flags; 266 } __packed; 267 268 /* HvDepositMemory hypercall */ 269 struct hv_deposit_memory { /* HV_INPUT_DEPOSIT_MEMORY */ 270 u64 partition_id; 271 u64 gpa_page_list[]; 272 } __packed; 273 274 struct hv_input_withdraw_memory { 275 u64 partition_id; 276 struct hv_proximity_domain_info proximity_domain_info; 277 } __packed; 278 279 struct hv_output_withdraw_memory { 280 DECLARE_FLEX_ARRAY(u64, gpa_page_list); 281 } __packed; 282 283 /* HV Map GPA (Guest Physical Address) Flags */ 284 #define HV_MAP_GPA_PERMISSIONS_NONE 0x0 285 #define HV_MAP_GPA_READABLE 0x1 286 #define HV_MAP_GPA_WRITABLE 0x2 287 #define HV_MAP_GPA_KERNEL_EXECUTABLE 0x4 288 #define HV_MAP_GPA_USER_EXECUTABLE 0x8 289 #define HV_MAP_GPA_EXECUTABLE 0xC 290 #define HV_MAP_GPA_PERMISSIONS_MASK 0xF 291 #define HV_MAP_GPA_ADJUSTABLE 0x8000 292 #define HV_MAP_GPA_NO_ACCESS 0x10000 293 #define HV_MAP_GPA_NOT_CACHED 0x200000 294 #define HV_MAP_GPA_LARGE_PAGE 0x80000000 295 296 struct hv_input_map_gpa_pages { 297 u64 target_partition_id; 298 u64 target_gpa_base; 299 u32 map_flags; 300 u32 padding; 301 u64 source_gpa_page_list[]; 302 } __packed; 303 304 union hv_gpa_page_access_state_flags { 305 struct { 306 u64 clear_accessed : 1; 307 u64 set_accessed : 1; 308 u64 clear_dirty : 1; 309 u64 set_dirty : 1; 310 u64 reserved : 60; 311 } __packed; 312 u64 as_uint64; 313 }; 314 315 struct hv_input_get_gpa_pages_access_state { 316 u64 partition_id; 317 union hv_gpa_page_access_state_flags flags; 318 u64 hv_gpa_page_number; 319 } __packed; 320 321 union hv_gpa_page_access_state { 322 struct { 323 u8 accessed : 1; 324 u8 dirty : 1; 325 u8 reserved: 6; 326 }; 327 u8 as_uint8; 328 } __packed; 329 330 enum hv_crashdump_action { 331 HV_CRASHDUMP_NONE = 0, 332 HV_CRASHDUMP_SUSPEND_ALL_VPS, 333 HV_CRASHDUMP_PREPARE_FOR_STATE_SAVE, 334 HV_CRASHDUMP_STATE_SAVED, 335 HV_CRASHDUMP_ENTRY, 336 }; 337 338 struct hv_partition_event_root_crashdump_input { 339 u32 crashdump_action; /* enum hv_crashdump_action */ 340 } __packed; 341 342 struct hv_input_disable_hyp_ex { /* HV_X64_INPUT_DISABLE_HYPERVISOR_EX */ 343 u64 rip; 344 u64 arg; 345 } __packed; 346 347 struct hv_crashdump_area { /* HV_CRASHDUMP_AREA */ 348 u32 version; 349 union { 350 u32 flags_as_uint32; 351 struct { 352 u32 cda_valid : 1; 353 u32 cda_unused : 31; 354 } __packed; 355 }; 356 /* more unused fields */ 357 } __packed; 358 359 union hv_partition_event_input { 360 struct hv_partition_event_root_crashdump_input crashdump_input; 361 }; 362 363 enum hv_partition_event { 364 HV_PARTITION_EVENT_ROOT_CRASHDUMP = 2, 365 HV_PARTITION_ALL_LOGICAL_PROCESSORS_STARTED = 4, 366 }; 367 368 struct hv_input_notify_partition_event { 369 u32 event; /* enum hv_partition_event */ 370 union hv_partition_event_input input; 371 } __packed; 372 373 struct hv_input_get_logical_processor_run_time { 374 u32 lp_index; 375 } __packed; 376 377 struct hv_output_get_logical_processor_run_time { 378 u64 global_time; 379 u64 local_run_time; 380 u64 rsvdz0; 381 u64 hypervisor_time; 382 } __packed; 383 384 struct hv_lp_startup_status { 385 u64 hv_status; 386 u64 substatus1; 387 u64 substatus2; 388 u64 substatus3; 389 u64 substatus4; 390 u64 substatus5; 391 u64 substatus6; 392 } __packed; 393 394 struct hv_input_add_logical_processor { 395 u32 lp_index; 396 u32 apic_id; 397 struct hv_proximity_domain_info proximity_domain_info; 398 } __packed; 399 400 struct hv_output_add_logical_processor { 401 struct hv_lp_startup_status startup_status; 402 } __packed; 403 404 enum { /* HV_SUBNODE_TYPE */ 405 HV_SUBNODE_ANY = 0, 406 HV_SUBNODE_SOCKET, 407 HV_SUBNODE_CLUSTER, 408 HV_SUBNODE_L3, 409 HV_SUBNODE_COUNT, 410 HV_SUBNODE_INVALID = -1 411 }; 412 413 struct hv_create_vp { /* HV_INPUT_CREATE_VP */ 414 u64 partition_id; 415 u32 vp_index; 416 u8 padding[3]; 417 u8 subnode_type; 418 u64 subnode_id; 419 struct hv_proximity_domain_info proximity_domain_info; 420 u64 flags; 421 } __packed; 422 423 /* HV_INTERRUPT_TRIGGER_MODE */ 424 enum hv_interrupt_trigger_mode { 425 HV_INTERRUPT_TRIGGER_MODE_EDGE = 0, 426 HV_INTERRUPT_TRIGGER_MODE_LEVEL = 1, 427 }; 428 429 /* HV_DEVICE_INTERRUPT_DESCRIPTOR */ 430 struct hv_device_interrupt_descriptor { 431 u32 interrupt_type; 432 u32 trigger_mode; 433 u32 vector_count; 434 u32 reserved; 435 struct hv_device_interrupt_target target; 436 } __packed; 437 438 /* HV_INPUT_MAP_DEVICE_INTERRUPT */ 439 struct hv_input_map_device_interrupt { 440 u64 partition_id; 441 u64 device_id; 442 u32 flags; 443 u32 base_irt_idx; 444 struct hv_interrupt_entry logical_interrupt_entry; 445 struct hv_device_interrupt_descriptor interrupt_descriptor; 446 } __packed; 447 448 /* HV_OUTPUT_MAP_DEVICE_INTERRUPT */ 449 struct hv_output_map_device_interrupt { 450 struct hv_interrupt_entry interrupt_entry; 451 u64 ext_status_deprecated[5]; 452 } __packed; 453 454 /* HV_INPUT_UNMAP_DEVICE_INTERRUPT */ 455 struct hv_input_unmap_device_interrupt { 456 u64 partition_id; 457 u64 device_id; 458 struct hv_interrupt_entry interrupt_entry; 459 u32 flags; 460 } __packed; 461 462 #define HV_SOURCE_SHADOW_NONE 0x0 463 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1 464 465 struct hv_send_ipi_ex { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI_EX */ 466 u32 vector; 467 u32 reserved; 468 struct hv_vpset vp_set; 469 } __packed; 470 471 typedef u16 hv_pci_rid; /* HV_PCI_RID */ 472 typedef u16 hv_pci_segment; /* HV_PCI_SEGMENT */ 473 typedef u64 hv_logical_device_id; 474 union hv_pci_bdf { /* HV_PCI_BDF */ 475 u16 as_uint16; 476 477 struct { 478 u8 function : 3; 479 u8 device : 5; 480 u8 bus; 481 }; 482 } __packed; 483 484 union hv_pci_bus_range { 485 u16 as_uint16; 486 487 struct { 488 u8 subordinate_bus; 489 u8 secondary_bus; 490 }; 491 } __packed; 492 493 enum hv_device_type { /* HV_DEVICE_TYPE */ 494 HV_DEVICE_TYPE_LOGICAL = 0, 495 HV_DEVICE_TYPE_PCI = 1, 496 HV_DEVICE_TYPE_IOAPIC = 2, 497 HV_DEVICE_TYPE_ACPI = 3, 498 }; 499 500 union hv_device_id { /* HV_DEVICE_ID */ 501 u64 as_uint64; 502 503 struct { 504 u64 reserved0 : 62; 505 u64 device_type : 2; 506 }; 507 508 /* HV_DEVICE_TYPE_LOGICAL */ 509 struct { 510 u64 id : 62; 511 u64 device_type : 2; 512 } logical; 513 514 /* HV_DEVICE_TYPE_PCI */ 515 struct { 516 union { 517 hv_pci_rid rid; 518 union hv_pci_bdf bdf; 519 }; 520 521 hv_pci_segment segment; 522 union hv_pci_bus_range shadow_bus_range; 523 524 u16 phantom_function_bits : 2; 525 u16 source_shadow : 1; 526 527 u16 rsvdz0 : 11; 528 u16 device_type : 2; 529 } pci; 530 531 /* HV_DEVICE_TYPE_IOAPIC */ 532 struct { 533 u8 ioapic_id; 534 u8 rsvdz0; 535 u16 rsvdz1; 536 u16 rsvdz2; 537 538 u16 rsvdz3 : 14; 539 u16 device_type : 2; 540 } ioapic; 541 542 /* HV_DEVICE_TYPE_ACPI */ 543 struct { 544 u32 input_mapping_base; 545 u32 input_mapping_count : 30; 546 u32 device_type : 2; 547 } acpi; 548 } __packed; 549 550 #endif /* _HV_HVHDK_MINI_H */ 551