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