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