File Index
Files and directories
Sign in
FILE

hvhdk.h

File preview with syntax highlighting.

linux-6.19.14/include/hyperv/hvhdk.h C
  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
 24union 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
 32struct 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
131union 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
230union 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
240struct 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
248union 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
306union 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
337struct 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
346struct hv_output_create_partition {
347	u64 partition_id;
348} __packed;
349
350struct hv_input_initialize_partition {
351	u64 partition_id;
352} __packed;
353
354struct hv_input_finalize_partition {
355	u64 partition_id;
356} __packed;
357
358struct hv_input_delete_partition {
359	u64 partition_id;
360} __packed;
361
362struct hv_input_get_partition_property {
363	u64 partition_id;
364	u32 property_code; /* enum hv_partition_property_code */
365	u32 padding;
366} __packed;
367
368struct hv_output_get_partition_property {
369	u64 property_value;
370} __packed;
371
372struct 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
379union 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
392struct 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
409union 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
415struct hv_output_get_partition_property_ex {
416	union hv_partition_property_ex property_value;
417} __packed;
418
419enum 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
426struct 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
441struct hv_output_map_vp_state_page {
442	u64 map_location; /* GPA page number */
443} __packed;
444
445struct 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
453struct hv_x64_apic_eoi_message {
454	u32 vp_index;
455	u32 interrupt_vector;
456} __packed;
457
458struct hv_opaque_intercept_message {
459	u32 vp_index;
460} __packed;
461
462enum 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
469struct 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
497struct 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. */
527union 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
533struct 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
539struct 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
546struct 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. */
551union 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 */
560union 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
569union 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
578union 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
594struct 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
606struct hv_synthetic_timers_state {
607	struct hv_stimer_state timers[HV_SYNIC_STIMER_COUNT];
608	u64 reserved[5];
609} __packed;
610
611struct hv_async_completion_message_payload {
612	u64 partition_id;
613	u32 status;
614	u32 completion_count;
615	u64 sub_status;
616} __packed;
617
618union 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
627struct 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
637struct 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
648union 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
657struct 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
670union 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
680union hv_input_notify_port_ring_empty {
681	u64 as_uint64;
682	struct {
683		u32 sint_index;
684		u32 reserved;
685	};
686} __packed;
687
688struct 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
708enum 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
717struct hv_vp_state_data {
718	u32 type;
719	u32 rsvd;
720	struct hv_vp_state_data_xsave xsave;
721} __packed;
722
723struct 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
733union hv_output_get_vp_state {
734	struct hv_synthetic_timers_state synthetic_timers_state;
735} __packed;
736
737union hv_input_set_vp_state_data {
738	u64 pfns;
739	u8 bytes;
740} __packed;
741
742struct 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
752union 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
769struct 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; /* enum hv_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
780union 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
791struct 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#if IS_ENABLED(CONFIG_ARM64)
804union hv_arm64_vp_execution_state {
805	u16 as_uint16;
806	struct {
807		u16 cpl:2; /* Exception Level (EL) */
808		u16 debug_active:1;
809		u16 interruption_pending:1;
810		u16 vtl:4;
811		u16 virtualization_fault_active:1;
812		u16 reserved:7;
813	} __packed;
814};
815
816struct hv_arm64_intercept_message_header {
817	u32 vp_index;
818	u8 instruction_length;
819	u8 intercept_access_type; /* enum hv_intercept_access_type */
820	union hv_arm64_vp_execution_state execution_state;
821	u64 pc;
822	u64 cpsr;
823} __packed;
824
825union hv_arm64_memory_access_info {
826	u8 as_uint8;
827	struct {
828		u8 gva_valid:1;
829		u8 gva_gpa_valid:1;
830		u8 hypercall_output_pending:1;
831		u8 reserved:5;
832	} __packed;
833};
834
835struct hv_arm64_memory_intercept_message {
836	struct hv_arm64_intercept_message_header header;
837	u32 cache_type; /* enum hv_cache_type */
838	u8 instruction_byte_count;
839	union hv_arm64_memory_access_info memory_access_info;
840	u16 reserved1;
841	u8 instruction_bytes[4];
842	u32 reserved2;
843	u64 guest_virtual_address;
844	u64 guest_physical_address;
845	u64 syndrome;
846} __packed;
847
848#endif /* CONFIG_ARM64 */
849
850/*
851 * Dispatch state for the VP communicated by the hypervisor to the
852 * VP-dispatching thread in the root on return from HVCALL_DISPATCH_VP.
853 */
854enum hv_vp_dispatch_state {
855	HV_VP_DISPATCH_STATE_INVALID	= 0,
856	HV_VP_DISPATCH_STATE_BLOCKED	= 1,
857	HV_VP_DISPATCH_STATE_READY	= 2,
858};
859
860/*
861 * Dispatch event that caused the current dispatch state on return from
862 * HVCALL_DISPATCH_VP.
863 */
864enum hv_vp_dispatch_event {
865	HV_VP_DISPATCH_EVENT_INVALID	= 0x00000000,
866	HV_VP_DISPATCH_EVENT_SUSPEND	= 0x00000001,
867	HV_VP_DISPATCH_EVENT_INTERCEPT	= 0x00000002,
868};
869
870#define HV_ROOT_SCHEDULER_MAX_VPS_PER_CHILD_PARTITION   1024
871/* The maximum array size of HV_GENERIC_SET (vp_set) buffer */
872#define HV_GENERIC_SET_QWORD_COUNT(max) (((((max) - 1) >> 6) + 1) + 2)
873
874struct hv_vp_signal_bitset_scheduler_message {
875	u64 partition_id;
876	u32 overflow_count;
877	u16 vp_count;
878	u16 reserved;
879
880#define BITSET_BUFFER_SIZE \
881	HV_GENERIC_SET_QWORD_COUNT(HV_ROOT_SCHEDULER_MAX_VPS_PER_CHILD_PARTITION)
882	union {
883		struct hv_vpset bitset;
884		u64 bitset_buffer[BITSET_BUFFER_SIZE];
885	} vp_bitset;
886#undef BITSET_BUFFER_SIZE
887} __packed;
888
889static_assert(sizeof(struct hv_vp_signal_bitset_scheduler_message) <=
890	(sizeof(struct hv_message) - sizeof(struct hv_message_header)));
891
892#define HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT \
893	(((sizeof(struct hv_message) - sizeof(struct hv_message_header)) / \
894	 (sizeof(u64 /* partition id */) + sizeof(u32 /* vp index */))) - 1)
895
896struct hv_vp_signal_pair_scheduler_message {
897	u32 overflow_count;
898	u8 vp_count;
899	u8 reserved1[3];
900
901	u64 partition_ids[HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT];
902	u32 vp_indexes[HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT];
903
904	u8 reserved2[4];
905} __packed;
906
907static_assert(sizeof(struct hv_vp_signal_pair_scheduler_message) ==
908	(sizeof(struct hv_message) - sizeof(struct hv_message_header)));
909
910/* Input and output structures for HVCALL_DISPATCH_VP */
911#define HV_DISPATCH_VP_FLAG_CLEAR_INTERCEPT_SUSPEND	0x1
912#define HV_DISPATCH_VP_FLAG_ENABLE_CALLER_INTERRUPTS	0x2
913#define HV_DISPATCH_VP_FLAG_SET_CALLER_SPEC_CTRL	0x4
914#define HV_DISPATCH_VP_FLAG_SKIP_VP_SPEC_FLUSH		0x8
915#define HV_DISPATCH_VP_FLAG_SKIP_CALLER_SPEC_FLUSH	0x10
916#define HV_DISPATCH_VP_FLAG_SKIP_CALLER_USER_SPEC_FLUSH	0x20
917#define HV_DISPATCH_VP_FLAG_SCAN_INTERRUPT_INJECTION	0x40
918
919struct hv_input_dispatch_vp {
920	u64 partition_id;
921	u32 vp_index;
922	u32 flags;
923	u64 time_slice; /* in 100ns */
924	u64 spec_ctrl;
925} __packed;
926
927struct hv_output_dispatch_vp {
928	u32 dispatch_state; /* enum hv_vp_dispatch_state */
929	u32 dispatch_event; /* enum hv_vp_dispatch_event */
930} __packed;
931
932struct hv_input_modify_sparse_spa_page_host_access {
933	u32 host_access : 2;
934	u32 reserved : 30;
935	u32 flags;
936	u64 partition_id;
937	u64 spa_page_list[];
938} __packed;
939
940/* hv_input_modify_sparse_spa_page_host_access flags */
941#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE  0x1
942#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_SHARED     0x2
943#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE      0x4
944#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_HUGE_PAGE       0x8
945
946#endif /* _HV_HVHDK_H */
~/ Read-only file preview.