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 }; 366 367 struct hv_input_notify_partition_event { 368 u32 event; /* enum hv_partition_event */ 369 union hv_partition_event_input input; 370 } __packed; 371 372 struct hv_lp_startup_status { 373 u64 hv_status; 374 u64 substatus1; 375 u64 substatus2; 376 u64 substatus3; 377 u64 substatus4; 378 u64 substatus5; 379 u64 substatus6; 380 } __packed; 381 382 struct hv_input_add_logical_processor { 383 u32 lp_index; 384 u32 apic_id; 385 struct hv_proximity_domain_info proximity_domain_info; 386 } __packed; 387 388 struct hv_output_add_logical_processor { 389 struct hv_lp_startup_status startup_status; 390 } __packed; 391 392 enum { /* HV_SUBNODE_TYPE */ 393 HV_SUBNODE_ANY = 0, 394 HV_SUBNODE_SOCKET, 395 HV_SUBNODE_CLUSTER, 396 HV_SUBNODE_L3, 397 HV_SUBNODE_COUNT, 398 HV_SUBNODE_INVALID = -1 399 }; 400 401 struct hv_create_vp { /* HV_INPUT_CREATE_VP */ 402 u64 partition_id; 403 u32 vp_index; 404 u8 padding[3]; 405 u8 subnode_type; 406 u64 subnode_id; 407 struct hv_proximity_domain_info proximity_domain_info; 408 u64 flags; 409 } __packed; 410 411 /* HV_INTERRUPT_TRIGGER_MODE */ 412 enum hv_interrupt_trigger_mode { 413 HV_INTERRUPT_TRIGGER_MODE_EDGE = 0, 414 HV_INTERRUPT_TRIGGER_MODE_LEVEL = 1, 415 }; 416 417 /* HV_DEVICE_INTERRUPT_DESCRIPTOR */ 418 struct hv_device_interrupt_descriptor { 419 u32 interrupt_type; 420 u32 trigger_mode; 421 u32 vector_count; 422 u32 reserved; 423 struct hv_device_interrupt_target target; 424 } __packed; 425 426 /* HV_INPUT_MAP_DEVICE_INTERRUPT */ 427 struct hv_input_map_device_interrupt { 428 u64 partition_id; 429 u64 device_id; 430 u32 flags; 431 u32 base_irt_idx; 432 struct hv_interrupt_entry logical_interrupt_entry; 433 struct hv_device_interrupt_descriptor interrupt_descriptor; 434 } __packed; 435 436 /* HV_OUTPUT_MAP_DEVICE_INTERRUPT */ 437 struct hv_output_map_device_interrupt { 438 struct hv_interrupt_entry interrupt_entry; 439 u64 ext_status_deprecated[5]; 440 } __packed; 441 442 /* HV_INPUT_UNMAP_DEVICE_INTERRUPT */ 443 struct hv_input_unmap_device_interrupt { 444 u64 partition_id; 445 u64 device_id; 446 struct hv_interrupt_entry interrupt_entry; 447 u32 flags; 448 } __packed; 449 450 #define HV_SOURCE_SHADOW_NONE 0x0 451 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1 452 453 struct hv_send_ipi_ex { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI_EX */ 454 u32 vector; 455 u32 reserved; 456 struct hv_vpset vp_set; 457 } __packed; 458 459 typedef u16 hv_pci_rid; /* HV_PCI_RID */ 460 typedef u16 hv_pci_segment; /* HV_PCI_SEGMENT */ 461 typedef u64 hv_logical_device_id; 462 union hv_pci_bdf { /* HV_PCI_BDF */ 463 u16 as_uint16; 464 465 struct { 466 u8 function : 3; 467 u8 device : 5; 468 u8 bus; 469 }; 470 } __packed; 471 472 union hv_pci_bus_range { 473 u16 as_uint16; 474 475 struct { 476 u8 subordinate_bus; 477 u8 secondary_bus; 478 }; 479 } __packed; 480 481 enum hv_device_type { /* HV_DEVICE_TYPE */ 482 HV_DEVICE_TYPE_LOGICAL = 0, 483 HV_DEVICE_TYPE_PCI = 1, 484 HV_DEVICE_TYPE_IOAPIC = 2, 485 HV_DEVICE_TYPE_ACPI = 3, 486 }; 487 488 union hv_device_id { /* HV_DEVICE_ID */ 489 u64 as_uint64; 490 491 struct { 492 u64 reserved0 : 62; 493 u64 device_type : 2; 494 }; 495 496 /* HV_DEVICE_TYPE_LOGICAL */ 497 struct { 498 u64 id : 62; 499 u64 device_type : 2; 500 } logical; 501 502 /* HV_DEVICE_TYPE_PCI */ 503 struct { 504 union { 505 hv_pci_rid rid; 506 union hv_pci_bdf bdf; 507 }; 508 509 hv_pci_segment segment; 510 union hv_pci_bus_range shadow_bus_range; 511 512 u16 phantom_function_bits : 2; 513 u16 source_shadow : 1; 514 515 u16 rsvdz0 : 11; 516 u16 device_type : 2; 517 } pci; 518 519 /* HV_DEVICE_TYPE_IOAPIC */ 520 struct { 521 u8 ioapic_id; 522 u8 rsvdz0; 523 u16 rsvdz1; 524 u16 rsvdz2; 525 526 u16 rsvdz3 : 14; 527 u16 device_type : 2; 528 } ioapic; 529 530 /* HV_DEVICE_TYPE_ACPI */ 531 struct { 532 u32 input_mapping_base; 533 u32 input_mapping_count : 30; 534 u32 device_type : 2; 535 } acpi; 536 } __packed; 537 538 #endif /* _HV_HVHDK_MINI_H */ 539