1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Type definitions for the Microsoft hypervisor. 4 */ 5 #ifndef _HV_HVHDK_H 6 #define _HV_HVHDK_H 7 8 #include <linux/build_bug.h> 9 10 #include "hvhdk_mini.h" 11 #include "hvgdk.h" 12 13 /* Bits for dirty mask of hv_vp_register_page */ 14 #define HV_X64_REGISTER_CLASS_GENERAL 0 15 #define HV_X64_REGISTER_CLASS_IP 1 16 #define HV_X64_REGISTER_CLASS_XMM 2 17 #define HV_X64_REGISTER_CLASS_SEGMENT 3 18 #define HV_X64_REGISTER_CLASS_FLAGS 4 19 20 #define HV_VP_REGISTER_PAGE_VERSION_1 1u 21 22 #define HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT 7 23 24 union hv_vp_register_page_interrupt_vectors { 25 u64 as_uint64; 26 struct { 27 u8 vector_count; 28 u8 vector[HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT]; 29 } __packed; 30 }; 31 32 struct hv_vp_register_page { 33 u16 version; 34 u8 isvalid; 35 u8 rsvdz; 36 u32 dirty; 37 38 #if IS_ENABLED(CONFIG_X86) 39 40 union { 41 struct { 42 /* General purpose registers 43 * (HV_X64_REGISTER_CLASS_GENERAL) 44 */ 45 union { 46 struct { 47 u64 rax; 48 u64 rcx; 49 u64 rdx; 50 u64 rbx; 51 u64 rsp; 52 u64 rbp; 53 u64 rsi; 54 u64 rdi; 55 u64 r8; 56 u64 r9; 57 u64 r10; 58 u64 r11; 59 u64 r12; 60 u64 r13; 61 u64 r14; 62 u64 r15; 63 } __packed; 64 65 u64 gp_registers[16]; 66 }; 67 /* Instruction pointer (HV_X64_REGISTER_CLASS_IP) */ 68 u64 rip; 69 /* Flags (HV_X64_REGISTER_CLASS_FLAGS) */ 70 u64 rflags; 71 } __packed; 72 73 u64 registers[18]; 74 }; 75 /* Volatile XMM registers (HV_X64_REGISTER_CLASS_XMM) */ 76 union { 77 struct { 78 struct hv_u128 xmm0; 79 struct hv_u128 xmm1; 80 struct hv_u128 xmm2; 81 struct hv_u128 xmm3; 82 struct hv_u128 xmm4; 83 struct hv_u128 xmm5; 84 } __packed; 85 86 struct hv_u128 xmm_registers[6]; 87 }; 88 /* Segment registers (HV_X64_REGISTER_CLASS_SEGMENT) */ 89 union { 90 struct { 91 struct hv_x64_segment_register es; 92 struct hv_x64_segment_register cs; 93 struct hv_x64_segment_register ss; 94 struct hv_x64_segment_register ds; 95 struct hv_x64_segment_register fs; 96 struct hv_x64_segment_register gs; 97 } __packed; 98 99 struct hv_x64_segment_register segment_registers[6]; 100 }; 101 /* Misc. control registers (cannot be set via this interface) */ 102 u64 cr0; 103 u64 cr3; 104 u64 cr4; 105 u64 cr8; 106 u64 efer; 107 u64 dr7; 108 union hv_x64_pending_interruption_register pending_interruption; 109 union hv_x64_interrupt_state_register interrupt_state; 110 u64 instruction_emulation_hints; 111 u64 xfem; 112 113 /* 114 * Fields from this point are not included in the register page save chunk. 115 * The reserved field is intended to maintain alignment for unsaved fields. 116 */ 117 u8 reserved1[0x100]; 118 119 /* 120 * Interrupts injected as part of HvCallDispatchVp. 121 */ 122 union hv_vp_register_page_interrupt_vectors interrupt_vectors; 123 124 #elif IS_ENABLED(CONFIG_ARM64) 125 /* Not yet supported in ARM */ 126 #endif 127 } __packed; 128 129 #define HV_PARTITION_PROCESSOR_FEATURES_BANKS 2 130 131 union hv_partition_processor_features { 132 u64 as_uint64[HV_PARTITION_PROCESSOR_FEATURES_BANKS]; 133 struct { 134 u64 sse3_support : 1; 135 u64 lahf_sahf_support : 1; 136 u64 ssse3_support : 1; 137 u64 sse4_1_support : 1; 138 u64 sse4_2_support : 1; 139 u64 sse4a_support : 1; 140 u64 xop_support : 1; 141 u64 pop_cnt_support : 1; 142 u64 cmpxchg16b_support : 1; 143 u64 altmovcr8_support : 1; 144 u64 lzcnt_support : 1; 145 u64 mis_align_sse_support : 1; 146 u64 mmx_ext_support : 1; 147 u64 amd3dnow_support : 1; 148 u64 extended_amd3dnow_support : 1; 149 u64 page_1gb_support : 1; 150 u64 aes_support : 1; 151 u64 pclmulqdq_support : 1; 152 u64 pcid_support : 1; 153 u64 fma4_support : 1; 154 u64 f16c_support : 1; 155 u64 rd_rand_support : 1; 156 u64 rd_wr_fs_gs_support : 1; 157 u64 smep_support : 1; 158 u64 enhanced_fast_string_support : 1; 159 u64 bmi1_support : 1; 160 u64 bmi2_support : 1; 161 u64 hle_support_deprecated : 1; 162 u64 rtm_support_deprecated : 1; 163 u64 movbe_support : 1; 164 u64 npiep1_support : 1; 165 u64 dep_x87_fpu_save_support : 1; 166 u64 rd_seed_support : 1; 167 u64 adx_support : 1; 168 u64 intel_prefetch_support : 1; 169 u64 smap_support : 1; 170 u64 hle_support : 1; 171 u64 rtm_support : 1; 172 u64 rdtscp_support : 1; 173 u64 clflushopt_support : 1; 174 u64 clwb_support : 1; 175 u64 sha_support : 1; 176 u64 x87_pointers_saved_support : 1; 177 u64 invpcid_support : 1; 178 u64 ibrs_support : 1; 179 u64 stibp_support : 1; 180 u64 ibpb_support: 1; 181 u64 unrestricted_guest_support : 1; 182 u64 mdd_support : 1; 183 u64 fast_short_rep_mov_support : 1; 184 u64 l1dcache_flush_support : 1; 185 u64 rdcl_no_support : 1; 186 u64 ibrs_all_support : 1; 187 u64 skip_l1df_support : 1; 188 u64 ssb_no_support : 1; 189 u64 rsb_a_no_support : 1; 190 u64 virt_spec_ctrl_support : 1; 191 u64 rd_pid_support : 1; 192 u64 umip_support : 1; 193 u64 mbs_no_support : 1; 194 u64 mb_clear_support : 1; 195 u64 taa_no_support : 1; 196 u64 tsx_ctrl_support : 1; 197 /* 198 * N.B. The final processor feature bit in bank 0 is reserved to 199 * simplify potential downlevel backports. 200 */ 201 u64 reserved_bank0 : 1; 202 203 /* N.B. Begin bank 1 processor features. */ 204 u64 acount_mcount_support : 1; 205 u64 tsc_invariant_support : 1; 206 u64 cl_zero_support : 1; 207 u64 rdpru_support : 1; 208 u64 la57_support : 1; 209 u64 mbec_support : 1; 210 u64 nested_virt_support : 1; 211 u64 psfd_support : 1; 212 u64 cet_ss_support : 1; 213 u64 cet_ibt_support : 1; 214 u64 vmx_exception_inject_support : 1; 215 u64 enqcmd_support : 1; 216 u64 umwait_tpause_support : 1; 217 u64 movdiri_support : 1; 218 u64 movdir64b_support : 1; 219 u64 cldemote_support : 1; 220 u64 serialize_support : 1; 221 u64 tsc_deadline_tmr_support : 1; 222 u64 tsc_adjust_support : 1; 223 u64 fzlrep_movsb : 1; 224 u64 fsrep_stosb : 1; 225 u64 fsrep_cmpsb : 1; 226 u64 reserved_bank1 : 42; 227 } __packed; 228 }; 229 230 union hv_partition_processor_xsave_features { 231 struct { 232 u64 xsave_support : 1; 233 u64 xsaveopt_support : 1; 234 u64 avx_support : 1; 235 u64 reserved1 : 61; 236 } __packed; 237 u64 as_uint64; 238 }; 239 240 struct hv_partition_creation_properties { 241 union hv_partition_processor_features disabled_processor_features; 242 union hv_partition_processor_xsave_features 243 disabled_processor_xsave_features; 244 } __packed; 245 246 #define HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS 1 247 248 union hv_partition_synthetic_processor_features { 249 u64 as_uint64[HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS]; 250 251 struct { 252 u64 hypervisor_present : 1; 253 /* Support for HV#1: (CPUID leaves 0x40000000 - 0x40000006)*/ 254 u64 hv1 : 1; 255 u64 access_vp_run_time_reg : 1; /* HV_X64_MSR_VP_RUNTIME */ 256 u64 access_partition_reference_counter : 1; /* HV_X64_MSR_TIME_REF_COUNT */ 257 u64 access_synic_regs : 1; /* SINT-related registers */ 258 /* 259 * Access to HV_X64_MSR_STIMER0_CONFIG through 260 * HV_X64_MSR_STIMER3_COUNT. 261 */ 262 u64 access_synthetic_timer_regs : 1; 263 u64 access_intr_ctrl_regs : 1; /* APIC MSRs and VP assist page*/ 264 /* HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL */ 265 u64 access_hypercall_regs : 1; 266 u64 access_vp_index : 1; 267 u64 access_partition_reference_tsc : 1; 268 u64 access_guest_idle_reg : 1; 269 u64 access_frequency_regs : 1; 270 u64 reserved_z12 : 1; 271 u64 reserved_z13 : 1; 272 u64 reserved_z14 : 1; 273 u64 enable_extended_gva_ranges_for_flush_virtual_address_list : 1; 274 u64 reserved_z16 : 1; 275 u64 reserved_z17 : 1; 276 /* Use fast hypercall output. Corresponds to privilege. */ 277 u64 fast_hypercall_output : 1; 278 u64 reserved_z19 : 1; 279 u64 start_virtual_processor : 1; /* Can start VPs */ 280 u64 reserved_z21 : 1; 281 /* Synthetic timers in direct mode. */ 282 u64 direct_synthetic_timers : 1; 283 u64 reserved_z23 : 1; 284 u64 extended_processor_masks : 1; 285 286 /* Enable various hypercalls */ 287 u64 tb_flush_hypercalls : 1; 288 u64 synthetic_cluster_ipi : 1; 289 u64 notify_long_spin_wait : 1; 290 u64 query_numa_distance : 1; 291 u64 signal_events : 1; 292 u64 retarget_device_interrupt : 1; 293 u64 restore_time : 1; 294 295 /* EnlightenedVmcs nested enlightenment is supported. */ 296 u64 enlightened_vmcs : 1; 297 u64 reserved : 31; 298 } __packed; 299 }; 300 301 #define HV_MAKE_COMPATIBILITY_VERSION(major_, minor_) \ 302 ((u32)((major_) << 8 | (minor_))) 303 304 #define HV_COMPATIBILITY_21_H2 HV_MAKE_COMPATIBILITY_VERSION(0X6, 0X9) 305 306 union hv_partition_isolation_properties { 307 u64 as_uint64; 308 struct { 309 u64 isolation_type: 5; 310 u64 isolation_host_type : 2; 311 u64 rsvd_z: 5; 312 u64 shared_gpa_boundary_page_number: 52; 313 } __packed; 314 }; 315 316 /* 317 * Various isolation types supported by MSHV. 318 */ 319 #define HV_PARTITION_ISOLATION_TYPE_NONE 0 320 #define HV_PARTITION_ISOLATION_TYPE_SNP 2 321 #define HV_PARTITION_ISOLATION_TYPE_TDX 3 322 323 /* 324 * Various host isolation types supported by MSHV. 325 */ 326 #define HV_PARTITION_ISOLATION_HOST_TYPE_NONE 0x0 327 #define HV_PARTITION_ISOLATION_HOST_TYPE_HARDWARE 0x1 328 #define HV_PARTITION_ISOLATION_HOST_TYPE_RESERVED 0x2 329 330 /* Note: Exo partition is enabled by default */ 331 #define HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED BIT(4) 332 #define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8) 333 #define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13) 334 #define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19) 335 #define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22) 336 337 struct hv_input_create_partition { 338 u64 flags; 339 struct hv_proximity_domain_info proximity_domain_info; 340 u32 compatibility_version; 341 u32 padding; 342 struct hv_partition_creation_properties partition_creation_properties; 343 union hv_partition_isolation_properties isolation_properties; 344 } __packed; 345 346 struct hv_output_create_partition { 347 u64 partition_id; 348 } __packed; 349 350 struct hv_input_initialize_partition { 351 u64 partition_id; 352 } __packed; 353 354 struct hv_input_finalize_partition { 355 u64 partition_id; 356 } __packed; 357 358 struct hv_input_delete_partition { 359 u64 partition_id; 360 } __packed; 361 362 struct hv_input_get_partition_property { 363 u64 partition_id; 364 u32 property_code; /* enum hv_partition_property_code */ 365 u32 padding; 366 } __packed; 367 368 struct hv_output_get_partition_property { 369 u64 property_value; 370 } __packed; 371 372 struct hv_input_set_partition_property { 373 u64 partition_id; 374 u32 property_code; /* enum hv_partition_property_code */ 375 u32 padding; 376 u64 property_value; 377 } __packed; 378 379 union hv_partition_property_arg { 380 u64 as_uint64; 381 struct { 382 union { 383 u32 arg; 384 u32 vp_index; 385 }; 386 u16 reserved0; 387 u8 reserved1; 388 u8 object_type; 389 } __packed; 390 }; 391 392 struct hv_input_get_partition_property_ex { 393 u64 partition_id; 394 u32 property_code; /* enum hv_partition_property_code */ 395 u32 padding; 396 union { 397 union hv_partition_property_arg arg_data; 398 u64 arg; 399 }; 400 } __packed; 401 402 /* 403 * NOTE: Should use hv_input_set_partition_property_ex_header to compute this 404 * size, but hv_input_get_partition_property_ex is identical so it suffices 405 */ 406 #define HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE \ 407 (HV_HYP_PAGE_SIZE - sizeof(struct hv_input_get_partition_property_ex)) 408 409 union hv_partition_property_ex { 410 u8 buffer[HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE]; 411 struct hv_partition_property_vmm_capabilities vmm_capabilities; 412 /* More fields to be filled in when needed */ 413 }; 414 415 struct hv_output_get_partition_property_ex { 416 union hv_partition_property_ex property_value; 417 } __packed; 418 419 enum hv_vp_state_page_type { 420 HV_VP_STATE_PAGE_REGISTERS = 0, 421 HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1, 422 HV_VP_STATE_PAGE_GHCB = 2, 423 HV_VP_STATE_PAGE_COUNT 424 }; 425 426 struct hv_input_map_vp_state_page { 427 u64 partition_id; 428 u32 vp_index; 429 u16 type; /* enum hv_vp_state_page_type */ 430 union hv_input_vtl input_vtl; 431 union { 432 u8 as_uint8; 433 struct { 434 u8 map_location_provided : 1; 435 u8 reserved : 7; 436 }; 437 } flags; 438 u64 requested_map_location; 439 } __packed; 440 441 struct hv_output_map_vp_state_page { 442 u64 map_location; /* GPA page number */ 443 } __packed; 444 445 struct hv_input_unmap_vp_state_page { 446 u64 partition_id; 447 u32 vp_index; 448 u16 type; /* enum hv_vp_state_page_type */ 449 union hv_input_vtl input_vtl; 450 u8 reserved0; 451 } __packed; 452 453 struct hv_x64_apic_eoi_message { 454 u32 vp_index; 455 u32 interrupt_vector; 456 } __packed; 457 458 struct hv_opaque_intercept_message { 459 u32 vp_index; 460 } __packed; 461 462 enum hv_port_type { 463 HV_PORT_TYPE_MESSAGE = 1, 464 HV_PORT_TYPE_EVENT = 2, 465 HV_PORT_TYPE_MONITOR = 3, 466 HV_PORT_TYPE_DOORBELL = 4 /* Root Partition only */ 467 }; 468 469 struct hv_port_info { 470 u32 port_type; /* enum hv_port_type */ 471 u32 padding; 472 union { 473 struct { 474 u32 target_sint; 475 u32 target_vp; 476 u64 rsvdz; 477 } message_port_info; 478 struct { 479 u32 target_sint; 480 u32 target_vp; 481 u16 base_flag_number; 482 u16 flag_count; 483 u32 rsvdz; 484 } event_port_info; 485 struct { 486 u64 monitor_address; 487 u64 rsvdz; 488 } monitor_port_info; 489 struct { 490 u32 target_sint; 491 u32 target_vp; 492 u64 rsvdz; 493 } doorbell_port_info; 494 }; 495 } __packed; 496 497 struct hv_connection_info { 498 u32 port_type; 499 u32 padding; 500 union { 501 struct { 502 u64 rsvdz; 503 } message_connection_info; 504 struct { 505 u64 rsvdz; 506 } event_connection_info; 507 struct { 508 u64 monitor_address; 509 } monitor_connection_info; 510 struct { 511 u64 gpa; 512 u64 trigger_value; 513 u64 flags; 514 } doorbell_connection_info; 515 }; 516 } __packed; 517 518 /* Define synthetic interrupt controller flag constants. */ 519 #define HV_EVENT_FLAGS_COUNT (256 * 8) 520 #define HV_EVENT_FLAGS_BYTE_COUNT (256) 521 #define HV_EVENT_FLAGS32_COUNT (256 / sizeof(u32)) 522 523 /* linux side we create long version of flags to use long bit ops on flags */ 524 #define HV_EVENT_FLAGS_UL_COUNT (256 / sizeof(ulong)) 525 526 /* Define the synthetic interrupt controller event flags format. */ 527 union hv_synic_event_flags { 528 unsigned char flags8[HV_EVENT_FLAGS_BYTE_COUNT]; 529 u32 flags32[HV_EVENT_FLAGS32_COUNT]; 530 ulong flags[HV_EVENT_FLAGS_UL_COUNT]; /* linux only */ 531 }; 532 533 struct hv_synic_event_flags_page { 534 volatile union hv_synic_event_flags event_flags[HV_SYNIC_SINT_COUNT]; 535 }; 536 537 #define HV_SYNIC_EVENT_RING_MESSAGE_COUNT 63 538 539 struct hv_synic_event_ring { 540 u8 signal_masked; 541 u8 ring_full; 542 u16 reserved_z; 543 u32 data[HV_SYNIC_EVENT_RING_MESSAGE_COUNT]; 544 } __packed; 545 546 struct hv_synic_event_ring_page { 547 struct hv_synic_event_ring sint_event_ring[HV_SYNIC_SINT_COUNT]; 548 }; 549 550 /* Define SynIC control register. */ 551 union hv_synic_scontrol { 552 u64 as_uint64; 553 struct { 554 u64 enable : 1; 555 u64 reserved : 63; 556 } __packed; 557 }; 558 559 /* Define the format of the SIEFP register */ 560 union hv_synic_siefp { 561 u64 as_uint64; 562 struct { 563 u64 siefp_enabled : 1; 564 u64 preserved : 11; 565 u64 base_siefp_gpa : 52; 566 } __packed; 567 }; 568 569 union hv_synic_sirbp { 570 u64 as_uint64; 571 struct { 572 u64 sirbp_enabled : 1; 573 u64 preserved : 11; 574 u64 base_sirbp_gpa : 52; 575 } __packed; 576 }; 577 578 union hv_interrupt_control { 579 u64 as_uint64; 580 struct { 581 u32 interrupt_type; /* enum hv_interrupt_type */ 582 #if IS_ENABLED(CONFIG_X86) 583 u32 level_triggered : 1; 584 u32 logical_dest_mode : 1; 585 u32 rsvd : 30; 586 #elif IS_ENABLED(CONFIG_ARM64) 587 u32 rsvd1 : 2; 588 u32 asserted : 1; 589 u32 rsvd2 : 29; 590 #endif 591 } __packed; 592 }; 593 594 struct hv_stimer_state { 595 struct { 596 u32 undelivered_msg_pending : 1; 597 u32 reserved : 31; 598 } __packed flags; 599 u32 resvd; 600 u64 config; 601 u64 count; 602 u64 adjustment; 603 u64 undelivered_exp_time; 604 } __packed; 605 606 struct hv_synthetic_timers_state { 607 struct hv_stimer_state timers[HV_SYNIC_STIMER_COUNT]; 608 u64 reserved[5]; 609 } __packed; 610 611 struct hv_async_completion_message_payload { 612 u64 partition_id; 613 u32 status; 614 u32 completion_count; 615 u64 sub_status; 616 } __packed; 617 618 union hv_input_delete_vp { 619 u64 as_uint64[2]; 620 struct { 621 u64 partition_id; 622 u32 vp_index; 623 u8 reserved[4]; 624 } __packed; 625 } __packed; 626 627 struct hv_input_assert_virtual_interrupt { 628 u64 partition_id; 629 union hv_interrupt_control control; 630 u64 dest_addr; /* cpu's apic id */ 631 u32 vector; 632 u8 target_vtl; 633 u8 rsvd_z0; 634 u16 rsvd_z1; 635 } __packed; 636 637 struct hv_input_create_port { 638 u64 port_partition_id; 639 union hv_port_id port_id; 640 u8 port_vtl; 641 u8 min_connection_vtl; 642 u16 padding; 643 u64 connection_partition_id; 644 struct hv_port_info port_info; 645 struct hv_proximity_domain_info proximity_domain_info; 646 } __packed; 647 648 union hv_input_delete_port { 649 u64 as_uint64[2]; 650 struct { 651 u64 port_partition_id; 652 union hv_port_id port_id; 653 u32 reserved; 654 }; 655 } __packed; 656 657 struct hv_input_connect_port { 658 u64 connection_partition_id; 659 union hv_connection_id connection_id; 660 u8 connection_vtl; 661 u8 rsvdz0; 662 u16 rsvdz1; 663 u64 port_partition_id; 664 union hv_port_id port_id; 665 u32 reserved2; 666 struct hv_connection_info connection_info; 667 struct hv_proximity_domain_info proximity_domain_info; 668 } __packed; 669 670 union hv_input_disconnect_port { 671 u64 as_uint64[2]; 672 struct { 673 u64 connection_partition_id; 674 union hv_connection_id connection_id; 675 u32 is_doorbell: 1; 676 u32 reserved: 31; 677 } __packed; 678 } __packed; 679 680 union hv_input_notify_port_ring_empty { 681 u64 as_uint64; 682 struct { 683 u32 sint_index; 684 u32 reserved; 685 }; 686 } __packed; 687 688 struct hv_vp_state_data_xsave { 689 u64 flags; 690 union hv_x64_xsave_xfem_register states; 691 } __packed; 692 693 /* 694 * For getting and setting VP state, there are two options based on the state type: 695 * 696 * 1.) Data that is accessed by PFNs in the input hypercall page. This is used 697 * for state which may not fit into the hypercall pages. 698 * 2.) Data that is accessed directly in the input\output hypercall pages. 699 * This is used for state that will always fit into the hypercall pages. 700 * 701 * In the future this could be dynamic based on the size if needed. 702 * 703 * Note these hypercalls have an 8-byte aligned variable header size as per the tlfs 704 */ 705 706 #define HV_GET_SET_VP_STATE_TYPE_PFN BIT(31) 707 708 enum hv_get_set_vp_state_type { 709 /* HvGetSetVpStateLocalInterruptControllerState - APIC/GIC state */ 710 HV_GET_SET_VP_STATE_LAPIC_STATE = 0 | HV_GET_SET_VP_STATE_TYPE_PFN, 711 HV_GET_SET_VP_STATE_XSAVE = 1 | HV_GET_SET_VP_STATE_TYPE_PFN, 712 HV_GET_SET_VP_STATE_SIM_PAGE = 2 | HV_GET_SET_VP_STATE_TYPE_PFN, 713 HV_GET_SET_VP_STATE_SIEF_PAGE = 3 | HV_GET_SET_VP_STATE_TYPE_PFN, 714 HV_GET_SET_VP_STATE_SYNTHETIC_TIMERS = 4, 715 }; 716 717 struct hv_vp_state_data { 718 u32 type; 719 u32 rsvd; 720 struct hv_vp_state_data_xsave xsave; 721 } __packed; 722 723 struct hv_input_get_vp_state { 724 u64 partition_id; 725 u32 vp_index; 726 u8 input_vtl; 727 u8 rsvd0; 728 u16 rsvd1; 729 struct hv_vp_state_data state_data; 730 u64 output_data_pfns[]; 731 } __packed; 732 733 union hv_output_get_vp_state { 734 struct hv_synthetic_timers_state synthetic_timers_state; 735 } __packed; 736 737 union hv_input_set_vp_state_data { 738 u64 pfns; 739 u8 bytes; 740 } __packed; 741 742 struct hv_input_set_vp_state { 743 u64 partition_id; 744 u32 vp_index; 745 u8 input_vtl; 746 u8 rsvd0; 747 u16 rsvd1; 748 struct hv_vp_state_data state_data; 749 union hv_input_set_vp_state_data data[]; 750 } __packed; 751 752 union hv_x64_vp_execution_state { 753 u16 as_uint16; 754 struct { 755 u16 cpl:2; 756 u16 cr0_pe:1; 757 u16 cr0_am:1; 758 u16 efer_lma:1; 759 u16 debug_active:1; 760 u16 interruption_pending:1; 761 u16 vtl:4; 762 u16 enclave_mode:1; 763 u16 interrupt_shadow:1; 764 u16 virtualization_fault_active:1; 765 u16 reserved:2; 766 } __packed; 767 }; 768 769 struct hv_x64_intercept_message_header { 770 u32 vp_index; 771 u8 instruction_length:4; 772 u8 cr8:4; /* Only set for exo partitions */ 773 u8 intercept_access_type; 774 union hv_x64_vp_execution_state execution_state; 775 struct hv_x64_segment_register cs_segment; 776 u64 rip; 777 u64 rflags; 778 } __packed; 779 780 union hv_x64_memory_access_info { 781 u8 as_uint8; 782 struct { 783 u8 gva_valid:1; 784 u8 gva_gpa_valid:1; 785 u8 hypercall_output_pending:1; 786 u8 tlb_locked_no_overlay:1; 787 u8 reserved:4; 788 } __packed; 789 }; 790 791 struct hv_x64_memory_intercept_message { 792 struct hv_x64_intercept_message_header header; 793 u32 cache_type; /* enum hv_cache_type */ 794 u8 instruction_byte_count; 795 union hv_x64_memory_access_info memory_access_info; 796 u8 tpr_priority; 797 u8 reserved1; 798 u64 guest_virtual_address; 799 u64 guest_physical_address; 800 u8 instruction_bytes[16]; 801 } __packed; 802 803 /* 804 * Dispatch state for the VP communicated by the hypervisor to the 805 * VP-dispatching thread in the root on return from HVCALL_DISPATCH_VP. 806 */ 807 enum hv_vp_dispatch_state { 808 HV_VP_DISPATCH_STATE_INVALID = 0, 809 HV_VP_DISPATCH_STATE_BLOCKED = 1, 810 HV_VP_DISPATCH_STATE_READY = 2, 811 }; 812 813 /* 814 * Dispatch event that caused the current dispatch state on return from 815 * HVCALL_DISPATCH_VP. 816 */ 817 enum hv_vp_dispatch_event { 818 HV_VP_DISPATCH_EVENT_INVALID = 0x00000000, 819 HV_VP_DISPATCH_EVENT_SUSPEND = 0x00000001, 820 HV_VP_DISPATCH_EVENT_INTERCEPT = 0x00000002, 821 }; 822 823 #define HV_ROOT_SCHEDULER_MAX_VPS_PER_CHILD_PARTITION 1024 824 /* The maximum array size of HV_GENERIC_SET (vp_set) buffer */ 825 #define HV_GENERIC_SET_QWORD_COUNT(max) (((((max) - 1) >> 6) + 1) + 2) 826 827 struct hv_vp_signal_bitset_scheduler_message { 828 u64 partition_id; 829 u32 overflow_count; 830 u16 vp_count; 831 u16 reserved; 832 833 #define BITSET_BUFFER_SIZE \ 834 HV_GENERIC_SET_QWORD_COUNT(HV_ROOT_SCHEDULER_MAX_VPS_PER_CHILD_PARTITION) 835 union { 836 struct hv_vpset bitset; 837 u64 bitset_buffer[BITSET_BUFFER_SIZE]; 838 } vp_bitset; 839 #undef BITSET_BUFFER_SIZE 840 } __packed; 841 842 static_assert(sizeof(struct hv_vp_signal_bitset_scheduler_message) <= 843 (sizeof(struct hv_message) - sizeof(struct hv_message_header))); 844 845 #define HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT \ 846 (((sizeof(struct hv_message) - sizeof(struct hv_message_header)) / \ 847 (sizeof(u64 /* partition id */) + sizeof(u32 /* vp index */))) - 1) 848 849 struct hv_vp_signal_pair_scheduler_message { 850 u32 overflow_count; 851 u8 vp_count; 852 u8 reserved1[3]; 853 854 u64 partition_ids[HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT]; 855 u32 vp_indexes[HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT]; 856 857 u8 reserved2[4]; 858 } __packed; 859 860 static_assert(sizeof(struct hv_vp_signal_pair_scheduler_message) == 861 (sizeof(struct hv_message) - sizeof(struct hv_message_header))); 862 863 /* Input and output structures for HVCALL_DISPATCH_VP */ 864 #define HV_DISPATCH_VP_FLAG_CLEAR_INTERCEPT_SUSPEND 0x1 865 #define HV_DISPATCH_VP_FLAG_ENABLE_CALLER_INTERRUPTS 0x2 866 #define HV_DISPATCH_VP_FLAG_SET_CALLER_SPEC_CTRL 0x4 867 #define HV_DISPATCH_VP_FLAG_SKIP_VP_SPEC_FLUSH 0x8 868 #define HV_DISPATCH_VP_FLAG_SKIP_CALLER_SPEC_FLUSH 0x10 869 #define HV_DISPATCH_VP_FLAG_SKIP_CALLER_USER_SPEC_FLUSH 0x20 870 #define HV_DISPATCH_VP_FLAG_SCAN_INTERRUPT_INJECTION 0x40 871 872 struct hv_input_dispatch_vp { 873 u64 partition_id; 874 u32 vp_index; 875 u32 flags; 876 u64 time_slice; /* in 100ns */ 877 u64 spec_ctrl; 878 } __packed; 879 880 struct hv_output_dispatch_vp { 881 u32 dispatch_state; /* enum hv_vp_dispatch_state */ 882 u32 dispatch_event; /* enum hv_vp_dispatch_event */ 883 } __packed; 884 885 struct hv_input_modify_sparse_spa_page_host_access { 886 u32 host_access : 2; 887 u32 reserved : 30; 888 u32 flags; 889 u64 partition_id; 890 u64 spa_page_list[]; 891 } __packed; 892 893 /* hv_input_modify_sparse_spa_page_host_access flags */ 894 #define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE 0x1 895 #define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_SHARED 0x2 896 #define HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE 0x4 897 #define HV_MODIFY_SPA_PAGE_HOST_ACCESS_HUGE_PAGE 0x8 898 899 #endif /* _HV_HVHDK_H */ 900