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
25enum 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
31enum 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 */
40enum 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
47enum 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
54union 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
85enum 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
101enum 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
115enum 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
121enum 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
127struct 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
139struct 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
148struct 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
154struct hv_output_map_stats_page {
155 u64 map_location;
156} __packed;
157
158struct 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
164struct hv_proximity_domain_flags {
165 u32 proximity_preferred : 1;
166 u32 reserved : 30;
167 u32 proximity_info_valid : 1;
168} __packed;
169
170struct hv_proximity_domain_info {
171 u32 domain_id;
172 struct hv_proximity_domain_flags flags;
173} __packed;
174
175/* HvDepositMemory hypercall */
176struct hv_deposit_memory { /* HV_INPUT_DEPOSIT_MEMORY */
177 u64 partition_id;
178 u64 gpa_page_list[];
179} __packed;
180
181struct hv_input_withdraw_memory {
182 u64 partition_id;
183 struct hv_proximity_domain_info proximity_domain_info;
184} __packed;
185
186struct 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
203struct 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
211union 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
222struct 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
228union 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
237struct 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
247struct 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
253struct hv_output_add_logical_processor {
254 struct hv_lp_startup_status startup_status;
255} __packed;
256
257enum { /* 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
266struct 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 */
277enum 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 */
283struct 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 */
292struct 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 */
302struct hv_output_map_device_interrupt {
303 struct hv_interrupt_entry interrupt_entry;
304 u64 ext_status_deprecated[5];
305} __packed;
306
307/* HV_INPUT_UNMAP_DEVICE_INTERRUPT */
308struct hv_input_unmap_device_interrupt {
309 u64 partition_id;
310 u64 device_id;
311 struct hv_interrupt_entry interrupt_entry;
312 u32 flags;
313} __packed;
314
315#define HV_SOURCE_SHADOW_NONE 0x0
316#define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1
317
318struct hv_send_ipi_ex { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI_EX */
319 u32 vector;
320 u32 reserved;
321 struct hv_vpset vp_set;
322} __packed;
323
324typedef u16 hv_pci_rid; /* HV_PCI_RID */
325typedef u16 hv_pci_segment; /* HV_PCI_SEGMENT */
326typedef u64 hv_logical_device_id;
327union hv_pci_bdf { /* HV_PCI_BDF */
328 u16 as_uint16;
329
330 struct {
331 u8 function : 3;
332 u8 device : 5;
333 u8 bus;
334 };
335} __packed;
336
337union hv_pci_bus_range {
338 u16 as_uint16;
339
340 struct {
341 u8 subordinate_bus;
342 u8 secondary_bus;
343 };
344} __packed;
345
346enum hv_device_type { /* HV_DEVICE_TYPE */
347 HV_DEVICE_TYPE_LOGICAL = 0,
348 HV_DEVICE_TYPE_PCI = 1,
349 HV_DEVICE_TYPE_IOAPIC = 2,
350 HV_DEVICE_TYPE_ACPI = 3,
351};
352
353union hv_device_id { /* HV_DEVICE_ID */
354 u64 as_uint64;
355
356 struct {
357 u64 reserved0 : 62;
358 u64 device_type : 2;
359 };
360
361 /* HV_DEVICE_TYPE_LOGICAL */
362 struct {
363 u64 id : 62;
364 u64 device_type : 2;
365 } logical;
366
367 /* HV_DEVICE_TYPE_PCI */
368 struct {
369 union {
370 hv_pci_rid rid;
371 union hv_pci_bdf bdf;
372 };
373
374 hv_pci_segment segment;
375 union hv_pci_bus_range shadow_bus_range;
376
377 u16 phantom_function_bits : 2;
378 u16 source_shadow : 1;
379
380 u16 rsvdz0 : 11;
381 u16 device_type : 2;
382 } pci;
383
384 /* HV_DEVICE_TYPE_IOAPIC */
385 struct {
386 u8 ioapic_id;
387 u8 rsvdz0;
388 u16 rsvdz1;
389 u16 rsvdz2;
390
391 u16 rsvdz3 : 14;
392 u16 device_type : 2;
393 } ioapic;
394
395 /* HV_DEVICE_TYPE_ACPI */
396 struct {
397 u32 input_mapping_base;
398 u32 input_mapping_count : 30;
399 u32 device_type : 2;
400 } acpi;
401} __packed;
402
403#endif /* _HV_HVHDK_MINI_H */
404