xref: /linux/include/hyperv/hvhdk_mini.h (revision 8fd12b03c7c888303c3c45559d8c3e270a916f9f)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Type definitions for the Microsoft Hypervisor.
4  */
5 #ifndef _HV_HVHDK_MINI_H
6 #define _HV_HVHDK_MINI_H
7 
8 #include "hvgdk_mini.h"
9 
10 #define HV_MAX_CONTIGUOUS_ALLOCATION_PAGES	8
11 
12 /*
13  * Doorbell connection_info flags.
14  */
15 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_MASK  0x00000007
16 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_ANY   0x00000000
17 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_BYTE  0x00000001
18 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_WORD  0x00000002
19 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_DWORD 0x00000003
20 #define HV_DOORBELL_FLAG_TRIGGER_SIZE_QWORD 0x00000004
21 #define HV_DOORBELL_FLAG_TRIGGER_ANY_VALUE  0x80000000
22 
23 /* Each generic set contains 64 elements */
24 #define HV_GENERIC_SET_SHIFT		(6)
25 #define HV_GENERIC_SET_MASK		(63)
26 
27 enum hv_generic_set_format {
28 	HV_GENERIC_SET_SPARSE_4K,
29 	HV_GENERIC_SET_ALL,
30 };
31 #define HV_GENERIC_SET_FORMAT hv_generic_set_format
32 
33 enum hv_scheduler_type {
34 	HV_SCHEDULER_TYPE_LP		= 1, /* Classic scheduler w/o SMT */
35 	HV_SCHEDULER_TYPE_LP_SMT	= 2, /* Classic scheduler w/ SMT */
36 	HV_SCHEDULER_TYPE_CORE_SMT	= 3, /* Core scheduler */
37 	HV_SCHEDULER_TYPE_ROOT		= 4, /* Root / integrated scheduler */
38 	HV_SCHEDULER_TYPE_MAX
39 };
40 
41 /* HV_STATS_AREA_TYPE */
42 enum hv_stats_area_type {
43 	HV_STATS_AREA_SELF = 0,
44 	HV_STATS_AREA_PARENT = 1,
45 	HV_STATS_AREA_INTERNAL = 2,
46 	HV_STATS_AREA_COUNT
47 };
48 
49 enum hv_stats_object_type {
50 	HV_STATS_OBJECT_HYPERVISOR		= 0x00000001,
51 	HV_STATS_OBJECT_LOGICAL_PROCESSOR	= 0x00000002,
52 	HV_STATS_OBJECT_PARTITION		= 0x00010001,
53 	HV_STATS_OBJECT_VP			= 0x00010002
54 };
55 
56 union hv_stats_object_identity {
57 	/* hv_stats_hypervisor */
58 	struct {
59 		u8 reserved[15];
60 		u8 stats_area_type;
61 	} __packed hv;
62 
63 	/* hv_stats_logical_processor */
64 	struct {
65 		u32 lp_index;
66 		u8 reserved[11];
67 		u8 stats_area_type;
68 	} __packed lp;
69 
70 	/* hv_stats_partition */
71 	struct {
72 		u64 partition_id;
73 		u8  reserved[7];
74 		u8  stats_area_type;
75 	} __packed partition;
76 
77 	/* hv_stats_vp */
78 	struct {
79 		u64 partition_id;
80 		u32 vp_index;
81 		u16 flags;
82 		u8  reserved;
83 		u8  stats_area_type;
84 	} __packed vp;
85 };
86 
87 enum hv_partition_property_code {
88 	/* Privilege properties */
89 	HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS			= 0x00010000,
90 	HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES		= 0x00010001,
91 
92 	/* Integrated scheduling properties */
93 	HV_PARTITION_PROPERTY_INTEGRATED_SCHEDULER_ENABLED	= 0x00020005,
94 
95 	/* Resource properties */
96 	HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING		= 0x00050005,
97 	HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION		= 0x00050017,
98 
99 	/* Compatibility properties */
100 	HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES		= 0x00060002,
101 	HV_PARTITION_PROPERTY_XSAVE_STATES                      = 0x00060007,
102 	HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE		= 0x00060008,
103 	HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY		= 0x00060009,
104 
105 	/* Extended properties with larger property values */
106 	HV_PARTITION_PROPERTY_VMM_CAPABILITIES			= 0x00090007,
107 };
108 
109 #define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT		1
110 #define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT	57
111 
112 struct hv_partition_property_vmm_capabilities {
113 	u16 bank_count;
114 	u16 reserved[3];
115 	union {
116 		u64 as_uint64[HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT];
117 		struct {
118 			u64 map_gpa_preserve_adjustable: 1;
119 			u64 vmm_can_provide_overlay_gpfn: 1;
120 			u64 vp_affinity_property: 1;
121 #if IS_ENABLED(CONFIG_ARM64)
122 			u64 vmm_can_provide_gic_overlay_locations: 1;
123 #else
124 			u64 reservedbit3: 1;
125 #endif
126 			u64 assignable_synthetic_proc_features: 1;
127 			u64 reservedbit5: 1;
128 			u64 vmm_enable_integrated_scheduler : 1;
129 			u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT;
130 		} __packed;
131 	};
132 } __packed;
133 
134 enum hv_snp_status {
135 	HV_SNP_STATUS_NONE = 0,
136 	HV_SNP_STATUS_AVAILABLE = 1,
137 	HV_SNP_STATUS_INCOMPATIBLE = 2,
138 	HV_SNP_STATUS_PSP_UNAVAILABLE = 3,
139 	HV_SNP_STATUS_PSP_INIT_FAILED = 4,
140 	HV_SNP_STATUS_PSP_BAD_FW_VERSION = 5,
141 	HV_SNP_STATUS_BAD_CONFIGURATION = 6,
142 	HV_SNP_STATUS_PSP_FW_UPDATE_IN_PROGRESS = 7,
143 	HV_SNP_STATUS_PSP_RB_INIT_FAILED = 8,
144 	HV_SNP_STATUS_PSP_PLATFORM_STATUS_FAILED = 9,
145 	HV_SNP_STATUS_PSP_INIT_LATE_FAILED = 10,
146 };
147 
148 enum hv_system_property {
149 	/* Add more values when needed */
150 	HV_SYSTEM_PROPERTY_SLEEP_STATE = 3,
151 	HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15,
152 	HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21,
153 	HV_SYSTEM_PROPERTY_CRASHDUMPAREA = 47,
154 };
155 
156 #define HV_PFN_RANGE_PGBITS 24  /* HV_SPA_PAGE_RANGE_ADDITIONAL_PAGES_BITS */
157 union hv_pfn_range {            /* HV_SPA_PAGE_RANGE */
158 	u64 as_uint64;
159 	struct {
160 		/* 39:0: base pfn.  63:40: additional pages */
161 		u64 base_pfn : 64 - HV_PFN_RANGE_PGBITS;
162 		u64 add_pfns : HV_PFN_RANGE_PGBITS;
163 	} __packed;
164 };
165 
166 enum hv_sleep_state {
167 	HV_SLEEP_STATE_S1 = 1,
168 	HV_SLEEP_STATE_S2 = 2,
169 	HV_SLEEP_STATE_S3 = 3,
170 	HV_SLEEP_STATE_S4 = 4,
171 	HV_SLEEP_STATE_S5 = 5,
172 	/*
173 	 * After hypervisor has received this, any follow up sleep
174 	 * state registration requests will be rejected.
175 	 */
176 	HV_SLEEP_STATE_LOCK = 6
177 };
178 
179 enum hv_dynamic_processor_feature_property {
180 	/* Add more values when needed */
181 	HV_X64_DYNAMIC_PROCESSOR_FEATURE_MAX_ENCRYPTED_PARTITIONS = 13,
182 	HV_X64_DYNAMIC_PROCESSOR_FEATURE_SNP_STATUS = 16,
183 };
184 
185 struct hv_input_get_system_property {
186 	u32 property_id; /* enum hv_system_property */
187 	union {
188 		u32 as_uint32;
189 #if IS_ENABLED(CONFIG_X86)
190 		/* enum hv_dynamic_processor_feature_property */
191 		u32 hv_processor_feature;
192 #endif
193 		/* More fields to be filled in when needed */
194 	};
195 } __packed;
196 
197 struct hv_output_get_system_property {
198 	union {
199 		u32 scheduler_type; /* enum hv_scheduler_type */
200 #if IS_ENABLED(CONFIG_X86)
201 		u64 hv_processor_feature_value;
202 #endif
203 		union hv_pfn_range hv_cda_info; /* CrashdumpAreaAddress */
204 		u64 hv_tramp_pa;                /* CrashdumpTrampolineAddress */
205 	};
206 } __packed;
207 
208 struct hv_sleep_state_info {
209 	u32 sleep_state; /* enum hv_sleep_state */
210 	u8 pm1a_slp_typ;
211 	u8 pm1b_slp_typ;
212 } __packed;
213 
214 struct hv_input_set_system_property {
215 	u32 property_id; /* enum hv_system_property */
216 	u32 reserved;
217 	union {
218 		/* More fields to be filled in when needed */
219 		struct hv_sleep_state_info set_sleep_state_info;
220 
221 		/*
222 		 * Add a reserved field to ensure the union is 8-byte aligned as
223 		 * existing members may not be. This is a temporary measure
224 		 * until all remaining members are added.
225 		 */
226 		 u64 reserved0[8];
227 	};
228 } __packed;
229 
230 struct hv_input_enter_sleep_state {     /* HV_INPUT_ENTER_SLEEP_STATE */
231 	u32 sleep_state;        /* enum hv_sleep_state */
232 } __packed;
233 
234 struct hv_input_map_stats_page {
235 	u32 type; /* enum hv_stats_object_type */
236 	u32 padding;
237 	union hv_stats_object_identity identity;
238 } __packed;
239 
240 struct hv_input_map_stats_page2 {
241 	u32 type; /* enum hv_stats_object_type */
242 	u32 padding;
243 	union hv_stats_object_identity identity;
244 	u64 map_location;
245 } __packed;
246 
247 struct hv_output_map_stats_page {
248 	u64 map_location;
249 } __packed;
250 
251 struct hv_input_unmap_stats_page {
252 	u32 type; /* enum hv_stats_object_type */
253 	u32 padding;
254 	union hv_stats_object_identity identity;
255 } __packed;
256 
257 struct hv_proximity_domain_flags {
258 	u32 proximity_preferred : 1;
259 	u32 reserved : 30;
260 	u32 proximity_info_valid : 1;
261 } __packed;
262 
263 struct hv_proximity_domain_info {
264 	u32 domain_id;
265 	struct hv_proximity_domain_flags flags;
266 } __packed;
267 
268 /* HvDepositMemory hypercall */
269 struct hv_deposit_memory {	/* HV_INPUT_DEPOSIT_MEMORY */
270 	u64 partition_id;
271 	u64 gpa_page_list[];
272 } __packed;
273 
274 struct hv_input_withdraw_memory {
275 	u64 partition_id;
276 	struct hv_proximity_domain_info proximity_domain_info;
277 } __packed;
278 
279 struct hv_output_withdraw_memory {
280 	DECLARE_FLEX_ARRAY(u64, gpa_page_list);
281 } __packed;
282 
283 /* HV Map GPA (Guest Physical Address) Flags */
284 #define HV_MAP_GPA_PERMISSIONS_NONE	       0x0
285 #define HV_MAP_GPA_READABLE		       0x1
286 #define HV_MAP_GPA_WRITABLE		       0x2
287 #define HV_MAP_GPA_KERNEL_EXECUTABLE	       0x4
288 #define HV_MAP_GPA_USER_EXECUTABLE	       0x8
289 #define HV_MAP_GPA_EXECUTABLE		       0xC
290 #define HV_MAP_GPA_PERMISSIONS_MASK	       0xF
291 #define HV_MAP_GPA_ADJUSTABLE		    0x8000
292 #define HV_MAP_GPA_NO_ACCESS		   0x10000
293 #define HV_MAP_GPA_NOT_CACHED		  0x200000
294 #define HV_MAP_GPA_LARGE_PAGE		0x80000000
295 
296 struct hv_input_map_gpa_pages {
297 	u64 target_partition_id;
298 	u64 target_gpa_base;
299 	u32 map_flags;
300 	u32 padding;
301 	u64 source_gpa_page_list[];
302 } __packed;
303 
304 union hv_gpa_page_access_state_flags {
305 	struct {
306 		u64 clear_accessed : 1;
307 		u64 set_accessed : 1;
308 		u64 clear_dirty : 1;
309 		u64 set_dirty : 1;
310 		u64 reserved : 60;
311 	} __packed;
312 	u64 as_uint64;
313 };
314 
315 struct hv_input_get_gpa_pages_access_state {
316 	u64  partition_id;
317 	union hv_gpa_page_access_state_flags flags;
318 	u64 hv_gpa_page_number;
319 } __packed;
320 
321 union hv_gpa_page_access_state {
322 	struct {
323 		u8 accessed : 1;
324 		u8 dirty : 1;
325 		u8 reserved: 6;
326 	};
327 	u8 as_uint8;
328 } __packed;
329 
330 enum hv_crashdump_action {
331 	HV_CRASHDUMP_NONE = 0,
332 	HV_CRASHDUMP_SUSPEND_ALL_VPS,
333 	HV_CRASHDUMP_PREPARE_FOR_STATE_SAVE,
334 	HV_CRASHDUMP_STATE_SAVED,
335 	HV_CRASHDUMP_ENTRY,
336 };
337 
338 struct hv_partition_event_root_crashdump_input {
339 	u32 crashdump_action; /* enum hv_crashdump_action */
340 } __packed;
341 
342 struct hv_input_disable_hyp_ex {   /* HV_X64_INPUT_DISABLE_HYPERVISOR_EX */
343 	u64 rip;
344 	u64 arg;
345 } __packed;
346 
347 struct hv_crashdump_area {	   /* HV_CRASHDUMP_AREA */
348 	u32 version;
349 	union {
350 		u32 flags_as_uint32;
351 		struct {
352 			u32 cda_valid : 1;
353 			u32 cda_unused : 31;
354 		} __packed;
355 	};
356 	/* more unused fields */
357 } __packed;
358 
359 union hv_partition_event_input {
360 	struct hv_partition_event_root_crashdump_input crashdump_input;
361 };
362 
363 enum hv_partition_event {
364 	HV_PARTITION_EVENT_ROOT_CRASHDUMP = 2,
365 	HV_PARTITION_ALL_LOGICAL_PROCESSORS_STARTED = 4,
366 };
367 
368 struct hv_input_notify_partition_event {
369 	u32 event;      /* enum hv_partition_event */
370 	union hv_partition_event_input input;
371 } __packed;
372 
373 struct hv_input_get_logical_processor_run_time {
374 	u32 lp_index;
375 } __packed;
376 
377 struct hv_output_get_logical_processor_run_time {
378 	u64 global_time;
379 	u64 local_run_time;
380 	u64 rsvdz0;
381 	u64 hypervisor_time;
382 } __packed;
383 
384 struct hv_lp_startup_status {
385 	u64 hv_status;
386 	u64 substatus1;
387 	u64 substatus2;
388 	u64 substatus3;
389 	u64 substatus4;
390 	u64 substatus5;
391 	u64 substatus6;
392 } __packed;
393 
394 struct hv_input_add_logical_processor {
395 	u32 lp_index;
396 	u32 apic_id;
397 	struct hv_proximity_domain_info proximity_domain_info;
398 } __packed;
399 
400 struct hv_output_add_logical_processor {
401 	struct hv_lp_startup_status startup_status;
402 } __packed;
403 
404 enum {	/* HV_SUBNODE_TYPE */
405 	HV_SUBNODE_ANY		= 0,
406 	HV_SUBNODE_SOCKET,
407 	HV_SUBNODE_CLUSTER,
408 	HV_SUBNODE_L3,
409 	HV_SUBNODE_COUNT,
410 	HV_SUBNODE_INVALID	= -1
411 };
412 
413 struct hv_create_vp {	/* HV_INPUT_CREATE_VP */
414 	u64 partition_id;
415 	u32 vp_index;
416 	u8 padding[3];
417 	u8 subnode_type;
418 	u64 subnode_id;
419 	struct hv_proximity_domain_info proximity_domain_info;
420 	u64 flags;
421 } __packed;
422 
423 /* HV_INTERRUPT_TRIGGER_MODE */
424 enum hv_interrupt_trigger_mode {
425 	HV_INTERRUPT_TRIGGER_MODE_EDGE	= 0,
426 	HV_INTERRUPT_TRIGGER_MODE_LEVEL	= 1,
427 };
428 
429 /* HV_DEVICE_INTERRUPT_DESCRIPTOR */
430 struct hv_device_interrupt_descriptor {
431 	u32 interrupt_type;
432 	u32 trigger_mode;
433 	u32 vector_count;
434 	u32 reserved;
435 	struct hv_device_interrupt_target target;
436 } __packed;
437 
438 /* HV_INPUT_MAP_DEVICE_INTERRUPT */
439 struct hv_input_map_device_interrupt {
440 	u64 partition_id;
441 	u64 device_id;
442 	u32 flags;
443 	u32 base_irt_idx;
444 	struct hv_interrupt_entry logical_interrupt_entry;
445 	struct hv_device_interrupt_descriptor interrupt_descriptor;
446 } __packed;
447 
448 /* HV_OUTPUT_MAP_DEVICE_INTERRUPT */
449 struct hv_output_map_device_interrupt {
450 	struct hv_interrupt_entry interrupt_entry;
451 	u64 ext_status_deprecated[5];
452 } __packed;
453 
454 /* HV_INPUT_UNMAP_DEVICE_INTERRUPT */
455 struct hv_input_unmap_device_interrupt {
456 	u64 partition_id;
457 	u64 device_id;
458 	struct hv_interrupt_entry interrupt_entry;
459 	u32 flags;
460 } __packed;
461 
462 #define HV_SOURCE_SHADOW_NONE		    0x0
463 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE   0x1
464 
465 struct hv_send_ipi_ex { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI_EX */
466 	u32 vector;
467 	u32 reserved;
468 	struct hv_vpset vp_set;
469 } __packed;
470 
471 typedef u16 hv_pci_rid;		/* HV_PCI_RID */
472 typedef u16 hv_pci_segment;	/* HV_PCI_SEGMENT */
473 typedef u64 hv_logical_device_id;
474 union hv_pci_bdf {	/* HV_PCI_BDF */
475 	u16 as_uint16;
476 
477 	struct {
478 		u8 function : 3;
479 		u8 device : 5;
480 		u8 bus;
481 	};
482 } __packed;
483 
484 union hv_pci_bus_range {
485 	u16 as_uint16;
486 
487 	struct {
488 		u8 subordinate_bus;
489 		u8 secondary_bus;
490 	};
491 } __packed;
492 
493 enum hv_device_type {		/* HV_DEVICE_TYPE */
494 	HV_DEVICE_TYPE_LOGICAL	= 0,
495 	HV_DEVICE_TYPE_PCI	= 1,
496 	HV_DEVICE_TYPE_IOAPIC	= 2,
497 	HV_DEVICE_TYPE_ACPI	= 3,
498 };
499 
500 union hv_device_id {		/* HV_DEVICE_ID */
501 	u64 as_uint64;
502 
503 	struct {
504 		u64 reserved0 : 62;
505 		u64 device_type : 2;
506 	};
507 
508 	/* HV_DEVICE_TYPE_LOGICAL */
509 	struct {
510 		u64 id : 62;
511 		u64 device_type : 2;
512 	} logical;
513 
514 	/* HV_DEVICE_TYPE_PCI */
515 	struct {
516 		union {
517 			hv_pci_rid rid;
518 			union hv_pci_bdf bdf;
519 		};
520 
521 		hv_pci_segment segment;
522 		union hv_pci_bus_range shadow_bus_range;
523 
524 		u16 phantom_function_bits : 2;
525 		u16 source_shadow : 1;
526 
527 		u16 rsvdz0 : 11;
528 		u16 device_type : 2;
529 	} pci;
530 
531 	/* HV_DEVICE_TYPE_IOAPIC */
532 	struct {
533 		u8 ioapic_id;
534 		u8 rsvdz0;
535 		u16 rsvdz1;
536 		u16 rsvdz2;
537 
538 		u16 rsvdz3 : 14;
539 		u16 device_type : 2;
540 	} ioapic;
541 
542 	/* HV_DEVICE_TYPE_ACPI */
543 	struct {
544 		u32 input_mapping_base;
545 		u32 input_mapping_count : 30;
546 		u32 device_type : 2;
547 	} acpi;
548 } __packed;
549 
550 #endif /* _HV_HVHDK_MINI_H */
551