xref: /linux/include/hyperv/hvhdk_mini.h (revision d62313bdf5961b5f815f0b212f029cf146a8a804)
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 	/* Resource properties */
91 	HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING		= 0x00050005,
92 	HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION		= 0x00050017,
93 
94 	/* Compatibility properties */
95 	HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES		= 0x00060002,
96 	HV_PARTITION_PROPERTY_XSAVE_STATES                      = 0x00060007,
97 	HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE		= 0x00060008,
98 	HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY		= 0x00060009,
99 
100 	/* Extended properties with larger property values */
101 	HV_PARTITION_PROPERTY_VMM_CAPABILITIES			= 0x00090007,
102 };
103 
104 #define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT		1
105 #define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT	59
106 
107 struct hv_partition_property_vmm_capabilities {
108 	u16 bank_count;
109 	u16 reserved[3];
110 	union {
111 		u64 as_uint64[HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT];
112 		struct {
113 			u64 map_gpa_preserve_adjustable: 1;
114 			u64 vmm_can_provide_overlay_gpfn: 1;
115 			u64 vp_affinity_property: 1;
116 #if IS_ENABLED(CONFIG_ARM64)
117 			u64 vmm_can_provide_gic_overlay_locations: 1;
118 #else
119 			u64 reservedbit3: 1;
120 #endif
121 			u64 assignable_synthetic_proc_features: 1;
122 			u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT;
123 		} __packed;
124 	};
125 } __packed;
126 
127 enum hv_snp_status {
128 	HV_SNP_STATUS_NONE = 0,
129 	HV_SNP_STATUS_AVAILABLE = 1,
130 	HV_SNP_STATUS_INCOMPATIBLE = 2,
131 	HV_SNP_STATUS_PSP_UNAVAILABLE = 3,
132 	HV_SNP_STATUS_PSP_INIT_FAILED = 4,
133 	HV_SNP_STATUS_PSP_BAD_FW_VERSION = 5,
134 	HV_SNP_STATUS_BAD_CONFIGURATION = 6,
135 	HV_SNP_STATUS_PSP_FW_UPDATE_IN_PROGRESS = 7,
136 	HV_SNP_STATUS_PSP_RB_INIT_FAILED = 8,
137 	HV_SNP_STATUS_PSP_PLATFORM_STATUS_FAILED = 9,
138 	HV_SNP_STATUS_PSP_INIT_LATE_FAILED = 10,
139 };
140 
141 enum hv_system_property {
142 	/* Add more values when needed */
143 	HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15,
144 	HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21,
145 };
146 
147 enum hv_dynamic_processor_feature_property {
148 	/* Add more values when needed */
149 	HV_X64_DYNAMIC_PROCESSOR_FEATURE_MAX_ENCRYPTED_PARTITIONS = 13,
150 	HV_X64_DYNAMIC_PROCESSOR_FEATURE_SNP_STATUS = 16,
151 };
152 
153 struct hv_input_get_system_property {
154 	u32 property_id; /* enum hv_system_property */
155 	union {
156 		u32 as_uint32;
157 #if IS_ENABLED(CONFIG_X86)
158 		/* enum hv_dynamic_processor_feature_property */
159 		u32 hv_processor_feature;
160 #endif
161 		/* More fields to be filled in when needed */
162 	};
163 } __packed;
164 
165 struct hv_output_get_system_property {
166 	union {
167 		u32 scheduler_type; /* enum hv_scheduler_type */
168 #if IS_ENABLED(CONFIG_X86)
169 		u64 hv_processor_feature_value;
170 #endif
171 	};
172 } __packed;
173 
174 struct hv_input_map_stats_page {
175 	u32 type; /* enum hv_stats_object_type */
176 	u32 padding;
177 	union hv_stats_object_identity identity;
178 } __packed;
179 
180 struct hv_input_map_stats_page2 {
181 	u32 type; /* enum hv_stats_object_type */
182 	u32 padding;
183 	union hv_stats_object_identity identity;
184 	u64 map_location;
185 } __packed;
186 
187 struct hv_output_map_stats_page {
188 	u64 map_location;
189 } __packed;
190 
191 struct hv_input_unmap_stats_page {
192 	u32 type; /* enum hv_stats_object_type */
193 	u32 padding;
194 	union hv_stats_object_identity identity;
195 } __packed;
196 
197 struct hv_proximity_domain_flags {
198 	u32 proximity_preferred : 1;
199 	u32 reserved : 30;
200 	u32 proximity_info_valid : 1;
201 } __packed;
202 
203 struct hv_proximity_domain_info {
204 	u32 domain_id;
205 	struct hv_proximity_domain_flags flags;
206 } __packed;
207 
208 /* HvDepositMemory hypercall */
209 struct hv_deposit_memory {	/* HV_INPUT_DEPOSIT_MEMORY */
210 	u64 partition_id;
211 	u64 gpa_page_list[];
212 } __packed;
213 
214 struct hv_input_withdraw_memory {
215 	u64 partition_id;
216 	struct hv_proximity_domain_info proximity_domain_info;
217 } __packed;
218 
219 struct hv_output_withdraw_memory {
220 	DECLARE_FLEX_ARRAY(u64, gpa_page_list);
221 } __packed;
222 
223 /* HV Map GPA (Guest Physical Address) Flags */
224 #define HV_MAP_GPA_PERMISSIONS_NONE	       0x0
225 #define HV_MAP_GPA_READABLE		       0x1
226 #define HV_MAP_GPA_WRITABLE		       0x2
227 #define HV_MAP_GPA_KERNEL_EXECUTABLE	       0x4
228 #define HV_MAP_GPA_USER_EXECUTABLE	       0x8
229 #define HV_MAP_GPA_EXECUTABLE		       0xC
230 #define HV_MAP_GPA_PERMISSIONS_MASK	       0xF
231 #define HV_MAP_GPA_ADJUSTABLE		    0x8000
232 #define HV_MAP_GPA_NO_ACCESS		   0x10000
233 #define HV_MAP_GPA_NOT_CACHED		  0x200000
234 #define HV_MAP_GPA_LARGE_PAGE		0x80000000
235 
236 struct hv_input_map_gpa_pages {
237 	u64 target_partition_id;
238 	u64 target_gpa_base;
239 	u32 map_flags;
240 	u32 padding;
241 	u64 source_gpa_page_list[];
242 } __packed;
243 
244 union hv_gpa_page_access_state_flags {
245 	struct {
246 		u64 clear_accessed : 1;
247 		u64 set_accessed : 1;
248 		u64 clear_dirty : 1;
249 		u64 set_dirty : 1;
250 		u64 reserved : 60;
251 	} __packed;
252 	u64 as_uint64;
253 };
254 
255 struct hv_input_get_gpa_pages_access_state {
256 	u64  partition_id;
257 	union hv_gpa_page_access_state_flags flags;
258 	u64 hv_gpa_page_number;
259 } __packed;
260 
261 union hv_gpa_page_access_state {
262 	struct {
263 		u8 accessed : 1;
264 		u8 dirty : 1;
265 		u8 reserved: 6;
266 	};
267 	u8 as_uint8;
268 } __packed;
269 
270 struct hv_lp_startup_status {
271 	u64 hv_status;
272 	u64 substatus1;
273 	u64 substatus2;
274 	u64 substatus3;
275 	u64 substatus4;
276 	u64 substatus5;
277 	u64 substatus6;
278 } __packed;
279 
280 struct hv_input_add_logical_processor {
281 	u32 lp_index;
282 	u32 apic_id;
283 	struct hv_proximity_domain_info proximity_domain_info;
284 } __packed;
285 
286 struct hv_output_add_logical_processor {
287 	struct hv_lp_startup_status startup_status;
288 } __packed;
289 
290 enum {	/* HV_SUBNODE_TYPE */
291 	HV_SUBNODE_ANY		= 0,
292 	HV_SUBNODE_SOCKET,
293 	HV_SUBNODE_CLUSTER,
294 	HV_SUBNODE_L3,
295 	HV_SUBNODE_COUNT,
296 	HV_SUBNODE_INVALID	= -1
297 };
298 
299 struct hv_create_vp {	/* HV_INPUT_CREATE_VP */
300 	u64 partition_id;
301 	u32 vp_index;
302 	u8 padding[3];
303 	u8 subnode_type;
304 	u64 subnode_id;
305 	struct hv_proximity_domain_info proximity_domain_info;
306 	u64 flags;
307 } __packed;
308 
309 /* HV_INTERRUPT_TRIGGER_MODE */
310 enum hv_interrupt_trigger_mode {
311 	HV_INTERRUPT_TRIGGER_MODE_EDGE	= 0,
312 	HV_INTERRUPT_TRIGGER_MODE_LEVEL	= 1,
313 };
314 
315 /* HV_DEVICE_INTERRUPT_DESCRIPTOR */
316 struct hv_device_interrupt_descriptor {
317 	u32 interrupt_type;
318 	u32 trigger_mode;
319 	u32 vector_count;
320 	u32 reserved;
321 	struct hv_device_interrupt_target target;
322 } __packed;
323 
324 /* HV_INPUT_MAP_DEVICE_INTERRUPT */
325 struct hv_input_map_device_interrupt {
326 	u64 partition_id;
327 	u64 device_id;
328 	u32 flags;
329 	u32 base_irt_idx;
330 	struct hv_interrupt_entry logical_interrupt_entry;
331 	struct hv_device_interrupt_descriptor interrupt_descriptor;
332 } __packed;
333 
334 /* HV_OUTPUT_MAP_DEVICE_INTERRUPT */
335 struct hv_output_map_device_interrupt {
336 	struct hv_interrupt_entry interrupt_entry;
337 	u64 ext_status_deprecated[5];
338 } __packed;
339 
340 /* HV_INPUT_UNMAP_DEVICE_INTERRUPT */
341 struct hv_input_unmap_device_interrupt {
342 	u64 partition_id;
343 	u64 device_id;
344 	struct hv_interrupt_entry interrupt_entry;
345 	u32 flags;
346 } __packed;
347 
348 #define HV_SOURCE_SHADOW_NONE		    0x0
349 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE   0x1
350 
351 struct hv_send_ipi_ex { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI_EX */
352 	u32 vector;
353 	u32 reserved;
354 	struct hv_vpset vp_set;
355 } __packed;
356 
357 typedef u16 hv_pci_rid;		/* HV_PCI_RID */
358 typedef u16 hv_pci_segment;	/* HV_PCI_SEGMENT */
359 typedef u64 hv_logical_device_id;
360 union hv_pci_bdf {	/* HV_PCI_BDF */
361 	u16 as_uint16;
362 
363 	struct {
364 		u8 function : 3;
365 		u8 device : 5;
366 		u8 bus;
367 	};
368 } __packed;
369 
370 union hv_pci_bus_range {
371 	u16 as_uint16;
372 
373 	struct {
374 		u8 subordinate_bus;
375 		u8 secondary_bus;
376 	};
377 } __packed;
378 
379 enum hv_device_type {		/* HV_DEVICE_TYPE */
380 	HV_DEVICE_TYPE_LOGICAL	= 0,
381 	HV_DEVICE_TYPE_PCI	= 1,
382 	HV_DEVICE_TYPE_IOAPIC	= 2,
383 	HV_DEVICE_TYPE_ACPI	= 3,
384 };
385 
386 union hv_device_id {		/* HV_DEVICE_ID */
387 	u64 as_uint64;
388 
389 	struct {
390 		u64 reserved0 : 62;
391 		u64 device_type : 2;
392 	};
393 
394 	/* HV_DEVICE_TYPE_LOGICAL */
395 	struct {
396 		u64 id : 62;
397 		u64 device_type : 2;
398 	} logical;
399 
400 	/* HV_DEVICE_TYPE_PCI */
401 	struct {
402 		union {
403 			hv_pci_rid rid;
404 			union hv_pci_bdf bdf;
405 		};
406 
407 		hv_pci_segment segment;
408 		union hv_pci_bus_range shadow_bus_range;
409 
410 		u16 phantom_function_bits : 2;
411 		u16 source_shadow : 1;
412 
413 		u16 rsvdz0 : 11;
414 		u16 device_type : 2;
415 	} pci;
416 
417 	/* HV_DEVICE_TYPE_IOAPIC */
418 	struct {
419 		u8 ioapic_id;
420 		u8 rsvdz0;
421 		u16 rsvdz1;
422 		u16 rsvdz2;
423 
424 		u16 rsvdz3 : 14;
425 		u16 device_type : 2;
426 	} ioapic;
427 
428 	/* HV_DEVICE_TYPE_ACPI */
429 	struct {
430 		u32 input_mapping_base;
431 		u32 input_mapping_count : 30;
432 		u32 device_type : 2;
433 	} acpi;
434 } __packed;
435 
436 #endif /* _HV_HVHDK_MINI_H */
437