projects/linux·blob master · refs

956 lines · 23.0 KiB

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