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